Skip to content

Commit

Permalink
Fix for issue #2924.
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.thedarkmod.com/svn/darkmod_src/trunk@5720 49c82d7f-2e2a-0410-a16f-ae8f201b507f
  • Loading branch information
grayman committed Mar 21, 2013
1 parent 118ed1e commit 2eb829d
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 27 deletions.
4 changes: 4 additions & 0 deletions game/ai/AI.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ extern const idEventDef AI_OnUnconsciousPersonEncounter; // grayman #3317

extern const idEventDef AI_AllowGreetings; // grayman #3338

extern const idEventDef AI_DelayedVisualStim; // grayman #2924

class idPathCorner;

typedef struct particleEmitter_s {
Expand Down Expand Up @@ -2240,6 +2242,8 @@ class idAI : public idActor {

void Event_AllowGreetings(); // grayman #3338

void Event_DelayedVisualStim(idEntity* stimSource); // grayman #2924

#ifdef TIMING_BUILD
private:
int aiThinkTimer;
Expand Down
15 changes: 13 additions & 2 deletions game/ai/AI_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,9 @@ const idEventDef AI_RestartPatrol( "restartPatrol", EventArgs(), EV_RETURNS_VOID
const idEventDef AI_OnDeadPersonEncounter( "<onDeadPersonEncounter>", EventArgs('e', "person", "the dead AI"), EV_RETURNS_VOID, "internal" ); // grayman #3317
const idEventDef AI_OnUnconsciousPersonEncounter( "<onUnconsciousPersonEncounter>", EventArgs('e', "person", "the unconscious AI"), EV_RETURNS_VOID, "internal" ); // grayman #3317

const idEventDef AI_AllowGreetings( "<allowGreetings>", EventArgs(), EV_RETURNS_VOID, "internal" ); // grayman #debug
const idEventDef AI_AllowGreetings( "<allowGreetings>", EventArgs(), EV_RETURNS_VOID, "internal" ); // grayman #3338

const idEventDef AI_DelayedVisualStim( "<delayedVisualStim>", EventArgs('e', "stimSource", ""), EV_RETURNS_VOID, "internal" ); // grayman #2924

/*
* This is the AI event table class for a generic NPC actor.
Expand Down Expand Up @@ -637,6 +639,7 @@ CLASS_DECLARATION( idActor, idAI )
EVENT ( AI_OnDeadPersonEncounter, idAI::Event_OnDeadPersonEncounter) // grayman #3317
EVENT ( AI_OnUnconsciousPersonEncounter, idAI::Event_OnUnconsciousPersonEncounter) // grayman #3317
EVENT ( AI_AllowGreetings, idAI::Event_AllowGreetings) // grayman #3338
EVENT ( AI_DelayedVisualStim, idAI::Event_DelayedVisualStim) // grayman #2924

END_CLASS

Expand Down Expand Up @@ -3630,7 +3633,6 @@ void idAI::Event_DropTorch() // grayman #2603
}
}


void idAI::Event_Bark(const char* soundName)
{
idStr bark = soundName;
Expand All @@ -3656,6 +3658,15 @@ void idAI::Event_AllowGreetings()
greetingState = ENotGreetingAnybody;
}

// grayman #2924

void idAI::Event_DelayedVisualStim(idEntity* stimSource)
{
mind->GetState()->DelayedVisualStim(stimSource, this);
}






Expand Down
7 changes: 7 additions & 0 deletions game/ai/States/CombatState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,13 @@ bool CombatState::CheckEnemyStatus(idActor* enemy, idAI* owner)
return true; // Enemy still alive and kicking
}

// grayman #2924 - don't process any stim that ends up here; we're busy

void CombatState::DelayedVisualStim(idEntity* stimSource, idAI* owner)
{
stimSource->AllowResponse(ST_VISUAL, owner); // see it again later
}

void CombatState::Save(idSaveGame* savefile) const
{
State::Save(savefile);
Expand Down
2 changes: 2 additions & 0 deletions game/ai/States/CombatState.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ class CombatState :
// Override base class method
virtual bool CheckAlertLevel(idAI* owner);

virtual void DelayedVisualStim( idEntity* stimSource, idAI* owner); // grayman #2924

// Checks enemy status (dead, visible, not an enemy anymore).
// Returns false if the enemy is not applicable anymore and the state has ended
bool CheckEnemyStatus(idActor* enemy, idAI* owner);
Expand Down
112 changes: 87 additions & 25 deletions game/ai/States/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ const int WARN_DIST_BODY_CAN_SHIFT = 100;

const int WARN_DIST_MAX_Z = 100; // no warning if the sender is farther than this vertically from the alert spot (same for each alert type)
//----------------------------------------------------------------------------------------
const int VIS_STIM_DELAY_MIN = 1500; // grayman #2924 - min amount of time delay (ms) before processing certain visual stims
const int VIS_STIM_DELAY_MAX = 3000; // grayman #2924 - max amount of time delay (ms) before processing certain visual stims
//----------------------------------------------------------------------------------------
// The following defines a key that should be non-0 if the device should be closed
#define AIUSE_SHOULDBECLOSED_KEY "shouldBeClosed"

Expand Down Expand Up @@ -885,60 +888,108 @@ void State::OnVisualStim(idEntity* stimSource)

// Process non-actor stim types

// grayman #2924 - Check whether this alert type should be
// processed, based on what other stims/alerts the AI has experienced.

switch(aiUseType)
{
case EAIuse_Weapon:
if (ShouldProcessAlert(EAlertTypeWeapon))
if (!ShouldProcessAlert(EAlertTypeWeapon))
{
OnVisualStimWeapon(stimSource,owner);
return;
}
break;
case EAIuse_Suspicious: // grayman #1327
if (ShouldProcessAlert(EAlertTypeSuspiciousItem))
if (!ShouldProcessAlert(EAlertTypeSuspiciousItem))
{
OnVisualStimSuspicious(stimSource,owner);
return;
}
break;
case EAIuse_Rope: // grayman #2872
if (ShouldProcessAlert(EAlertTypeRope))
{
OnVisualStimRope(stimSource,owner,ropeStimSource);
}
return;
break;
case EAIuse_Blood_Evidence:
if (ShouldProcessAlert(EAlertTypeBlood))
if (!ShouldProcessAlert(EAlertTypeBlood))
{
OnVisualStimBlood(stimSource,owner);
return;
}
break;
case EAIuse_Lightsource:
if (ShouldProcessAlert(EAlertTypeLightSource))
{
OnVisualStimLightSource(stimSource,owner);
}
return;
break;
case EAIuse_Missing_Item_Marker:
if (ShouldProcessAlert(EAlertTypeMissingItem))
if (!ShouldProcessAlert(EAlertTypeMissingItem))
{
OnVisualStimMissingItem(stimSource,owner);
return;
}
break;
case EAIuse_Broken_Item:
if (ShouldProcessAlert(EAlertTypeBrokenItem))
if (!ShouldProcessAlert(EAlertTypeBrokenItem))
{
OnVisualStimBrokenItem(stimSource,owner);
return;
}
break;
case EAIuse_Door:
if (ShouldProcessAlert(EAlertTypeDoor))
if (!ShouldProcessAlert(EAlertTypeDoor))
{
OnVisualStimDoor(stimSource,owner);
return;
}
break;
case EAIuse_Default:
default:
return;
break;
}

// grayman #2924 - We're going to process this visual stim.
// Ignore it in the future

stimSource->IgnoreResponse(ST_VISUAL, owner);

// Delay the processing randomly between VIS_STIM_DELAY_MIN and VIS_STIM_DELAY_MAX ms.

int delay = VIS_STIM_DELAY_MIN + gameLocal.random.RandomInt(VIS_STIM_DELAY_MAX - VIS_STIM_DELAY_MIN);

// Post the event to do the processing
owner->PostEventMS( &AI_DelayedVisualStim, delay, stimSource);
}

void State::DelayedVisualStim(idEntity* stimSource, idAI* owner)
{
idStr aiUse = stimSource->spawnArgs.GetString("AIUse");

if (aiUse == AIUSE_WEAPON)
{
OnVisualStimWeapon(stimSource,owner);
}
else if (aiUse == AIUSE_DOOR)
{
OnVisualStimDoor(stimSource,owner);
}
else if (aiUse == AIUSE_SUSPICIOUS)
{
OnVisualStimSuspicious(stimSource,owner);
}
else if (aiUse == AIUSE_BLOOD_EVIDENCE)
{
OnVisualStimBlood(stimSource,owner);
}
else if (aiUse == AIUSE_MISSING_ITEM_MARKER)
{
OnVisualStimMissingItem(stimSource,owner);
}
else if (aiUse == AIUSE_BROKEN_ITEM)
{
OnVisualStimBrokenItem(stimSource,owner);
}
}

bool State::ShouldProcessAlert(EAlertType newAlertType)
Expand All @@ -965,7 +1016,7 @@ void State::OnVisualStimWeapon(idEntity* stimSource, idAI* owner)
Memory& memory = owner->GetMemory();

// We've seen this object, don't respond to it again
stimSource->IgnoreResponse(ST_VISUAL, owner);
// stimSource->IgnoreResponse(ST_VISUAL, owner); // grayman #2924 - already done

if (stimSource->IsType(idWeapon::Type))
{
Expand Down Expand Up @@ -1031,6 +1082,7 @@ void State::OnVisualStimSuspicious(idEntity* stimSource, idAI* owner)

if ( owner->AI_AlertLevel >= owner->thresh_5 ) // grayman #2423 - pay no attention if in combat
{
stimSource->AllowResponse(ST_VISUAL, owner); // grayman #2924
return;
}

Expand Down Expand Up @@ -1537,7 +1589,7 @@ void State::OnActorEncounter(idEntity* stimSource, idAI* owner)
{
if ( InsideWarningVolume( memory.posEnemySeen, otherOrigin, WARN_DIST_ENEMY_SEEN ) ) // grayman #2903
{
gameLocal.Printf("%s sees %s, and warns that enemies have been seen.\n",owner->name.c_str(),other->name.c_str());
gameLocal.Printf("%d: %s sees %s, and warns that enemies have been seen.\n",gameLocal.time,owner->name.c_str(),otherAI->name.c_str());
message = CommMessagePtr(new CommMessage(
CommMessage::ConveyWarning_EnemiesHaveBeenSeen_CommType,
owner, other, // from this AI to the other
Expand All @@ -1561,7 +1613,7 @@ void State::OnActorEncounter(idEntity* stimSource, idAI* owner)
{
if ( InsideWarningVolume( memory.posCorpseFound, otherOrigin, WARN_DIST_CORPSE_FOUND ) ) // grayman #2903
{
gameLocal.Printf("%s sees %s, and warns that a dead person was found.\n",owner->name.c_str(),other->name.c_str());
gameLocal.Printf("%d: %s sees %s, and warns that a dead person was found.\n",gameLocal.time,owner->name.c_str(),otherAI->name.c_str());
message = CommMessagePtr(new CommMessage(
CommMessage::ConveyWarning_CorpseHasBeenSeen_CommType,
owner, other, // from this AI to the other
Expand All @@ -1582,7 +1634,7 @@ void State::OnActorEncounter(idEntity* stimSource, idAI* owner)
{
if ( InsideWarningVolume( memory.posMissingItem, otherOrigin, WARN_DIST_MISSING_ITEM ) ) // grayman #2903
{
gameLocal.Printf("%s sees %s, and warns that items were stolen.\n",owner->name.c_str(),other->name.c_str());
gameLocal.Printf("%d: %s sees %s, and warns that something missing.\n",gameLocal.time,owner->name.c_str(),otherAI->name.c_str());
message = CommMessagePtr(new CommMessage(
CommMessage::ConveyWarning_ItemsHaveBeenStolen_CommType,
owner, other, // from this AI to the other
Expand All @@ -1605,7 +1657,7 @@ void State::OnActorEncounter(idEntity* stimSource, idAI* owner)
{
if ( InsideWarningVolume( memory.posEvidenceIntruders, otherOrigin, WARN_DIST_EVIDENCE_INTRUDERS ) ) // grayman #2903
{
gameLocal.Printf("%s sees %s, and warns of evidence he's concerned about\n",owner->name.c_str(),other->name.c_str());
gameLocal.Printf("%d: %s sees %s, and warns of evidence he's concerned about\n",gameLocal.time,owner->name.c_str(),otherAI->name.c_str());
message = CommMessagePtr(new CommMessage(
CommMessage::ConveyWarning_EvidenceOfIntruders_CommType,
owner, other, // from this AI to the other
Expand Down Expand Up @@ -2721,7 +2773,7 @@ void State::OnVisualStimBlood(idEntity* stimSource, idAI* owner)
Memory& memory = owner->GetMemory();

// Ignore from now on
stimSource->IgnoreResponse(ST_VISUAL, owner);
// stimSource->IgnoreResponse(ST_VISUAL, owner); // grayman #2924 - already done

// angua: ignore blood after dead bodies have been found
/* grayman #3075 - no longer
Expand Down Expand Up @@ -3167,7 +3219,7 @@ void State::OnVisualStimMissingItem(idEntity* stimSource, idAI* owner)
Memory& memory = owner->GetMemory();

// We've seen this object, don't respond to it again
stimSource->IgnoreResponse(ST_VISUAL, owner);
// stimSource->IgnoreResponse(ST_VISUAL, owner); // grayman #2924 - already done

// Can we notice missing items
if (owner->spawnArgs.GetFloat("chanceNoticeMissingItem") <= 0.0)
Expand Down Expand Up @@ -3246,15 +3298,14 @@ void State::OnVisualStimMissingItem(idEntity* stimSource, idAI* owner)
}
}


void State::OnVisualStimBrokenItem(idEntity* stimSource, idAI* owner)
{
assert(stimSource != NULL && owner != NULL); // must be fulfilled

Memory& memory = owner->GetMemory();

// We've seen this object, don't respond to it again
stimSource->IgnoreResponse(ST_VISUAL, owner);
// stimSource->IgnoreResponse(ST_VISUAL, owner); // grayman #2924 - already done

gameLocal.Printf("Something is broken over there!\n");

Expand Down Expand Up @@ -3352,6 +3403,9 @@ void State::OnVisualStimDoor(idEntity* stimSource, idAI* owner)
Memory& memory = owner->GetMemory();
CFrobDoor* door = static_cast<CFrobDoor*>(stimSource);

// grayman #2924 - enable the response
stimSource->AllowResponse(ST_VISUAL, owner);

// Update the info structure for this door
DoorInfo& doorInfo = memory.GetDoorInfo(door);

Expand Down Expand Up @@ -3553,6 +3607,14 @@ void State::OnAICommMessage(CommMessage& message, float psychLoud)

idEntity* issuingEntity = message.m_p_issuingEntity.GetEntity();
idEntity* recipientEntity = message.m_p_recipientEntity.GetEntity();

// grayman #2924 - was this message was meant for me? If recipientEntity
// is me or is NULL, I'll listen to it. Otherwise, I'll ignore it.
if ( recipientEntity && ( recipientEntity != owner ) )
{
return;
}

idEntity* directObjectEntity = message.m_p_directObjectEntity.GetEntity();
const idVec3& directObjectLocation = message.m_directObjectLocation;

Expand Down Expand Up @@ -3873,7 +3935,7 @@ void State::OnAICommMessage(CommMessage& message, float psychLoud)
}
}

gameLocal.Printf("%s has been warned by %s about evidence of intruders.\n",owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
gameLocal.Printf("%d: %s has been warned by %s about evidence of intruders.\n",gameLocal.time,owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
// grayman #2920 - issue a delayed warning response
owner->PostEventMS(&AI_Bark,WARNING_RESPONSE_DELAY,"snd_warn_response");
}
Expand Down Expand Up @@ -3902,7 +3964,7 @@ void State::OnAICommMessage(CommMessage& message, float psychLoud)
owner->SetAlertLevel(owner->thresh_2*0.5f);
}

gameLocal.Printf("%s has been warned by %s that items were stolen.\n",owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
gameLocal.Printf("%d: %s has been warned by %s that items were stolen.\n",gameLocal.time,owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
// grayman #2920 - issue a delayed warning response
owner->PostEventMS(&AI_Bark,WARNING_RESPONSE_DELAY,"snd_warn_response");
break;
Expand Down Expand Up @@ -3930,7 +3992,7 @@ void State::OnAICommMessage(CommMessage& message, float psychLoud)
owner->SetAlertLevel(owner->thresh_2*0.5f);
}

gameLocal.Printf("%s has been warned by %s that a dead person was found.\n",owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
gameLocal.Printf("%d: %s has been warned by %s that a dead person was found.\n",gameLocal.time,owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
// grayman #2920 - issue a delayed warning response
owner->PostEventMS(&AI_Bark,WARNING_RESPONSE_DELAY,"snd_warn_response");
break;
Expand All @@ -3953,7 +4015,7 @@ void State::OnAICommMessage(CommMessage& message, float psychLoud)
owner->SetAlertLevel(owner->thresh_2*0.5f);
}

gameLocal.Printf("%s has been warned by %s that an enemy was seen.\n",owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
gameLocal.Printf("%d: %s has been warned by %s that an enemy was seen.\n",gameLocal.time,owner->name.c_str(),issuingEntity ? issuingEntity->name.c_str():"NULL");
// grayman #2920 - issue a delayed warning response
owner->PostEventMS(&AI_Bark,WARNING_RESPONSE_DELAY,"snd_warn_response");
break;
Expand Down
3 changes: 3 additions & 0 deletions game/ai/States/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ class State
virtual void Post_OnDeadActorEncounter(idActor* person, idAI* owner);
virtual void Post_OnUnconsciousActorEncounter(idActor* person, idAI* owner);

// grayman #2924 - process visual stims after a delay
virtual void DelayedVisualStim( idEntity* stimSource, idAI* owner);

/**
* greebo: Called if an attacker performed a failed knockout attack
*
Expand Down

0 comments on commit 2eb829d

Please sign in to comment.