From: <lyn...@us...> - 2009-09-22 13:30:44
|
Revision: 7246 http://gemrb.svn.sourceforge.net/gemrb/?rev=7246&view=rev Author: lynxlupodian Date: 2009-09-22 13:30:36 +0000 (Tue, 22 Sep 2009) Log Message: ----------- implemented most of the Hide action Modified Paths: -------------- gemrb/trunk/gemrb/plugins/Core/Actions.cpp gemrb/trunk/gemrb/plugins/Core/Game.cpp gemrb/trunk/gemrb/plugins/Core/Game.h Modified: gemrb/trunk/gemrb/plugins/Core/Actions.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2009-09-22 12:39:27 UTC (rev 7245) +++ gemrb/trunk/gemrb/plugins/Core/Actions.cpp 2009-09-22 13:30:36 UTC (rev 7246) @@ -5312,13 +5312,69 @@ actor->SetModal( MS_DETECTTRAPS); } +static EffectRef fx_disable_button_ref={ "DisableButton", NULL, -1 }; + +inline void HideFailed(Actor* actor) +{ + core->DisplayConstantStringName(STR_HIDEFAILED, 0xffffff, actor); + actor->SetModal(MS_NONE); + + Effect *newfx; + newfx = EffectQueue::CreateEffect(fx_disable_button_ref, 0, ACT_STEALTH, FX_DURATION_INSTANT_LIMITED); + newfx->Duration = 6; // 90 ticks, 1 round + core->ApplyEffect(newfx, actor, actor); + delete newfx; +} + void GameScript::Hide(Scriptable* Sender, Action* /*parameters*/) { if (Sender->Type!=ST_ACTOR) { return; } Actor *actor = (Actor *) Sender; + + ieDword roll = actor->LuckyRoll(1, 100, 0); + if (roll == 1) { + HideFailed(actor); + return; + } + + // TODO: unknown missing failing check; maybe class? + + if (actor->Modified[IE_DISABLEDBUTTON] & (1<<ACT_STEALTH)) { + HideFailed(actor); + return; + } + + // check if the pc is in combat (seen / heard) + Game *game = core->GetGame(); + if (game->PCInCombat(actor)) { + HideFailed(actor); + return; + } + + ieDword skill; + if (core->HasFeature(GF_HAS_HIDE_IN_SHADOWS)) { + skill = (actor->GetStat(IE_HIDEINSHADOWS) + actor->GetStat(IE_STEALTH))/2; + } else { + skill = actor->GetStat(IE_STEALTH); + } + + // check how bright our spot is + Color feet = game->GetCurrentArea()->LightMap->GetPixel(actor->Pos.x/16, actor->Pos.y/12); + ieDword lightness = (feet.r + feet.g + feet.b)*100/255/3; //average and convert to [0-100] + ieDword diff = (100 - lightness) * skill/100; + if (roll > diff) { + HideFailed(actor); + return; + } + actor->SetModal( MS_STEALTH); + core->DisplayConstantStringName(STR_HIDEDONE, 0xffffff, actor); + + //TODO: show STR_HIDENOMORE on expiry/abort + //TODO: expiry isn't instant (skill based transition?) + } void GameScript::Turn(Scriptable* Sender, Action* /*parameters*/) Modified: gemrb/trunk/gemrb/plugins/Core/Game.cpp =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Game.cpp 2009-09-22 12:39:27 UTC (rev 7245) +++ gemrb/trunk/gemrb/plugins/Core/Game.cpp 2009-09-22 13:30:36 UTC (rev 7246) @@ -1125,6 +1125,21 @@ return (PCs.size()>partysize); } +bool Game::PCInCombat(Actor* actor) const +{ + if (!CombatCounter) { + return false; + } + + if (actor->LastTarget) { + return true; + } + if (AttackersOf(actor->GetID(), actor->GetCurrentArea())) { + return true; + } + return false; +} + bool Game::AnyPCInCombat() const { if (!CombatCounter) { @@ -1132,14 +1147,9 @@ } for (unsigned int i=0; i<PCs.size(); i++) { - Actor *actor = PCs[i]; - - if ((actor->LastTarget) ) { + if (PCInCombat (PCs[i])) { return true; } - if (AttackersOf(actor->GetID(), actor->GetCurrentArea()) ) { - return true; - } } return false; } Modified: gemrb/trunk/gemrb/plugins/Core/Game.h =================================================================== --- gemrb/trunk/gemrb/plugins/Core/Game.h 2009-09-22 12:39:27 UTC (rev 7245) +++ gemrb/trunk/gemrb/plugins/Core/Game.h 2009-09-22 13:30:36 UTC (rev 7246) @@ -359,6 +359,8 @@ void ShareXP(int XP, int flags); /** returns true if we should start the party overflow window */ bool PartyOverflow() const; + /** returns true if actor is an attacker or being attacked */ + bool PCInCombat(Actor *actor) const; /** returns true if any pc is attacker or being attacked */ bool AnyPCInCombat() const; /** returns true if the party death condition is true */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |