td.AddField("name", FieldDescription(((char *)&i.name) - ((char *)&i), stringId, true));
td.AddField("cost", FieldDescription(((char *)&i.cost) - ((char *)&i), numberId, false));
td.AddField("targets", FieldDescription(((char *)&i.targetingMode) - ((char *)&i), targetsId, false));
- td.AddField("physical", FieldDescription(((char *)&i.isPhysical) - ((char *)&i), boolId, true));
+ td.AddField("type", FieldDescription(((char *)&i.isPhysical) - ((char *)&i), boolId, true));
}
}
, value(0)
, properties(0)
-, usability(0)
-, equipable(0) {
+, equipability(0)
+
+, mostUseful(false)
+, equipable(false)
+, cursed(false)
+, fruit(false)
+, scenario(false)
+, status(false)
+, battle(false) {
}
Item i;
int animationId(TypeDescription::GetTypeId("Animation"));
+ int boolId(TypeDescription::GetTypeId("Boolean"));
int ikariId(TypeDescription::GetTypeId("Ikari"));
int spriteId(TypeDescription::GetTypeId("Sprite"));
int stringId(TypeDescription::GetTypeId("String"));
td.AddField("name", FieldDescription(((char *)&i.name) - ((char *)&i), stringId, true));
td.AddField("menuicon", FieldDescription(((char *)&i.menuIcon) - ((char *)&i), spriteId, true));
- // TODO: implement flags/fields (e.g. for usability)
+
+ td.AddField("mostUseful", FieldDescription(((char *)&i.mostUseful) - ((char *)&i), boolId, false));
+ td.AddField("equipable", FieldDescription(((char *)&i.equipable) - ((char *)&i), boolId, false));
+ td.AddField("cursed", FieldDescription(((char *)&i.cursed) - ((char *)&i), boolId, false));
+ td.AddField("fruit", FieldDescription(((char *)&i.fruit) - ((char *)&i), boolId, false));
+ td.AddField("scenario", FieldDescription(((char *)&i.scenario) - ((char *)&i), boolId, false));
+ td.AddField("status", FieldDescription(((char *)&i.status) - ((char *)&i), boolId, false));
+ td.AddField("battle", FieldDescription(((char *)&i.battle) - ((char *)&i), boolId, false));
+
td.AddField("targets", FieldDescription(((char *)&i.targettingMode) - ((char *)&i), targetsId, false));
td.AddField("ikari", FieldDescription(((char *)&i.ikari) - ((char *)&i), ikariId, true));
td.AddField("attackanimation", FieldDescription(((char *)&i.attackAnimation) - ((char *)&i), animationId, true));
public:
const char *Name() const { return name; }
- bool IsMostUseful() const { return usability & USABILITY_MOST_USEFUL; }
- bool IsEquipable() const { return usability & USABILITY_EQUIPABLE; }
- bool IsCursed() const { return usability & USABILITY_CURSED; }
- bool IsFruit() const { return usability & USABILITY_FRUIT; }
- bool IsScenario() const { return usability & USABILITY_SCENARIO; }
+ bool IsMostUseful() const { return mostUseful; }
+ bool IsEquipable() const { return equipable; }
+ bool IsCursed() const { return cursed; }
+ bool IsFruit() const { return fruit; }
+ bool IsScenario() const { return scenario; }
bool CanSell() const { return !IsScenario(); }
bool CanDrop() const { return !IsScenario(); }
- bool CanUseOnStatusScreen() const { return usability & USABILITY_STATUS; }
- bool CanUseInBattle() const { return usability & USABILITY_BATTLE; }
+ bool CanUseOnStatusScreen() const { return status; }
+ bool CanUseInBattle() const { return battle; }
TargetingMode &GetTargetingMode() { return targettingMode; }
const TargetingMode &GetTargetingMode() const { return targettingMode; }
Uint16 Value() const { return value; }
- bool CanEquipWeapon() const { return equipable & EQUIPPABLE_WEAPON; }
- bool CanEquipArmor() const { return equipable & EQUIPPABLE_ARMOR; }
- bool CanEquipShield() const { return equipable & EQUIPPABLE_SHIELD; }
- bool CanEquipHelmet() const { return equipable & EQUIPPABLE_HELMET; }
- bool CanEquipRing() const { return equipable & EQUIPPABLE_RING; }
- bool CanEquipJewel() const { return equipable & EQUIPPABLE_JEWEL; }
+ bool CanEquipWeapon() const { return equipability & EQUIPPABLE_WEAPON; }
+ bool CanEquipArmor() const { return equipability & EQUIPPABLE_ARMOR; }
+ bool CanEquipShield() const { return equipability & EQUIPPABLE_SHIELD; }
+ bool CanEquipHelmet() const { return equipability & EQUIPPABLE_HELMET; }
+ bool CanEquipRing() const { return equipability & EQUIPPABLE_RING; }
+ bool CanEquipJewel() const { return equipability & EQUIPPABLE_JEWEL; }
HeroGroup &EquipableBy() { return equipableBy; }
const HeroGroup &EquipableBy() const { return equipableBy; }
public:
void SetName(const char *n) { name = n; }
void SetMenuIcon(const graphics::Sprite *icon) { menuIcon = icon; }
- void SetUsableInBattle() { usability |= USABILITY_BATTLE; }
+ void SetUsableInBattle() { battle = true; }
void SetIkari(const Ikari *i) { ikari = i; }
void SetAttackAnimation(graphics::Animation *a) { attackAnimation = a; }
static void CreateTypeDescription();
private:
- enum Usability {
- USABILITY_MOST_USEFUL = 1,
- USABILITY_EQUIPABLE = 2,
- // USABILITY_UNUSED = 4,
- USABILITY_CURSED = 8,
- USABILITY_FRUIT = 16,
- USABILITY_SCENARIO = 32,
- USABILITY_STATUS = 64,
- USABILITY_BATTLE = 128,
- };
enum Equipable {
EQUIPPABLE_NONE = 0,
EQUIPPABLE_WEAPON = 1,
Uint16 value;
Uint16 properties;
- Uint8 usability;
TargetingMode targettingMode;
- Uint8 equipable;
+ Uint8 equipability;
HeroGroup equipableBy;
+ // TODO: turn these back into bits as soon as fields are implemented in the loader
+ bool mostUseful;
+ bool equipable;
+ bool cursed;
+ bool fruit;
+ bool scenario;
+ bool status;
+ bool battle;
+
};
}
void TargetingMode::CreateTypeDescription() {
TargetingMode t;
+ int boolId(TypeDescription::GetTypeId("Boolean"));
+ int numberId(TypeDescription::GetTypeId("Number"));
+
TypeDescription &td(TypeDescription::CreateOrGet("TargetingMode"));
td.SetSize(sizeof(TargetingMode));
- // TODO: fields
+ td.AddField("faction", FieldDescription(((char *)&t.ally) - ((char *)&t), boolId, true));
+ td.AddField("mode", FieldDescription(((char *)&t.mode) - ((char *)&t), numberId, true));
}
}
class TargetingMode {
public:
- TargetingMode() : mode(0) { }
+ TargetingMode() : mode(0), ally(true) { }
public:
- bool TargetsEnemy() const { return (mode & FACTION_MASK) == ENEMY; }
- bool TargetsAlly() const { return (mode & FACTION_MASK) == ALLY; }
- bool TargetsAll() const { return (mode & COUNT_MASK) == ALL; }
- bool TargetsMultiple() const { return (mode & COUNT_MASK) == MULTIPLE; }
- bool TargetsSingle() const { return (mode & COUNT_MASK) == SINGLE; }
-
- void TargetAll() { mode = (mode & FACTION_MASK) | ALL; }
- void TargetMultiple() { mode = (mode & FACTION_MASK) | MULTIPLE; }
- void TargetSingle() { mode = (mode & FACTION_MASK) | SINGLE; }
- void TargetAlly() { mode = ALLY | (mode & COUNT_MASK); }
- void TargetEnemy() { mode = ENEMY | (mode & COUNT_MASK); }
-
- void TargetAllEnemies() { mode = ENEMY | ALL; }
- void TargetMultipleEnemies() { mode = ENEMY | MULTIPLE; }
- void TargetSingleEnemy() { mode = ENEMY | SINGLE; }
- void TargetAllAllies() { mode = ALLY | ALL; }
- void TargetMultipleAllies() { mode = ALLY | MULTIPLE; }
- void TargetSingleAlly() { mode = ALLY | SINGLE; }
+ bool TargetsEnemy() const { return !ally; }
+ bool TargetsAlly() const { return ally; }
+ bool TargetsAll() const { return mode == ALL; }
+ bool TargetsMultiple() const { return mode == MULTIPLE; }
+ bool TargetsSingle() const { return mode == SINGLE; }
+
+ void TargetAll() { mode = ALL; }
+ void TargetMultiple() { mode = MULTIPLE; }
+ void TargetSingle() { mode = SINGLE; }
+ void TargetAlly() { ally = true; }
+ void TargetEnemy() { ally = false; }
static void CreateTypeDescription();
private:
enum {
ALL = 0,
- ALLY = 0,
MULTIPLE = 1,
SINGLE = 2,
- COUNT_MASK = 127,
- ENEMY = 128,
- FACTION_MASK = 128,
};
- Uint8 mode;
+ int mode;
+ bool ally;
};
td.SetSize(sizeof(ComplexAnimation));
td.AddSupertype(animationId, ((char *)a) - ((char *)&ca));
+ Animation::AddFields(td, ca, ((char *)a) - ((char *)&ca));
td.AddField("frames", FieldDescription(((char *)&ca.frames) - ((char *)&ca), frameId, true, true));
TypeDescription &td(TypeDescription::CreateOrGet("Frame"));
td.SetSize(sizeof(Frame));
- td.AddField("surface", FieldDescription(((char *)&f.surface) - ((char *)&f), imageId, true));
- td.AddField("borderSize", FieldDescription(((char *)&f.borderSize) - ((char *)&f), vectorId, false));
- td.AddField("repeatSize", FieldDescription(((char *)&f.repeatSize) - ((char *)&f), vectorId, false));
+ td.AddField("image", FieldDescription(((char *)&f.surface) - ((char *)&f), imageId, true));
+ td.AddField("border", FieldDescription(((char *)&f.borderSize) - ((char *)&f), vectorId, false));
+ td.AddField("repeat", FieldDescription(((char *)&f.repeatSize) - ((char *)&f), vectorId, false));
td.AddField("offset", FieldDescription(((char *)&f.offset) - ((char *)&f), vectorId, false));
}
Parser("test-data/ikaris.l2s", source).Parse();
Parser("test-data/items.l2s", source).Parse();
Parser("test-data/spells.l2s", source).Parse();
+ Parser("test-data/constants.l2s", source).Parse();
Interpreter intp(source);
intp.ReadSource();
--- /dev/null
+// TargetingMode
+Boolean ally
+Boolean enemy
+
+Number all
+Number single
+Number multiple
+
+// Ikari
+Boolean magical
+Boolean physical
--- /dev/null
+// TargetingMode
+export Boolean ally true
+export Boolean enemy false
+
+export Number all 0
+export Number multiple 1
+export Number single 2
+
+// Ikari
+export Boolean magical false
+export Boolean physical true
+include "constants.l2h"
+
export Ikari boomerangIkari {
name: "Boomerang",
cost: 164,
targets: TargetingMode {
- ally: true,
- all: true
+ faction: ally,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari courageIkari {
name: "Courage",
cost: 64,
targets: TargetingMode {
- ally: true,
- multiple: true
+ faction: ally,
+ mode: multiple
},
- magical: true
+ type: magical
}
export Ikari crisisCureIkari {
name: "Crisis cure",
cost: 164,
targets: TargetingMode {
- ally: true,
- all: true
+ faction: ally,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari destroyIkari {
name: "Destroy",
cost: 128,
targets: TargetingMode {
- enemy: true,
- multiple: true
+ faction: enemy,
+ mode: multiple
},
- magical: true
+ type: magical
}
export Ikari diveIkari {
name: "Dive",
cost: 128,
targets: TargetingMode {
- enemy: true,
- single: true
+ faction: enemy,
+ mode: single
},
- physical: true
+ type: physical
}
export Ikari dragonRushIkari {
name: "Dragon rush",
cost: 164,
targets: TargetingMode {
- enemy: true,
- single: true
+ faction: enemy,
+ mode: single
},
- physical: true
+ type: physical
}
export Ikari fakeIkari {
name: "Fake",
cost: 32,
targets: TargetingMode {
- ally: true,
- single: true
+ faction: ally,
+ mode: single
},
- magical: true
+ type: magical
}
export Ikari firestormIkari {
name: "Firestorm",
cost: 224,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- physical: true
+ type: physical
}
export Ikari forcefieldIkari {
name: "Forcefield",
cost: 64,
targets: TargetingMode {
- ally: true,
- all: true
+ faction: ally,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari gloomyIkari {
name: "Gloomy",
cost: 164,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari ironBarrierIkari {
name: "Iron barrier",
cost: 255,
targets: TargetingMode {
- ally: true,
- all: true
+ faction: ally,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari lightGuardIkari {
name: "Light guard",
cost: 128,
targets: TargetingMode {
- ally: true,
- all: true
+ faction: ally,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari magicCureIkari {
name: "Magic cure",
cost: 128,
targets: TargetingMode {
- ally: true,
- single: true
+ faction: ally,
+ mode: single
},
- magical: true
+ type: magical
}
export Ikari slowIkari {
name: "Slow",
cost: 196,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- physical: true
+ type: physical
}
export Ikari suddenCureIkari {
name: "Sudden cure",
cost: 96,
targets: TargetingMode {
- ally: true,
- all: true
+ faction: ally,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari tenLeggerIkari {
name: "Ten-legger",
cost: 164,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- physical: true
+ type: physical
}
export Ikari thundershriekIkari {
name: "Thundershriek",
cost: 224,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- physical: true
+ type: physical
}
export Ikari torrentIkari {
name: "Torrent",
cost: 224,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- physical: true
+ type: physical
}
export Ikari trickIkari {
name: "Trick",
cost: 32,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- magical: true
+ type: magical
}
export Ikari vulnerableIkari {
name: "Vulnerable",
cost: 196,
targets: TargetingMode {
- enemy: true,
- all: true
+ faction: enemy,
+ mode: all
},
- physical: true
+ type: physical
}
+include "constants.l2h"
include "ikaris.l2h"
export Sprite potionIcon {
menuicon: potionIcon,
battle: true,
targets: TargetingMode {
- ally: true,
- single: true
+ faction: ally,
+ mode: single
}
}
export Item eagleRockItem {
menuicon: potionIcon,
battle: true,
targets: TargetingMode {
- ally: true,
- single: true
+ faction: ally,
+ mode: single
}
}
export Item holyCapItem {
menuicon: swordIcon,
ikari: dragonRushIkari,
targets: TargetingMode {
- enemy: true,
- single: true
+ faction: enemy,
+ mode: single
}
}
export Item magicJarItem {
menuicon: potionIcon,
battle: true,
targets: TargetingMode {
- ally: true,
- single: true
+ faction: ally,
+ mode: single
}
}
export Item megaShieldItem {
menuicon: ballIcon,
battle: true,
targets: TargetingMode {
- enemy: true,
- single: true
+ faction: enemy,
+ mode: single
}
}
export Item sProRingItem {
menuicon: axIcon,
ikari: torrentIkari,
targets: TargetingMode {
- enemy: true,
- single: true
+ faction: enemy,
+ mode: single
}
}
export Item zircoGlovesItem {
menuicon: swordIcon,
battle: false,
targets: TargetingMode {
- enemy: true,
- single: true
+ faction: enemy,
+ mode: single
},
ikari: firestormIkari,
attackanimation: swordAttackAnimation
name: "Zirco whip",
menuicon: rodIcon,
targets: TargetingMode {
- enemy: true,
- single: true
+ faction: enemy,
+ mode: single
},
ikari: thundershriekIkari
}
+include "constants.l2h"
+
export Spell championSpell {
name: "Champion",
cost: 16,
battle: true,
targets: TargetingMode {
- ally: true,
- multiple: true
+ faction: ally,
+ mode: multiple
}
}
cost: 10,
battle: true,
targets: TargetingMode {
- ally: true,
- multiple: true
+ faction: ally,
+ mode: multiple
}
}
cost: 3,
battle: true,
targets: TargetingMode {
- ally: true,
- multiple: true
+ faction: ally,
+ mode: multiple
}
}
cost: 8,
battle: true,
targets: TargetingMode {
- ally: true,
- multiple: true
+ faction: ally,
+ mode: multiple
}
}
cost: 30,
battle: true,
targets: TargetingMode {
- ally: true,
- multiple: true
+ faction: ally,
+ mode: multiple
}
}