void Attack::melee(Actor& attacker, const Weapon& wpn, Actor& defender) { MeleeAttackData data(attacker, wpn, defender, eng); printMeleeMsgAndPlaySfx(data, wpn); if(data.isEtherealDefenderMissed == false) { if(data.attackResult >= successSmall && data.isDefenderDodging == false) { const bool IS_DEFENDER_KILLED = data.curDefender->hit(data.dmg, wpn.getData().meleeDmgType, true); if(IS_DEFENDER_KILLED == false) { data.curDefender->getPropHandler().tryApplyPropFromWpn(wpn, true); } if(data.attackResult >= successNormal) { if(data.curDefender->getData().canBleed == true) { eng.gore->makeBlood(data.curDefender->pos); } } if(IS_DEFENDER_KILLED == false) { if(wpn.getData().meleeCausesKnockBack) { if(data.attackResult > successSmall) { eng.knockBack->tryKnockBack( *(data.curDefender), data.attacker->pos, false); } } } const ItemData& itemData = wpn.getData(); if( itemData.itemWeight > itemWeight_light && itemData.isIntrinsic == false) { Snd snd("", SfxId::endOfSfxId, IgnoreMsgIfOriginSeen::yes, data.curDefender->pos, NULL, SndVol::low, AlertsMonsters::yes); SndEmit::emitSnd(snd, eng); } } } if(data.curDefender == eng.player) { if(data.attackResult >= failSmall) { dynamic_cast<Monster*>(data.attacker)->isStealth = false; } } else { Monster* const monster = dynamic_cast<Monster*>(data.curDefender); monster->awareOfPlayerCounter_ = monster->getData().nrTurnsAwarePlayer; } eng.gameTime->actorDidAct(); }
void Attack::melee(Actor& attacker, const Weapon& wpn, Actor& defender) { MeleeAttackData data(attacker, wpn, defender, eng); printMeleeMessages(data, wpn); eng->renderer->drawMapAndInterface(); if(data.isEtherealDefenderMissed == false) { if(data.attackResult >= successSmall && data.isDefenderDodging == false) { const bool IS_DEFENDER_KILLED = data.currentDefender->hit(data.dmg, wpn.getData().meleeDmgType, true); if(IS_DEFENDER_KILLED == false) { data.currentDefender->getPropHandler()->tryApplyPropFromWpn(wpn, true); } if(data.attackResult >= successNormal) { if(data.currentDefender->getData()->canBleed == true) { eng->gore->makeBlood(data.currentDefender->pos); } } if(IS_DEFENDER_KILLED == false) { if(wpn.getData().meleeCausesKnockBack) { if(data.attackResult > successSmall) { eng->knockBack->tryKnockBack( data.currentDefender, data.attacker->pos, false); } } } const ItemData& itemData = wpn.getData(); if( itemData.itemWeight > itemWeight_light && itemData.isIntrinsic == false) { Sound snd("", endOfSfx, true, data.currentDefender->pos, false, true); eng->soundEmitter->emitSound(snd); } } } if(data.currentDefender == eng->player) { if(data.attackResult >= failSmall) { dynamic_cast<Monster*>(data.attacker)->isStealth = false; } } else { Monster* const monster = dynamic_cast<Monster*>(data.currentDefender); monster->playerAwarenessCounter = monster->getData()->nrTurnsAwarePlayer; } eng->gameTime->endTurnOfCurrentActor(); }
void Attack::printMeleeMsgAndPlaySfx(const MeleeAttackData& data, const Weapon& wpn) { string otherName = ""; if(data.isDefenderDodging) { //----- DEFENDER DODGES -------- if(data.attacker == eng.player) { if(eng.player->isSeeingActor(*data.curDefender, NULL)) { otherName = data.curDefender->getNameThe(); } else { otherName = "It "; } eng.log->addMsg(otherName + " dodges my attack."); } else { if(eng.player->isSeeingActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } eng.log->addMsg("I dodge an attack from " + otherName + ".", clrMsgGood); } } else if(data.attackResult <= failSmall) { //----- BAD AIMING -------- if(data.attacker == eng.player) { if(data.attackResult == failSmall) { eng.log->addMsg("I barely miss!"); } else if(data.attackResult == failNormal) { eng.log->addMsg("I miss."); } else if(data.attackResult == failBig) { eng.log->addMsg("I miss completely."); } Audio::play(wpn.getData().meleeMissSfx); } else { if(eng.player->isSeeingActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } if(data.attackResult == failSmall) { eng.log->addMsg(otherName + " barely misses me!", clrWhite, true); } else if(data.attackResult == failNormal) { eng.log->addMsg(otherName + " misses me.", clrWhite, true); } else if(data.attackResult == failBig) { eng.log->addMsg(otherName + " misses me completely.", clrWhite, true); } } } else { //----- AIM IS CORRECT ------- if(data.isEtherealDefenderMissed) { //----- ATTACK MISSED DUE TO ETHEREAL TARGET -------- if(data.attacker == eng.player) { if(eng.player->isSeeingActor(*data.curDefender, NULL)) { otherName = data.curDefender->getNameThe(); } else { otherName = "It "; } eng.log->addMsg( "My attack passes right through " + otherName + "!"); } else { if(eng.player->isSeeingActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } eng.log->addMsg( "The attack of " + otherName + " passes right through me!", clrMsgGood); } } else { //----- ATTACK CONNECTS WITH DEFENDER -------- //Determine the relative "size" of the hit MeleeHitSize hitSize = MeleeHitSize::small; const int MAX_DMG_ROLL = data.dmgRolls * data.dmgSides; if(MAX_DMG_ROLL >= 4) { if(data.dmgRoll > (MAX_DMG_ROLL * 5) / 6) { hitSize = MeleeHitSize::hard; } else if(data.dmgRoll > MAX_DMG_ROLL / 2) { hitSize = MeleeHitSize::medium; } } //Punctuation depends on attack strength string dmgPunct = "."; switch(hitSize) { case MeleeHitSize::small: break; case MeleeHitSize::medium: dmgPunct = "!"; break; case MeleeHitSize::hard: dmgPunct = "!!!"; break; } if(data.attacker == eng.player) { const string wpnVerb = wpn.getData().meleeAttMsgs.player; if(eng.player->isSeeingActor(*data.curDefender, NULL)) { otherName = data.curDefender->getNameThe(); } else { otherName = "it"; } if(data.isIntrinsicAttack) { const string ATTACK_MOD_STR = data.isWeakAttack ? " feebly" : ""; eng.log->addMsg( "I " + wpnVerb + " " + otherName + ATTACK_MOD_STR + dmgPunct, clrMsgGood); } else { const string ATTACK_MOD_STR = data.isWeakAttack ? "feebly " : data.isBackstab ? "covertly " : ""; const SDL_Color clr = data.isBackstab ? clrBlueLgt : clrMsgGood; const string wpnName_a = eng.itemDataHandler->getItemRef(wpn, ItemRefType::a, true); eng.log->addMsg( "I " + wpnVerb + " " + otherName + " " + ATTACK_MOD_STR + "with " + wpnName_a + dmgPunct, clr); } } else { const string wpnVerb = wpn.getData().meleeAttMsgs.other; if(eng.player->isSeeingActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } eng.log->addMsg(otherName + " " + wpnVerb + dmgPunct, clrMsgBad, true); } SfxId hitSfx = SfxId::endOfSfxId; switch(hitSize) { case MeleeHitSize::small: { hitSfx = wpn.getData().meleeHitSmallSfx; } break; case MeleeHitSize::medium: { hitSfx = wpn.getData().meleeHitMediumSfx; } break; case MeleeHitSize::hard: { hitSfx = wpn.getData().meleeHitHardSfx; } break; } Audio::play(hitSfx); } } }
void Input::handleKeyPress(const KeyboardReadReturnData& d) { //----------------------------------------MOVEMENT if(d.sdlKey_ == SDLK_RIGHT || d.key_ == '6') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); if(d.isShiftHeld_) { eng->player->moveDir(dirUpRight); } else if(d.isCtrlHeld_) { eng->player->moveDir(dirDownRight); } else { eng->player->moveDir(dirRight); } } clearEvents(); return; } else if(d.sdlKey_ == SDLK_DOWN || d.key_ == '2') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); eng->player->moveDir(dirDown); } clearEvents(); return; } else if(d.sdlKey_ == SDLK_LEFT || d.key_ == '4') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); if(d.isShiftHeld_) { eng->player->moveDir(dirUpLeft); } else if(d.isCtrlHeld_) { eng->player->moveDir(dirDownLeft); } else { eng->player->moveDir(dirLeft); } } clearEvents(); return; } else if(d.sdlKey_ == SDLK_UP || d.key_ == '8') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); eng->player->moveDir(dirUp); } clearEvents(); return; } else if(d.sdlKey_ == SDLK_PAGEUP || d.key_ == '9') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); eng->player->moveDir(dirUpRight); } clearEvents(); return; } else if(d.sdlKey_ == SDLK_PAGEUP || d.key_ == '3') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); eng->player->moveDir(dirDownRight); } clearEvents(); return; } else if(d.sdlKey_ == SDLK_PAGEUP || d.key_ == '1') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); eng->player->moveDir(dirDownLeft); } clearEvents(); return; } else if(d.sdlKey_ == SDLK_PAGEUP || d.key_ == '7') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); eng->player->moveDir(dirUpLeft); } clearEvents(); return; } else if(d.key_ == '5' || d.key_ == '.') { if(eng->player->deadState == actorDeadState_alive) { clearLogMessages(); eng->player->moveDir(dirCenter); if(eng->playerBonHandler->isBonPicked(playerBon_marksman)) { eng->player->getPropHandler()->tryApplyProp( new PropStill(eng, propTurnsSpecified, 1)); } } clearEvents(); return; } //----------------------------------------DESCEND else if(d.key_ == '>') { trace << "Input: User pressed '>'" << endl; clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { trace << "Input: Calling DungeonClimb::tryUseDownStairs()" << endl; eng->dungeonClimb->tryUseDownStairs(); } clearEvents(); return; } //----------------------------------------EXAMINE else if(d.key_ == 'a') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { if(eng->player->getPropHandler()->allowSee()) { eng->examine->playerExamine(); eng->renderer->drawMapAndInterface(); } else { eng->log->addMsg("Not while blind."); eng->renderer->drawMapAndInterface(); } } clearEvents(); return; } //----------------------------------------RELOAD else if(d.key_ == 'r') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->reload->reloadWieldedWpn(*(eng->player)); } clearEvents(); return; } //----------------------------------------BASH else if(d.key_ == 'b') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->bash->playerBash(); eng->renderer->drawMapAndInterface(); } clearEvents(); return; } //----------------------------------------CLOSE else if(d.key_ == 'c') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->close->playerClose(); eng->renderer->drawMapAndInterface(); } clearEvents(); return; } //----------------------------------------JAM else if(d.key_ == 'j') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->jamWithSpike->playerJam(); eng->renderer->drawMapAndInterface(); } clearEvents(); return; } //----------------------------------------DISARM // else if(d.key_ == 'd') { // clearLogMessages(); // if(eng->player->deadState == actorDeadState_alive) { // if(eng->player->getPropHandler()->allowSee()) { // eng->disarm->playerDisarm(); // eng->renderer->drawMapAndInterface(); // } else { // } // } // clearEvents(); // return; // } //----------------------------------------UNLOAD AMMO FROM GROUND else if(d.key_ == 'u') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->itemPickup->tryUnloadWeaponOrPickupAmmoFromGround(); } clearEvents(); return; } //----------------------------------------AIM/FIRE FIREARM else if(d.key_ == 'f') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { if(eng->player->getPropHandler()->allowAttackRanged(true)) { Item* const item = eng->player->getInventory()->getItemInSlot(slot_wielded); Weapon* wpn = NULL; if(item == NULL) { eng->log->addMsg("I am not wielding a weapon."); } else { wpn = dynamic_cast<Weapon*>(item); if( wpn->nrAmmoLoaded >= 1 || wpn->getData().rangedHasInfiniteAmmo ) { eng->marker->run(markerTask_aimRangedWeapon, NULL); } else if(eng->config->useRangedWpnAutoReload) { eng->reload->reloadWieldedWpn(*(eng->player)); } else { eng->log->addMsg("There is no ammo loaded."); } } } } clearEvents(); return; } //----------------------------------------GET else if(d.key_ == 'g') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { Item* const itemAtPlayer = eng->map->items[eng->player->pos.x][eng->player->pos.y]; if(itemAtPlayer != NULL) { if(itemAtPlayer->getData().id == item_trapezohedron) { eng->dungeonMaster->winGame(); *quitToMainMenu_ = true; } } if(*quitToMainMenu_ == false) { eng->itemPickup->tryPick(); } } clearEvents(); return; } //----------------------------------------SLOTS SCREEN else if(d.key_ == 'w') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->inventoryHandler->runSlotsScreen(); } clearEvents(); return; } //----------------------------------------INVENTORY else if(d.key_ == 'i') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->inventoryHandler->runBrowseInventoryMode(); } clearEvents(); return; } //----------------------------------------USE else if(d.key_ == 'e') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { if( eng->player->dynamiteFuseTurns > 0 || eng->player->flareFuseTurns > 0 || eng->player->molotovFuseTurns > 0) { eng->marker->run(markerTask_aimLitExplosive, NULL); } else { eng->inventoryHandler->runUseScreen(); } } clearEvents(); return; } //----------------------------------------SWAP TO PREPARED ITEM else if(d.key_ == 'z') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { const bool IS_FREE_TURN = false; //eng->playerBonHandler->isBonPicked(playerBon_nimble); const string swiftStr = IS_FREE_TURN ? " swiftly" : ""; Item* const itemWielded = eng->player->getInventory()->getItemInSlot(slot_wielded); Item* const itemAlt = eng->player->getInventory()->getItemInSlot(slot_wieldedAlt); const string ITEM_WIELDED_NAME = itemWielded == NULL ? "" : eng->itemDataHandler->getItemRef(*itemWielded, itemRef_a); const string ITEM_ALT_NAME = itemAlt == NULL ? "" : eng->itemDataHandler->getItemRef(*itemAlt, itemRef_a); if(itemWielded == NULL && itemAlt == NULL) { eng->log->addMsg("I have neither a wielded nor a prepared weapon."); } else { if(itemWielded == NULL) { eng->log->addMsg( "I" + swiftStr + " wield my prepared weapon (" + ITEM_ALT_NAME + ")."); } else { if(itemAlt == NULL) { eng->log->addMsg( "I" + swiftStr + " put away my weapon (" + ITEM_WIELDED_NAME + ")."); } else { eng->log->addMsg( "I" + swiftStr + " swap to my prepared weapon (" + ITEM_ALT_NAME + ")."); } } eng->player->getInventory()->swapWieldedAndPrepared(IS_FREE_TURN == false, eng); } } clearEvents(); return; } //----------------------------------------SEARCH (REALLY JUST A WAIT BUTTON) else if(d.key_ == 's') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { vector<Actor*> spotedEnemies; eng->player->getSpotedEnemies(spotedEnemies); if(spotedEnemies.empty()) { const int TURNS_TO_APPLY = 10; const string TURNS_STR = toString(TURNS_TO_APPLY); eng->log->addMsg("I pause for a while (" + TURNS_STR + " turns)."); eng->player->waitTurnsLeft = TURNS_TO_APPLY - 1; eng->gameTime->endTurnOfCurrentActor(); } else { eng->log->addMsg("Not while an enemy is near."); eng->renderer->drawMapAndInterface(); } } clearEvents(); return; } //----------------------------------------THROW ITEM else if(d.key_ == 't') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { if(eng->player->getPropHandler()->allowAttackRanged(true)) { Inventory* const playerInv = eng->player->getInventory(); Item* itemStack = playerInv->getItemInSlot(slot_missiles); if(itemStack == NULL) { eng->log->addMsg( "I have no missiles chosen for throwing (press 'w')."); } else { Item* itemToThrow = eng->itemFactory->copyItem(itemStack); itemToThrow->nrItems = 1; const MarkerReturnData markerReturnData = eng->marker->run(markerTask_aimThrownWeapon, itemToThrow); if(markerReturnData.didThrowMissile) { playerInv->decreaseItemInSlot(slot_missiles); } else { delete itemToThrow; } } } } clearEvents(); return; } //---------------------------------------- LOOK AROUND else if(d.key_ == 'l') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { if(eng->player->getPropHandler()->allowSee()) { eng->marker->run(markerTask_look, NULL); } else { eng->log->addMsg("I am blind."); } } clearEvents(); return; } //----------------------------------------AUTO MELEE else if(d.sdlKey_ == SDLK_TAB) { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { eng->player->autoMelee(); } clearEvents(); return; } //----------------------------------------POWERS - MEMORIZED else if(d.key_ == 'x') { clearLogMessages(); if(eng->player->deadState == actorDeadState_alive) { if(eng->player->getPropHandler()->allowRead(true)) { eng->playerSpellsHandler->run(); } } clearEvents(); return; } //----------------------------------------MANUAL else if(d.key_ == '?') { eng->manual->run(); eng->renderer->drawMapAndInterface(); clearEvents(); return; } //----------------------------------------CHARACTER INFO else if(d.key_ == '@') { eng->characterDescr->run(); clearEvents(); return; } //----------------------------------------LOG HISTORY else if(d.key_ == 'L') { eng->log->displayHistory(); clearEvents(); return; } //----------------------------------------QUIT else if(d.sdlKey_ == SDLK_ESCAPE || d.key_ == 'Q') { if(eng->player->deadState == actorDeadState_alive) { eng->log->clearLog(); eng->log->addMsg( "Quit the current game (y/n)? Save and highscore are not kept.", clrWhiteHigh); eng->renderer->drawMapAndInterface(); if(eng->query->yesOrNo()) { *quitToMainMenu_ = true; } else { eng->log->clearLog(); eng->renderer->drawMapAndInterface(); } } else { *quitToMainMenu_ = true; } clearEvents(); return; } //----------------------------------------SAVE AND QUIT else if(d.key_ == 'S') { if(eng->player->deadState == actorDeadState_alive) { if(eng->map->featuresStatic[eng->player->pos.x][eng->player->pos.y]->getId() == feature_stairsDown) { eng->log->clearLog(); eng->log->addMsg("Save and quit (y/n)?", clrWhiteHigh); eng->renderer->drawMapAndInterface(); if(eng->query->yesOrNo()) { eng->saveHandler->save(); *quitToMainMenu_ = true; } else { eng->log->clearLog(); eng->renderer->drawMapAndInterface(); } } else { eng->log->clearLog(); eng->renderer->drawMapAndInterface(); } } else { eng->log->addMsg("Saving can only be done on stairs."); eng->renderer->drawMapAndInterface(); } clearEvents(); return; } //----------------------------------------DESCEND CHEAT else if(d.sdlKey_ == SDLK_F2) { if(IS_DEBUG_MODE) { eng->dungeonClimb->travelDown(1); clearEvents(); } return; } //----------------------------------------XP CHEAT else if(d.sdlKey_ == SDLK_F3) { if(IS_DEBUG_MODE) { eng->dungeonMaster->playerGainXp(100); clearEvents(); } return; } //----------------------------------------VISION CHEAT else if(d.sdlKey_ == SDLK_F4) { if(IS_DEBUG_MODE) { if(eng->isCheatVisionEnabled) { for(int y = 0; y < MAP_Y_CELLS; y++) { for(int x = 0; x < MAP_X_CELLS; x++) { eng->map->explored[x][y] = false; } } eng->isCheatVisionEnabled = false; } else { eng->isCheatVisionEnabled = true; } } clearEvents(); } //----------------------------------------INSANITY CHEAT else if(d.sdlKey_ == SDLK_F5) { if(IS_DEBUG_MODE) { eng->player->incrShock(50); clearEvents(); } return; } //----------------------------------------MTH CHEAT else if(d.sdlKey_ == SDLK_F6) { if(IS_DEBUG_MODE) { eng->player->incrMth(8); clearEvents(); } return; } //----------------------------------------DROP ALL SCROLLS AND POTIONS ON PLAYER else if(d.sdlKey_ == SDLK_F7) { if(IS_DEBUG_MODE) { for(unsigned int i = 1; i < endOfItemIds; i++) { const ItemData* const data = eng->itemDataHandler->dataList[i]; if( data->isIntrinsic == false && (data->isPotion || data->isScroll)) { eng->itemFactory->spawnItemOnMap((ItemId_t)(i), eng->player->pos); } } clearEvents(); } return; } //----------------------------------------TELEPORT else if(d.sdlKey_ == SDLK_F8) { if(IS_DEBUG_MODE) { eng->player->teleport(false); clearEvents(); } return; } //----------------------------------------INFECTED else if(d.sdlKey_ == SDLK_F9) { if(IS_DEBUG_MODE) { eng->player->getPropHandler()->tryApplyProp( new PropInfected(eng, propTurnsStandard)); clearEvents(); } return; } //----------------------------------------UNDEFINED COMMANDS else if(d.key_ != -1) { string cmdTried = " "; cmdTried.at(0) = d.key_; eng->log->clearLog(); eng->log->addMsg( "Unknown command '" + cmdTried + "'. Press '?' for commands."); clearEvents(); return; } }
void Attack::printMeleeMessages(const MeleeAttackData& data, const Weapon& wpn) { string otherName = ""; if(data.isDefenderDodging) { //----- DEFENDER DODGES -------- if(data.attacker == eng->player) { if(eng->player->checkIfSeeActor(*data.currentDefender, NULL)) { otherName = data.currentDefender->getNameThe(); } else { otherName = "It "; } eng->log->addMsg(otherName + " dodges my attack."); } else { if(eng->player->checkIfSeeActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } eng->log->addMsg( "I dodge an attack from " + otherName + ".", clrMessageGood); } } else if(data.attackResult <= failSmall) { //----- BAD AIMING -------- if(data.attacker == eng->player) { if(data.attackResult == failSmall) { eng->log->addMsg("I barely miss!"); } else if(data.attackResult == failNormal) { eng->log->addMsg("I miss."); } else if(data.attackResult == failBig) { eng->log->addMsg("I miss completely."); } } else { if(eng->player->checkIfSeeActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } if(data.attackResult == failSmall) { eng->log->addMsg(otherName + " barely misses me!", clrWhite, true); } else if(data.attackResult == failNormal) { eng->log->addMsg(otherName + " misses me.", clrWhite, true); } else if(data.attackResult == failBig) { eng->log->addMsg(otherName + " misses me completely.", clrWhite, true); } } } else { //----- AIM IS CORRECT ------- if(data.isEtherealDefenderMissed) { //----- ATTACK MISSED DUE TO ETHEREAL TARGET -------- if(data.attacker == eng->player) { if(eng->player->checkIfSeeActor(*data.currentDefender, NULL)) { otherName = data.currentDefender->getNameThe(); } else { otherName = "It "; } eng->log->addMsg( "My attack passes right throuth " + otherName + "!"); } else { if(eng->player->checkIfSeeActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } eng->log->addMsg( "The attack of " + otherName + " passes right through me!", clrMessageGood); } } else { //----- ATTACK CONNECTS WITH DEFENDER -------- //Punctuation or exclamation marks depending on attack strength string dmgPunct = "."; const int MAX_DMG_ROLL = data.dmgRolls * data.dmgSides; if(MAX_DMG_ROLL >= 4) { dmgPunct = data.dmgRoll > MAX_DMG_ROLL * 5 / 6 ? "!!!" : data.dmgRoll > MAX_DMG_ROLL / 2 ? "!" : dmgPunct; } if(data.attacker == eng->player) { const string wpnVerb = wpn.getData().meleeAttackMessages.player; if(eng->player->checkIfSeeActor(*data.currentDefender, NULL)) { otherName = data.currentDefender->getNameThe(); } else { otherName = "it"; } if(data.isIntrinsicAttack) { const string ATTACK_MOD_STR = data.isWeakAttack ? " feebly" : ""; eng->log->addMsg( "I " + wpnVerb + " " + otherName + ATTACK_MOD_STR + dmgPunct, clrMessageGood); } else { const string ATTACK_MOD_STR = data.isWeakAttack ? "feebly " : data.isBackstab ? "covertly " : ""; const SDL_Color clr = data.isBackstab ? clrBlueLgt : clrMessageGood; const string wpnName_a = eng->itemDataHandler->getItemRef(wpn, itemRef_a, true); eng->log->addMsg( "I " + wpnVerb + " " + otherName + " " + ATTACK_MOD_STR + "with " + wpnName_a + dmgPunct, clr); } } else { const string wpnVerb = wpn.getData().meleeAttackMessages.other; if(eng->player->checkIfSeeActor(*data.attacker, NULL)) { otherName = data.attacker->getNameThe(); } else { otherName = "It"; } eng->log->addMsg(otherName + " " + wpnVerb + dmgPunct, clrMessageBad, true); } } } }