Отлично! Друзья, я вам буду очень признателен за любую наводку на более "красивое" решение.
Я попытался максимально компактно и доходчиво сформулировать ниже, почему у меня активно применяются строковые ID.
Класс игрового действия состоит из 3-х компонентов: справочных данных (ActionData), а также 2-х персонажей, один из которых - "актор" (кто активно действует), а второй - "реципиент" (кто принимает эффект от действия). Вот смотрите кусочек класса ActionEntity:
Код AS3:
protected var _actionData: ADEntity; // Данные выполняемого действия
protected var _actor: Character; // Актор - активный участник, совершающий действие
protected var _recipient: Character; // Реципиент - пассивный участник, получающий эффект от действия
public function ActionEntity(data: ADEntity, character1: Character, character2: Character = null)
{
_actionData = data;
this.recognizeRoles(character1, character2);
}
Обратите внимание, что если, например, действие рассчитано на одного персонажа (например, применить на себя какой-нибудь предмет), то в таком случае в конструктор будет передан один персонаж, который будет и актором, и реципиентом. С этим разбирается метод recognizeRoles(). Он запускается прямо в конструкторе и сохраняет полученных персонажей в абстрактных переменных _actor и _recipient.
ActionData (наследник класса ADEntity) - содержит "справочные" данные действия. Они неизменны, и теоретически их можно (и наверное нужно) вообще из кода перенести куда-нибудь, но сейчас не об этом. Важно, что там формулируются условия нескольких видов: критические (при их невыполнении действие не будет создано), видимости (действие не будет выведено игроку) и активности (действие будет неактивно). Вот как это сделано сейчас:
Код AS3:
public class ADEntity
{
protected var _criticalConditions: Vector.<ACEntity> = new Vector.<ACEntity>;
protected var _visibleConditions: Vector.<ACEntity> = new Vector.<ACEntity>;
protected var _activeConditions: Vector.<ACEntity> = new Vector.<ACEntity>;
}
В каждом векторе - набор одновременно выполняемых условий - наследники класса ACEntity. В своём предыдущем сообщении я приводил код одного из его наследников - класса ACPropEquality, проверяющего свойство на равенство указанному значению.
Вот маленький кусочек кода, где создаётся действие рукопашной атаки:
Код AS3:
_act = new ADDoubleMelee(ActionIDs.MELEE);
_act.criticalConditions = new <ACEntity>
[
new ACPropEquality(ActionIDs.OWNER_ACTOR, ChIDs.RPG_CLASS, ChIDs.CLASS_FIGHTER)
];
Загвоздка в том, что, будучи прописанными в классе ADEntity, условия "не знают" и "не могут знать", что за действующие лица попадут в конструктор ActionEntity. Как мне сформулировать необходимость проверки каких-то свойств экземпляров Character в классе, не имеющим на них ссылок. Вот я и выкрутился со строковыми идентификаторами.
В классе ActionEntity запуск проверки условий выглядит так:
Код AS3:
public function testVisibleConditions() : Boolean
{
for each (var cond: ACEntity in this._actionData.visibleConditions)
{
if (!cond.testCondition(this)) return false;
}
return true;
}
Если сможете сказать, как в таком раскладе обойтись без использования строковых ID, я буду очень благодарен.
Добавлено через 21 час 11 минут
Посидел-подумал... Вот такой вариант проверки условий придумался без использования строковых идентификаторов.
Код AS3:
public class ConditionStrength
{
private var _measureMin: Number;
private var _measureMax: Number;
public function ConditionStrength(measureMin: Number = 0, measureMax: Number = 0)
{
_measureMin = measureMin;
_measureMax = measureMax;
}
public function testCondition(ch: Character) : Boolean
{
if (ch.strength >= _measureMin && ch.strength < _measureMax) return true;
return false;
}
}
Что скажете?