diff --git a/library/include/modules/EventManager.h b/library/include/modules/EventManager.h index 623fa0823..95fb96ab5 100644 --- a/library/include/modules/EventManager.h +++ b/library/include/modules/EventManager.h @@ -60,8 +60,9 @@ namespace DFHack { struct SyndromeData { int32_t unitId; int32_t syndromeIndex; - SyndromeData(int32_t unitId_in, int32_t syndromeIndex_in): unitId(unitId_in), syndromeIndex(syndromeIndex_in) { - + SyndromeData(int32_t unitId_in, int32_t syndromeIndex_in): unitId(unitId_in), syndromeIndex(syndromeIndex_in) {} + bool operator==(const SyndromeData &other) const { + return unitId == other.unitId && syndromeIndex == other.syndromeIndex; } }; @@ -78,12 +79,26 @@ namespace DFHack { InventoryItem* item_new; InventoryChangeData() {} InventoryChangeData(int32_t id_in, InventoryItem* old_in, InventoryItem* new_in): unitId(id_in), item_old(old_in), item_new(new_in) {} + bool operator==(const InventoryChangeData &other) const { + bool unit = unitId == other.unitId; + bool newItem = (item_new && other.item_new && item_new->itemId == other.item_new->itemId) || + (!item_new && item_new == other.item_new); + bool oldItem = (item_old && other.item_old && item_old->itemId == other.item_old->itemId) || + (!item_old && item_old == other.item_old); + return unit && newItem && oldItem; + } }; struct UnitAttackData { + int32_t report_id; int32_t attacker; int32_t defender; int32_t wound; + + bool operator==(const UnitAttackData &other) const { + // fairly sure the report_id is the only thing that matters + return report_id == other.report_id && wound == other.wound; + } }; struct InteractionData { @@ -93,6 +108,12 @@ namespace DFHack { int32_t defender; int32_t attackReport; int32_t defendReport; + bool operator==(const InteractionData &other) const { + bool reports = attackReport == other.attackReport && defendReport == other.defendReport; + // based on code in the manager it doesn't need reports or verbs checked. + // since the units are deduced (it seems) from the reports... this + return reports; + } }; DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin); @@ -126,6 +147,73 @@ namespace std { return r; } }; + template <> + struct hash { + std::size_t operator()(const df::construction& construct) const { + auto &c = construct.pos; + size_t r = 17; + const size_t m = 65537; + r = m*(r+c.x); + r = m*(r+c.y); + r = m*(r+c.z); + return r; + } + }; + template <> + struct hash { + std::size_t operator()(const DFHack::EventManager::SyndromeData& syndrome) const { + size_t r = 43; + const size_t m = 65537; + r = m*(r+syndrome.unitId); + r = m*(r+syndrome.syndromeIndex); + return r; + } + }; + template <> + struct hash { + std::size_t operator()(const DFHack::EventManager::InventoryChangeData& icd) const { + size_t r = 43; + const size_t m = 65537; + r = m*(r+icd.unitId); + if (icd.item_new) { + r=m*(r+icd.item_new->itemId); + } + if (icd.item_old) { + r=m*(r+(2*icd.item_old->itemId)); + } + return r; + } + }; + template <> + struct hash { + std::size_t operator()(const DFHack::EventManager::UnitAttackData& uad) const { + size_t r = 43; + const size_t m = 65537; + r = m*(r+uad.report_id); + r = m*(r+uad.attacker); + r = m*(r+uad.defender); + r = m*(r+uad.wound); + return r; + } + }; + template <> + struct hash { + std::size_t operator()(const DFHack::EventManager::InteractionData& interactionData) const { + size_t r = 43; + const size_t m = 65537; + r = m*(r+interactionData.attackReport); + r = m*(r+interactionData.defendReport); + r = m*(r+interactionData.attacker); + r = m*(r+interactionData.defender); + return r; + } + }; +} + +namespace df{ + bool operator==(const df::construction &A, const df::construction &B){ + return A.pos == B.pos; + } } #endif diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index 6e7435029..5ec65b490 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -970,6 +970,7 @@ static void manageUnitAttackEvent(color_ostream& out) { df::unit_wound* wound2 = getWound(unit2,unit1); UnitAttackData data{}; + data.report_id = report->id; if ( wound1 && !alreadyDone[unit1->id][unit2->id] ) { data.attacker = unit1->id; data.defender = unit2->id;