#include "Inventory.h"
+#include "Item.h"
+
+#include <algorithm>
+
+
namespace common {
Inventory::Inventory() {
return !ItemAt(offset);
}
+
+void Inventory::Sort() {
+ std::sort(entries, entries + 96, Entry::Less);
+}
+
+bool Inventory::Entry::Less(const Entry &lhs, const Entry &rhs) {
+ if (lhs.item) {
+ if (rhs.item) {
+ return Item::Less(*lhs.item, *rhs.item);
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+}
+
}
const Item *ItemAt(int offset) const { return entries[offset].item; }
int ItemCountAt(int offset) const { return entries[offset].count; }
+ void Sort();
+
private:
struct Entry {
Entry() : item(0), count(0) { }
const Item *item;
Uint8 count;
+ static bool Less(const Entry &, const Entry &);
};
private:
, equipability(0)
, mostUseful(false)
-, equipable(false)
, cursed(false)
, fruit(false)
, scenario(false)
td.AddField("menuicon", FieldDescription(((char *)&i.menuIcon) - ((char *)&i), Sprite::TYPE_ID).SetReferenced().SetDescription("icon that is displayed in menus"));
td.AddField("mostUseful", FieldDescription(((char *)&i.mostUseful) - ((char *)&i), Interpreter::BOOLEAN_ID));
- td.AddField("equipable", FieldDescription(((char *)&i.equipable) - ((char *)&i), Interpreter::BOOLEAN_ID));
td.AddField("cursed", FieldDescription(((char *)&i.cursed) - ((char *)&i), Interpreter::BOOLEAN_ID));
td.AddField("fruit", FieldDescription(((char *)&i.fruit) - ((char *)&i), Interpreter::BOOLEAN_ID));
td.AddField("scenario", FieldDescription(((char *)&i.scenario) - ((char *)&i), Interpreter::BOOLEAN_ID));
td.AddField("targets", FieldDescription(((char *)&i.targettingMode) - ((char *)&i), TargetingMode::TYPE_ID).SetDescription("how target selection is to be performed"));
td.AddField("ikari", FieldDescription(((char *)&i.ikari) - ((char *)&i), Ikari::TYPE_ID).SetReferenced().SetDescription("ikari attack of the item (sensible only for equipment)"));
td.AddField("attackanimation", FieldDescription(((char *)&i.attackAnimation) - ((char *)&i), Animation::TYPE_ID).SetReferenced().SetDescription("animation that is run when the item is used for attacking"));
+ td.AddField("equipability", FieldDescription(((char *)&i.equipability) - ((char *)&i), Interpreter::NUMBER_ID).SetDescription("how this item can be equipped"));
}
void Item::Construct(void *data) {
new (data) Item;
}
+
+bool Item::Less(const Item &lhs, const Item &rhs) {
+ if (lhs.IsMostUseful()) {
+ return !rhs.IsMostUseful();
+ }
+ if (lhs.IsEquipable()) {
+ if (rhs.IsMostUseful()) {
+ return false;
+ }
+ if (!rhs.IsEquipable()) {
+ return true;
+ }
+ return lhs.equipability < rhs.equipability;
+ }
+ if (lhs.IsFruit()) {
+ if (rhs.IsMostUseful() || rhs.IsEquipable()) {
+ return true;
+ }
+ return !rhs.IsFruit();
+ }
+ return false;
+}
+
}
const char *Name() const { return name; }
bool IsMostUseful() const { return mostUseful; }
- bool IsEquipable() const { return equipable; }
+ bool IsEquipable() const { return equipability; }
bool IsCursed() const { return cursed; }
bool IsFruit() const { return fruit; }
bool IsScenario() const { return scenario; }
bool HasBattleAnimation() const { return properties & PROPERTY_HAS_BATTLE_ANIMATION; }
bool HasIkariEffect() const { return properties & PROPERTY_HAS_IKARI_EFFECT; }
+ static bool Less(const Item &, const Item &);
+
// temporary setters
public:
void SetName(const char *n) { name = n; }
Uint16 properties;
TargetingMode targettingMode;
- Uint8 equipability;
+ int 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;
Boolean magical
Boolean physical
+// Items
+Number weapon
+Number armor
+Number shield
+Number helmet
+Number ring
+Number jewel
+
// Trigger type
Number triggerNorth
Number triggerEast
export Boolean magical false
export Boolean physical true
+// Items
+export Number weapon 1
+export Number armor 2
+export Number shield 4
+export Number helmet 8
+export Number ring 16
+export Number jewel 32
+
// Trigger type
export Number triggerNorth 0
export Number triggerEast 1
targets: TargetingMode {
faction: ally,
mode: single
- }
+ },
+ mostUseful: true
}
export Item eagleRockItem {
name: "Eagle rock",
menuicon: jewelIcon,
- ikari: diveIkari
+ ikari: diveIkari,
+ equipability: jewel
}
export Item escapeItem {
name: "Escape",
- battle: false
+ battle: false,
+ mostUseful: true
}
export Item evilJewelItem {
name: "Evil jewel",
menuicon: jewelIcon,
- ikari: gloomyIkari
+ ikari: gloomyIkari,
+ equipability: jewel
}
export Item ghostRingItem {
name: "Ghost ring",
menuicon: ringIcon,
- ikari: destroyIkari
+ ikari: destroyIkari,
+ equipability: ring
}
export Item hiPotionItem {
name: "Hi-Potion",
targets: TargetingMode {
faction: ally,
mode: single
- }
+ },
+ mostUseful: true
}
export Item holyCapItem {
name: "Holy cap",
menuicon: helmetIcon,
- ikari: vulnerableIkari
+ ikari: vulnerableIkari,
+ equipability: helmet
}
export Item holyRobeItem {
name: "Holy robe",
menuicon: armorIcon,
- ikari: crisisCureIkari
+ ikari: crisisCureIkari,
+ equipability: armor
}
export Item holyShieldItem {
name: "Holy shield",
menuicon: shieldIcon,
- ikari: lightGuardIkari
+ ikari: lightGuardIkari,
+ equipability: shield
}
export Item krakenRockItem {
name: "Kraken rock",
menuicon: jewelIcon,
- ikari: tenLeggerIkari
+ ikari: tenLeggerIkari,
+ equipability: jewel
}
export Item legendHelmItem {
name: "Legend helm",
menuicon: helmetIcon,
- ikari: boomerangIkari
+ ikari: boomerangIkari,
+ equipability: helmet
}
export Item lizardBlowItem {
name: "Lizard blow",
targets: TargetingMode {
faction: enemy,
mode: single
- }
+ },
+ equipability: weapon
}
export Item magicJarItem {
name: "Magic jar",
targets: TargetingMode {
faction: ally,
mode: single
- }
+ },
+ mostUseful: true
}
export Item megaShieldItem {
name: "Mega shield",
menuicon: shieldIcon,
- ikari: ironBarrierIkari
+ ikari: ironBarrierIkari,
+ equipability: shield
}
export Item powerPotionItem {
name: "Power potion",
menuicon: potionIcon,
- battle: false
+ battle: false,
+ mostUseful: true
}
export Item powerRingItem {
name: "Power ring",
menuicon: ringIcon,
- ikari: trickIkari
+ ikari: trickIkari,
+ equipability: ring
}
export Item rocketRingItem {
name: "Rocket ring",
menuicon: ringIcon,
- ikari: fakeIkari
+ ikari: fakeIkari,
+ equipability: ring
}
export Item sleepBallItem {
name: "Sleep ball",
targets: TargetingMode {
faction: enemy,
mode: single
- }
+ },
+ mostUseful: true
}
export Item sProRingItem {
name: "S-pro ring",
menuicon: ringIcon,
- ikari: courageIkari
+ ikari: courageIkari,
+ equipability: ring
}
export Item zircoAxItem {
name: "Zirco ax",
targets: TargetingMode {
faction: enemy,
mode: single
- }
+ },
+ equipability: weapon
}
export Item zircoGlovesItem {
name: "Zirco gloves",
menuicon: shieldIcon,
- ikari: forcefieldIkari
+ ikari: forcefieldIkari,
+ equipability: shield
}
export Item zircoHelmetItem {
name: "Zirco helmet",
menuicon: helmetIcon,
- ikari: slowIkari
+ ikari: slowIkari,
+ equipability: helmet
}
export Item zirconArmorItem {
name: "Zircon armor",
menuicon: armorIcon,
battle: false,
- ikari: magicCureIkari
+ ikari: magicCureIkari,
+ equipability: armor
}
export Item zirconPlateItem {
name: "Zircon plate",
menuicon: armorIcon,
- ikari: suddenCureIkari
+ ikari: suddenCureIkari,
+ equipability: armor
}
export Item zircoSwordItem {
name: "Zirco sword",
mode: single
},
ikari: firestormIkari,
- attackanimation: swordAttackAnimation
+ attackanimation: swordAttackAnimation,
+ equipability: weapon
}
export Item zircoWhipItem {
name: "Zirco whip",
faction: enemy,
mode: single
},
- ikari: thundershriekIkari
+ ikari: thundershriekIkari,
+ equipability: weapon
}