bool Cocoon::openFeature() { eng->log->addMessage("The cocoon opens."); triggerTrap(); if(itemContainer_.items_.size() > 0) { eng->log->addMessage("There are some items inside."); itemContainer_.dropItems(pos_, eng); } else { eng->log->addMessage("There is nothing of value inside."); } eng->renderer->drawMapAndInterface(true); isContentKnown_ = true; return true; }
bool Chest::openFeature() { eng->log->addMessage("The chest opens."); if(isTrapped_) { triggerTrap(); } if(eng->player->deadState == actorDeadState_alive) { if(itemContainer_.items_.empty()) { eng->log->addMessage("There is nothing of value inside."); } else { eng->log->addMessage("There are some items inside."); itemContainer_.dropItems(pos_, eng); eng->renderer->drawMapAndInterface(true); } isContentKnown_ = true; isTrapStatusKnown_ = true; } return true; }
void Trap::bump(Actor& actorBumping) { trace << "Trap::bump()..." << endl; const ActorData& d = actorBumping.getData(); trace << "Trap: Name of actor bumping: \"" << d.name_a << "\"" << endl; vector<PropId> props; actorBumping.getPropHandler().getAllActivePropIds(props); if( find(props.begin(), props.end(), propEthereal) == props.end() && find(props.begin(), props.end(), propFlying) == props.end()) { const bool IS_PLAYER = &actorBumping == actorBumping.eng.player; const bool ACTOR_CAN_SEE = actorBumping.getPropHandler().allowSee(); AbilityValues& abilities = actorBumping.getData().abilityVals; const int DODGE_SKILL = abilities.getVal(ability_dodgeTrap, true, actorBumping); const int BASE_CHANCE_TO_AVOID = 30; const string trapName = specificTrap_->getTitle(); if(IS_PLAYER) { trace << "Trap: Player bumping" << endl; const int CHANCE_TO_AVOID = isHidden_ == true ? 10 : (BASE_CHANCE_TO_AVOID + DODGE_SKILL); const AbilityRollResult result = actorBumping.eng.abilityRoll->roll(CHANCE_TO_AVOID); if(result >= successSmall) { if(isHidden_ == false) { if(ACTOR_CAN_SEE) { actorBumping.eng.log->addMsg( "I avoid a " + trapName + ".", clrMsgGood); } } } else { triggerTrap(actorBumping); } } else { if(d.actorSize == actorSize_humanoid && d.isSpider == false) { trace << "Trap: Humanoid monster bumping" << endl; Monster* const monster = dynamic_cast<Monster*>(&actorBumping); if( monster->awareOfPlayerCounter_ > 0 && monster->isStealth == false) { trace << "Trap: Monster eligible for triggering trap" << endl; const bool IS_ACTOR_SEEN_BY_PLAYER = actorBumping.eng.player->isSeeingActor(actorBumping, NULL); const int CHANCE_TO_AVOID = BASE_CHANCE_TO_AVOID + DODGE_SKILL; const AbilityRollResult result = actorBumping.eng.abilityRoll->roll(CHANCE_TO_AVOID); if(result >= successSmall) { if(isHidden_ == false && IS_ACTOR_SEEN_BY_PLAYER) { const string actorName = actorBumping.getNameThe(); actorBumping.eng.log->addMsg( actorName + " avoids a " + trapName + "."); } } else { triggerTrap(actorBumping); } } } } } trace << "Trap::bump() [DONE]" << endl; }
void Trap::disarm() { //Abort if trap is hidden if(isHidden()) { eng.log->addMsg(msgDisarmNoTrap); Renderer::drawMapAndInterface(); return; } //Spider webs are automatically destroyed if wielding machete bool isAutoSucceed = false; if(getTrapType() == trap_spiderWeb) { Item* item = eng.player->getInv().getItemInSlot(SlotId::wielded); if(item != NULL) { isAutoSucceed = item->getData().id == ItemId::machete; } } const bool IS_OCCULTIST = PlayerBon::getBg() == Bg::occultist; if(isMagical() && IS_OCCULTIST == false) { eng.log->addMsg("I do not know how to dispel magic traps."); return; } vector<PropId> props; eng.player->getPropHandler().getAllActivePropIds(props); const bool IS_BLESSED = find(props.begin(), props.end(), propBlessed) != props.end(); const bool IS_CURSED = find(props.begin(), props.end(), propCursed) != props.end(); int disarmNumerator = 5; const int DISARM_DENOMINATOR = 10; if(IS_BLESSED) disarmNumerator += 3; if(IS_CURSED) disarmNumerator -= 3; constrInRange(1, disarmNumerator, DISARM_DENOMINATOR - 1); const bool IS_DISARMED = Rnd::fraction(disarmNumerator, DISARM_DENOMINATOR) || isAutoSucceed; if(IS_DISARMED) { eng.log->addMsg(specificTrap_->getDisarmMsg()); } else { eng.log->addMsg(specificTrap_->getDisarmFailMsg()); Renderer::drawMapAndInterface(); const int TRIGGER_ONE_IN_N = IS_BLESSED ? 9 : IS_CURSED ? 2 : 4; if(Rnd::oneIn(TRIGGER_ONE_IN_N)) { if(getTrapType() == trap_spiderWeb) { eng.player->pos = pos_; } triggerTrap(*eng.player); } } eng.gameTime->actorDidAct(); if(IS_DISARMED) { eng.featureFactory->spawnFeatureAt(feature_stoneFloor, pos_); } }