Skip to content

Commit

Permalink
add new flag to check for unscheduled actors in ValidTarget
Browse files Browse the repository at this point in the history
It turns out unscheduled actors can be targeted after all, e.g. for
the Activate() script action.
  • Loading branch information
fizzet committed May 19, 2013
1 parent c6dd6c5 commit 1529978
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 22 deletions.
2 changes: 1 addition & 1 deletion gemrb/core/GUI/GameControl.cpp
Expand Up @@ -554,7 +554,7 @@ void GameControl::Draw(unsigned short x, unsigned short y)
Actor *actor = area->GetActorByGlobalID(trackerID);

if (actor) {
Actor **monsters = area->GetAllActorsInRadius(actor->Pos, GA_NO_DEAD|GA_NO_LOS, distance);
Actor **monsters = area->GetAllActorsInRadius(actor->Pos, GA_NO_DEAD|GA_NO_LOS|GA_NO_UNSCHEDULED, distance);

int i = 0;
while(monsters[i]) {
Expand Down
14 changes: 7 additions & 7 deletions gemrb/core/GameScript/GSUtils.cpp
Expand Up @@ -2336,24 +2336,24 @@ Actor *GetNearestEnemyOf(Map *map, Actor *origin, int whoseeswho)

int distance = Distance(ac, origin);
if (whoseeswho&ENEMY_SEES_ORIGIN) {
if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
if (!CanSee(ac, origin, true, GA_NO_DEAD|GA_NO_UNSCHEDULED)) {
continue;
}
}
if (whoseeswho&ORIGIN_SEES_ENEMY) {
if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
if (!CanSee(ac, origin, true, GA_NO_DEAD|GA_NO_UNSCHEDULED)) {
continue;
}
}

if (type) { //origin is PC
if (ac->GetStat(IE_EA) >= EA_EVILCUTOFF) {
tgts->AddTarget(ac, distance, GA_NO_DEAD);
tgts->AddTarget(ac, distance, GA_NO_DEAD|GA_NO_UNSCHEDULED);
}
}
else {
if (ac->GetStat(IE_EA) <= EA_GOODCUTOFF) {
tgts->AddTarget(ac, distance, GA_NO_DEAD);
tgts->AddTarget(ac, distance, GA_NO_DEAD|GA_NO_UNSCHEDULED);
}
}
}
Expand All @@ -2374,17 +2374,17 @@ Actor *GetNearestOf(Map *map, Actor *origin, int whoseeswho)

int distance = Distance(ac, origin);
if (whoseeswho&ENEMY_SEES_ORIGIN) {
if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
if (!CanSee(ac, origin, true, GA_NO_DEAD|GA_NO_UNSCHEDULED)) {
continue;
}
}
if (whoseeswho&ORIGIN_SEES_ENEMY) {
if (!CanSee(ac, origin, true, GA_NO_DEAD)) {
if (!CanSee(ac, origin, true, GA_NO_DEAD|GA_NO_UNSCHEDULED)) {
continue;
}
}

tgts->AddTarget(ac, distance, GA_NO_DEAD);
tgts->AddTarget(ac, distance, GA_NO_DEAD|GA_NO_UNSCHEDULED);
}
ac = (Actor *) tgts->GetTarget(0, ST_ACTOR);
delete tgts;
Expand Down
4 changes: 2 additions & 2 deletions gemrb/core/GameScript/Triggers.cpp
Expand Up @@ -220,7 +220,7 @@ int GameScript::NearbyDialog(Scriptable* Sender, Trigger* parameters)
if ( !target ) {
return 0;
}
return CanSee( Sender, target, true, GA_NO_DEAD | GA_NO_HIDDEN );
return CanSee( Sender, target, true, GA_NO_DEAD|GA_NO_HIDDEN|GA_NO_UNSCHEDULED );
}

//atm this checks for InParty and See, it is unsure what is required
Expand Down Expand Up @@ -253,7 +253,7 @@ int GameScript::IsValidForPartyDialog(Scriptable* Sender, Trigger* parameters)
if(!pc->GetDialog(GD_CHECK)) {
return 0;
}
return CanSee( Sender, target, false, GA_NO_DEAD );
return CanSee( Sender, target, false, GA_NO_DEAD|GA_NO_UNSCHEDULED );
}

int GameScript::InParty(Scriptable* Sender, Trigger* parameters)
Expand Down
8 changes: 4 additions & 4 deletions gemrb/core/Map.cpp
Expand Up @@ -926,7 +926,7 @@ bool Map::DoStepForActor(Actor *actor, int speed, ieDword time) {
}

void Map::ClearSearchMapFor( Movable *actor ) {
Actor** nearActors = GetAllActorsInRadius(actor->Pos, GA_NO_DEAD|GA_NO_LOS, MAX_CIRCLE_SIZE*2*16);
Actor** nearActors = GetAllActorsInRadius(actor->Pos, GA_NO_DEAD|GA_NO_LOS|GA_NO_UNSCHEDULED, MAX_CIRCLE_SIZE*2*16);
BlockSearchMap( actor->Pos, actor->size, PATH_MAP_FREE);

// Restore the searchmap areas of any nearby actors that could
Expand Down Expand Up @@ -1810,7 +1810,7 @@ int Map::GetActorInRect(Actor**& actorlist, Region& rgn, bool onlyparty)
// this is called by non-selection code..
if (onlyparty && !actor->ValidTarget(GA_SELECT))
continue;
if (!actor->ValidTarget(GA_NO_DEAD) )
if (!actor->ValidTarget(GA_NO_DEAD|GA_NO_UNSCHEDULED))
continue;
if ((actor->Pos.x<rgn.x) || (actor->Pos.y<rgn.y))
continue;
Expand All @@ -1827,7 +1827,7 @@ bool Map::SpawnsAlive() const
size_t i = actors.size();
while (i--) {
Actor* actor = actors[i];
if (!actor->ValidTarget(GA_NO_DEAD) )
if (!actor->ValidTarget(GA_NO_DEAD|GA_NO_UNSCHEDULED))
continue;
if (actor->Spawned) {
return true;
Expand Down Expand Up @@ -3131,7 +3131,7 @@ void Map::UpdateSpawns()
//only reactivate the spawn point if the party cannot currently see it;
//also make sure the party has moved away some
if (spawn->NextSpawn < time && !IsVisible(spawn->Pos, false) &&
!GetActorInRadius(spawn->Pos, GA_NO_DEAD|GA_NO_ENEMY|GA_NO_NEUTRAL, SPAWN_RANGE * 2)) {
!GetActorInRadius(spawn->Pos, GA_NO_DEAD|GA_NO_ENEMY|GA_NO_NEUTRAL|GA_NO_UNSCHEDULED, SPAWN_RANGE * 2)) {
spawn->Method &= ~SPF_WAIT;
}
}
Expand Down
14 changes: 7 additions & 7 deletions gemrb/core/Scriptable/Actor.cpp
Expand Up @@ -5220,11 +5220,11 @@ bool Actor::ValidTarget(int ga_flags, Scriptable *checker) const
{
//scripts can still see this type of actor

//assuming that unscheduled actors can never be valid targets
Game *game = core->GetGame();
if (game) {
ieDword gametime = game->GameTime;
if (!Schedule(gametime, true)) return false;
if (ga_flags&GA_NO_UNSCHEDULED) {
Game *game = core->GetGame();
if (game) {
if (!Schedule(game->GameTime, true)) return false;
}
}

if (ga_flags&GA_NO_HIDDEN) {
Expand Down Expand Up @@ -9157,7 +9157,7 @@ bool Actor::SeeAnyOne(bool enemy, bool seenby)
Map *area = GetCurrentArea();
if (!area) return false;

int flag = seenby?GA_NO_DEAD:GA_NO_DEAD|GA_NO_HIDDEN;
int flag = (seenby?0:GA_NO_HIDDEN)|GA_NO_DEAD|GA_NO_UNSCHEDULED;
if (enemy) {
ieDword ea = GetSafeStat(IE_EA);
if (ea>=EA_EVILCUTOFF) {
Expand Down Expand Up @@ -9250,7 +9250,7 @@ bool Actor::TryToHide()
// skill check when trying to maintain invisibility: separate move silently and visibility check
bool Actor::TryToHideIWD2()
{
Actor **neighbours = area->GetAllActorsInRadius(Pos, GA_NO_DEAD|GA_NO_LOS|GA_NO_ALLY|GA_NO_NEUTRAL|GA_NO_SELF, 60);
Actor **neighbours = area->GetAllActorsInRadius(Pos, GA_NO_DEAD|GA_NO_LOS|GA_NO_ALLY|GA_NO_NEUTRAL|GA_NO_SELF|GA_NO_UNSCHEDULED, 60);
Actor **poi = neighbours;
ieDword roll = LuckyRoll(1, 20, GetArmorSkillPenalty(0));
int targetDC = 0;
Expand Down
2 changes: 2 additions & 0 deletions gemrb/core/Scriptable/Actor.h
Expand Up @@ -149,6 +149,8 @@ namespace GemRB {

// Detect() mode: IDS matching ignores invisibility
#define GA_DETECT 8192
//cannot target unscheduled actors
#define GA_NO_UNSCHEDULED 16384

#define VCONST_COUNT 100

Expand Down
2 changes: 1 addition & 1 deletion gemrb/core/Scriptable/Scriptable.cpp
Expand Up @@ -1170,7 +1170,7 @@ void Scriptable::SpellcraftCheck(const Actor *caster, const ieResRef SpellResRef
Spell* spl = gamedata->GetSpell(SpellResRef);
assert(spl); // only a bad surge could make this fail and we want to catch it
int AdjustedSpellLevel = spl->SpellLevel + 15;
Actor **neighbours = area->GetAllActorsInRadius(caster->Pos, GA_NO_DEAD|GA_NO_ENEMY|GA_NO_SELF, 10*caster->GetBase(IE_VISUALRANGE));
Actor **neighbours = area->GetAllActorsInRadius(caster->Pos, GA_NO_DEAD|GA_NO_ENEMY|GA_NO_SELF|GA_NO_UNSCHEDULED, 10*caster->GetBase(IE_VISUALRANGE));
Actor **poi = neighbours;
while (*poi) {
Actor *detective = *poi;
Expand Down

0 comments on commit 1529978

Please sign in to comment.