void Weapon::onEvent(event::Event* const event) { if (event->id() == ChangedInventoryItems::ID) { ChangedInventoryItems* e = static_cast<ChangedInventoryItems*> (event); for (set<unsigned char>::iterator k = e->keys().begin(); k != e->keys().end(); ++k) { const Item& item = Inventory::itemAtKey(*k); if (item.count() <= 0) { /* we lost this item */ _range_weapons.erase(*k); _melee_weapons.erase(*k); continue; } map<const string, const data::Weapon*>::const_iterator w = data::Weapon::weapons().find(item.name()); if (w == data::Weapon::weapons().end()) continue; // not a weapon int score = calculateWeaponScore(item, w->second); if (isRangedWeapon(w->second)) _range_weapons[*k] = score; else _melee_weapons[*k] = score; } setBestWeapons(); } else if (event->id() == ReceivedItems::ID) { ReceivedItems* e = static_cast<ReceivedItems*> (event); for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) { map<const string, const data::Weapon*>::const_iterator w = data::Weapon::weapons().find(i->second.name()); if (w == data::Weapon::weapons().end()) continue; // not a weapon int score = calculateWeaponScore(i->second, w->second); if (isRangedWeapon(w->second)) { _range_weapons[i->first] = score; } else { _melee_weapons[i->first] = score; if (i->second.beatitude() == BEATITUDE_UNKNOWN) { Beatify b(i->first, 175); EventBus::broadcast(&b); } } } setBestWeapons(); } else if (event->id() == WantItems::ID) { WantItems* e = static_cast<WantItems*> (event); // if (e->dropping() || Saiph::encumbrance() < BURDENED) { /* dropping items or we're burdened (which means don't loot weapons) */ for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) { if (e->dropping()) { if (_range_weapons.find(i->first) != _range_weapons.end() || _melee_weapons.find(i->first) != _melee_weapons.end()) { /* don't drop weapons in one of our lists */ i->second.want(i->second.count()); } } else { /* looting, is this better than what we got? */ if (betterThanWhatWeGot(i->second)) i->second.want(i->second.count()); } } // } } }
/* methods */ void DiggingTool::onEvent(Event* const event) { if (event->id() == ChangedInventoryItems::ID || event->id() == ReceivedItems::ID) { findDigger(); } else if (event->id() == WantItems::ID) { WantItems* e = static_cast<WantItems*> (event); int key; int score; // WantItems is called once per page while dropping, but the ranking needs to see the whole list... rankDiggers(key, score, (e->dropping() ? NULL : &Inventory::items()), (e->dropping() ? &Inventory::items() : &e->items())); if (key >= 0 && e->items().find(key) != e->items().end()) { Item& item = e->items()[(unsigned char)key]; item.want(min(1, item.count())); } } }
void Door::onEvent(Event* const event) { if (event->id() == ChangedInventoryItems::ID) { /* inventory changed, see if we lost our unlocking device or got a new/better one */ if (Inventory::items().find(_unlock_tool_key) == Inventory::items().end()) _unlock_tool_key = 0; // darn, we lost our unlocking device ChangedInventoryItems* e = static_cast<ChangedInventoryItems*> (event); for (set<unsigned char>::iterator k = e->keys().begin(); k != e->keys().end(); ++k) { map<unsigned char, Item>::iterator i = Inventory::items().find(*k); if (i != Inventory::items().end() && wantItem(i->second)) _unlock_tool_key = *k; // better key than what we currently got } } else if (event->id() == ReceivedItems::ID) { ReceivedItems* e = static_cast<ReceivedItems*> (event); for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) { if (wantItem(i->second)) _unlock_tool_key = i->first; // better key than what we currently got } } else if (event->id() == WantItems::ID) { WantItems* e = static_cast<WantItems*> (event); for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) { if ((e->dropping() && _unlock_tool_key != ILLEGAL_ITEM && i->first == _unlock_tool_key) || wantItem(i->second)) i->second.want(i->second.count()); } } else if (event->id() == ShopDetected::ID) { ShopDetected* e = static_cast<ShopDetected*> (event); stack<Point> ps; for (int x = e->ul().col(); x <= e->lr().col(); ++x) { ps.push(Point(e->ul().row() - 1, x)); ps.push(Point(e->lr().row() + 1, x)); } for (int y = e->ul().row() - 1; y <= e->lr().row() + 1; ++y) { ps.push(Point(y, e->ul().col() - 1)); ps.push(Point(y, e->lr().col() + 1)); } for (; !ps.empty(); ps.pop()) { if (World::level().tile(ps.top()).symbol() != CLOSED_DOOR) continue; World::level().setDungeonSymbolValue(ps.top(), getDoorFlags(ps.top()) | DOOR_IS_SHOP); } } }
void Beatitude::onEvent(event::Event* const event) { if (event->id() == Beatify::ID) { Beatify* e = static_cast<Beatify*> (event); set<unsigned char>::iterator b = _beatify.find(e->key()); _beatify.insert(e->key()); if (e->priority() > _max_priority) _max_priority = e->priority(); } else if (event->id() == WantItems::ID && World::level().tile().symbol() == ALTAR) { /* looting or picking up items at an altar */ WantItems* e = static_cast<WantItems*> (event); if (e->dropping()) { for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) { if (i->second.beatitude() != BEATITUDE_UNKNOWN) continue; // know beatitude already /* should drop this item, force it by setting count to 0 */ i->second.count(0); } _beatify.clear(); _max_priority = ILLEGAL_PRIORITY; } } }