XLINQ - возможно ли иметь условия в запросе? - PullRequest
0 голосов
/ 18 августа 2010

Пытаясь научить себя ASP.NET и дизайну OO в целом, я решил сделать простую веб-игру.Это элементарная ролевая игра, в которой игрок может создать персонажа определенной профессии.Эти профессии дают персонажу определенные виды атак, и некоторые из этих способностей имеют статусные эффекты (яд на врагов, защитные баффы для персонажа и т. Д.).

Данные профессии хранятся в файлах XML.Я подумал, что это будет лучший способ сделать его расширяемым в будущем.Если бы я (или кто-либо еще) хотел добавить / изменить профессии, все, что им нужно было бы сделать, это отредактировать или добавить файлы XML.

Итак, со всем этим я проверял, какуспешно извлекать различные атаки из XML-файлов моей профессии.Как я уже говорил, некоторые из них имеют статусные эффекты, но не все.Ниже приведена тестовая профессия:

<?xml version="1.0" encoding="utf-8" ?>
<CharacterClass>
  <Name>Hacker</Name>
  <InitialStats>
    <HP>10</HP>
    <TP>25</TP>
    <BaseDMG>2</BaseDMG>
    <BaseDefense>25</BaseDefense>
  </InitialStats>
  <LevelingStats>
    <HPMultiplier>2</HPMultiplier>
    <TPMultiplier>4</TPMultiplier>
    <BaseDMGMultiplier>2</BaseDMGMultiplier>
    <DefenseIncrease>5</DefenseIncrease>
  </LevelingStats>
  <Attacks>
    <Attack>
      <AttackName>Basic Attack</AttackName>
      <AttackLevel>1</AttackLevel>
      <TPCost>0</TPCost>
      <DMGModifier>1</DMGModifier>
      <HitPenalty>0</HitPenalty>
      <StatusEffect>
        <Type>null</Type>
        <Duration>0</Duration>
        <Level>0</Level>
      </StatusEffect>
    </Attack>
  </Attacks>
</CharacterClass>

Как видите, каждая профессия наносит различные атаки, которые являются объектами в моей системе.Эффекты статуса также являются объектами - фактически они являются наблюдателями, которые могут быть прикреплены к персонажам.

Моя проблема связана с атаками, которые не имеют эффектов статуса, как, например, Базовая атака, показанная выше.У меня есть частичное решение, но оно кажется не элегантным:

public partial class xmltest : System.Web.UI.Page
{
    public StatusEffect CreateStatusEffect(XElement se)
    {
        if (se.Element("Type") != null)
        {
            StatusEffect result = (StatusEffect)Assembly.GetExecutingAssembly().CreateInstance(((string)se.Element("Type")));
            result.Name = (string)se.Element("Name");
            result.Duration = (int)se.Element("Duration");
            result.Level = (int)se.Element("Level");

            return result;
        }
        else
        {
            throw new Exception();
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        List<Attack> charAttacks = (from a in XElement.Load(MapPath("CharacterClasses/Hacker.xml")).Element("Attacks").Elements("Attack")
                                    let se = a.Element("StatusEffect")
                                    select new Attack
                                    (
                                        (string)a.Element("AttackName"),
                                        (int)a.Element("AttackLevel"),
                                        (int)a.Element("TPCost"),
                                        (double)a.Element("DMGModifier"),
                                        (double)a.Element("HitPenalty"),
                                        CreateStatusEffect(se)
                                    )).ToList();


        foreach (Attack attack in charAttacks)
        {
            output.InnerHtml = attack.Name + "<br />";
        }
    }
}

Могу ли я:

  1. Проверить наличие эффекта состояния
  2. Построить его, если он существует

В самом запросе LINQ?Игра с текущими исполняемыми сборками регистрируется как неприятный запах кода для меня.Я уверен, что упускаю что-то очевидное.

1 Ответ

1 голос
/ 21 августа 2010

Попробуйте это

XDocument doc = XDocument.Load( MapPath("CharacterClasses/Hacker.xml"));   
List<Attack> charAttacks = (from attack in doc.Descendants("Attack")
                                    select new Attack()
                                    {
                                        AttackName = (string)attack.Element("AttackName") ?? null,
                                        AttackLevel = (int)attack.Element("AttackLevel"),
                                        TPCost = (int)attack.Element("TPCost"),
                                        DMGModifier = (double)attack.Element("DMGModifier"),
                                        HitPenalty = (double)attack.Element("HitPenalty"),
                                        StatusEffect = attack.Element("StatusEffect") == null ? null :
                                                              new StatusEffect()
                                                              {
                                                                  Name = (string)attack.Element("StatusEffect").Element("Name"),
                                                                  Duration = (int)attack.Element("StatusEffect").Element("Duration"),
                                                                  Level = (int)attack.Element("StatusEffect").Element("Level")
                                                              }
                                    }).ToList();`enter code here`

Определения классов для Attack и StatusEffect должны иметь открытые свойства, как показано ниже для работы приведенного выше оператора linq

class Attack
    {
        public string AttackName { get; set; }
        public int AttackLevel { get; set; }
        public int TPCost { get; set; }
        public double DMGModifier { get; set; }
        public double HitPenalty { get; set; }
        public StatusEffect StatusEffect { get; set; }
    }

    class StatusEffect
    {
        public string Name { get; set; }
        public int Duration { get; set; }
        public int Level { get; set; }
    }
...