Files
FC1/CryGame/ScriptObjectAI.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

1452 lines
42 KiB
C++

//////////////////////////////////////////////////////////////////////
//
// Crytek Source code
// Copyright (c) Crytek 2001-2004
//
// File: ScriptObjectAI.cpp
//
// Description:
// ScriptObjectAI.cpp: implementation of the CScriptObjectAI class.
//
// History:
// - created by Marco C.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ScriptObjectAI.h"
#include "ScriptObjectVector.h"
#include <IAISystem.h>
#include <IAgent.h>
#include <ISound.h>
#include <physinterface.h>
#include "XObjectProxy.h"
#include "XPuppetProxy.h"
#include "XVehicleProxy.h"
#include "XPlayer.h"
#include "XVehicle.h"
#include "ScriptObjectAI.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
_DECLARE_SCRIPTABLEEX(CScriptObjectAI)
//////////////////////////////////////////////////////////////////////
CScriptObjectAI::CScriptObjectAI()
{
}
//////////////////////////////////////////////////////////////////////
CScriptObjectAI::~CScriptObjectAI()
{
}
//////////////////////////////////////////////////////////////////////
void CScriptObjectAI::Init(IScriptSystem *pScriptSystem, ISystem *pSystem, CXGame *pGame)
{
m_pScriptSystem = pScriptSystem;
m_pEntitySystem = pSystem->GetIEntitySystem();
m_pAISystem = pSystem->GetAISystem();
m_pSoundSystem = pSystem->GetISoundSystem();
m_pLog = pSystem->GetILog();
m_pGame = pGame;
InitGlobal(pScriptSystem,"AI",this);
//! Set some defines
m_pScriptSystem->SetGlobalValue("AIPARAM_SIGHTRANGE",1);
m_pScriptSystem->SetGlobalValue("AIPARAM_ATTACKRANGE",2);
m_pScriptSystem->SetGlobalValue("AIPARAM_ACCURACY",3);
m_pScriptSystem->SetGlobalValue("AIPARAM_AGGRESION",4);
m_pScriptSystem->SetGlobalValue("AIPARAM_GROUPID",5);
m_pScriptSystem->SetGlobalValue("AIPARAM_SOUNDRANGE",6);
m_pScriptSystem->SetGlobalValue("AIPARAM_FOV",7);
m_pScriptSystem->SetGlobalValue("AIPARAM_COMMRANGE",8);
m_pScriptSystem->SetGlobalValue("AIPARAM_FWDSPEED", 9);
m_pScriptSystem->SetGlobalValue("AIPARAM_RESPONSIVENESS", 10);
m_pScriptSystem->SetGlobalValue("AIPARAM_SPECIES", 11);
pScriptSystem->SetGlobalValue("AIOBJECT_PUPPET", AIOBJECT_PUPPET);
// pScriptSystem->SetGlobalValue("AIOBJECT_VEHICLE", AIOBJECT_VEHICLE);
pScriptSystem->SetGlobalValue("AIOBJECT_CAR", AIOBJECT_CAR);
pScriptSystem->SetGlobalValue("AIOBJECT_BOAT", AIOBJECT_BOAT);
pScriptSystem->SetGlobalValue("AIOBJECT_HELICOPTER", AIOBJECT_HELICOPTER);
pScriptSystem->SetGlobalValue("AIOBJECT_ATTRIBUTE", AIOBJECT_ATTRIBUTE);
pScriptSystem->SetGlobalValue("AIOBJECT_WAYPOINT", AIOBJECT_WAYPOINT);
pScriptSystem->SetGlobalValue("AIOBJECT_SNDSUPRESSOR", AIOBJECT_SNDSUPRESSOR);
pScriptSystem->SetGlobalValue("AIOBJECT_MOUNTEDWEAPON", AIOBJECT_MOUNTEDWEAPON);
pScriptSystem->SetGlobalValue("AIOBJECT_PLAYER", AIOBJECT_PLAYER);
pScriptSystem->SetGlobalValue("AIOBJECT_DUMMY", AIOBJECT_DUMMY);
pScriptSystem->SetGlobalValue("AIOBJECT_NONE", AIOBJECT_NONE);
pScriptSystem->SetGlobalValue("AIEVENT_ONBODYSENSOR", AIEVENT_ONBODYSENSOR);
pScriptSystem->SetGlobalValue("AIEVENT_ONVISUALSTIMULUS", AIEVENT_ONVISUALSTIMULUS);
pScriptSystem->SetGlobalValue("AIEVENT_AGENTDIED", AIEVENT_AGENTDIED);
pScriptSystem->SetGlobalValue("AIEVENT_SLEEP", AIEVENT_SLEEP);
pScriptSystem->SetGlobalValue("AIEVENT_WAKEUP", AIEVENT_WAKEUP);
pScriptSystem->SetGlobalValue("AIEVENT_ENABLE", AIEVENT_ENABLE);
pScriptSystem->SetGlobalValue("AIEVENT_DISABLE", AIEVENT_DISABLE);
pScriptSystem->SetGlobalValue("AIEVENT_REJECT", AIEVENT_REJECT);
pScriptSystem->SetGlobalValue("AIEVENT_PATHFINDON", AIEVENT_PATHFINDON);
pScriptSystem->SetGlobalValue("AIEVENT_PATHFINDOFF", AIEVENT_PATHFINDOFF);
pScriptSystem->SetGlobalValue("AIEVENT_CLEAR", AIEVENT_CLEAR);
pScriptSystem->SetGlobalValue("AIEVENT_DROPBEACON", AIEVENT_DROPBEACON);
pScriptSystem->SetGlobalValue("AIREADIBILITY_NORMAL",AIREADIBILITY_NORMAL);
pScriptSystem->SetGlobalValue("AIREADIBILITY_NOPRORITY",AIREADIBILITY_NOPRIORITY);
pScriptSystem->SetGlobalValue("AIREADIBILITY_SEEN",AIREADIBILITY_SEEN);
pScriptSystem->SetGlobalValue("AIREADIBILITY_LOST",AIREADIBILITY_LOST);
pScriptSystem->SetGlobalValue("AIREADIBILITY_INTERESTING",AIREADIBILITY_INTERESTING);
pScriptSystem->SetGlobalValue("SIGNALID_THROWGRENADE",-10);
pScriptSystem->SetGlobalValue("SIGNALID_READIBILITY",100);
pScriptSystem->SetGlobalValue("SIGNALFILTER_LASTOP", 1);
pScriptSystem->SetGlobalValue("SIGNALFILTER_GROUPONLY", 2);
pScriptSystem->SetGlobalValue("SIGNALFILTER_SPECIESONLY", 3);
pScriptSystem->SetGlobalValue("SIGNALFILTER_ANYONEINCOMM",4);
pScriptSystem->SetGlobalValue("SIGNALFILTER_TARGET", 5);
pScriptSystem->SetGlobalValue("SIGNALFILTER_SUPERGROUP", 6);
pScriptSystem->SetGlobalValue("SIGNALFILTER_SUPERSPECIES",7);
pScriptSystem->SetGlobalValue("SIGNALFILTER_SUPERTARGET", 8);
pScriptSystem->SetGlobalValue("SIGNALFILTER_NEARESTGROUP",9);
pScriptSystem->SetGlobalValue("SIGNALFILTER_NEARESTINCOMM",SIGNALFILTER_NEARESTINCOMM);
pScriptSystem->SetGlobalValue("SIGNALFILTER_HALFOFGROUP",12);
pScriptSystem->SetGlobalValue("HM_NEAREST",0);
pScriptSystem->SetGlobalValue("HM_FARTHEST_FROM_TARGET",1);
pScriptSystem->SetGlobalValue("HM_NEAREST_TO_TARGET",2);
pScriptSystem->SetGlobalValue("HM_FARTHEST_FROM_GROUP",3);
pScriptSystem->SetGlobalValue("HM_NEAREST_TO_GROUP",4);
pScriptSystem->SetGlobalValue("HM_LEFTMOST_FROM_TARGET",5);
pScriptSystem->SetGlobalValue("HM_RIGHTMOST_FROM_TARGET",6);
pScriptSystem->SetGlobalValue("HM_RANDOM",7);
pScriptSystem->SetGlobalValue("HM_FRONTLEFTMOST_FROM_TARGET",8);
pScriptSystem->SetGlobalValue("HM_FRONTRIGHTMOST_FROM_TARGET",9);
pScriptSystem->SetGlobalValue("HM_NEAREST_TO_FORMATION",10);
pScriptSystem->SetGlobalValue("HM_FARTHEST_FROM_FORMATION",11);
pScriptSystem->SetGlobalValue("HM_NEAREST_TO_LASTOPRESULT",20);
pScriptSystem->SetGlobalValue("HM_FARTHEST_FROM_LASTOPRESULT",21);
pScriptSystem->SetGlobalValue("HM_NEAREST_TO_LASTOPRESULT_NOSAME",22);
pScriptSystem->SetGlobalValue("BODYPOS_STAND",BODYPOS_STAND);
pScriptSystem->SetGlobalValue("BODYPOS_CROUCH",BODYPOS_CROUCH);
pScriptSystem->SetGlobalValue("BODYPOS_PRONE",BODYPOS_PRONE);
pScriptSystem->SetGlobalValue("BODYPOS_RELAX",BODYPOS_RELAX);
pScriptSystem->SetGlobalValue("BODYPOS_STEALTH",BODYPOS_STEALTH);
}
//////////////////////////////////////////////////////////////////////
void CScriptObjectAI::InitializeTemplate(IScriptSystem *pSS)
{
_ScriptableEx<CScriptObjectAI>::InitializeTemplate(pSS);
REG_FUNC(CScriptObjectAI,CreateGoalPipe);
REG_FUNC(CScriptObjectAI,PushGoal);
REG_FUNC(CScriptObjectAI,Signal);
REG_FUNC(CScriptObjectAI,FreeSignal);
REG_FUNC(CScriptObjectAI,SoundEvent);
REG_FUNC(CScriptObjectAI,GetGroupCount);
REG_FUNC(CScriptObjectAI,Log);
REG_FUNC(CScriptObjectAI,MakePuppetIgnorant);
REG_FUNC(CScriptObjectAI,GetAttentionTargetOf);
REG_FUNC(CScriptObjectAI,SetAssesmentMultiplier);
REG_FUNC(CScriptObjectAI,FindObjectOfType);
REG_FUNC(CScriptObjectAI,GetGroupOf);
REG_FUNC(CScriptObjectAI,GetAnchor);
REG_FUNC(CScriptObjectAI,GetPerception);
REG_FUNC(CScriptObjectAI,RegisterWithAI);
REG_FUNC(CScriptObjectAI,AIBind);
REG_FUNC(CScriptObjectAI,CreateBoundObject);
REG_FUNC(CScriptObjectAI,Cloak);
REG_FUNC(CScriptObjectAI,DeCloak);
REG_FUNC(CScriptObjectAI,ProjectileShoot);
REG_FUNC(CScriptObjectAI,SetTheSkip);
REG_FUNC(CScriptObjectAI,SetAllowedDeathCount);
REG_FUNC(CScriptObjectAI,Checkpoint);
REG_FUNC(CScriptObjectAI,RegisterPlayerHit);
REG_FUNC(CScriptObjectAI,FireOverride);
REG_FUNC(CScriptObjectAI,SetSpeciesThreatMultiplier);
REG_FUNC(CScriptObjectAI,EnablePuppetMovement);
REG_FUNC(CScriptObjectAI,IsMoving);
REG_FUNC(CScriptObjectAI,EnableNodesInSphere);
REG_FUNC(CScriptObjectAI,GetStats);
}
/*!Create a sequence of AI atomic commands (a goal pipe)
@param desired name of the goal pipe
*/
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::CreateGoalPipe(IFunctionHandler *pH)
{
CHECK_PARAMETERS(1);
const char *name;
pH->GetParam(1,name);
IGoalPipe *pPipe = m_pAISystem->CreateGoalPipe(name);
// m_mapGoals.insert(goalmap::iterator::value_type(name,pPipe));
return pH->EndFunctionNull();
}
/*!Push a goal into a goal pipe. The goal is appended at the end of the goal pipe. Pipe of given name has to be previously created.
@param name of the goal pipe in which the goal will be pushed.
@param name of atomic goal that needs to be pushed into the pipe
@param 1 if the goal should block the pipe execution, 0 if the goal should not block the goal execution
@see CScriptObjectAI::CreateGoalPipe
*/
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::PushGoal(IFunctionHandler *pH)
{
const char *pipename;
const char *temp;
string goalname;
// int id;
GoalParameters params;
bool blocking;
pH->GetParam(1,pipename);
pH->GetParam(2,temp);
pH->GetParam(3,blocking);
goalname = temp;
IGoalPipe *pPipe=0;
if (!(pPipe = m_pAISystem->OpenGoalPipe(pipename)))
return pH->EndFunctionNull();
if (goalname == AIOP_ACQUIRETARGET)
{
pH->GetParam(4,temp);
IAIObject *pObject = m_pAISystem->GetAIObjectByName(AIOBJECT_WAYPOINT,temp);
params.m_pTarget = pObject;
pPipe->PushGoal(AIOP_ACQUIRETARGET,blocking,params);
}
else if (goalname == AIOP_FORM)
{
pH->GetParam(4,temp);
params.szString = temp;
pPipe->PushGoal(AIOP_FORM,blocking,params);
}
else if (goalname == AIOP_PATHFIND)
{
pH->GetParam(4,temp);
IAIObject *pObject = 0;
if (strlen(temp) > 0)
pObject = m_pAISystem->GetAIObjectByName(0,temp);
params.m_pTarget = pObject;
params.szString = temp;
pPipe->PushGoal(AIOP_PATHFIND,blocking,params);
}
else if (goalname == AIOP_LOCATE)
{
if (pH->GetParamType(4) == svtString)
{
const char *temp;
pH->GetParam(4,temp);
params.szString = temp;
params.nValue = 0;
}
else if (pH->GetParamType(4) == svtNumber)
{
params.szString.clear();
pH->GetParam(4,params.nValue);
}
pPipe->PushGoal(AIOP_LOCATE,blocking,params);
}
else if (goalname == AIOP_HIDE)
{
pH->GetParam(4,params.fValue);
pH->GetParam(5,params.nValue);
if (pH->GetParamCount() > 5 )
pH->GetParam(6,params.bValue);
else
params.bValue = false;
pPipe->PushGoal(AIOP_HIDE,blocking,params);
}
else if (goalname == AIOP_JUMP)
{
pH->GetParam(4,params.fValue);
pH->GetParam(5,params.nValue);
if (pH->GetParamCount() > 5 )
pH->GetParam(6,params.bValue);
else
params.bValue = false;
if (pH->GetParamCount()>6)
pH->GetParam(7,params.fValueAux);
else
params.fValueAux = 20.f; // default degrees for jump
pPipe->PushGoal(AIOP_JUMP,blocking,params);
}
else if (goalname == AIOP_TRACE)
{
if (pH->GetParamCount()>3)
{
pH->GetParam(4,params.nValue);
if (pH->GetParamCount() > 4)
pH->GetParam(5,params.fValue);
else
params.fValue = 0;
}
else
{
params.fValue = 0;
params.nValue = 0;
}
pPipe->PushGoal(AIOP_TRACE,blocking,params);
}
else if (goalname == AIOP_LOOKAT)
{
pH->GetParam(4,params.fValue);
pH->GetParam(5,params.nValue);
pPipe->PushGoal(AIOP_LOOKAT,blocking,params);
}
else if (goalname == AIOP_SIGNAL)
{
pH->GetParam(4,params.fValue); // get the signal id
params.nValue = 0;
if (pH->GetParamCount()>4)
{
const char *sTemp;
pH->GetParam(5,sTemp); // get the signal text
params.szString = sTemp;
}
if (pH->GetParamCount()>5)
{
pH->GetParam(6,params.nValue); // get the desired filter
}
pPipe->PushGoal(AIOP_SIGNAL,blocking,params);
}
else if (goalname == AIOP_APPROACH)
{
pH->GetParam(4,params.fValue);
if (params.fValue < 1)
params.nValue = 1;
else
params.nValue = 0;
if (pH->GetParamCount() > 4)
{
int useLastOpRes=0;
pH->GetParam(5,useLastOpRes);
params.bValue = (useLastOpRes!=0);
}
else
params.bValue = false;
pPipe->PushGoal(goalname,blocking,params);
}
else if (goalname == AIOP_BACKOFF)
{
pH->GetParam(4,params.fValue);
if (params.fValue < 1)
params.nValue = 1;
else
params.nValue = 0;
pPipe->PushGoal(goalname,blocking,params);
}
else if (goalname == AIOP_TIMEOUT)
{
pH->GetParam(4,params.fValue);
if (pH->GetParamCount() > 4)
pH->GetParam(5,params.fValueAux);
else
params.fValueAux = 0;
pPipe->PushGoal(goalname,blocking,params);
}
else if (goalname == AIOP_LOOP)
{
pH->GetParam(4,params.fValue);
if (pH->GetParamCount() > 4)
pH->GetParam(5,params.nValue);
else
params.nValue = 0;
pPipe->PushGoal(goalname,blocking,params);
}
else if ( pH->GetParamCount() > 3 )
{
// with float parametar one
pH->GetParam(4,params.fValue);
pPipe->PushGoal(goalname,blocking,params);
}
else
{
// without parameters
pPipe->PushGoal(goalname,blocking,params);
}
return pH->EndFunctionNull();
}
/*!Generates a sound event in the AI system with the given parameters.
@param id of the sound that is played for this event
@param position of the origin of the sound event
@param radius in which this sound event should be heard
@param threat value of the sound event
@param interest value of the sound event
@param id of the entity who generated this sound event
*/
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::SoundEvent(IFunctionHandler *pH)
{
CHECK_PARAMETERS(6);
float fThreat,fInterest,fRadius;
int nID;
USER_DATA val;
int cookie;
pH->GetParamUDVal(1,val,cookie);
CScriptObjectVector oVec(m_pScriptSystem,true);
pH->GetParam(2,*oVec);
pH->GetParam(3,fRadius);
pH->GetParam(4,fThreat);
pH->GetParam(5,fInterest);
pH->GetParam(6,nID);
Vec3d pos = oVec.Get();
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity)
{
if (pEntity->GetAI())
{
m_pAISystem->SoundEvent(val,pos,fRadius,fThreat,fInterest,pEntity->GetAI());
//if (stricmp("Player",pEntity->GetName())!=0)
// m_pLog->LogToConsole("SoundEvent,%s, position=%f,%f,%f",pEntity->GetName(),pos.x,pos.y,pos.z);
}
}
return pH->EndFunction();
}
/*!Log into special AI log file
@param string to log
*/
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::Log(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
const char *pLogText;
pH->GetParam(1,pLogText);
/*
m_pLog->SetFileName("AILOG.txt");
m_pLog->LogToFile(pLogText);
m_pLog->SetFileName("Log.txt");
*/
return pH->EndFunction();
}
/*!Sends a signal to ai objects defined by the parameters given
@param filter which defines to which subset of the ai object this signal will be delivered. One of the SIGNALFILTER_ defines
@param integer defining the signal (value bigger than zero). If you are not sure, put 1
@param text which will be sent using the signal
@param entity id of the entity sending this signal
*/
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::Signal(IFunctionHandler * pH)
{
CHECK_PARAMETERS(4);
int cFilter;
int nSignalID;
const char *szSignalText;
int EntityID;
pH->GetParam(1,cFilter);
pH->GetParam(2,nSignalID);
pH->GetParam(3,szSignalText);
pH->GetParam(4,EntityID);
IEntity *pEntity = m_pEntitySystem->GetEntity(EntityID);
if ((pEntity) && (pEntity->GetAI()))
m_pAISystem->SendSignal(cFilter,nSignalID,szSignalText,pEntity->GetAI());
return pH->EndFunction();
}
/*!Returns number of objects in a given group
@param the id of the desired group
*/
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::GetGroupCount(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1)
int nEntityID;
pH->GetParam(1,nEntityID);
IEntity *pEntity = m_pEntitySystem->GetEntity(nEntityID);
if (pEntity)
{
IAIObject *pObject = pEntity->GetAI();
if (pObject)
{
IPuppet *pPuppet=0;
if (pObject->CanBeConvertedTo(AIOBJECT_PUPPET,(void**)&pPuppet))
{
AgentParameters ap = pPuppet->GetPuppetParameters();
return pH->EndFunction(m_pAISystem->GetGroupCount(ap.m_nGroup));
}
}
}
return pH->EndFunction(0);
}
/*! Retrieves the attention target of a given entity
*/
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::GetAttentionTargetOf(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
int nID;
pH->GetParam(1,nID);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity && pEntity->GetAI())
{
IAIObject *pObject = pEntity->GetAI();
IPipeUser *pPipeUser = 0;
if (pObject->CanBeConvertedTo(AIOBJECT_PIPEUSER,(void**) &pPipeUser))
{
IAIObject *pTheTarget = pPipeUser->GetAttentionTarget();
if (pTheTarget)
{
IEntity *pTargetEntity = 0;
if (pTheTarget->GetType()==AIOBJECT_PLAYER || pTheTarget->GetType()==AIOBJECT_PUPPET)
pTargetEntity = (IEntity *) pTheTarget->GetAssociation();
if (pTargetEntity)
return pH->EndFunction(pTargetEntity->GetScriptObject());
else
{
if (pTheTarget->GetType()==AIOBJECT_DUMMY)
return pH->EndFunction(AIOBJECT_DUMMY);
else
return pH->EndFunction(AIOBJECT_NONE);
}
}
}
}
return pH->EndFunctionNull();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::ReloadAll(IFunctionHandler * pH)
{
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::MakePuppetIgnorant(IFunctionHandler * pH)
{
CHECK_PARAMETERS(2);
int nID;
bool bIgnorant;
pH->GetParam(1,nID);
pH->GetParam(2,bIgnorant);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity && pEntity->GetAI())
{
IAIObject *pObject = pEntity->GetAI();
IPuppet *pPuppet = 0;
if (pObject->CanBeConvertedTo(AIOBJECT_PUPPET,(void**) &pPuppet))
{
AgentParameters params = pPuppet->GetPuppetParameters();
params.m_bIgnoreTargets = bIgnorant;
pPuppet->SetPuppetParameters(params);
}
}
return pH->EndFunctionNull();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::FreeSignal(IFunctionHandler * pH)
{
//CHECK_PARAMETERS(4);
float fRadius;
int nSignalID,nID = 0;
const char *szSignalText;
CScriptObjectVector vPos(m_pScriptSystem,true);
pH->GetParam(1,nSignalID);
pH->GetParam(2,szSignalText);
pH->GetParam(3,vPos);
pH->GetParam(4,fRadius);
if (pH->GetParamCount()>4)
pH->GetParam(5,nID);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
IAIObject *pObject=0;
if (pEntity)
{
pObject = pEntity->GetAI();
}
m_pAISystem->SendAnonimousSignal(nSignalID,szSignalText,vPos.Get(),fRadius,pObject);
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::SetAssesmentMultiplier(IFunctionHandler * pH)
{
CHECK_PARAMETERS(2)
int type;
float fMultiplier;
pH->GetParam(1,type);
pH->GetParam(2,fMultiplier);
if (type < 0)
{
m_pLog->Log("\002[AIWARNING] Tried to set assesment multiplier to a negative type. Not allowed.");
return pH->EndFunction();
}
m_pAISystem->SetAssesmentMultiplier((unsigned short)type, fMultiplier);
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::SetSpeciesThreatMultiplier(IFunctionHandler * pH)
{
CHECK_PARAMETERS(2)
int species;
float fMultiplier;
pH->GetParam(1,species);
pH->GetParam(2,fMultiplier);
m_pAISystem->SetSpeciesThreatMultiplier(species, fMultiplier);
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::FindObjectOfType(IFunctionHandler * pH)
{
int type;
Vec3d pos;
float fRadius;
int nFlags = 0;
CScriptObjectVector vPos(m_pScriptSystem,true);
if (pH->GetParamType(1) == svtNumber)
{
int nID;
pH->GetParam(1,nID);
pH->GetParam(2,fRadius);
pH->GetParam(3,type);
if (pH->GetParamCount()>3)
pH->GetParam(4,nFlags);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity)
{
if (pEntity->GetAI())
{
IAIObject *pObject = m_pAISystem->GetNearestObjectOfType(pEntity->GetAI(),type, fRadius,nFlags);
if (pObject)
{
if (type==6)
{
m_pLog->Log("\001 Entity %s requested a waypoint anchor! Here is a dump of its state:");
m_pAISystem->DumpStateOf(pObject);
return pH->EndFunctionNull();
}
IEntity *pEntity = (IEntity*)pObject->GetAssociation();
if (pEntity)
{
pEntity->SendScriptEvent(ScriptEvent_Activate,0);
if (pEntity->GetAI() != pObject)
return pH->EndFunctionNull();
else
return pH->EndFunction(pObject->GetName());
}
else
return pH->EndFunction(pObject->GetName());
}
}
}
}
else
{
CScriptObjectVector vReturnPos(m_pScriptSystem,true);
pH->GetParam(1,vPos);
pH->GetParam(2,fRadius);
pH->GetParam(3,type);
if (pH->GetParamCount()>3)
pH->GetParam(4,vReturnPos);
IAIObject *pObject = m_pAISystem->GetNearestObjectOfType(vPos.Get(),type, fRadius);
if (pObject)
{
IEntity *pEntity = (IEntity*)pObject->GetAssociation();
if (pEntity)
pEntity->SendScriptEvent(ScriptEvent_Activate,0);
vReturnPos.Set(pObject->GetPos());
return pH->EndFunction(pObject->GetName());
}
}
return pH->EndFunctionNull();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::GetGroupOf(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
int nID;
pH->GetParam(1,nID);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
IAIObject *pObject=0;
if (pEntity)
{
pObject = pEntity->GetAI();
if (pObject)
{
IPuppet *pPuppet = 0;
if (pObject->CanBeConvertedTo(AIOBJECT_PUPPET,(void**)&pPuppet))
{
return pH->EndFunction(pPuppet->GetPuppetParameters().m_nGroup);
}
}
}
return pH->EndFunction(0);
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::GetAnchor(IFunctionHandler * pH)
{
CHECK_PARAMETERS(3);
int nAnchor;
int nID;
float fRadius;
pH->GetParam(1,nID);
pH->GetParam(2,nAnchor);
pH->GetParam(3,fRadius);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
IAIObject *pObject = 0;
if (pEntity)
{
pObject = pEntity->GetAI();
if (pObject)
{
IAIObject *pAnchor = m_pAISystem->GetNearestToObject(pObject,nAnchor,fRadius);
if (pAnchor)
return pH->EndFunction(pAnchor->GetName());
}
}
return pH->EndFunctionNull();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::GetPerception(IFunctionHandler * pH)
{
if (m_pAISystem && m_pGame)
{
if (m_pGame->GetMyPlayer())
{
if (m_pGame->GetMyPlayer()->GetAI())
return pH->EndFunction(m_pAISystem->GetPerceptionValue(m_pGame->GetMyPlayer()->GetAI()));
}
}
return pH->EndFunction(0);
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::RegisterWithAI(IFunctionHandler *pH)
{
// CHECK_PARAMETERS(3);
AIObjectParameters params;
_SmartScriptObject pTable(m_pScriptSystem,true);
_SmartScriptObject pTableInstance(m_pScriptSystem,true);
int type;
_SmartScriptObject pObj(m_pScriptSystem,true);
_SmartScriptObject pTempObj(m_pScriptSystem,true);
IEntity *pEntity;
int nID;
float fRadius = 0;
params.bUsePathfindOutdoors = true;
pH->GetParam(1,nID);
pEntity=m_pEntitySystem->GetEntity(nID);
if(pEntity==NULL)
{
TRACE("CScriptObjectAI::RegisterWithAI() entity in nil");
return pH->EndFunctionNull();
}
pH->GetParam(2,type);
switch (type)
{
case AIOBJECT_PUPPET:
{
float fwdspeed,bckspeed;
CXPuppetProxy *pProxy;
pProxy = new CXPuppetProxy(pEntity,m_pScriptSystem,m_pGame);
if (pH->GetParamCount() > 2)
pH->GetParam(3,*pTable);
else
return pH->EndFunction();
if (pH->GetParamCount() > 3)
pH->GetParam(4,*pTableInstance);
else
return pH->EndFunction();
if (!pTable->GetValue("special",params.m_sParamStruct.m_bSpecial))
params.m_sParamStruct.m_bSpecial = false;
if (!pTable->GetValue("aggression",params.m_sParamStruct.m_fAggression))
if (!pTableInstance->GetValue("aggression",params.m_sParamStruct.m_fAggression))
return pH->EndFunction();
if (!pTable->GetValue("sightrange",params.m_sParamStruct.m_fSightRange))
if (!pTableInstance->GetValue("sightrange",params.m_sParamStruct.m_fSightRange))
return pH->EndFunction();
pTable->GetValue("fSpeciesHostility",params.m_sParamStruct.m_fSpeciesHostility);
pTable->GetValue("bAffectSOM",params.m_sParamStruct.m_bPerceivePlayer);
pTable->GetValue("bAwareOfPlayerTargeting",params.m_sParamStruct.m_bAwareOfPlayerTargeting);
pTable->GetValue("fMeleeDistance",params.m_sParamStruct.m_fMeleeDistance);
pTable->GetValue("fGroupHostility",params.m_sParamStruct.m_fGroupHostility);
pTable->GetValue("fPersistence",params.m_sParamStruct.m_fPersistence);
if (!pTable->GetValue("bSmartMelee",params.m_sParamStruct.m_bSmartMelee))
if (!pTableInstance->GetValue("bSmartMelee",params.m_sParamStruct.m_bSmartMelee))
params.m_sParamStruct.m_bSmartMelee = true;
if (!pTable->GetValue("soundrange",params.m_sParamStruct.m_fSoundRange))
if (!pTableInstance->GetValue("soundrange",params.m_sParamStruct.m_fSoundRange))
return pH->EndFunction();
if (!pTable->GetValue("attackrange",params.m_sParamStruct.m_fAttackRange))
if (!pTableInstance->GetValue("attackrange",params.m_sParamStruct.m_fAttackRange))
return pH->EndFunction();
if (!pTable->GetValue("commrange",params.m_sParamStruct.m_fCommRange))
if (!pTableInstance->GetValue("commrange",params.m_sParamStruct.m_fCommRange))
return pH->EndFunction();
if (!pTable->GetValue("horizontal_fov",params.m_sParamStruct.m_fHorizontalFov))
if (!pTableInstance->GetValue("horizontal_fov",params.m_sParamStruct.m_fHorizontalFov))
return pH->EndFunction();
if (!pTable->GetValue("gravity_multiplier",params.m_sParamStruct.m_fGravityMultiplier))
params.m_sParamStruct.m_fGravityMultiplier = 1.f;
pTable->GetValue("eye_height",params.fEyeHeight);
pTable->GetValue("max_health",params.m_sParamStruct.m_fMaxHealth);
if (!pTable->GetValue("accuracy",params.m_sParamStruct.m_fAccuracy))
if (!pTableInstance->GetValue("accuracy",params.m_sParamStruct.m_fAccuracy))
return pH->EndFunction();
pTable->GetValue("responsiveness",params.m_sParamStruct.m_fResponsiveness);
params.m_sParamStruct.m_fResponsiveness*=400.f/7.5f;
if (!pTable->GetValue("groupid",params.m_sParamStruct.m_nGroup))
if (!pTableInstance->GetValue("groupid",params.m_sParamStruct.m_nGroup))
return pH->EndFunction();
pTable->GetValue("species",params.m_sParamStruct.m_nSpecies);
pTable->GetValue("forward_speed",fwdspeed);
pTable->GetValue("back_speed",bckspeed);
float gameAggression = params.m_sParamStruct.m_fAggression * m_pGame->cv_game_Aggression->GetFVal();
if (gameAggression > 1)
gameAggression = 1;
else if (gameAggression < 0)
gameAggression = 0;
params.m_sParamStruct.m_fAggression = gameAggression;
params.m_sParamStruct.m_fOriginalAggression = gameAggression;
params.m_sParamStruct.m_fAggression = 1.f - params.m_sParamStruct.m_fAggression;
float gameAccuracy = params.m_sParamStruct.m_fAccuracy * m_pGame->cv_game_Accuracy->GetFVal();
if (gameAccuracy > 1)
gameAccuracy = 1;
else if (gameAccuracy < 0)
gameAccuracy = 0;
params.m_sParamStruct.m_fAccuracy = gameAccuracy;
params.m_sParamStruct.m_fOriginalAccuracy = gameAccuracy;
params.m_sParamStruct.m_fAccuracy = 1.f - params.m_sParamStruct.m_fAccuracy;
float gameHealth = params.m_sParamStruct.m_fMaxHealth * m_pGame->cv_game_Health->GetFVal();
params.m_sParamStruct.m_fMaxHealth = gameHealth;
if (type != AIOBJECT_PUPPET)
params.m_sParamStruct.m_bIgnoreTargets = true;
else
params.m_sParamStruct.m_bIgnoreTargets = false;
pe_player_dimensions dims;
dims.heightEye = params.fEyeHeight;
dims.heightCollider = params.fEyeHeight;
dims.sizeCollider.x = params.fEyeHeight;
pProxy->SetPuppetDimensions(dims.heightEye+0.05f,dims.heightEye,dims.heightCollider,dims.sizeCollider.x);
//pProxy->SetRootBone(rootbone);
pProxy->SetSpeeds(fwdspeed,bckspeed);
params.pProxy = (IUnknownProxy *) pProxy;
}
break;
case AIOBJECT_CAR:
case AIOBJECT_BOAT:
case AIOBJECT_HELICOPTER:
case AIOBJECT_AIRPLANE:
{
const char *rootbone;
float fwdspeed,bckspeed;
float minAlt;
CXVehicleProxy *pProxy;
// pProxy = new CXPuppetProxy(m_pEntity,m_pScriptSystem,m_pGame);
pProxy = new CXVehicleProxy(pEntity,m_pScriptSystem,m_pGame);
if (pH->GetParamCount() > 2)
pH->GetParam(3,*pTable);
else
return pH->EndFunction();
if (pH->GetParamCount() > 3)
pH->GetParam(4,*pTableInstance);
else
return pH->EndFunction();
pTable->GetValue("aggression",params.m_sParamStruct.m_fAggression);
if (!pTable->GetValue("sightrange",params.m_sParamStruct.m_fSightRange))
if (!pTableInstance->GetValue("sightrange",params.m_sParamStruct.m_fSightRange))
return pH->EndFunction();
pTable->GetValue("fSpeciesHostility",params.m_sParamStruct.m_fSpeciesHostility);
pTable->GetValue("fGroupHostility",params.m_sParamStruct.m_fGroupHostility);
pTable->GetValue("fPersistence",params.m_sParamStruct.m_fPersistence);
if (!pTable->GetValue("soundrange",params.m_sParamStruct.m_fSoundRange))
if (!pTableInstance->GetValue("soundrange",params.m_sParamStruct.m_fSoundRange))
return pH->EndFunction();
pTable->GetValue("attackrange",params.m_sParamStruct.m_fAttackRange);
pTable->GetValue("commrange",params.m_sParamStruct.m_fCommRange);
pTable->GetValue("horizontal_fov",params.m_sParamStruct.m_fHorizontalFov);
// pTable->GetValue("vertical_fov",params.m_sParamStruct.m_fVerticalFov);
pTable->GetValue("eye_height",params.fEyeHeight);
pTable->GetValue("max_health",params.m_sParamStruct.m_fMaxHealth);
pTable->GetValue("accuracy",params.m_sParamStruct.m_fAccuracy);
params.m_sParamStruct.m_fAccuracy = 1.f - params.m_sParamStruct.m_fAccuracy;
pTable->GetValue("responsiveness",params.m_sParamStruct.m_fResponsiveness);
if (!pTable->GetValue("groupid",params.m_sParamStruct.m_nGroup))
if (!pTableInstance->GetValue("groupid",params.m_sParamStruct.m_nGroup))
return pH->EndFunction();
pTable->GetValue("species",params.m_sParamStruct.m_nSpecies);
pTable->GetValue("cohesion",params.m_sParamStruct.m_fCohesion);
pTable->GetValue("bUsePathfind",params.bUsePathfindOutdoors);
pTable->GetValue("root_bone",rootbone);
pTable->GetValue("forward_speed",fwdspeed);
pTable->GetValue("back_speed",bckspeed);
pTable->GetValue("fFlightAltitudeMin",minAlt);
// if (type != AIOBJECT_PUPPET)
// params.m_sParamStruct.m_bIgnoreTargets = true;
// else
params.m_sParamStruct.m_bIgnoreTargets = false;
pe_player_dimensions dims;
pProxy->SetMinAltitude( minAlt );
pProxy->SetSpeeds(fwdspeed,bckspeed);
pProxy->SetType( type );
// pProxy->m_nSpecialMovement = type;
params.pProxy = (IUnknownProxy *) pProxy;
}
break;
case AIOBJECT_PLAYER:
params.pProxy = new CXObjectProxy(pEntity,m_pScriptSystem);
if (pH->GetParamCount() > 1)
pH->GetParam(3,*pTable);
else
return pH->EndFunction();
pTable->GetValue("eye_height",params.fEyeHeight);
pTable->GetValue("groupid",params.m_sParamStruct.m_nGroup);
pTable->GetValue("species",params.m_sParamStruct.m_nSpecies);
break;
case AIOBJECT_AWARE:
{
CXObjectProxy *pProxy = new CXObjectProxy(pEntity, m_pScriptSystem);
const char *szSignalFunction;
if (pH->GetParamCount() > 1)
pH->GetParam(2,szSignalFunction);
else
return pH->EndFunction();
pProxy->SetSignalFuncName(szSignalFunction);
params.pProxy = pProxy;
}
break;
case AIOBJECT_ATTRIBUTE:
{
if (!pEntity->RegisterInAISystem(type,params))
{
m_pLog->Log("Could not register entity with AI");
}
else if (pEntity->GetAI())
{
if (pH->GetParamCount() > 2)
{
int ownerID;
IEntity *pOwnerEntity;
pH->GetParam(3,ownerID);
pOwnerEntity=m_pEntitySystem->GetEntity(ownerID);
if(pOwnerEntity==NULL)
{
m_pLog->Log("\002 CScriptObjectAI::RegisterWithAI() Owner entity of attribute AI %s cannot be found",pEntity->GetName());
return pH->EndFunction();
}
pEntity->GetAI()->Bind(pOwnerEntity->GetAI());
}
else
m_pLog->Log("\002 Entity %s registered as attribute AI without specifying owner",pEntity->GetName());
}
}
return pH->EndFunction();
default:
{
if (pH->GetParamCount() > 2)
pH->GetParam(3,fRadius);
}
break;
}
if (!pEntity->RegisterInAISystem(type,params))
{
m_pLog->Log("Could not register entity with AI");
}
else
{
if (pEntity->GetAI())
{
pEntity->GetAI()->SetName(pEntity->GetName());
pEntity->GetAI()->SetRadius(fRadius);
}
}
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::AIBind(IFunctionHandler *pH)
{
CHECK_PARAMETERS(2);
IEntity *pParent;
IEntity *pChild;
int nID;
pH->GetParam(1,nID);
pParent=m_pEntitySystem->GetEntity(nID);
if(pParent==NULL)
{
TRACE("CScriptObjectAI::AIBind() parent in nil");
return pH->EndFunctionNull();
}
pH->GetParam(2,nID);
pChild=m_pEntitySystem->GetEntity(nID);
if(pChild==NULL)
{
TRACE("CScriptObjectAI::AIBind() chilt in nil");
return pH->EndFunctionNull();
}
IAIObject *pParentAI = pParent->GetAI();
IAIObject *pChildAI = pChild->GetAI();
if( pParentAI && pChildAI )
pParentAI->Bind(pChildAI);
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::CreateBoundObject(IFunctionHandler *pH)
{
CHECK_PARAMETERS(4);
IEntity *pParent;
int type;
int nID;
CScriptObjectVector oVec(m_pScriptSystem,true);
pH->GetParam(1,nID);
pH->GetParam(2,type);
pH->GetParam(3,*oVec);
Vec3d pos = oVec.Get();
pH->GetParam(4,*oVec);
Vec3d angl = oVec.Get();
pParent=m_pEntitySystem->GetEntity(nID);
if(pParent==NULL)
{
TRACE("CScriptObjectAI::CreateBoundObject() entity in nil");
return pH->EndFunctionNull();
}
IAIObject *pParentAI = pParent->GetAI();
if( pParentAI )
{
pParentAI->CreateBoundObject( type, pos, angl );
}
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::Cloak(IFunctionHandler * pH)
{
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::DeCloak(IFunctionHandler * pH)
{
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::ProjectileShoot(IFunctionHandler * pH)
{
CHECK_PARAMETERS(2);
int nID;
_SmartScriptObject pParamsTable(m_pScriptSystem,true);
pH->GetParam(1,nID);
pH->GetParam(2,pParamsTable);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity)
{
IAIObject *pAIObject = pEntity->GetAI();
if (pAIObject)
{
IPipeUser *pPipeUser = 0;
if (pAIObject->CanBeConvertedTo(AIOBJECT_PIPEUSER,(void**)&pPipeUser))
{
IAIObject *pTarget = pPipeUser->GetAttentionTarget();
if (!pTarget)
return pH->EndFunction(0.f);
Vec3d vTargetPos = pTarget->GetPos();
if (pTarget->GetAssociation() && (pTarget->GetType()!=AIOBJECT_WAYPOINT))
{
IEntity *pTargetEntity = (IEntity*)pTarget->GetAssociation();
if (pTargetEntity)
{
if (pTargetEntity->GetContainer())
{
CPlayer* pPlayer = 0;
if (pTargetEntity->GetContainer()->QueryContainerInterface(CIT_IPLAYER,(void**)&pPlayer))
{
if (pPlayer->GetVehicle())
pTargetEntity = pPlayer->GetVehicle()->GetEntity();
}
}
// we have a real target - calculate
vTargetPos = pTargetEntity->GetPos();
IPhysicalEntity *pPhysicalEntity = pTargetEntity->GetPhysics();
if (pPhysicalEntity)
{
pe_status_dynamics pdyn;
pPhysicalEntity->GetStatus(&pdyn);
vTargetPos += pdyn.v*1.5f;
//vTargetPos.z = m_pGame->GetSystem()->GetI3DEngine()->GetTerrainElevation(vTargetPos.x,vTargetPos.y);
}
}
}
// else
// {
// randomize end position
vTargetPos.x+= float((rand()%20))-10.f;
vTargetPos.y+= float((rand()%20))-10.f;
// }
Vec3d vShot = vTargetPos - pEntity->GetPos();
float d = vShot.GetLength();
Vec3d vShotProjected = vShot;
vShotProjected.z = 0;
float dx = vShotProjected.GetLength();
float dy = vShot.z;
// velocity of shot
float vel;
// calculate angles
float beta = asin(dy/d);
float gamma = 3.14f/4.f+beta;
float sbeta,cbeta,sgamma,cgamma,tgamma;
sbeta = sin(beta);
cbeta = cos(beta);
sgamma = sin(gamma);
cgamma = cos(gamma);
tgamma = sgamma/cgamma;
float A = 4.f*9.81f * dx* dx;
float B = dx*sin(2*gamma) - dy*cgamma*cgamma;
vel = sqrt(A/B);
vShot/=d;
Vec3 axis = vShot.Cross(Vec3d(0,0,1));
Vec3 vLaunchDir = vShot.rotated(axis,3.14f/4.f);
CScriptObjectVector vHeading(m_pScriptSystem);
vHeading = GetNormalized(vLaunchDir);
pParamsTable->SetValue("heading",vHeading);
// now this is returned
//pParamsTable->SetValue("initial_velocity",fVelocity);
return pH->EndFunction(vel);
}
}
}
return pH->EndFunction(0.f);
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::SetTheSkip(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
int nID;
pH->GetParam(1,nID);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (!pEntity)
{
m_pAISystem->SetTheSkip( NULL );
return pH->EndFunction();
}
IPhysicalEntity *pPhys = pEntity->GetPhysics();
if(pPhys)
m_pAISystem->SetTheSkip( pPhys );
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::SetAllowedDeathCount(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
int nDeaths;
pH->GetParam(1,nDeaths);
if (m_pAISystem->GetAutoBalanceInterface())
m_pAISystem->GetAutoBalanceInterface()->SetAllowedDeathCount(nDeaths);
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::Checkpoint(IFunctionHandler * pH)
{
if (m_pAISystem->GetAutoBalanceInterface())
m_pAISystem->GetAutoBalanceInterface()->Checkpoint();
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::RegisterPlayerHit(IFunctionHandler * pH)
{
if (m_pAISystem->GetAutoBalanceInterface())
m_pAISystem->GetAutoBalanceInterface()->RegisterPlayerHit();
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::FireOverride(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
int nID;
pH->GetParam(1,nID);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity)
{
IAIObject *pAIObject = pEntity->GetAI();
if (pAIObject)
{
IUnknownProxy *pProxy = pAIObject->GetProxy();
if (pProxy)
{
CXPuppetProxy *pPuppetProxy = 0;
if (pProxy->QueryProxy(AIPROXY_PUPPET,(void**) &pPuppetProxy))
pPuppetProxy->SetFireOverride();
}
}
}
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::EnablePuppetMovement(IFunctionHandler * pH)
{
//CHECK_PARAMETERS(2);
int nID;
int nEnable;
float fDuration=-1;
pH->GetParam(1,nID);
pH->GetParam(2,nEnable);
if (pH->GetParamCount()>2)
pH->GetParam(3,fDuration);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity)
{
IAIObject *pAIObject = pEntity->GetAI();
if (pAIObject)
{
IUnknownProxy *pProxy = pAIObject->GetProxy();
if (pProxy)
{
IPuppetProxy *pPuppetProxy = 0;
if (pProxy->QueryProxy(AIPROXY_PUPPET,(void**) &pPuppetProxy))
pPuppetProxy->MovementControl(nEnable==1, fDuration);
}
}
}
return pH->EndFunction();
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::IsMoving(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
int nID;
pH->GetParam(1,nID);
IEntity *pEntity = m_pEntitySystem->GetEntity(nID);
if (pEntity)
{
IAIObject *pAIObject = pEntity->GetAI();
if (pAIObject)
{
if (pAIObject->IsMoving())
return pH->EndFunction(true);
}
}
return pH->EndFunction(false);
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::EnableNodesInSphere(IFunctionHandler * pH)
{
CHECK_PARAMETERS(3);
float fRadius;
bool bEnable;
CScriptObjectVector oVec(m_pScriptSystem,true);
pH->GetParam(1,*oVec);
pH->GetParam(2,fRadius);
pH->GetParam(3,bEnable);
if (bEnable)
m_pAISystem->GetNodeGraph()->EnableInSphere(oVec.Get(),fRadius);
else
m_pAISystem->GetNodeGraph()->DisableInSphere(oVec.Get(),fRadius);
return pH->EndFunction(false);
}
//////////////////////////////////////////////////////////////////////
int CScriptObjectAI::GetStats(IFunctionHandler * pH)
{
CHECK_PARAMETERS(1);
_SmartScriptObject pTable(m_pScriptSystem,true);
pH->GetParam(1,*pTable);
if (m_pAISystem)
{
if (m_pAISystem->GetAutoBalanceInterface())
{
AIBalanceStats stats;
stats.bFinal = true;
m_pAISystem->GetAutoBalanceInterface()->GetAutobalanceStats(stats);
pTable->SetValue("AVGEnemyLifetime",stats.fAVGEnemyLifetime);
pTable->SetValue("AVGPlayerLifetime",stats.fAVGPlayerLifetime);
pTable->SetValue("CheckpointsHit",stats.nCheckpointsHit);
pTable->SetValue("EnemiesKilled",stats.nEnemiesKilled);
pTable->SetValue("ShotsFired",stats.nShotsFires);
pTable->SetValue("ShotsHit",stats.nShotsHit);
pTable->SetValue("SilentKills",stats.nSilentKills);
pTable->SetValue("TotalEnemiesInLevel",stats.nTotalEnemiesInLevel);
pTable->SetValue("TotalPlayerDeaths",stats.nTotalPlayerDeaths);
pTable->SetValue("VehiclesDestroyed",stats.nVehiclesDestroyed);
pTable->SetValue("TotalTimeSecs",stats.fTotalTimeSeconds);
int sec,min,hr;
sec = (int)stats.fTotalTimeSeconds;
sec %=60;
min = stats.fTotalTimeSeconds/60;
hr = stats.fTotalTimeSeconds/3600;
char str[256];
sprintf(str,"%d:%d:%d",hr,min,sec);
pTable->SetValue("TotalTime",str);
}
}
return pH->EndFunction();
}