Esempio n. 1
0
void Fight::onEvent(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) {
			map<unsigned char, Item>::iterator i = Inventory::items().find(*k);
			if (i == Inventory::items().end()) {
				/* we lost this item, remove it from projectile_slots */
				_projectile_slots.erase(*k);
			} else {
				/* this item is new or changed.
				 * if we intend to throw it, add it to projectile_slots.
				 * otherwise remove it from projectile_slots */
				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
				if (w->second->type() == WEAPON_DAGGER || w->second->type() == WEAPON_DART || w->second->type() == WEAPON_JAVELIN || w->second->type() == WEAPON_KNIFE || w->second->type() == WEAPON_SHURIKEN || w->second->type() == WEAPON_SPEAR)
					_projectile_slots.insert(*k);
				else
					_projectile_slots.erase(*k);
			}
		}
	} 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
			if (w->second->type() == WEAPON_DAGGER || w->second->type() == WEAPON_DART || w->second->type() == WEAPON_JAVELIN || w->second->type() == WEAPON_KNIFE || w->second->type() == WEAPON_SHURIKEN || w->second->type() == WEAPON_SPEAR)
				_projectile_slots.insert(i->first);
		}
	}
}
Esempio n. 2
0
/* methods */
void Amulet::onEvent(Event * const event) {
	if (event->id() == ChangedInventoryItems::ID) {
		ChangedInventoryItems* e = static_cast<ChangedInventoryItems*> (event);
		for (set<unsigned char>::iterator i = e->keys().begin(); i != e->keys().end(); ++i) {
			Item item = Inventory::itemAtKey(*i);
			if (item.beatitude() != CURSED && item.beatitude() != BEATITUDE_UNKNOWN && data::Amulet::amulets().find(item.name()) != data::Amulet::amulets().end()) {
				if (item.name().find("strangulation") != string::npos && item.name().find("restful") != string::npos)
					_amulet_key = *i;
				break;
			}
		}
		//todo: determine best amulet
	} 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 (i->second.beatitude() != BEATITUDE_UNKNOWN || data::Amulet::amulets().find(i->second.name()) == data::Amulet::amulets().end())
				continue; // known beatitude or not an amulet
			else if (i->second.beatitude() == BEATITUDE_UNKNOWN && data::Amulet::amulets().find(i->second.name()) != data::Amulet::amulets().end()) {
				Beatify b(i->first, 175);
				EventBus::broadcast(&b);
			} else if (i->second.beatitude() != CURSED && data::Amulet::amulets().find(i->second.name()) != data::Amulet::amulets().end()) {
				if (i->second.name().find("strangulation") != string::npos && i->second.name().find("restful") != string::npos)
					_amulet_key = i->first;
			}
		}
	} else if (event->id() == WantItems::ID) {
		Debug::info() << "WantItems appeared, wearing?" << endl;
		WantItems* e = static_cast<WantItems*> (event);
		for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) {
			if (wantItem(i->second))
				i->second.want(i->second.count());
		}
	}
}
Esempio n. 3
0
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());
				}
			}
//		}
	}
}
Esempio n. 4
0
void Health::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) {
			map<unsigned char, Item>::iterator i = Inventory::items().find(*k);
			if (*k == _unihorn_key) {
				if (i == Inventory::items().end() || i->second.beatitude() == CURSED || data::UnicornHorn::unicornHorns().find(i->second.name()) == data::UnicornHorn::unicornHorns().end()) {
					_unihorn_key = ILLEGAL_ITEM;
					continue;
				}
			} else if (*k == _lizard_key) {
				if (i == Inventory::items().end()) {
					_lizard_key = ILLEGAL_ITEM;
					continue;
				}
				map<const string, const data::Corpse*>::const_iterator c = data::Corpse::corpses().find(i->second.name());
				if (c == data::Corpse::corpses().end() || !(c->second->effects() & EAT_EFFECT_CURE_STONING)) {
					_lizard_key = ILLEGAL_ITEM;
					continue;
				}
			}
		}
	} 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 (data::UnicornHorn::unicornHorns().find(i->second.name()) != data::UnicornHorn::unicornHorns().end()) {
				if (i->second.beatitude() == BEATITUDE_UNKNOWN) {
					Beatify b(i->first, 175);
					EventBus::broadcast(&b);
				} else if (i->second.beatitude() != CURSED) {
					map<unsigned char, Item>::iterator u = Inventory::items().find(_unihorn_key);
					if (u == Inventory::items().end() || u->second.beatitude() == UNCURSED)
						_unihorn_key = i->first;
				}
				continue;
			}
			map<const string, const data::Corpse*>::const_iterator c = data::Corpse::corpses().find(i->second.name());
			if (c != data::Corpse::corpses().end() && (c->second->effects() & EAT_EFFECT_CURE_STONING)) {
				_lizard_key = i->first;
				continue;
			}
		}
	} 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 (i->second.beatitude() != CURSED && data::UnicornHorn::unicornHorns().find(i->second.name()) != data::UnicornHorn::unicornHorns().end()) {
				/* let's pick up all non-cursed unihorns */
				i->second.want(i->second.count());
				continue;
			}
			map<const string, const data::Corpse*>::const_iterator c = data::Corpse::corpses().find(i->second.name());
			if (c != data::Corpse::corpses().end() && (c->second->effects() & EAT_EFFECT_CURE_STONING)) {
				/* let's pick up all lizard corpses */
				i->second.want(i->second.count());
				continue;
			}
		}
	}
}
Esempio n. 5
0
void Armor::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) {
			if (betterThanCurrent(Inventory::itemAtKey(*k)))
				_put_on.insert(*k);
			else
				_put_on.erase(*k);
		}
	} 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 (data::Armor::armors().find(i->second.name()) == data::Armor::armors().end())
				continue; // not armor
			if (i->second.beatitude() != BEATITUDE_UNKNOWN) {
				/* known beatitude, should we wear it? */
				if (i->second.beatitude() != CURSED && betterThanCurrent(i->second))
					_put_on.insert(i->first); // it's not cursed and (possibly) better than what we're wearing
				else
					_put_on.erase(i->first);
				continue;
			}
			Beatify b(i->first, 175);
			EventBus::broadcast(&b);
		}
	} else if (event->id() == WantItems::ID) {
		WantItems* e = static_cast<WantItems*> (event);
		if (Saiph::encumbrance() >= BURDENED) {
			/* burdened and beatifying, (and is on a stash): pick up */
			if (World::shortestPath(ALTAR).cost() < UNPASSABLE) {
				if (Saiph::encumbrance() < STRESSED) {
					if (e->safeStash()) {
						for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) {
							if (betterThanCurrent(i->second))
								i->second.want(i->second.count());
						}
					}
				}
				/* burdened and not beatifying: stash */
			} else if (e->safeStash()) {
				loopTimeout = World::turn() + 10;
			}
			/* not burdened */
		} else {
			/* and not on safe stash: pick up */
			if (!e->safeStash() && loopTimeout <= World::turn()) {
				/* ^ this also means 'drop at every safe stash if not burdened' */
				/* TODO: to avoid this, check whether on upstair, without stashing */
				for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) {
					if (betterThanCurrent(i->second))
						i->second.want(i->second.count());
				}
			}
		}
	}
}
Esempio n. 6
0
/* methods */
void Amulet::onEvent(Event* const event) {
	if (event->id() == ChangedInventoryItems::ID) {
		ChangedInventoryItems* e = static_cast<ChangedInventoryItems*> (event);
		map<unsigned char, Item> k;
		for (set<unsigned char>::iterator i = e->keys().begin(); i != e->keys().end(); ++i) {
			Item item = Inventory::itemAtKey(*i);
			k.insert(pair<unsigned char, Item>(*i, item));
		}
		_amulet_key = bestAmulet(k);
	} else if (event->id() == ReceivedItems::ID) {
		ReceivedItems* e = static_cast<ReceivedItems*> (event);
		_amulet_key = bestAmulet((e->items()));
	} 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 (wantItem(i->second))
				i->second.want(i->second.count());
		}
	}
}
Esempio n. 7
0
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);
		}
	}
}
Esempio n. 8
0
void Armor::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) {
			if (betterThanCurrent(Inventory::itemAtKey(*k)))
				_put_on.insert(*k);
			else
				_put_on.erase(*k);
		}
	} 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 (data::Armor::armors().find(i->second.name()) == data::Armor::armors().end())
				continue; // not armor
			if (i->second.beatitude() != BEATITUDE_UNKNOWN) {
				/* known beatitude, should we wear it? */
				if (i->second.beatitude() != CURSED && betterThanCurrent(i->second))
					_put_on.insert(i->first); // it's not cursed and (possibly) better than what we're wearing
				else
					_put_on.erase(i->first);
				continue;
			}
			Beatify b(i->first, 175);
			EventBus::broadcast(&b);
		}
	} else if (event->id() == WantItems::ID) {
		WantItems* e = static_cast<WantItems*> (event);
		if (e->safeStash() && World::shortestPath(ALTAR).cost() >= UNPASSABLE) {
			/* on safe stash and can't path to altar, drop */
		} else if (Saiph::encumbrance() < BURDENED && (!e->safeStash() || World::shortestPath(ALTAR).cost() < UNPASSABLE)) {
			/* we're not burdened and not on a safe stash or we can't reach an altar, loot armor */
			/* if we are on a safe stash and can't reach an altar then we will drop armor */
			for (map<unsigned char, Item>::iterator i = e->items().begin(); i != e->items().end(); ++i) {
				if (betterThanCurrent(i->second))
					i->second.want(i->second.count());
			}
		}
	}
}
Esempio n. 9
0
void Health::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) {
			map<unsigned char, Item>::iterator i = Inventory::items().find(*k);
			if (*k == _unihorn_key) {
				if (i == Inventory::items().end() || i->second.beatitude() == CURSED || data::UnicornHorn::unicornHorns().find(i->second.name()) == data::UnicornHorn::unicornHorns().end()) {
					_unihorn_key = ILLEGAL_ITEM;
					continue;
				}
			} else if (*k == _lizard_key) {
				if (i == Inventory::items().end()) {
					_lizard_key = ILLEGAL_ITEM;
					continue;
				}
				map<const string, const data::Corpse*>::const_iterator c = data::Corpse::corpses().find(i->second.name());
				if (c == data::Corpse::corpses().end() || !(c->second->effects() & EAT_EFFECT_CURE_STONING)) {
					_lizard_key = ILLEGAL_ITEM;
					continue;
				}
			}
		}
	} 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 (data::UnicornHorn::unicornHorns().find(i->second.name()) != data::UnicornHorn::unicornHorns().end()) {
				if (i->second.beatitude() == BEATITUDE_UNKNOWN) {
					Beatify b(i->first, 175);
					EventBus::broadcast(&b);
				} else if (i->second.beatitude() != CURSED) {
					map<unsigned char, Item>::iterator u = Inventory::items().find(_unihorn_key);
					if (u == Inventory::items().end() || u->second.beatitude() == UNCURSED)
						_unihorn_key = i->first;
				}
				continue;
			}
			map<const string, const data::Corpse*>::const_iterator c = data::Corpse::corpses().find(i->second.name());
			if (c != data::Corpse::corpses().end() && (c->second->effects() & EAT_EFFECT_CURE_STONING)) {
				_lizard_key = i->first;
				continue;
			}
		}
	} 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 (i->second.beatitude() != CURSED && data::UnicornHorn::unicornHorns().find(i->second.name()) != data::UnicornHorn::unicornHorns().end()) {
				/* non-cursed unihorn */
				/* if we want to limit amount of unihorns, do it here, check inventory how many we got */
				int unihornNum = 0;
				for (map<unsigned char, Item>::iterator i2 = e->items().begin(); i2 != e->items().end(); ++i2) {
					if (i2->second.beatitude() != CURSED && data::UnicornHorn::unicornHorns().find(i->second.name()) != data::UnicornHorn::unicornHorns().end())
						unihornNum++;
				}
				/* keep at least 3 on hand */
				if (unihornNum < 3)
					i->second.want(i->second.count());
				continue;
			}
			map<const string, const data::Corpse*>::const_iterator c = data::Corpse::corpses().find(i->second.name());
			if (c != data::Corpse::corpses().end() && (c->second->effects() & EAT_EFFECT_CURE_STONING)) {
				/* lizard corpse */
				/* if we want to limit amount of lizard corpses, do it here, check inventory how many we got */
				int lizardNum = 0;
				for (map<unsigned char, Item>::iterator i2 = e->items().begin(); i2 != e->items().end(); ++i2) {
					map<const string, const data::Corpse*>::const_iterator c2 = data::Corpse::corpses().find(i2->second.name());
					if (c != data::Corpse::corpses().end() && (c->second->effects() & EAT_EFFECT_CURE_STONING))
						lizardNum++;
				}
				if (lizardNum < 3)
					i->second.want(i->second.count());
				continue;
			}
		}
	}
}