Files
firestorm/Gameleap/code/mw4/Code/MW4/ablxstd.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

9823 lines
240 KiB
C++

//***************************************************************************
//
// ABLXSTD.CPP
//
//***************************************************************************
#include "MW4Headers.hpp"
#include <abl.h>
#include <ablheap.h>
#include <ablfile.h>
#include "ablfuncs.hpp"
#include "ablprofiler.hpp"
#include <ai.hpp>
#include <Adept\player.hpp>
#include "vehicle.hpp"
#include "moverai.hpp"
#include "combatai.hpp"
#include "mwmission.hpp"
#include "bucket.hpp"
#include "mwdamageobject.hpp"
#include "AI_FindObject.hpp"
#include "AI_DebugRenderer.hpp"
#include "AI_Groups.hpp"
#include "AI_Squad.hpp"
#include "AI_Graveyard.hpp"
#include "AI_LancemateCommands.hpp"
#include "aiutils.hpp"
#include "objective.hpp"
#include "NavPoint.hpp"
#include "planeai.hpp"
#include "Building.hpp"
#include "mwplayer.hpp"
#include "vehicleinterface.hpp"
#include "CameraShip.hpp"
#include "EffectGenerator.hpp"
#include <Adept\AudioRenderer.hpp>
#include <adept\map.hpp>
#include <Adept\CollisionGrid.hpp>
#include <Adept\CollisionVolume.hpp>
#include <ElementRenderer\StateChange.hpp>
#include "move_formation.hpp"
#include "MWCampaign.hpp"
#include "AI_Specials.hpp"
#include <Adept\Controls.hpp>
#include "Salvage.hpp"
#include "mwapplication.hpp"
#include <ElementRenderer\CameraElement.hpp>
#include "flag.hpp"
#include "MWGame.hpp"
#include "sensor.hpp"
#include "Team.hpp"
#include <GameOS\ToolOS.hpp>
#include <Compost\TerrainTextureLogistic.hpp>
#include "lancemate.hpp"
#include "MechLabHeaders.h"
#include "mwguimanager.hpp"
#include "hudtimer.hpp"
#include "hudhelparrow.hpp"
#include "hudcomm.hpp"
#include "DamageDispatch.hpp"
#include "AI_Action.hpp"
#include "AI_Damage.hpp"
#include "weapon.hpp"
#include "ABLAudio.hpp"
#include <Adept\Zone.hpp>
#include <Adept\DropZone.hpp>
#include <Adept\AudioCommand.hpp>
#include "mw4shell.hpp"
#include "nglog_mw4.hpp"
#pragma warning (disable : 4189)
using namespace Stuff;
using namespace MW4AI;
namespace MW4AI
{
bool BoardDropShip (stlport::vector<MoverAI *>& GroupList,Dropship *drop);
}
namespace ABL
{
bool g_MissionMusic = true;
inline signed int double2long(double _in)
{
_in+=6755399441055744.0;
return(*(signed int*)&_in);
}
ObjectID most_recent_no_team_nav = -1;
const Stuff::Scalar who_shot_duration = 5.0f;
const Stuff::Scalar who_rammed_duration = 5.0f;
const char* talker_suffixes[]={
"_IAN.wav{handle}",
"_RAT.wav{handle}",
"_CAS.wav{handle}",
"_GON.wav{handle}",
"_JEN.wav{handle}",
"_TER.wav{handle}",
"_DAM.wav{handle}",
"_RES.wav{handle}",
"_65C.wav{handle}",
"_EV1.wav{handle}",
"_EV2.wav{handle}",
"_SAL.wav{handle}",
"_REC.wav{handle}",
"_SUP.wav{handle}",
"_FO1.wav{handle}",
"_FO2.wav{handle}",
"_FO3.wav{handle}",
"_FO4.wav{handle}",
"_FO5.wav{handle}",
"_FO6.wav{handle}",
"_PI1.wav{handle}",
"_PI2.wav{handle}",
"_PI3.wav{handle}",
"_PI4.wav{handle}",
"_ART.wav{handle}",
"_SHE.wav{handle}",
"_BD1.wav{handle}",
"_BD2.wav{handle}",
"_FOX.wav{handle}",
"_KIL.wav{handle}",
"_SGT.wav{handle}",
"_ROM.wav{handle}",
"_XRY.wav{handle}",
"_CCG.wav{handle}",
"_ERL.wav{handle}",
"_PA1.wav{handle}",
"_PA2.wav{handle}",
"_PA3.wav{handle}",
"_PA4.wav{handle}",
"_BRV.wav{handle}",
"_CHL.wav{handle}",
"_DEN.wav{handle}",
"_RCG.wav{handle}",
"_VRD.wav{handle}",
"_VOR.wav{handle}",
"_HQ1.wav{handle}",
"_HQ2.wav{handle}",
"_HQ3.wav{handle}",
"_MED.wav{handle}",
"_SFQ.wav{handle}",
"_CJK.wav{handle}",
"_ABC.wav{handle}",
"_BRK.wav{handle}",
"_CST.wav{handle}",
"_ROL.wav{handle}",
"_WIL.wav{handle}",
"_EPS.wav{handle}",
"_PET.wav{handle}",
"_EP2.wav{handle}",
"_BET.wav{handle}" // the last one should always be betty
};
int FindTalkerID (const char *suf)
{
int i;
for (i=0;i<(sizeof (talker_suffixes) / sizeof (const char *));i++)
{
if (!strnicmp (suf,talker_suffixes[i],4))
{
return i;
}
}
return -1;
}
//***************************************************************************
//----------
// EXTERNALS
extern StackItem returnValue;
extern bool eofFlag;
extern bool ExitWithReturn;
extern bool ExitFromTacOrder;
extern long level;
extern long execLineNumber;
extern long FileNumber;
extern char* codeSegmentPtr;
extern TokenCodeType codeToken;
extern StackItem* stack;
extern StackItemPtr tos;
extern StackItemPtr stackFrameBasePtr;
extern SymTableNodePtr CurRoutineIdPtr;
extern long CurModuleHandle;
extern TypePtr IntegerTypePtr;
extern TypePtr RealTypePtr;
extern TypePtr BooleanTypePtr;
extern TypePtr CharTypePtr;
extern ABLModulePtr CurModule;
//--------
// GLOBALS
extern TokenCodeType ExitRoutineCodeSegment[];
extern TokenCodeType ExitOrderCodeSegment[];
extern UserHeapPtr AblStackHeap;
extern long MaxLoopIterations;
extern DebuggerPtr debugger;
#define ABL_NO_UNIT (-2)
const int ABL_ERROR_STRING_SIZE = 2048;
char ablErrorString[ABL_ERROR_STRING_SIZE];
char *ablERROR(char *str)
{
ablErrorString[0] = 0;
ABL_runtimeErrorString (ablErrorString,ABL_ERROR_STRING_SIZE);
Str_Cat (ablErrorString," ",ABL_ERROR_STRING_SIZE);
Str_Cat (ablErrorString,str,ABL_ERROR_STRING_SIZE);
return ablErrorString;
}
//---------------------
// MW SPECIFIC STUFF...
MechWarrior4::Vehicle *CurVehicle = NULL;
extern MechWarrior4::AI *CurWarrior;
MechWarrior4::MoverAI *CurMoverAI = NULL;
char* ExceptionGameMsg;
char ChunkDebugMsg[5120];
#define DEBUG_MISSION_SCRIPT
#define MAX_MISSION_MSGS 1000
long NumMissionScriptMessages = 0;
short MissionScriptMessageLog[MAX_MISSION_MSGS][3];
#ifdef USE_OBJECTS
//extern TerrainPtr land;
//extern CreatedPartRoster createdPartRoster[];
//extern long currentCreatorPart;
//extern long languageOffset;
#endif
//***************************************************************************
// DEBUG ROUTINES
//***************************************************************************
void DebugMissionScriptMessages (void)
{
#if 0
ChunkDebugMsg[0] = NULL;
char outString[512];
sprintf(outString, "\n%d Mission Script Messages\n\n", NumMissionScriptMessages);
strcat(ChunkDebugMsg, outString);
for (long i = 0; i < NumMissionScriptMessages; i++)
{
sprintf(outString, "line %5d: %5d, %5d\n",
MissionScriptMessageLog[i][0],
MissionScriptMessageLog[i][1],
MissionScriptMessageLog[i][2]);
strcat(ChunkDebugMsg, outString);
}
File* debugFile = new File;
debugFile->create("scriptmsg.dbg");
debugFile->writeString(ChunkDebugMsg);
debugFile->close();
delete debugFile;
debugFile = NULL;
ExceptionGameMsg = ChunkDebugMsg;
#endif
}
//***************************************************************************
// USEFUL ABL HELP ROUTINES
//***************************************************************************
inline void startFunction (void)
{
//---------------------------
// Grab the opening LPAREN...
getCodeToken();
}
//---------------------------------------------------------------------------
inline void endFunction (void)
{
//-----------------------
// Grab closing RPAREN...
getCodeToken();
}
//---------------------------------------------------------------------------
// ABLContext: a helper class that will call startFunction() and endFunction()
// for you automatically. To use, create an ABLContext object at the start of
// your function. Instantiating the object will call startFunction(), and when it
// goes out of scope, endFunction() will be called.
class ABLContext
{
public:
ABLContext()
{
startFunction();
}
~ABLContext()
{
endFunction();
}
};
//---------------------------------------------------------------------------
// DECLARE_ABL_CONTEXT: a macro that automatically gives you an ABLContext object
#define DECLARE_ABL_CONTEXT ABLContext abl_context;
Stuff::Point3D popPoint()
{
Stuff::Point3D loc;
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
baseType(execVariable(idPtr, USE_REFPARAM));
long* waypoint = (long*)(&((StackItemPtr)tos->address)->integer);
Check_Pointer (waypoint);
pop();
loc.x = (float) waypoint[0];
loc.y = (float) waypoint[1];
loc.z = (float) waypoint[2];
return (loc);
}
//---------------------------------------------------------------------------
template <class T>
T* GetObjectForID(long object_id)
{
if (object_id == -1)
{
return(CurWarrior);
}
int array_index = NameTableEntry::GetArrayIndex(object_id);
ablREPORT(array_index >= 0,ablERROR ("invalid object id from abl"));
ablREPORT(array_index < NameTable::GetInstance()->TableSize,ablERROR ("invalid object id from abl"));
Entity* ent = NameTable::GetInstance()->FindData(object_id);
ablREPORT (ent,ablERROR ("invalid object id from abl"));
ablREPORT (ent->IsDerivedFrom (T::DefaultData),ablERROR ("tried to convert an objectid to the wrong type of object, probably from calling a function with the wrong type of objectid"));
if (!ent)
return NULL;
if (((int) ent) == -1)
return NULL;
return(Cast_Object(T*,ent));
}
Flag* GetFlagForID(long object_id)
{
int array_index = NameTableEntry::GetArrayIndex(object_id);
ablREPORT(array_index >= 0,ablERROR ("invalid flag id from abl"));
ablREPORT(array_index < NameTable::GetInstance()->TableSize,ablERROR ("invalid flag id from abl"));
Entity* ent = NameTable::GetInstance()->FindData(object_id);
ablREPORT (ent,ablERROR ("invalid flag id from abl"));
ablREPORT (ent->IsDerivedFrom (Flag::DefaultData),ablERROR ("tried to convert an objectid to the wrong type of object, probably from calling a function with the wrong type of objectid"));
if (!ent)
return NULL;
if (((int) ent) == -1)
return NULL;
return(Cast_Object(Flag*,ent));
}
MechWarrior4::MWObject* GetMWObjectForID(long object_id)
{
if (object_id == -1)
{
if (CurWarrior == 0)
{
return (0);
}
Adept::Entity* entity = CurWarrior->getEntity();
if ((entity != 0) &&
(entity->IsDerivedFrom(MWObject::DefaultData) == true))
{
return (Cast_Object(MWObject*,entity));
}
return (0);
}
int array_index = NameTableEntry::GetArrayIndex(object_id);
ablREPORT(array_index >= 0,ablERROR ("invalid object id from abl"));
ablREPORT(array_index < NameTable::GetInstance()->TableSize,ablERROR ("invalid object id from abl"));
Entity* ent = NameTable::GetInstance()->FindData(object_id);
if (!ent)
return NULL;
if (((int) ent) == -1)
return NULL;
if (ent->IsDerivedFrom(AI::DefaultData) == true)
{
AI* ai = Cast_Object(AI*,ent);
Check_Object(ai);
Adept::Entity* entity = ai->getEntity();
if ((entity != 0) &&
(entity->IsDerivedFrom(MWObject::DefaultData) == true))
{
return (Cast_Object(MWObject*,entity));
}
return (0);
}
ablREPORT (ent->IsDerivedFrom(MWObject::DefaultData),ablERROR ("tried to convert an objectid to the wrong type of object, probably from calling a function with the wrong type of objectid"));
return(Cast_Object(MWObject*,ent));
}
MechWarrior4::AI* GetAIForID(long object_id)
{
if (object_id == -1)
{
return (CurWarrior);
}
int array_index = NameTableEntry::GetArrayIndex(object_id);
ablREPORT(array_index >= 0,ablERROR ("invalid object id from abl"));
ablREPORT(array_index < NameTable::GetInstance()->TableSize,ablERROR ("invalid object id from abl"));
Entity* ent = NameTable::GetInstance()->FindData(object_id);
ablREPORT(ent,ablERROR ("invalid object id from abl"));
if (!ent)
return NULL;
if (((int) ent) == -1)
return NULL;
if ((ent->IsDerivedFrom(AI::DefaultData) == false) &&
(ent->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* mwobject = Cast_Object(MWObject*,ent);
return (mwobject->GetAI());
}
ablREPORT(ent->IsDerivedFrom(AI::DefaultData),ablERROR("tried to convert an objectid to the wrong type of object, probably from calling a function with the wrong type of objectid"));
return(Cast_Object(AI*,ent));
}
MechWarrior4::MoverAI* GetMoverAIForID(long object_id)
{
AI* ai = GetAIForID(object_id);
if ((ai != 0) &&
(ai->IsDerivedFrom(MoverAI::DefaultData) == true))
{
return (Cast_Object(MoverAI*,ai));
}
ablREPORT(false,ablERROR("tried to convert an objectid to the wrong type of object, probably from calling a function with the wrong type of objectid"));
return (0);
}
MechWarrior4::CombatAI* GetCombatAIForID(long object_id)
{
AI* ai = GetAIForID(object_id);
if ((ai != 0) &&
(ai->IsDerivedFrom(CombatAI::DefaultData) == true))
{
return (Cast_Object(CombatAI*,ai));
}
// ablREPORT(false,ablERROR("tried to convert an objectid to the wrong type of object, probably from calling a function with the wrong type of objectid"));
return (0);
}
Adept::Entity* ConvertAIToEntity(Entity *who) // if who is not an ai then just return it
{
if (who == 0)
{
ablREPORT(false,ablERROR("convert ai to entity called for a non object"));
return (0);
}
if (who->IsDerivedFrom (AI::DefaultData) == true)
{
AI* temp = Cast_Object(AI *,who);
return (temp->getEntity());
}
return who;
}
bool ObjectIDisGroup(long object_id)
{
return((object_id >> 24) == Adept::NameTable::Groups_Reserved);
}
bool ObjectIDisTeam(long object_id)
{
if ((object_id & 0x00F00000) > 0)
{
return ((object_id >> 24) == Adept::NameTable::Groups_Reserved);
}
return (false);
}
Group::identifier ObjectIDtoGroupID(long object_id)
{
ablREPORT(ObjectIDisGroup(object_id),ablERROR ("Bad group ID: must use GroupObjectID() to convert raw group ID to group object ID"));
return(object_id & 0x00FFFFFF);
}
int ObjectIDtoTeamNumber(long object_id)
{
return((object_id & 0x000FFFFF) - 0x00F00000);
}
GroupContainer& GetGroupContainer()
{
Verify(Adept::Mission::GetInstance() != 0);
Verify(Adept::Mission::GetInstance()->IsDerivedFrom(MechWarrior4::MWMission::DefaultData) == true);
MechWarrior4::MWMission* mission = Cast_Object(MechWarrior4::MWMission*,Adept::Mission::GetInstance());
Check_Object(mission);
return(mission->GetGroupContainer());
}
typedef std::vector<MWObject*> mwobject_list;
void GetVehiclesFromTeam(int team_number, mwobject_list& objects)
{
if ((team_number < 0) ||
(team_number > 8))
{
return;
}
NameTable *table = NameTable::GetInstance();
{
int size(table->nameTableArray[NameTable::VehicleArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data;
data = &table->nameTableArray [NameTable::VehicleArray][i];
Adept::Entity* entity = data->dataPointer->GetCurrent ();
if ((entity != 0) &&
(entity->IsDestroyed() == false) &&
(entity->IsDerivedFrom(Vehicle::DefaultData) == true))
{
Vehicle* vehicle = Cast_Object(Vehicle*,entity);
if (vehicle->GetTeam() != MWApplication::No_Team)
{
if ((team_number == 0) ||
(vehicle->GetTeam() == team_number - 1))
{
objects.push_back(vehicle);
}
}
}
}}
}
{
int size(table->nameTableArray[NameTable::PlayerArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data;
data = &table->nameTableArray [NameTable::PlayerArray][i];
Adept::Entity* entity = data->dataPointer->GetCurrent ();
if ((entity != 0) &&
(entity->IsDerivedFrom(MWPlayer::DefaultData) == true))
{
MWPlayer* player = Cast_Object(MWPlayer*,entity);
if ((player->vehicle != 0) &&
(player->vehicle->IsDestroyed() == false) &&
(player->vehicle->IsDerivedFrom(Vehicle::DefaultData) == true))
{
Vehicle* v = Cast_Object(Vehicle*,player->vehicle);
if (v->GetTeam() != MWApplication::No_Team)
{
if ((team_number == 0) ||
(v->GetTeam() == team_number - 1))
{
objects.push_back(v);
}
}
}
}
}}
}
}
void GetVehiclesFromGroup(Group::identifier group_id,
mwobject_list& objects,
bool can_be_dead = false)
{
Verify(Adept::NameTable::GetInstance() != 0);
if (group_id & 0x00F00000)
{
GetVehiclesFromTeam(group_id - 0x00F00000,objects);
return;
}
const GroupContainer& vgc = GetGroupContainer();
if (vgc.GroupExists(group_id) == false)
{
return;
}
const Group& group = vgc.GetGroup(group_id);
{for (Group::element_list::const_iterator i = group.GetElements().begin();
i != group.GetElements().end();
++i)
{
Entity* e = Adept::NameTable::GetInstance()->FindData(*i);
if ((e != 0) &&
(e->IsDerivedFrom(MWObject::DefaultData) == true))
{
if ((can_be_dead == true) ||
(e->IsDestroyed() == false))
{
MWObject* v = Cast_Object(MWObject*,e);
Check_Object(v);
objects.push_back(v);
}
}
}}
}
template <class T>
void GetAIsFromTeam(int team_number, std::vector<T*>& ais)
{
mwobject_list mwobjects;
GetVehiclesFromTeam(team_number,mwobjects);
{for (mwobject_list::const_iterator i = mwobjects.begin();
i != mwobjects.end();
++i)
{
if (((*i)->GetAI() != 0) &&
((*i)->GetAI()->IsDerivedFrom(T::DefaultData) == true))
{
T* p_ai = Cast_Object(T*,(*i)->GetAI());
ais.push_back(p_ai);
}
}}
}
template <class T>
void GetAIsFromGroup(Group::identifier group_id,
std::vector<T*>& ais)
{
Verify(Adept::NameTable::GetInstance() != 0);
if (group_id & 0x00F00000)
{
GetAIsFromTeam<T>(group_id - 0x00F00000,ais);
return;
}
const GroupContainer& vgc = GetGroupContainer();
if (vgc.GroupExists(group_id) == false)
{
return;
}
const Group& group = vgc.GetGroup(group_id);
{for (Group::element_list::const_iterator i = group.GetElements().begin();
i != group.GetElements().end();
++i)
{
Entity* e = Adept::NameTable::GetInstance()->FindData(*i);
if ((e != 0) &&
(e->IsDestroyed() == false) &&
(e->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* v = Cast_Object(MWObject*,e);
Check_Object(v);
if ((v->GetAI() != 0) &&
(v->GetAI()->IsDerivedFrom(T::DefaultData) == true) &&
(v->GetAI()->Dead() == false))
{
T* p_ai = Cast_Object(T*,v->GetAI());
ais.push_back(p_ai);
}
}
}}
}
bool IsDead(int id)
{
if (id < 0)
{
return (false);
}
MWObject* mwobject = GetMWObjectForID(id);
if (mwobject != 0)
{
AI *who = GetAIForID(id);
if ((who != 0) &&
(who->Dead() == true))
{
return (true);
}
Check_Object(mwobject);
return (mwobject->IsDestroyed());
}
return (true);
}
bool IsDead(const char* talker)
{
char s[5];
{for (int i = 0; i < 4; ++i)
{
s[i] = talker[i];
}}
s[4] = 0;
NameTable *table = NameTable::GetInstance();
int size = table->nameTableArray[NameTable::AIArray].GetLength ();
{for (int i=0;i<size;i++)
{
NameTableEntry *data = &table->nameTableArray[NameTable::AIArray][i];
if ((data != 0) &&
(data->dataPointer != 0) &&
(data->dataPointer->GetCurrent() != 0))
{
AI* ai = Cast_Object(AI *,data->dataPointer->GetCurrent());
if ((ai->getEntity() != 0) &&
(ai->GetTalkerSuffix() == s) &&
(ai->getEntity()->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,ai->getEntity());
if (mech->IsLanceMate() == true)
{
return (ai->Dead());
}
}
}
}}
return (false);
}
//---------------------------------------------------------------------------
inline long popInteger (void)
{
getCodeToken();
execExpression();
long val = tos->integer;
pop();
return(val);
}
//---------------------------------------------------------------------------
inline float popReal (void)
{
getCodeToken();
execExpression();
float val = tos->real;
pop();
return(val);
}
//---------------------------------------------------------------------------
inline bool popBoolean (void)
{
getCodeToken();
execExpression();
long val = tos->integer;
pop();
return(val == 1);
}
//---------------------------------------------------------------------------
inline char* popStringPtr (void)
{
//--------------------------
// Get destination string...
getCodeToken();
execExpression();
char* stringPtr = (char*)tos->address;
pop();
return(stringPtr);
}
//---------------------------------------------------------------------------
inline long* popIntegerPtr (void)
{
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
execVariable(idPtr, USE_REFPARAM);
long* integerPtr = (long*)(&((StackItemPtr)tos->address)->integer);
pop();
return(integerPtr);
}
//---------------------------------------------------------------------------
inline float* popRealPtr (void)
{
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
execVariable(idPtr, USE_REFPARAM);
float* realPtr = (float*)(&((StackItemPtr)tos->address)->real);
pop();
return(realPtr);
}
//---------------------------------------------------------------------------
inline long peekInteger (void)
{
getCodeToken();
execExpression();
return(tos->integer);
}
//---------------------------------------------------------------------------
inline float peekReal (void)
{
getCodeToken();
execExpression();
return(tos->real);
}
//---------------------------------------------------------------------------
inline bool peekBoolean (void)
{
getCodeToken();
execExpression();
return(tos->integer == 1);
}
//---------------------------------------------------------------------------
inline char* peekStringPtr (void)
{
getCodeToken();
execExpression();
return((char*)tos->address);
}
//---------------------------------------------------------------------------
inline long* peekIntegerPtr (void)
{
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
execVariable(idPtr, USE_REFPARAM);
return((long*)(&((StackItemPtr)tos->address)->integer));
}
//---------------------------------------------------------------------------
inline float* peekRealPtr (void)
{
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
execVariable(idPtr, USE_REFPARAM);
return((float*)(&((StackItemPtr)tos->address)->real));
}
//---------------------------------------------------------------------------
inline void pokeInteger (long val)
{
tos->integer = val;
}
//---------------------------------------------------------------------------
inline void pokeReal (float val)
{
tos->real = val;
}
//---------------------------------------------------------------------------
inline void pokeBoolean (bool val)
{
tos->integer = val ? 1 : 0;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//***************************************************************************
TypePtr execStdReturn (SymTableNodePtr routineIdPtr)
{
memset(&returnValue, 0, sizeof(StackItem));
if (CurRoutineIdPtr->typePtr)
{
//-----------------------------
// Assignment to function id...
StackFrameHeaderPtr headerPtr = (StackFrameHeaderPtr)stackFrameBasePtr;
long delta = level - CurRoutineIdPtr->level - 1;
while (delta-- > 0)
headerPtr = (StackFrameHeaderPtr)headerPtr->staticLink.address;
StackItemPtr targetPtr = (StackItemPtr)headerPtr;
TypePtr targetTypePtr = (TypePtr)(CurRoutineIdPtr->typePtr);
getCodeToken();
TypePtr baseTargetTypePtr = baseType(targetTypePtr);
//---------------------------------------------------------------
// Routine execExpression() leaves the expression value on top of
// stack...
getCodeToken();
TypePtr expressionTypePtr = execExpression();
//--------------------------
// Now, do the assignment...
if ((targetTypePtr == RealTypePtr) && (baseType(expressionTypePtr) == IntegerTypePtr))
{
//-------------------------
// integer assigned to real
targetPtr->real = (float)(tos->integer);
}
else if ((targetTypePtr->form == FRM_ARRAY) /*|| (targetTypePtr->form == FRM_RECORD)*/)
{
//-------------------------
// Copy the array/record...
char* dest = (char*)targetPtr;
char* src = tos->address;
long size = targetTypePtr->size;
memcpy(dest, src, size);
}
else if ((baseTargetTypePtr == IntegerTypePtr) || (targetTypePtr->form == FRM_ENUM))
{
//------------------------------------------------------
// Range check assignment to integer or enum subrange...
// NOTE: Need to put this line back in once we implement SUBRANGES...
// if ((targetTypePtr->form == FRM_SUBRANGE) &&
// ((tos->integer < targetTypePtr->info.subrange.min) || (tos->integer > targetTypePtr->info.subrange.max)))
// runtimeError(ABL_ERR_RUNTIME_VALUE_OUT_OF_RANGE);
targetPtr->integer = tos->integer;
}
//else if (baseTargetTypePtr == CharTypePtr) {
// }
else
{
//-----------------------
// Assign real to real...
targetPtr->real = tos->real;
}
//-----------------------------
// Grab the expression value...
pop();
//----------------------------------------------------------------------
// Preserve the return value, in case we need it for the calling user...
memcpy(&returnValue, targetPtr, sizeof(StackItem));
if (debugger)
debugger->traceDataStore(CurRoutineIdPtr, CurRoutineIdPtr->typePtr, targetPtr, targetTypePtr);
}
//-----------------------
// Grab the semi-colon...
getCodeToken();
codeSegmentPtr = (char*)ExitRoutineCodeSegment;
ExitWithReturn = true;
getCodeToken();
return NULL;
}
//***************************************************************************
TypePtr execStdPrint (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
TypePtr paramTypePtr = baseType(execExpression());
char buffer[20];
char* s = buffer;
if (paramTypePtr == IntegerTypePtr)
sprintf(buffer, "%d", tos->integer);
else if (paramTypePtr == BooleanTypePtr)
sprintf(buffer, "%s", tos->integer ? "true" : "false");
else if (paramTypePtr == CharTypePtr)
sprintf(buffer, "%c", tos->byte);
else if (paramTypePtr == RealTypePtr)
sprintf(buffer, "%.4f", tos->real);
else if ((paramTypePtr->form == FRM_ARRAY) && (paramTypePtr->info.array.elementTypePtr == CharTypePtr))
s = (char*)tos->address;
pop();
if (debugger)
{
char message[512];
sprintf(message, "PRINT: \"%s\"", s);
debugger->print(message);
sprintf(message, " MODULE %s", CurModule->getName());
debugger->print(message);
sprintf(message, " FILE %s", CurModule->getSourceFile(FileNumber));
debugger->print(message);
sprintf(message, " LINE %d", execLineNumber);
debugger->print(message);
}
#ifdef LAB_ONLY
{
Check_Object(Application::GetInstance());
MWApplication::GetInstance()->SendChat(
Connection::Local->GetID(),
MWApplication::SystemBroadcast,
0,
s);
}
#endif
#ifdef USE_IFACE
else if (TACMAP)
{
aChatWindow* chatWin = TACMAP->getChatWindow();
if (chatWin)
chatWin->processChatString(0, s, -1);
else
{
#ifdef _DEBUG
OutputDebugString(s);
#endif
}
}
else
{
#ifdef _DEBUG
OutputDebugString(s);
#endif
}
#endif
getCodeToken();
return NULL;
}
//***************************************************************************
TypePtr execStdConcat (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//--------------------------
// Get destination string...
getCodeToken();
execExpression();
char* dest = (char*)tos->address;
pop();
//----------------------
// Get item to append...
getCodeToken();
TypePtr paramTypePtr = baseType(execExpression());
char buffer[20];
if (paramTypePtr == IntegerTypePtr)
{
sprintf(buffer, "%d", tos->integer);
strcat(dest, buffer);
}
else if (paramTypePtr == CharTypePtr)
{
sprintf(buffer, "%c", tos->byte);
strcat(dest, buffer);
}
else if (paramTypePtr == RealTypePtr)
{
sprintf(buffer, "%.4f", tos->real);
strcat(dest, buffer);
}
else if (paramTypePtr == BooleanTypePtr)
{
sprintf(buffer, "%s", tos->integer ? "true" : "false");
strcat(dest, buffer);
}
else if ((paramTypePtr->form == FRM_ARRAY) && (paramTypePtr->info.array.elementTypePtr == CharTypePtr))
strcat(dest, (char*)tos->address);
tos->integer = 0;
getCodeToken();
return(IntegerTypePtr);
}
//***************************************************************************
TypePtr execStdAbs (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
TypePtr paramTypePtr = baseType(execExpression());
TypePtr resultTypePtr = NULL;
if (paramTypePtr == IntegerTypePtr)
{
if (tos->integer < 0)
tos->integer = -(tos->integer);
resultTypePtr = IntegerTypePtr;
}
else
{
if (tos->real < 0.0)
tos->real = -(tos->real);
resultTypePtr = RealTypePtr;
}
getCodeToken();
return(resultTypePtr);
}
//***************************************************************************
TypePtr execStdRound (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
execExpression();
if (tos->real > 0.0)
tos->integer = (long)(tos->real + 0.5);
else
tos->integer = (long)(tos->real - 0.5);
getCodeToken();
return(IntegerTypePtr);
}
//***************************************************************************
TypePtr execStdSqrt (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
TypePtr paramTypePtr = baseType(execExpression());
//-------------------------------------------------------
// If we have an integer parameter, force it to a real...
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)tos->integer;
if (tos->real < 0.0)
runtimeError(ABL_ERR_RUNTIME_INVALID_FUNCTION_ARGUMENT);
else
tos->real = (float)(sqrt(tos->real));
getCodeToken();
return(RealTypePtr);
}
//***************************************************************************
TypePtr execStdTrunc (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
TypePtr paramTypePtr = baseType(execExpression());
//------------------------------------------------------------------
// If we have a real parameter, trunc it. Else, leave the integer as
// it is...
if (paramTypePtr == RealTypePtr)
tos->integer = (long)(tos->real);
getCodeToken();
return(IntegerTypePtr);
}
//***************************************************************************
TypePtr execStdRandom (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
execExpression();
//---------------------------------------------------------------------
// This is, like, a really bad number generator. But, you get the idea.
// Once we know which pseudo-random number algorithm we want to use, we
// should plug it in here. The range for the random number, given a
// param of n, should be: 1<=r<=n.
tos->integer = Random::GetLessThan(tos->integer);
getCodeToken();
return(IntegerTypePtr);
}
//***************************************************************************
TypePtr execStdGetModHandle (SymTableNodePtr routineIdPtr)
{
//----------------------------------------------------------
// Return the handle of the current module being executed...
pushInteger(CurModuleHandle);
getCodeToken();
return(IntegerTypePtr);
}
//***************************************************************************
TypePtr execStdGetModName (SymTableNodePtr routineIdPtr)
{
//----------------------------------------------------------
// Return the handle of the current module being executed...
//tos->integer = CurModuleHandle;
//getCodeToken();
return(NULL/*TypePtr*/);
}
//***************************************************************************
TypePtr execStdSetModName (SymTableNodePtr routineIdPtr)
{
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
TypePtr paramTypePtr = baseType(execExpression());
if ((paramTypePtr->form == FRM_ARRAY) && (paramTypePtr->info.array.elementTypePtr == CharTypePtr))
{
//if (ModuleRegistry[CurModuleHandle].name)
// systemHeap->free(ModuleRegistry[CurModuleHandle].name);
//ModuleRegistry[CurModuleHandle].name = (char*)systemHeap->malloc(strlen((char*)tos->address) + 1);
//strcpy(ModuleRegistry[CurModuleName].name, (char*)tos->address);
}
else
runtimeError(ABL_ERR_RUNTIME_INVALID_FUNCTION_ARGUMENT);
getCodeToken();
return NULL;
}
//***************************************************************************
TypePtr execStdSetMaxLoops (SymTableNodePtr routineIdPtr)
{
//----------------------------------------------------------------------
//
// SET MAX LOOPS function:
//
// Sets the max number of loops that may occur (in a for, while or
// repeat loop) before an infinite loop run-time error occurs.
//
// PARAMS: integer
//
// RETURN: none
//
//----------------------------------------------------------------------
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
execExpression();
MaxLoopIterations = (tos->integer + 1);
pop();
getCodeToken();
return(NULL);
}
//---------------------------------------------------------------------------
TypePtr execStdFatal (SymTableNodePtr routineIdPtr)
{
//----------------------------------------------------------------------
//
// FATAL function:
//
// If the debugger is active, this immediately jumps into debug mode.
// Otherwise, it causes a fatal and exits the game (displaying the
// string passed in).
//
// PARAMS: integer fatal code to display
//
// char[] message
//
// RETURN: none
//
//----------------------------------------------------------------------
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
execExpression();
long code = tos->integer;
pop();
getCodeToken();
execExpression();
char* s = (char*)tos->address;
pop();
#ifdef LAB_ONLY
char message[512];
if (debugger)
{
sprintf(message, "FATAL: [%d] \"%s\"", code, s);
debugger->print(message);
sprintf(message, " MODULE (%d) %s", CurModule->getId(), CurModule->getName());
debugger->print(message);
sprintf(message, " FILE %s", CurModule->getSourceFile(FileNumber));
debugger->print(message);
sprintf(message, " LINE %d", execLineNumber);
debugger->print(message);
debugger->debugMode();
}
else
{
sprintf(message, "ABL FATAL: [%d] %s", code, s);
ABL_Fatal(0, s);
}
#endif
getCodeToken();
return(NULL);
}
//---------------------------------------------------------------------------
TypePtr execStdAssert (SymTableNodePtr routineIdPtr)
{
//----------------------------------------------------------------------
//
// ASSERT function:
//
// If the debugger is active, this immediately jumps into debug mode
// if expression is FALSE. Otherwise, the assert statement is ignored
// unless the #debug directive has been issued in the module. If
// so, a fatal occurs and exits the game (displaying the
// string passed in).
//
// PARAMS: boolean expression
//
// integer assert code to display
//
// char[] message
//
// RETURN: none
//
//----------------------------------------------------------------------
//-------------------
// Grab the LPAREN...
getCodeToken();
//----------------------------
// Get parameter expression...
getCodeToken();
execExpression();
long expression = tos->integer;
pop();
//----------------------------
// Get parameter expression...
getCodeToken();
execExpression();
long code = tos->integer;
pop();
getCodeToken();
execExpression();
char* s = (char*)tos->address;
pop();
#ifdef LAB_ONLY
if (!expression)
{
char message[512];
if (debugger)
{
sprintf(message, "ASSERT: [%d] \"%s\"", code, s);
debugger->print(message);
sprintf(message, " MODULE (%d) %s", CurModule->getId(), CurModule->getName());
debugger->print(message);
sprintf(message, " FILE %s", CurModule->getSourceFile(FileNumber));
debugger->print(message);
sprintf(message, " LINE %d", execLineNumber);
debugger->print(message);
debugger->debugMode();
}
else
{
sprintf(message, "ABL ASSERT: [%d] %s", code, s);
ABL_Fatal(0, message);
}
}
#endif
getCodeToken();
return(NULL);
}
//***************************************************************************
TypePtr execSetDebugString (SymTableNodePtr routineIdPtr)
{
startFunction();
long objectId = popInteger();
long stringNum = popInteger();
char* debugString = popStringPtr();
#if 0
#ifdef _DEBUG
GameObjectPtr obj = getObject(objectId);
if (obj)
{
MechWarriorPtr pilot = obj->getPilot();
if (pilot)
pilot->setDebugString(stringNum, debugString);
}
#endif
#endif
endFunction();
return NULL;
}
//***************************************************************************
TypePtr execgetPlayer (SymTableNodePtr routineIdPtr)
{
Check_Object (Adept::Player::GetInstance()); //blurt
pushInteger (Adept::Player::GetInstance()->objectID);
endFunction ();
return IntegerTypePtr;
}
TypePtr execgetSelf (SymTableNodePtr routineIdPtr)
{
if (CurWarrior == 0)
{
pushInteger(ABL_NO_UNIT);
}
else
{
Check_Object (CurWarrior);
pushInteger (CurWarrior->objectID);
}
endFunction ();
return IntegerTypePtr;
}
TypePtr execgetPlayerVehicle (SymTableNodePtr routineIdPtr)
{
int i,size;
NameTable *table = NameTable::GetInstance();
Check_Object (table);
DECLARE_ABL_CONTEXT;
int id = popInteger();
ablREPORT (id >=0,"to low of a number to getplayervehicle");
ablREPORT (id < 32,"to high of a number to getplayervehicle");
Check_Object(NameTable::GetInstance());
size = table->nameTableArray[NameTable::PlayerArray].GetLength ();
Player *player;
for (i=0;i<size;i++)
{
NameTableEntry *data;
data = &table->nameTableArray [NameTable::PlayerArray][i];
if (data->dataPointer->GetCurrent ())
{
if (id == 0)
{
player = Cast_Object(Player *,data->dataPointer->GetCurrent ());
Check_Object(player);
pushInteger(player->vehicle->objectID);
return IntegerTypePtr;
}
}
id--;
}
pushInteger (ABL_NO_UNIT);
return IntegerTypePtr;
}
void Group_execSetEntropyMood(Group::identifier group_id, Stuff::Scalar newmood)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->EntropyMood(newmood);
}}
}
TypePtr execsetEntropyMood (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
Stuff::Scalar newmood = (Stuff::Scalar)popInteger ();
ablREPORT (newmood>=MW4AI::MOODMIN,ablERROR ("entropy mood set too low"));
ablREPORT (newmood<=MW4AI::MOODMAX,ablERROR ("entropy mood set to high"));
if (ObjectIDisGroup(id) == true)
{
Group_execSetEntropyMood(ObjectIDtoGroupID(id),newmood);
return NULL;
}
AI *who = GetAIForID(id);
ablREPORT ((long) who != -1,ablERROR ("setEntropyMood asked for non-ai object"));
if (who)
{
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("setEntropyMood asked for non-ai object"));
Check_Object (who);
ablREPORT (!who->Dead (),ablERROR ("setEntropyMood asked for a dead object"));
who->EntropyMood (newmood);
}
return NULL;
}
bool Group_TargetObjectOrGroup(AI& ai, Group::identifier group_id)
{
if (ai.getEntity() == 0)
{
return (false);
}
mwobject_list targets;
GetVehiclesFromGroup(group_id,targets);
if (targets.size() == 0)
{
return (false);
}
Stuff::Scalar best_distance = -1;
mwobject_list::const_iterator best_found = targets.end();
{for (mwobject_list::const_iterator i = targets.begin();
i != targets.end();
++i)
{
if ((*i)->GetTargetDesirability() != MWObject::desirability_never)
{
Stuff::Scalar distance = GetLengthSquared((Stuff::Point3D)ai.getEntity()->GetLocalToWorld(),
(Stuff::Point3D)(*i)->GetLocalToWorld());
if ((best_distance < 0) ||
(distance < best_distance))
{
best_distance = distance;
best_found = i;
}
}
}}
if (best_found == targets.end())
{
return (false);
}
ai.Target(*best_found);
return (true);
}
void TargetObjectOrGroup(AI& ai, ObjectID target_id)
{
if (target_id == ABL_NO_UNIT)
{
ai.Target(0);
return;
}
if (ObjectIDisGroup(target_id) == true)
{
Group_TargetObjectOrGroup(ai,ObjectIDtoGroupID(target_id));
}
MWObject *target = GetMWObjectForID(target_id);
ablREPORT ((long) target != -1,ablERROR ("tried to set the target to no object"));
if (target == 0)
{
return;
}
Check_Object(target);
ai.Target(target);
}
void Group_execSetTarget(Group::identifier group_id, ObjectID target)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
TargetObjectOrGroup(**i,target);
}}
}
TypePtr execsetTarget (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long target_id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execSetTarget(ObjectIDtoGroupID(id),target_id);
return NULL;
}
AI *who = GetAIForID(id);
Verify ((long) who != -1);
if (who)
{
ablREPORT(((who->vehicle == 0) || (who->vehicle->objectID != target_id)),ablERROR ("tried to set our target to ourselves"));
if ((who != 0) &&
(who->vehicle->objectID == target_id))
{
return NULL;
}
ablREPORT (who->IsDerivedFrom(AI::DefaultData),ablERROR ("tried to set the target for a non-ai"));
Check_Object(who);
ablREPORT (!who->Dead (),ablERROR ("tried to set the target for a dead ai"));
TargetObjectOrGroup(*who,target_id);
}
return NULL;
}
TypePtr execgetTarget (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
ablREPORT (ObjectIDisGroup(id) == false,ablERROR ("tried to get the target for a group"));
AI *who = GetAIForID(id);
Verify ((long) who != -1);
if (who)
{
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to get the target of a non-ai"));
Check_Object (who);
Entity *target;
ablREPORT (!who->Dead (),ablERROR ("tried to get the target of a dead ai"));
target = who->Target ();
if (!target)
pushInteger (ABL_NO_UNIT);
else
{
Check_Object (target);
pushInteger (target->objectID);
}
}
else
pushInteger (ABL_NO_UNIT);
return IntegerTypePtr;
}
void Group_execWhoShot(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
Entity* shot_by = (*i)->ShotBy(gos_GetElapsedTime() - who_shot_duration);
if (shot_by != 0)
{
pushInteger(shot_by->objectID);
return;
}
}}
pushInteger(ABL_NO_UNIT);
}
TypePtr execwhoShot (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
if (ObjectIDisGroup(objectid) == true)
{
Group_execWhoShot(ObjectIDtoGroupID(objectid));
}
else
{
AI *who = GetAIForID(objectid);
Verify ((long) who != -1);
if (who)
{
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to ask for who shot a non ai"));
Check_Object (who);
Entity *target;
ablREPORT (!who->Dead (),ablERROR ("tried to ask for who shot a dead ai"));
if (who->Dead() == true)
{
pushInteger(ABL_NO_UNIT);
return IntegerTypePtr;
}
target = who->ShotBy (gos_GetElapsedTime () - who_shot_duration);
if (!target)
pushInteger (ABL_NO_UNIT);
else
{
Check_Object (target);
pushInteger (target->objectID);
}
}
else
pushInteger (ABL_NO_UNIT);
}
return IntegerTypePtr;
}
long Group_execwhoDestroyed(Group::identifier group_id)
{
Graveyard* graveyard = MechWarrior4::AI::GetGraveyard();
if (graveyard == 0)
{
return (ABL_NO_UNIT);
}
mwobject_list objects;
GetVehiclesFromGroup(group_id,objects,true);
{for (mwobject_list::iterator i_objects = objects.begin();
i_objects != objects.end();
++i_objects)
{
if ((*i_objects)->IsDestroyed() == true)
{
{for (grave_list::const_iterator i_graves = graveyard->GetGraves().begin();
i_graves != graveyard->GetGraves().end();
++i_graves)
{
if ((*i_graves).id == (*i_objects)->objectID)
{
return ((*i_graves).destroyer);
}
}}
}
}}
return (ABL_NO_UNIT);
}
TypePtr execwhoDestroyed (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
pushInteger(Group_execwhoDestroyed(ObjectIDtoGroupID(id)));
return IntegerTypePtr;
}
ablREPORT (ObjectIDisGroup(id) == false,ablERROR ("tried to call WhoDestroyed() on a group"));
Entity *who = GetAIForID(id);
ablREPORT ((long) who != -1,ablERROR ("tried to call WhoDestroyed() on a non entity"));
if (who)
{
Check_Object (who);
who = ConvertAIToEntity (who);
Check_Object(who);
Graveyard* graveyard = MechWarrior4::AI::GetGraveyard();
if (graveyard != 0)
{
{for (grave_list::const_iterator i = graveyard->GetGraves().begin();
i != graveyard->GetGraves().end();
++i)
{
if ((*i).id == who->objectID)
{
pushInteger((*i).destroyer);
return IntegerTypePtr;
}
}}
}
}
pushInteger(ABL_NO_UNIT);
return IntegerTypePtr;
}
long FindObjectForAI(AI* who,
int fa_alignment,
int ft_type,
int fc_criteria,
int ff_flags,
Stuff::Scalar distance_limit = MW4AI::FindObject::DISTANCE_LIMIT,
Adept::ObjectID* except_object = 0)
{
Check_Pointer(who);
if ((who != 0) &&
(who->getEntity() != 0) &&
(who->getEntity()->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* object = Cast_Object(MWObject*,who->getEntity());
if (object->GetSensor() != 0)
{
return(MW4AI::FindObject::Find(*object,
fa_alignment,
ft_type,
fc_criteria,
ff_flags,
distance_limit,
except_object));
}
}
return(ABL_NO_UNIT);
}
long Return_FindNearestEnemy(AI* who)
{
return(FindObjectForAI(who,
MW4AI::FindObject::FA_ENEMY,
MW4AI::FindObject::FT_DEFAULT,
MW4AI::FindObject::FC_NEAREST,
0));
}
long Group_execGetNearestEnemy(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::const_iterator i = ais.begin();
i != ais.end();
++i)
{
long rv = Return_FindNearestEnemy(*i);
if (rv >= 0)
{
return(rv);
}
}}
return(ABL_NO_UNIT);
}
TypePtr execgetNearestEnemy(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
if (ObjectIDisGroup(id) == true)
{
pushInteger(Group_execGetNearestEnemy(ObjectIDtoGroupID(id)));
}
else
{
AI *who = GetAIForID(id);
if (!who)
{
pushInteger (ABL_NO_UNIT);
return IntegerTypePtr;
}
ablREPORT ((long) who != -1,ablERROR ("tried to ask for the nearest enemy of a non-ai"));
ablREPORT (!who->Dead (),ablERROR ("tried to ask for the nearest enemy of a dead ai"));
int fred = Return_FindNearestEnemy(who);
pushInteger(fred);
}
return IntegerTypePtr;
}
long Group_execFindObject(Group::identifier group_id,
int fa_alignment,
int ft_type,
int fc_criteria,
int ff_flags,
Stuff::Scalar distance_limit,
Adept::ObjectID* except_object)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::const_iterator i = ais.begin();
i != ais.end();
++i)
{
long rv = FindObjectForAI(*i,
fa_alignment,
ft_type,
fc_criteria,
ff_flags,
distance_limit,
except_object);
if (rv >= 0)
{
return(rv);
}
}}
return(ABL_NO_UNIT);
}
TypePtr execFindObject(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
int fa_alignment = popInteger();
int ft_type = popInteger();
int fc_criteria = popInteger();
int ff_flags = popInteger();
int distance = popInteger();
if (ObjectIDisGroup(id) == true)
{
pushInteger(Group_execFindObject(ObjectIDtoGroupID(id),
fa_alignment,
ft_type,
fc_criteria,
ff_flags,
(Stuff::Scalar)distance,
0));
}
else
{
AI* who = GetAIForID(id);
if (!who)
{
pushInteger (ABL_NO_UNIT);
return IntegerTypePtr;
}
Verify ((long) who != -1);
ablREPORT (!who->Dead(),ablERROR ("calling findobject on a dead unit"));
pushInteger(FindObjectForAI(who,
fa_alignment,
ft_type,
fc_criteria,
ff_flags,
(Stuff::Scalar)distance));
}
return IntegerTypePtr;
}
TypePtr execFindObjectExcept(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
int fa_alignment = popInteger();
int ft_type = popInteger();
int fc_criteria = popInteger();
int ff_flags = popInteger();
int distance = popInteger();
int except = popInteger();
if (ObjectIDisGroup(id) == true)
{
pushInteger(Group_execFindObject(ObjectIDtoGroupID(id),
fa_alignment,
ft_type,
fc_criteria,
ff_flags,
(Stuff::Scalar)distance,
&except));
}
else
{
AI* who = GetAIForID(id);
if (!who)
{
pushInteger (ABL_NO_UNIT);
return IntegerTypePtr;
}
Verify ((long) who != -1);
ablREPORT (!who->Dead(),ablERROR ("calling findobject on a dead unit"));
pushInteger(FindObjectForAI(who,
fa_alignment,
ft_type,
fc_criteria,
ff_flags,
(Stuff::Scalar)distance,
&except));
}
return IntegerTypePtr;
}
void Group_execSetCurMood(Group::identifier group_id, Stuff::Scalar newmood)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->CurrentMood(newmood);
}}
}
TypePtr execsetCurMood (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
Stuff::Scalar newmood = (Stuff::Scalar)popInteger ();
ablREPORT (newmood>=MW4AI::MOODMIN,ablERROR ("tried to set the current mood below minimum"));
ablREPORT (newmood<=MW4AI::MOODMAX,ablERROR ("tried to set the current mood above maximum"));
if (ObjectIDisGroup(id) == true)
{
Group_execSetCurMood(ObjectIDtoGroupID(id),newmood);
}
else
{
AI *who = GetAIForID(id);
Verify ((long) who != -1);
if (who)
{
Check_Object (who);
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to set the current mood for a non-ai"));
ablREPORT (!who->Dead (),ablERROR ("tried to set the current mood for a dead ai"));
who->CurrentMood (newmood);
}
}
return NULL;
}
TypePtr execgetHP (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT ((ObjectIDisGroup(objectid) == false),ablERROR ("called gethp on a group"));
AI *who = GetAIForID(objectid);
Verify ((long) who != -1);
if (who)
{
Check_Object (who);
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to get the hp for a non-ai"));
}
MWObject* object = GetMWObjectForID (objectid);
pushInteger ((int)(object->m_HitPoints));
return IntegerTypePtr;
}
Stuff::Point3D Group_execGetLocation(Group::identifier group_id)
{
mwobject_list objects;
GetVehiclesFromGroup(group_id,objects);
if (objects.size() == 0)
{
return(Stuff::Point3D(-1,-1,-1));
}
Stuff::Point3D rv(0,0,0);
{for (mwobject_list::iterator i = objects.begin();
i != objects.end();
++i)
{
rv += (Stuff::Point3D)(*i)->GetLocalToWorld();
}}
rv.x /= objects.size();
rv.y /= objects.size();
rv.z /= objects.size();
return(rv);
}
TypePtr execgetLocation (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Stuff::Point3D loc (-1,-1,-1);
long id = popInteger ();
long *waypoint = popIntegerPtr (); // point to return;
waypoint[0] = (long) 0;
waypoint[1] = (long) 0;
waypoint[2] = (long) 0;
if (ObjectIDisGroup(id) == true)
{
loc = Group_execGetLocation(ObjectIDtoGroupID(id));
}
else
{
Entity* who = GetObjectForID<Entity>(id);
who = ConvertAIToEntity(who);
if (who)
{
Check_Object (who);
loc = (Stuff::Point3D) who->GetLocalToWorld ();
}
}
waypoint[0] = (int) loc.x;
waypoint[1] = (int) loc.y;
waypoint[2] = (int) loc.z;
return NULL;
}
TypePtr execDistance (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Stuff::Scalar dist;
int dx,dz;
long *point1 = popIntegerPtr (); // point to return;
long *point2 = popIntegerPtr (); // point to return;
dx = point1[0] - point2[0];
dz = point1[2] - point2[2];
dx *= dx;
dz *= dz;
dist = (Stuff::Scalar) (dx + dz);
dist = SqrtApproximate (dist);
pushInteger ((int) dist);
return IntegerTypePtr;
}
TypePtr execgetNearestPathPoint (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long pathid = popInteger ();
long *waypoint = popIntegerPtr (); // point to return;
Entity *entity;
Path* path;
ablREPORT (pathid!=-1,ablERROR ("pathid is invalid"));
entity = NameTable::GetInstance()->FindData (pathid);
ablREPORT (entity->IsDerivedFrom (Path::DefaultData),ablERROR ("tried to get nearest point to a path object that is not a path"));
path = Cast_Object (Path *,entity);
Stuff::Point3D loc;
if (ObjectIDisGroup(id) == true)
{
loc = Group_execGetLocation(ObjectIDtoGroupID(id));
}
else
{
Entity* who = GetObjectForID<Entity>(id);
who = ConvertAIToEntity(who);
if (!who)
return NULL;
Check_Object (who);
Check_Object (path);
loc = (Stuff::Point3D) who->GetLocalToWorld ();
}
Stuff::Point3D nearest = path->GetNearestPoint (loc);
waypoint[0] = (int) nearest.x;
waypoint[1] = (int) nearest.y;
waypoint[2] = (int) nearest.z;
return NULL;
}
long Return_execGetGreatestThreat(AI* who, Stuff::Scalar range)
{
return(FindObjectForAI(who,
MW4AI::FindObject::FA_ENEMY,
MW4AI::FindObject::FT_DEFAULT,
MW4AI::FindObject::FC_GREATEST_THREAT,
0,
range));
}
long Group_execGetGreatestThreat(Group::identifier group_id, Stuff::Scalar range)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::const_iterator i = ais.begin();
i != ais.end();
++i)
{
long rv = Return_execGetGreatestThreat(*i,range);
if (rv >= 0)
{
return(rv);
}
}}
return(ABL_NO_UNIT);
}
TypePtr execgetGreatestThreat (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long range = popInteger();
if (ObjectIDisGroup(id) == true)
{
pushInteger(Group_execGetGreatestThreat(ObjectIDtoGroupID(id),(Stuff::Scalar)range));
}
else
{
AI* who = GetAIForID(id);
if (!who)
{
pushInteger (ABL_NO_UNIT);
return IntegerTypePtr;
}
ablREPORT (!who->Dead (),ablERROR ("tried to get the greatest threat to a dead ai"));
pushInteger(Return_execGetGreatestThreat(who,(Stuff::Scalar)range));
}
return IntegerTypePtr;
}
long Return_execGetLeastThreat(AI* who, Stuff::Scalar range)
{
return(FindObjectForAI(who,
MW4AI::FindObject::FA_ENEMY,
MW4AI::FindObject::FT_DEFAULT,
MW4AI::FindObject::FC_LEAST_THREAT,
0,
range));
}
long Group_execGetLeastThreat(Group::identifier group_id, Stuff::Scalar range)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::const_iterator i = ais.begin();
i != ais.end();
++i)
{
long rv = Return_execGetLeastThreat(*i,range);
if (rv >= 0)
{
return(rv);
}
}}
return(ABL_NO_UNIT);
}
TypePtr execgetLeastThreat (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long range = popInteger();
if (ObjectIDisGroup(id) == true)
{
pushInteger(Group_execGetLeastThreat(ObjectIDtoGroupID(id),(Stuff::Scalar)range));
}
else
{
Verify(ObjectIDisGroup(id) == false);
AI* who = GetAIForID(id);
if (!who)
{
pushInteger (ABL_NO_UNIT);
return IntegerTypePtr;
}
ablREPORT (!who->Dead (),ablERROR ("tried to get the least threat for a dead ai"));
pushInteger(FindObjectForAI(who,
MW4AI::FindObject::FA_ENEMY,
MW4AI::FindObject::FT_DEFAULT,
MW4AI::FindObject::FC_LEAST_THREAT,
0,
(Stuff::Scalar)range));
}
return IntegerTypePtr;
}
TypePtr execgetMechType (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT (ObjectIDisGroup(objectid) == false,ablERROR ("Tried to get the 'Mech type for a group"));
MWObject* who = GetMWObjectForID(objectid);
if ((who != 0) &&
(who->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,who);
pushInteger(mech->GetGameModel()->mechID);
}
else
{
pushInteger(NoMechID);
}
return IntegerTypePtr;
}
TypePtr execgetAlignment (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT(ObjectIDisGroup(id) == false,ablERROR ("tried to get the alignment for a group"));
MWObject* who = GetMWObjectForID(id);
if (who == 0)
{
pushInteger(0);
}
else
{
Check_Object(who);
pushInteger(who->GetAlignment());
}
return IntegerTypePtr;
}
void Group_execSetAlignment(Group::identifier id, int new_alignment)
{
mwobject_list objects;
GetVehiclesFromGroup(id,objects);
{for (mwobject_list::const_iterator i = objects.begin();
i != objects.end();
++i)
{
if ((*i)->GetAlignment() != new_alignment)
{
(*i)->SetAlignment(new_alignment);
if ((*i)->GetAI() != 0)
{
(*i)->GetAI()->NotifyAlignmentChanged();
}
}
}}
}
TypePtr execsetAlignment (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
int newalign = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execSetAlignment(ObjectIDtoGroupID(id),newalign);
return NULL;
}
MWObject* vehicle = GetMWObjectForID(id);
if (vehicle == 0)
{
pushInteger(0);
}
else
{
if (vehicle->GetAlignment() != newalign)
{
vehicle->SetAlignment(newalign);
if (vehicle->GetAI() != 0)
{
vehicle->GetAI()->NotifyAlignmentChanged();
}
}
}
return NULL;
}
TypePtr execgetGunnerySkill (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT(ObjectIDisGroup(objectid) == false,ablERROR ("tried to get the gunnery skill of a group"));
AI *who = GetAIForID(objectid);
Verify ((long) who != -1);
if (who)
{
Check_Object (who);
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to get the gunnery skill of a non-ai"));
pushInteger (who->GunnerySkill ());
}
else
pushInteger (0);
return IntegerTypePtr;
}
TypePtr execgetPilotSkill (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT(ObjectIDisGroup(objectid) == false,ablERROR ("tried to get the pilot skill of a group"));
AI *who = GetAIForID(objectid);
Verify ((long) who != -1);
if (who)
{
Check_Object (who);
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to get the pilot skill of a non-ai"));
pushInteger (who->PilotSkill ());
}
else
pushInteger (0);
return IntegerTypePtr;
}
#if 0
void Group_execSetSkill(Group::identifier group_id, long pilotskill, long gunskill)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if (pilotskill != -1)
{
ablREPORT ((*i)->Dead (),ablERROR ("tried to set the pilot skill of a dead ai in a group"));
if (pilotskill < 0)
pilotskill = 0;
(*i)->PilotSkill(pilotskill);
}
if (gunskill != -1)
{
ablREPORT ((*i)->Dead (),ablERROR ("tried to set the gunnery skill of a dead ai in a group"));
if (gunskill < 0)
gunskill = 0;
(*i)->GunnerySkill(gunskill);
}
}}
}
TypePtr execsetSkill (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long pilotskill = popInteger ();
long gunskill = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execSetSkill(ObjectIDtoGroupID(id),pilotskill,gunskill);
}
else
{
AI* who = GetAIForID(id);
ablREPORT ((long) who != -1,ablERROR ("tried to set the skills for a non-ai"));
if (who)
{
Check_Object (who);
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to set the skills for a non-ai"));
if (pilotskill != -1)
{
ablREPORT (!who->Dead (),ablERROR ("tried to set the pilot skill of a dead ai"));
if (pilotskill < 0)
pilotskill = 0;
who->PilotSkill (pilotskill);
}
if (gunskill != -1)
{
ablREPORT (!who->Dead (),ablERROR ("tried to set the gunnery skill of a dead ai"));
if (gunskill < 0)
gunskill = 0;
who->GunnerySkill (gunskill);
}
}
}
return NULL;
}
#endif
void Group_execSetSkillLevel(Group::identifier group_id, long pilotskill, long gunskill,long eliteskill)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if (pilotskill != -1)
{
ablREPORT ((*i)->Dead (),ablERROR ("tried to set the pilot skill of a dead ai in a group"));
if (pilotskill < 0)
pilotskill = 0;
(*i)->PilotSkill(pilotskill);
}
if (gunskill != -1)
{
ablREPORT ((*i)->Dead (),ablERROR ("tried to set the gunnery skill of a dead ai in a group"));
if (gunskill < 0)
gunskill = 0;
(*i)->GunnerySkill(gunskill);
}
if (eliteskill != -1)
{
ablREPORT ((*i)->Dead (),ablERROR ("tried to set the elite skill of a dead ai in a group"));
if (eliteskill < 0)
eliteskill = 0;
(*i)->EliteSkill(eliteskill);
}
}}
}
TypePtr execsetSkillLevel (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long pilotskill = popInteger ();
long gunskill = popInteger ();
long eliteskill = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execSetSkillLevel(ObjectIDtoGroupID(id),pilotskill,gunskill,eliteskill);
}
else
{
AI* who = GetAIForID(id);
ablREPORT ((long) who != -1,ablERROR ("tried to set the skills for a non-ai"));
if (who)
{
Check_Object (who);
ablREPORT (who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to set the skills for a non-ai"));
if (pilotskill != -1)
{
ablREPORT (!who->Dead (),ablERROR ("tried to set the pilot skill of a dead ai"));
if (pilotskill < 0)
pilotskill = 0;
who->PilotSkill (pilotskill);
}
if (gunskill != -1)
{
ablREPORT (!who->Dead (),ablERROR ("tried to set the gunnery skill of a dead ai"));
if (gunskill < 0)
gunskill = 0;
who->GunnerySkill (gunskill);
}
if (eliteskill != -1)
{
ablREPORT (!who->Dead (),ablERROR ("tried to set the elite skill of a dead ai"));
if (eliteskill < 0)
eliteskill = 0;
who->EliteSkill (eliteskill);
}
}
}
return NULL;
}
void Group_SetAttackThrottle(Group::identifier group_id, Stuff::Scalar throttle)
{
std::vector<CombatAI*> ais;
GetAIsFromGroup<CombatAI>(group_id,ais);
{for (std::vector<CombatAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->SetAttackThrottle(throttle);
}}
}
TypePtr execSetAttackThrottle (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long object_id = popInteger();
long throttle = popInteger();
ablREPORT(throttle <= 100,ablERROR ("tried to set an attack throttle greater than 100"));
ablREPORT(throttle >= 0,ablERROR ("tried to set a negative attack throttle"));
if (ObjectIDisGroup(object_id) == true)
{
Group_SetAttackThrottle(ObjectIDtoGroupID(object_id),(Stuff::Scalar)throttle);
}
else
{
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(object_id);
Verify((long)combat_ai != -1);
if (combat_ai)
{
combat_ai->SetAttackThrottle((Stuff::Scalar)throttle);
}
}
return NULL;
}
TypePtr execGetAttackThrottle (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long object_id = popInteger();
ablREPORT(ObjectIDisGroup(object_id) == false,ablERROR ("tried to get the attack throttle for a group"));
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(object_id);
Verify((long)combat_ai != -1);
if (combat_ai)
{
pushInteger((int)combat_ai->GetAttackThrottle());
}
else
{
ablREPORT(0,ablERROR ("attempted to get the attack throttle for an invalid object"));
pushInteger(100);
}
return IntegerTypePtr;
}
void Group_SetIgnoreFriendlyFire(Group::identifier group_id, bool ignore)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->SetIgnoringFriendlyFire(ignore);
}}
}
TypePtr execSetIgnoreFriendlyFire (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long object_id = popInteger();
bool ignore_friendly_fire = popBoolean();
if (ObjectIDisGroup(object_id) == true)
{
Group_SetIgnoreFriendlyFire(ObjectIDtoGroupID(object_id),ignore_friendly_fire);
}
else
{
MechWarrior4::AI* ai = GetAIForID(object_id);
Verify((long)ai != -1);
if (ai)
{
ai->SetIgnoringFriendlyFire(ignore_friendly_fire);
}
else
{
ablREPORT(0,ablERROR ("Attempted to call SetIgnoreFriendlyFire() for an invalid object"));
}
}
return NULL;
}
void Group_SetFiringDelay(Group::identifier group_id, Stuff::Scalar min_delay, Stuff::Scalar max_delay)
{
std::vector<CombatAI*> ais;
GetAIsFromGroup<CombatAI>(group_id,ais);
{for (std::vector<CombatAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->SetFiringDelay(min_delay,max_delay);
}}
}
TypePtr execSetFiringDelay (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long object_id = popInteger();
float min_delay = popReal();
float max_delay = popReal();
ablREPORT(min_delay >= 0,ablERROR ("tried to set a negative minimum firing delay"));
ablREPORT(max_delay >= 0,ablERROR ("tried to set a negative maximum firing delay"));
ablREPORT(min_delay <= max_delay,ablERROR ("tried to set a minimum firing delay less than the maximum firing delay"));
if (ObjectIDisGroup(object_id) == true)
{
Group_SetFiringDelay(ObjectIDtoGroupID(object_id),(Stuff::Scalar)min_delay,(Stuff::Scalar)max_delay);
}
else
{
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(object_id);
Verify((long)combat_ai != -1);
if (combat_ai)
{
combat_ai->SetFiringDelay((Stuff::Scalar)min_delay,(Stuff::Scalar)max_delay);
}
}
return NULL;
}
void Group_SetCombatLeash(Group::identifier group_id, const Stuff::Point3D& center, Stuff::Scalar radius)
{
std::vector<MoverAI*> ais;
GetAIsFromGroup<MoverAI>(group_id,ais);
{for (std::vector<MoverAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->SetCombatLeash(center,radius);
}}
}
TypePtr execSetCombatLeash (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Point3D curlocation;
int object_id = popInteger ();
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
baseType(execVariable(idPtr, USE_REFPARAM));
long* waypoint = (long*)(&((StackItemPtr)tos->address)->integer);
pop();
Point3D center;
center.x = (float) waypoint[0];
center.y = (float) waypoint[1];
center.z = (float) waypoint[2];
int radius = popInteger ();
if (ObjectIDisGroup(object_id) == true)
{
Group_SetCombatLeash(ObjectIDtoGroupID(object_id),center,(Stuff::Scalar)radius);
}
else
{
MechWarrior4::MoverAI* mover_ai = GetMoverAIForID(object_id);
Verify((long)mover_ai != -1);
if (mover_ai)
{
mover_ai->SetCombatLeash(center,(Stuff::Scalar)radius);
}
}
return NULL;
}
TypePtr execSetGUITarget(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int src_id = popInteger();
int target_id = popInteger();
MWObject* src = GetMWObjectForID(src_id);
MWObject* target = 0;
if (target_id != ABL_NO_UNIT)
{
target = GetMWObjectForID(target_id);
}
if ((src != 0) &&
(src->IsDestroyed() == false) &&
(src->vehicleInterface != 0) &&
(src->vehicleInterface->IsDerivedFrom(MechWarrior4::VehicleInterface::DefaultData) == true))
{
MechWarrior4::VehicleInterface* vehicle_interface = Cast_Object(MechWarrior4::VehicleInterface*,src->vehicleInterface);
if ((target != 0) &&
(target->IsDestroyed() == false))
{
if ((vehicle_interface->vehicle != 0) &&
(vehicle_interface->vehicle->GetSensor() != 0))
{
vehicle_interface->vehicle->GetSensor()->Refresh();
if (target->IsDerivedFrom(Building::DefaultData) == true)
{
vehicle_interface->vehicle->GetSensor()->UpdateBuildingData();
}
}
vehicle_interface->SetGUITarget(target);
}
else
{
vehicle_interface->SetGUITarget(0);
}
}
return NULL;
}
TypePtr execGetGUITarget (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int src_id = popInteger();
MWObject* src = GetMWObjectForID(src_id);
if ((src != 0) &&
(src->IsDestroyed() == false) &&
(src->vehicleInterface != 0) &&
(src->vehicleInterface->IsDerivedFrom(MechWarrior4::VehicleInterface::DefaultData) == true))
{
MechWarrior4::VehicleInterface* vehicle_interface = Cast_Object(MechWarrior4::VehicleInterface*,src->vehicleInterface);
if (vehicle_interface->GetGUITarget() == 0)
{
pushInteger(ABL_NO_UNIT);
}
else
{
pushInteger(vehicle_interface->GetGUITarget()->objectID);
}
}
else
{
pushInteger(ABL_NO_UNIT);
}
return IntegerTypePtr;
}
TypePtr execGetZoomState (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int src_id = popInteger();
MWObject* src = GetMWObjectForID(src_id);
if ((src != 0) &&
(src->IsDestroyed() == false) &&
(src->vehicleInterface != 0) &&
(src->vehicleInterface->IsDerivedFrom(MechWarrior4::VehicleInterface::DefaultData) == true))
{
MechWarrior4::VehicleInterface* vehicle_interface = Cast_Object(MechWarrior4::VehicleInterface*,src->vehicleInterface);
pushBoolean (VehicleInterface::GetInstance()->reticuleZoomShowing);
return (BooleanTypePtr);
}
pushBoolean(false);
return BooleanTypePtr;
}
void Group_SetCrouchState(Group::identifier group_id, bool crouch)
{
std::vector<CombatAI*> ais;
GetAIsFromGroup<CombatAI>(group_id,ais);
{for (std::vector<CombatAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if ((*i)->Crouching() != crouch)
{
(*i)->Crouch();
}
}}
}
TypePtr execSetCrouchState(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int object_id = popInteger();
bool crouched = popBoolean();
if (ObjectIDisGroup(object_id) == true)
{
Group_SetCrouchState(ObjectIDtoGroupID(object_id),crouched);
}
else
{
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(object_id);
if (combat_ai != 0)
{
if (combat_ai->Crouching() != crouched)
{
combat_ai->Crouch();
}
}
}
return NULL;
}
TypePtr execGetTeamNumber(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int object_id = popInteger();
MWObject* object = GetMWObjectForID(object_id);
if ((object == 0) ||
(object->IsDestroyed() == true) ||
(object->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData) == false))
{
pushInteger(MechWarrior4::MWApplication::No_Team);
}
else
{
MechWarrior4::Vehicle* vehicle = Cast_Object(MechWarrior4::Vehicle*,object);
pushInteger(vehicle->teamNumber);
}
return IntegerTypePtr;
}
/*
void SetEntityToTeam(Adept::ObjectID object_id, int team)
{
MWObject* object = GetMWObjectForID(object_id);
if (object != 0)
{
if (object->IsDerivedFrom(Vehicle::DefaultData) == true)
{
Vehicle* vehicle = Cast_Object(Vehicle*,object);
vehicle->SetTeam(team);
}
}
else
{
Flag *flag = GetFlagForID(object_id);
if (flag != 0)
{
flag->SetTeam(team);
}
}
}
void Group_SetTeam(Group::identifier group_id, int team)
{
std::vector<MWObject*> objects;
GetVehiclesFromGroup(group_id,objects);
{for (std::vector<MWObject*>::iterator i = objects.begin();
i != objects.end();
++i)
{
if ((*i)->IsDerivedFrom(Vehicle::DefaultData) == true)
{
Vehicle* vehicle = Cast_Object(Vehicle*,*i);
vehicle->SetTeam(team);
}
}}
}
TypePtr execSetTeam(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int object_id = popInteger();
int team = popInteger();
ablREPORT(((team >= 0) && (team <= 7)),ablERROR ("Tried to set to a team number outside of the range 0..7"));
if (ObjectIDisGroup(object_id) == true)
{
Group_SetTeam(ObjectIDtoGroupID(object_id),team);
}
else
{
SetEntityToTeam(object_id,team);
}
return NULL;
}
*/
TypePtr execTeamExists(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int team = popInteger();
ablREPORT(((team >= 0) && (team <= 7)),ablERROR ("Tried to ask if a team outside of the range 0..7 exists"));
if (MWApplication::GetInstance() == 0)
{
pushBoolean(false);
}
else
{
if ((MWApplication::GetInstance()->teams[team] == 0) ||
(MWApplication::GetInstance()->teams[team]->GetCurrent() == 0))
{
pushBoolean(false);
}
else
{
pushBoolean(true);
}
}
return BooleanTypePtr;
}
enum // NOTE: these must EXACTLY match the constants in MWCONST.ABI!
{
GameParam_heatOn = 0,
GameParam_killLimit = 1,
GameParam_killLimitNumber = 2,
GameParam_respawnLimit = 3,
GameParam_respawnLimitNumber = 4,
GameParam_forceRespawn = 5,
GameParam_splashOn = 6,
GameParam_weaponjamOn = 7,
GameParam_ammobayfireOn = 8,
// MSL 5.05 Advance Mode
GameParam_advancemodeOn = 9,
// MSL 5.06 Armor Mode
GameParam_armormodeOn = 10,
GameParam_splashPercentage = 11,
GameParam_unlimitedAmmo = 12,
GameParam_friendlyFirePercentage = 13,
GameParam_allowZoom = 14,
GameParam_allow3rdPerson = 15,
GameParam_allowAutoAim = 16,
GameParam_allowDeadToChat = 17,
GameParam_invulnerableDrop = 18,
GameParam_isNight = 19,
GameParam_weather = 20,
GameParam_visibility = 21,
GameParam_reportStats = 22,
GameParam_serverConnection = 23,
GameParam_serverBandwidth = 24,
GameParam_onlyStockMech = 25,
GameParam_minimumTonnage = 26,
GameParam_maximumTonnage = 27,
GameParam_gameLength = 28,
GameParam_serverRecycle = 29,
GameParam_recycleDelay = 30,
GameParam_playMissionReview = 31,
GameParam_ruleType = 32,
GameParam_deadMechCantSee = 33,
GameParam_deadMechCantSeeOtherTeam = 34,
GameParam_allowdecaltransfer = 35,
GameParam_useMapCycle = 36,
GameParam_pureMapCycle = 37,
GameParam_teamAllowed = 38,
GameParam_teamCount = 39,
GameParam_closedGame = 40,
GameParam_playerLimit = 41
};
TypePtr execGetGameParam(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int param_type(popInteger());
if (Network::GetInstance() == 0)
{
pushInteger(-1);
return IntegerTypePtr;
}
NetMissionParameters::MWNetMissionParameters* net_params = 0;
if (Network::GetInstance()->AmIServer() == true)
{
net_params = MWApplication::GetInstance()->GetLocalNetParams();
}
else
{
net_params = MWApplication::GetInstance()->GetServerNetParams();
}
if (net_params == 0)
{
pushInteger(-1);
return IntegerTypePtr;
}
#define HANDLE_GAME_PARAM(param) \
case GameParam_##param: \
{ \
pushInteger(net_params->m_##param); \
break; \
}
switch (param_type)
{
HANDLE_GAME_PARAM(heatOn);
HANDLE_GAME_PARAM(killLimit);
HANDLE_GAME_PARAM(killLimitNumber);
HANDLE_GAME_PARAM(respawnLimit);
HANDLE_GAME_PARAM(respawnLimitNumber);
HANDLE_GAME_PARAM(forceRespawn);
HANDLE_GAME_PARAM(splashOn);
HANDLE_GAME_PARAM(weaponjamOn);
HANDLE_GAME_PARAM(ammobayfireOn);
HANDLE_GAME_PARAM(advancemodeOn);
HANDLE_GAME_PARAM(armormodeOn);
HANDLE_GAME_PARAM(splashPercentage);
HANDLE_GAME_PARAM(unlimitedAmmo);
HANDLE_GAME_PARAM(friendlyFirePercentage);
HANDLE_GAME_PARAM(allowZoom);
HANDLE_GAME_PARAM(allow3rdPerson);
HANDLE_GAME_PARAM(allowAutoAim);
HANDLE_GAME_PARAM(allowDeadToChat);
HANDLE_GAME_PARAM(invulnerableDrop);
HANDLE_GAME_PARAM(isNight);
HANDLE_GAME_PARAM(weather);
HANDLE_GAME_PARAM(visibility);
HANDLE_GAME_PARAM(reportStats);
HANDLE_GAME_PARAM(serverConnection);
HANDLE_GAME_PARAM(serverBandwidth);
HANDLE_GAME_PARAM(onlyStockMech);
HANDLE_GAME_PARAM(minimumTonnage);
HANDLE_GAME_PARAM(maximumTonnage);
HANDLE_GAME_PARAM(gameLength);
HANDLE_GAME_PARAM(serverRecycle);
HANDLE_GAME_PARAM(recycleDelay);
HANDLE_GAME_PARAM(playMissionReview);
HANDLE_GAME_PARAM(ruleType);
HANDLE_GAME_PARAM(deadMechCantSee);
HANDLE_GAME_PARAM(deadMechCantSeeOtherTeam);
HANDLE_GAME_PARAM(allowdecaltransfer);
HANDLE_GAME_PARAM(useMapCycle);
HANDLE_GAME_PARAM(pureMapCycle);
HANDLE_GAME_PARAM(teamAllowed);
HANDLE_GAME_PARAM(teamCount);
default:
{
pushInteger(-1);
break;
}
}
#undef HANDLE_GAME_PARAM
return IntegerTypePtr;
}
TypePtr execSetTeamTracking (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int object_id(popInteger());
int track_flag(popInteger());
// NOT YET IMPLEMENTED
return NULL;
}
TypePtr execgetTimer (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT(ObjectIDisGroup(objectid) == false,ablERROR ("tried to get the timer for a group"));
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT (objectid >=0,ablERROR ("tried to get the timer for timer id less than min"));
ablREPORT (objectid <MAX_MISSION_TIMERS,ablERROR ("tried to get the timer for a timer id greater than max"));
pushInteger ((long) mission->Timer (objectid).CurrTime ());
return IntegerTypePtr;
}
TypePtr execsetTimer (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT(ObjectIDisGroup(objectid) == false,ablERROR ("tried to set the timer for a group"));
long timervalue = popInteger ();
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT (objectid >=0,ablERROR ("tried to set the timer for a timer id less than min"));
ablREPORT (objectid <MAX_MISSION_TIMERS,ablERROR ("tried to set the timer for a timer id greater than max"));
mission->Timer (objectid).SetTime ((Stuff::Time) timervalue);
return NULL;
}
TypePtr execplayerOrder (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
pushInteger (0); //TODO;
return IntegerTypePtr;
}
TypePtr execgetEliteLevel (SymTableNodePtr routineIdPtr)
{
long id = popInteger ();
ablREPORT(ObjectIDisGroup(id) == false,ablERROR ("tried to get the elite flag for a group"));
AI *who = GetAIForID(id);
Verify ((long) who != -1);
if (who)
{
Check_Pointer (who);
ablREPORT(who->IsDerivedFrom (AI::DefaultData),ablERROR ("tried to get the elite flag for a non-ai"));
ablREPORT(!who->Dead (),ablERROR ("tried to get the elite flag for a dead ai"));
pushInteger(who->EliteSkill());
}
else
pushInteger (0);
return IntegerTypePtr;
}
void Group_execSetEliteLevel(Group::identifier group_id, int level)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
ablREPORT (!(*i)->Dead (),ablERROR ("tried to set the elite flag for a dead ai in a group"));
(*i)->EliteSkill(level);
}}
}
TypePtr execsetEliteLevel (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long level = popInteger ();
ablREPORT(level >= 0,ablERROR ("Tried to set an elite level less than 0%"));
ablREPORT(level <= 100,ablERROR ("Tried to set an elite level greater than 100%"));
if (ObjectIDisGroup(id) == true)
{
Group_execSetEliteLevel(ObjectIDtoGroupID(id),level);
}
else
{
AI *who = GetAIForID(id);
Verify ((long) who != -1);
if (who)
{
Check_Pointer (who);
ablREPORT (!who->Dead (),ablERROR ("tried to set the elite flag for a dead ai"));
who->EliteSkill (level);
}
}
return NULL;
}
void Group_execClearMoveOrder(Group::identifier group_id)
{
std::vector<MoverAI*> ais;
GetAIsFromGroup<MoverAI>(group_id,ais);
{for (std::vector<MoverAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->ClearMoveOrder();
}}
}
TypePtr execclearMoveOrder (SymTableNodePtr routineIdPtr)
{
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execClearMoveOrder(ObjectIDtoGroupID(id));
}
else
{
MoverAI *who;
who = GetMoverAIForID(id);
Verify ((long) who != -1);
if (who)
{
Check_Pointer (who);
ablREPORT (who->IsDerivedFrom (MoverAI::DefaultData),ablERROR ("tried to clear a move order for a non mover"));
ablREPORT (!who->Dead (),ablERROR ("tried to clear a move order on a dead ai"));
who->ClearMoveOrder ();
}
}
return NULL;
}
void ONE_SelfDestruct(int id)
{
MWObject* mwobject = GetMWObjectForID(id);
if (mwobject) {
if (mwobject->IsDerivedFrom(Vehicle::DefaultData) == true) {
Vehicle* vehicle = Cast_Object(Vehicle*,mwobject);
vehicle->SelfDestruct();
return;
}
}
AI *who;
who = GetAIForID(id);
Check_Object (who);
who->SelfDestruct ();
}
TypePtr execSelfDestruct (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group::identifier group_id = ObjectIDtoGroupID(id);
int i, nCount = MW4AI::Groups::Size(group_id);
Adept::ObjectID obj_id;
for(i = 0; i < nCount; i++)
{
if (MW4AI::Groups::GetMember(group_id, (unsigned)i, obj_id)) {
ONE_SelfDestruct(obj_id);
}
}
} else {
ONE_SelfDestruct(id);
}
return NULL;
}
TypePtr execIsShutdown (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
ablREPORT(ObjectIDisGroup(id) == false,ablERROR("Cannot call IsShutdown() on a group."));
MWObject* mwobject = GetMWObjectForID(id);
if ((mwobject == 0) ||
(mwobject->IsDerivedFrom(Vehicle::DefaultData) == false))
{
pushBoolean(false);
}
else
{
Vehicle* vehicle = Cast_Object(Vehicle*,mwobject);
pushBoolean(vehicle->vehicleShutDown);
}
return BooleanTypePtr;
}
void Group_execIsShot(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if ((*i)->ShotBy(gos_GetElapsedTime() - who_shot_duration) != 0)
{
pushBoolean(true);
return;
}
}}
pushBoolean(false);
}
TypePtr execisShot (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execIsShot(ObjectIDtoGroupID(id));
}
else
{
AI *who = GetAIForID(id);
Verify ((long) who != -1);
if (who)
{
Check_Object (who);
if (who->Dead())
{
pushBoolean(false);
return BooleanTypePtr;
}
if (who->ShotBy(gos_GetElapsedTime () - who_shot_duration) != 0)
{
pushBoolean(true);
}
else
{
pushBoolean(false);
}
}
else
{
pushBoolean(false);
}
}
return BooleanTypePtr;
}
bool Group_execIsWithin(Group::identifier group_id, Entity* who, Stuff::Scalar range)
{
mwobject_list objects;
GetVehiclesFromGroup(group_id,objects);
{for (mwobject_list::iterator i = objects.begin();
i != objects.end();
++i)
{
if ((*i)->IsWithin(who,range,true) == true)
{
return(true);
}
}}
return(false);
}
bool Group_execIsWithin(Group::identifier group_id1, Group::identifier group_id2, Stuff::Scalar range)
{
mwobject_list objects;
GetVehiclesFromGroup(group_id1,objects);
{for (mwobject_list::iterator i = objects.begin();
i != objects.end();
++i)
{
if (Group_execIsWithin(group_id2,*i,range) == true)
{
return(true);
}
}}
return(false);
}
TypePtr execPlayerShooting(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
int size,i;
Stuff::Time time = popInteger ();
NameTable *table = NameTable::GetInstance();
Check_Object (table);
ablREPORT (id >=0,"to low of a number to playershooting");
ablREPORT (id < 32,"to high of a number to playershooting");
Check_Object(NameTable::GetInstance());
size = table->nameTableArray[NameTable::PlayerArray].GetLength ();
MWPlayer *player;
for (i=0;i<size;i++)
{
NameTableEntry *data;
data = &table->nameTableArray [NameTable::PlayerArray][i];
if (data->dataPointer->GetCurrent ())
{
if (id == 0)
{
player = Cast_Object(MWPlayer *,data->dataPointer->GetCurrent ());
Check_Object(player);
VehicleInterface *inter;
inter = player->GetInterface ();
Check_Object (inter);
pushBoolean (inter->LastTimeShot () > (gos_GetElapsedTime() - time));
return BooleanTypePtr;
}
}
id--;
}
pushBoolean (false);
return BooleanTypePtr;
}
TypePtr execisWithin (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long object1 = popInteger ();
long object2 = popInteger ();
long range = popInteger ();
if ((object1 == ABL_NO_UNIT) ||
(object2 == ABL_NO_UNIT))
{
pushBoolean(false);
return BooleanTypePtr;
}
if ((ObjectIDisGroup(object1) == true) ||
(ObjectIDisGroup(object2) == true))
{
bool in_range = false;
if (ObjectIDisGroup(object1) == true)
{
if (ObjectIDisGroup(object2) == true)
{
in_range = Group_execIsWithin(ObjectIDtoGroupID(object1),ObjectIDtoGroupID(object2),(Stuff::Scalar)range);
}
else
{
Entity* who2 = GetObjectForID<Entity>(object2);
if (!who2)
in_range = false;
else if (who2->IsDestroyed() == true)
{
in_range = false;
}
else
{
in_range = Group_execIsWithin(ObjectIDtoGroupID(object1),who2,(Stuff::Scalar)range);
}
}
}
else
{
Entity* who1 = GetObjectForID<Entity>(object1);
if (!who1)
in_range = false;
else if (who1->IsDestroyed() == true)
{
in_range = false;
}
else
{
in_range = Group_execIsWithin(ObjectIDtoGroupID(object2),who1,(Stuff::Scalar)range);
}
}
pushBoolean(in_range);
}
else
{
Entity* who1 = GetObjectForID<Entity>(object1);
Entity* who2 = GetObjectForID<Entity>(object2);
who1 = ConvertAIToEntity(who1);
who2 = ConvertAIToEntity(who2);
if ((who1 == 0) ||
(who2 == 0) ||
(who1->IsDestroyed() == true) ||
(who2->IsDestroyed() == true))
{
pushBoolean(false);
}
else
{
ablREPORT(who1 != who2,ablERROR ("tried to ask if an object isWithin itself"));
Stuff::Scalar temp;
temp = (Stuff::Scalar) range;
pushBoolean(who1->IsWithin(who2,temp,true));
}
}
return BooleanTypePtr;
}
bool Group_execIsWithinLoc(Group::identifier id, const Stuff::Point3D& loc, int distance)
{
mwobject_list objects;
GetVehiclesFromGroup(id,objects);
{for (mwobject_list::iterator i = objects.begin();
i != objects.end();
++i)
{
if (GetApproximateLength(loc,(Stuff::Point3D)(*i)->GetLocalToWorld()) < (Stuff::Scalar)distance)
{
return (true);
}
}}
return (false);
}
TypePtr execisWithinLoc (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Stuff::Point3D loc;
long id = popInteger ();
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
baseType(execVariable(idPtr, USE_REFPARAM));
long* waypoint = (long*)(&((StackItemPtr)tos->address)->integer);
Check_Pointer (waypoint);
pop();
loc.x = (float) waypoint[0];
loc.y = (float) waypoint[1];
loc.z = (float) waypoint[2];
int distance = popInteger ();
if (distance < 0) { // jcem
distance = -distance;
loc = Point3D::HellPoint;
}
if (ObjectIDisGroup(id) == true)
{
pushBoolean(Group_execIsWithinLoc(ObjectIDtoGroupID(id),loc,distance));
}
else
{
Entity* who1 = GetObjectForID<Entity>(id);
who1 = ConvertAIToEntity(who1);
if (!who1)
pushBoolean (false);
else if (who1->IsDestroyed() == true)
{
pushBoolean(false);
}
else
{
Stuff::Point3D extra,entityloc;
entityloc = (Stuff::Point3D) who1->GetLocalToWorld ();
entityloc.y = 0;
loc.y = 0;
extra.Subtract (loc,entityloc);
distance *= distance;
pushBoolean (distance > extra.GetLengthSquared ());
}
}
return BooleanTypePtr;
}
TypePtr execisDead (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
pushBoolean(MW4AI::Groups::AllDead(ObjectIDtoGroupID(id)));
}
else
{
pushBoolean(IsDead(id));
}
return BooleanTypePtr;
}
TypePtr execisEqual (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
TypePtr paramTypePtr;
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float p1 = tos->real;
pop();
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float p2 = tos->real;
pop();
pushBoolean (p1 == p2);
return BooleanTypePtr;
}
TypePtr execisLesser (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
TypePtr paramTypePtr;
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float p1 = tos->real;
pop();
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float p2 = tos->real;
pop();
pushBoolean (p1 < p2);
return BooleanTypePtr;
}
TypePtr execisGreater (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
TypePtr paramTypePtr;
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float p1 = tos->real;
pop();
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float p2 = tos->real;
pop();
pushBoolean (p1 > p2);
return BooleanTypePtr;
}
TypePtr execequalID (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int p1 = popInteger ();
int p2 = popInteger ();
pushBoolean (p1 == p2);
return BooleanTypePtr;
}
bool Group_execIsRammed(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if ((*i)->RammedBy(gos_GetElapsedTime() - who_rammed_duration) != 0)
{
return (true);
}
}}
return (false);
}
TypePtr execisRammed (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
pushBoolean(Group_execIsRammed(ObjectIDtoGroupID(id)));
}
else
{
AI* who = GetAIForID(id);
if (who)
{
Check_Object (who);
if (who->RammedBy(gos_GetElapsedTime() - who_rammed_duration) == 0)
{
pushBoolean(false);
}
else
{
pushBoolean(true);
}
}
else
{
pushBoolean (false);
}
}
return BooleanTypePtr;
}
Adept::ObjectID Group_execWhoRammed(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
Entity* shot_by = (*i)->RammedBy(gos_GetElapsedTime() - who_rammed_duration);
if (shot_by != 0)
{
return (shot_by->objectID);
}
}}
return (ABL_NO_UNIT);
}
TypePtr execwhoRammed (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
if (ObjectIDisGroup(objectid) == true)
{
pushInteger(Group_execWhoRammed(ObjectIDtoGroupID(objectid)));
}
else
{
AI *who = GetAIForID(objectid);
Verify ((long) who != -1);
if (who)
{
Check_Object (who);
Entity *target;
target = who->RammedBy (gos_GetElapsedTime () - who_rammed_duration);
if (!target)
{
pushInteger (ABL_NO_UNIT);
}
else
{
Check_Object (target);
pushInteger (target->objectID);
}
}
else
{
pushInteger (ABL_NO_UNIT);
}
}
return IntegerTypePtr;
}
bool Group_execCanSee(Group::identifier id, MWObject& who)
{
std::vector<CombatAI*> ais;
GetAIsFromGroup<CombatAI>(id,ais);
{for (std::vector<CombatAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if ((*i)->CanSee(who) == true)
{
return (true);
}
}}
return (false);
}
TypePtr execcanSee (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long objectid = popInteger ();
MWObject* target = GetMWObjectForID(objectid);
if (target == 0)
{
ablREPORT(1 == 0,ablERROR("Invalid target for CanSee()"));
pushBoolean(false);
return BooleanTypePtr;
}
if (ObjectIDisGroup(id) == true)
{
pushBoolean(Group_execCanSee(ObjectIDtoGroupID(id),*target));
return BooleanTypePtr;
}
CombatAI* me = GetCombatAIForID(id);
if (me == 0)
{
ablREPORT(1 == 0,ablERROR("Invalid source for CanSee()"));
pushBoolean(false);
return BooleanTypePtr;
}
pushBoolean(me->CanSee(*target));
return BooleanTypePtr;
}
TypePtr execcanTarget (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
ablREPORT(ObjectIDisGroup(id) == false,ablERROR ("tried to call canTarget with a group"));
long objectid = popInteger ();
pushBoolean (true); //TODO
return BooleanTypePtr;
}
TypePtr execbattleValueLesser (SymTableNodePtr routineIdPtr)
{
long id = popInteger ();
ablREPORT(ObjectIDisGroup(id) == false,ablERROR ("tried to call battleValueLesser with a group"));
pushBoolean (true); //TODO
return BooleanTypePtr;
}
TypePtr execbattleValueLesserID (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
ablREPORT(ObjectIDisGroup(id) == false,ablERROR ("tried to call battleValueLesserID with a group"));
long objectid = popInteger ();
pushBoolean (true); //TODO
return BooleanTypePtr;
}
TypePtr exectimeLesser (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT ((ObjectIDisGroup(objectid) == false),ablERROR ("asked timeLesser for a group"));
TypePtr paramTypePtr;
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float time = tos->real;
pop();
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT (objectid >=0,ablERROR ("tried to check timeLesser on a timer id less than min"));
ablREPORT (objectid <MAX_MISSION_TIMERS,ablERROR ("tried to check timeLesser on a timer id greater than max"));
pushBoolean (mission->Timer (objectid).CurrTime () < time);
return BooleanTypePtr;
}
TypePtr exectimeGreater (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
ablREPORT ((ObjectIDisGroup(objectid) == false),ablERROR ("asked timeGreater for a group"));
TypePtr paramTypePtr;
getCodeToken ();
paramTypePtr = baseType(execExpression());
if (paramTypePtr == IntegerTypePtr)
tos->real = (float)(tos->integer);
float time = tos->real;
pop();
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT (objectid >=0,ablERROR ("tried to check timeGreater on a timer id less than min"));
ablREPORT (objectid <MAX_MISSION_TIMERS,ablERROR ("tried to check timeGreater on a timer id greater than max"));
pushBoolean (mission->Timer (objectid).CurrTime () > time);
return BooleanTypePtr;
}
TypePtr execrand (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long low = popInteger ();
long high = popInteger ();
Stuff::Scalar value;
value = Stuff::Random::GetFraction ();
value *= (high-low);
value += low;
pushInteger ((int) value);
return IntegerTypePtr;
}
TypePtr execplaySound (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
return NULL;
}
TypePtr execplaySoundOnce (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
return NULL;
}
TypePtr execkillSound (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
return NULL;
}
TypePtr execSetAudioFXEnabled (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
bool fred = popBoolean ();
return NULL;
}
TypePtr execplayMusic (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Scalar volume = popInteger () / 100.0f;
return NULL;
}
TypePtr execkillMusic (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
return NULL;
}
TypePtr execfadeInMusic (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
long time = popInteger ();
Scalar volume = popInteger () / 100.0f;
return NULL;
}
TypePtr execfadeOutMusic (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
long time = popInteger ();
Scalar volume = popInteger () / 100.0f;
return NULL;
}
TypePtr execplayEffect (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Entity *entity;
EffectGenerator *obj;
ablREPORT ((objectid != -1),ablERROR ("asked to playEffect for self"));
entity = GetObjectForID<Entity>(objectid);
if (!entity)
return NULL;
ablREPORT ((entity->IsDerivedFrom(EffectGenerator::DefaultData)),ablERROR ("trying to playEffect for a non effect"));
obj = Cast_Object(EffectGenerator *, entity);
Check_Object(obj);
obj->executionState->RequestState(Entity::ExecutionStateEngine::AlwaysExecuteState);
obj->PlayEffect();
return NULL;
}
TypePtr execkillEffect (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Entity *entity;
EffectGenerator *obj;
Verify (objectid != -1);
entity = GetObjectForID<Entity>(objectid);
if (!entity)
return NULL;
ablREPORT ((entity->IsDerivedFrom(EffectGenerator::DefaultData)),ablERROR ("trying to killEffect for a non effect"));
obj = Cast_Object(EffectGenerator *, entity);
Check_Object(obj);
obj->KillEffect();
obj->executionState->RequestState(Entity::ExecutionStateEngine::NeverExecuteState);
return NULL;
}
TypePtr execSetChanceLancematesEject (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int chance = popInteger();
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
mission->m_ChanceLancematesEject = chance;
return NULL;
}
TypePtr execSetChanceLancematesOKWhenEjecting (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int chance = popInteger();
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
mission->m_ChanceLancematesOKWhenEjecting = chance;
return NULL;
}
TypePtr execSetChanceLancematesInjuredWhenEjecting (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int chance = popInteger();
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
mission->m_ChanceLancematesInjuredWhenEjecting = chance;
return NULL;
}
TypePtr execRevealLancemate (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *name = popStringPtr();
MWGame* game = MWGame::GetInstance();
if (!game)
return NULL;
Check_Object (game);
LancemateManager *man = game->m_lancemates;
man->RevealLancemate (name);
return NULL;
}
TypePtr execHideLancemate (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *name = popStringPtr();
MWGame* game = MWGame::GetInstance();
if (!game)
return NULL;
Check_Object (game);
LancemateManager *man = game->m_lancemates;
man->HideLancemate (name);
return NULL;
}
TypePtr execIsMissionComplete (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *mission_name = popStringPtr();
bool result = false;
if(MWGame::GetInstance())
{
if(MWGame::GetInstance()->m_campaign)
{
CampaignMissionPlug *mission_plug;
mission_plug = MWGame::GetInstance()->m_campaign->FindMission(mission_name);
if(mission_plug)
{
if(mission_plug->m_status == MWCampaign::Completed)
result = true;
}
}
}
pushBoolean(result);
return BooleanTypePtr;
}
TypePtr execrevealNavPoint (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
NavPoint *nav_point;
nav_point = Cast_Object(NavPoint *,NameTable::GetInstance()->FindData(objectid));
Check_Object (nav_point);
nav_point->Reveal();
return NULL;
}
TypePtr execIsNavRevealed (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
NavPoint *nav_point;
nav_point = Cast_Object(NavPoint *,NameTable::GetInstance()->FindData(objectid));
Check_Object (nav_point);
pushBoolean(nav_point->IsVisible());
return BooleanTypePtr;
}
TypePtr execsetNavPoint (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
NavPoint *nav_point;
nav_point = Cast_Object(NavPoint *,NameTable::GetInstance()->FindData(objectid));
if (nav_point == 0)
{
return (0);
}
Check_Object (nav_point);
nav_point->Reveal();
if (VehicleInterface::GetInstance() != 0)
{
Check_Object(VehicleInterface::GetInstance());
VehicleInterface::GetInstance()->SetNavPoint(nav_point);
}
return NULL;
}
TypePtr execHideNav (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger();
NavPoint *nav_point;
nav_point = Cast_Object(NavPoint *,NameTable::GetInstance()->FindData(objectid));
if (nav_point == 0)
{
return (0);
}
Check_Object (nav_point);
nav_point->ClearVisibleFlag();
nav_point->RemoveFromNavList();
return NULL;
}
TypePtr execSetRadarNav (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger();
long radarid = popInteger ();
Verify ((radarid == -1) || ((radarid>=1)&&(radarid<=6)));
NavPoint *nav_point;
nav_point = Cast_Object(NavPoint *,NameTable::GetInstance()->FindData(objectid));
if (nav_point == 0)
{
return (0);
}
Check_Object (nav_point);
nav_point->m_RadarID = radarid;
return NULL;
}
TypePtr execcreateHeatSphere (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Entity *target_entity;
long radius = popInteger ();
long heat = popInteger ();
long secs = popInteger ();
target_entity = NameTable::GetInstance()->FindData(objectid);
Check_Object (target_entity);
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
Point3D center;
center = target_entity->GetLocalToWorld();
Scalar r_radius = (Scalar)radius;
Scalar seconds = (Scalar)secs;
Scalar heat_e = (Scalar)heat;
mission->CreateNewHeatSphere(center, r_radius, seconds, heat_e);
return NULL;
}
TypePtr execcreateInstantHeatSphere (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Entity *target_entity;
long radius = popInteger ();
long heat = popInteger ();
target_entity = NameTable::GetInstance()->FindData(objectid);
Check_Object (target_entity);
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
Point3D center;
center = target_entity->GetLocalToWorld();
Scalar r_radius = (Scalar)radius;
Scalar heat_amount = (Scalar)heat;
mission->CreateNewInstantHeatSphere(center, r_radius, heat_amount);
return NULL;
}
TypePtr execcreateFogSphere (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Entity *target_entity;
long radius = popInteger ();
long secs = popInteger ();
target_entity = NameTable::GetInstance()->FindData(objectid);
Check_Object (target_entity);
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
Point3D center;
center = target_entity->GetLocalToWorld();
Scalar r_radius = (Scalar)radius;
Scalar seconds = (Scalar)secs;
mission->CreateNewFogSphere(center, r_radius, seconds);
return NULL;
}
TypePtr execcreateRadarSphere (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Entity *target_entity;
long radius = popInteger ();
long radar_effic = popInteger ();
long secs = popInteger ();
target_entity = NameTable::GetInstance()->FindData(objectid);
Check_Object (target_entity);
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
Point3D center;
center = target_entity->GetLocalToWorld();
Scalar r_radius = (Scalar)radius;
Scalar seconds = (Scalar)secs;
Scalar radar_e = (Scalar)radar_effic;
mission->CreateNewRadarSphere(center, r_radius, seconds, radar_e);
return NULL;
}
TypePtr execshowAllRevealedObjectives (SymTableNodePtr routineIdPtr)
{
Check_Object (ObjectiveRenderer::Instance);
ObjectiveRenderer::Instance->ResetTime ();
endFunction ();
return NULL;
}
TypePtr execrevealObjective (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Objective *obj;
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objectid));
Check_Object (obj);
obj->Reveal ();
return NULL;
}
TypePtr exechideObjective (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Objective *obj;
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objectid));
Check_Object (obj);
obj->Hide ();
return NULL;
}
TypePtr execfailObjective (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Objective *obj;
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objectid));
Check_Object (obj);
ablREPORT (!obj->HelpMessage (),"Tried to fail a help message");
obj->Fail ();
return NULL;
}
TypePtr execfailObjectiveAll (SymTableNodePtr routineIdPtr)
{
int j,size;
NameTable *table = NameTable::GetInstance();
Check_Object (table);
DECLARE_ABL_CONTEXT;
long time = popInteger ();
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
mission->SetEndMissionTime ((Stuff::Scalar) time);
size = table->nameTableArray[NameTable::ObjectiveArray].GetLength ();
for (j=0;j<size;j++)
{
NameTableEntry *data;
data = &table->nameTableArray [NameTable::ObjectiveArray][j];
Objective *obj;
obj = Cast_Object (Objective *,data->dataPointer->GetCurrent());
Check_Object (obj);
if ((!obj->HelpMessage ()) && (obj->Status () == Objective::Objective_Neutral))
obj->Fail ();
}
mission->EndMissionState (false);
return NULL;
}
TypePtr execEndMission (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
bool good = popBoolean ();
long time = popInteger ();
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
mission->SetEndMissionTime ((Stuff::Scalar) time);
mission->EndMissionState (good);
return NULL;
}
TypePtr execRespawnMission (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
// MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
// Check_Object (mission);
// Mission *mission = Mission::GetInstance();
// Check_Object (mission);
// mission->RespawnMission();
#if 1
MWApplication *mw_app = MWApplication::GetInstance();
Check_Object(mw_app);
mw_app->RespawnMission();
#endif
return NULL;
}
TypePtr execsaveGame (SymTableNodePtr routineIdPtr)
{
// no parameters or return value
if(MWGame::GetInstance())
{
MWGame::GetInstance()->SaveInMissionGame();
}
endFunction ();
return NULL;
}
TypePtr execHelpMessage (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
long time = popInteger ();
Objective *obj;
if (objectid == -2)
{
ObjectiveRenderer::Instance->Help(0,0);
}
else
{
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objectid));
Check_Object (obj);
ablREPORT (obj->HelpMessage (),"Tried to show a regular objective as a help message");
obj->ShowHelp (time);
}
return NULL;
}
TypePtr execsuccessObjective (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Objective *obj;
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objectid));
Check_Object (obj);
ablREPORT (!obj->HelpMessage (),"Tried to succeed a help message");
obj->Succeed ();
return NULL;
}
TypePtr execsuccessObjectiveAll (SymTableNodePtr routineIdPtr)
{
int j,size;
NameTable *table = NameTable::GetInstance();
Check_Object (table);
DECLARE_ABL_CONTEXT;
long time = popInteger ();
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
mission->SetEndMissionTime ((Stuff::Scalar) time);
size = table->nameTableArray[NameTable::ObjectiveArray].GetLength ();
for (j=0;j<size;j++)
{
NameTableEntry *data;
data = &table->nameTableArray [NameTable::ObjectiveArray][j];
Objective *obj;
obj = Cast_Object (Objective *,data->dataPointer->GetCurrent());
Check_Object (obj);
if ((!obj->HelpMessage ()) && (obj->Status () == Objective::Objective_Neutral))
obj->Succeed ();
}
mission->EndMissionState (true);
return NULL;
}
TypePtr execcheckObjectiveCompletion (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Objective *obj;
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objectid));
Check_Object (obj);
pushInteger (obj->Status ());
return IntegerTypePtr;
}
TypePtr execisVisible (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Objective *obj;
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objectid));
Check_Object (obj);
if (((int) obj) == -1)
pushBoolean (false);
else if (!obj)
pushBoolean (false);
else
pushBoolean (obj->Visible ());
return BooleanTypePtr;
}
void TeleportWorker (MWObject *who1, const Point3D& lookpt, int flags, Point3D& new_translation)
{
ablREPORT (new_translation.x > MinX,"x coordinate in teleport is less than map size");
ablREPORT (new_translation.z > MinZ,"z coordinate in teleport is less than map size");
ablREPORT (new_translation.x < MaxX,"x coordinate in teleport is greater than map size");
ablREPORT (new_translation.z < MaxZ,"z coordinate in teleport is greater than map size");
if (!(flags & 1)) // overridey
{
// Find the ground
//
// make a line...
//
Point3D curlocation (who1->GetLocalToWorld ());
Stuff::Line3D line;
line.m_length = 20.0f;
line.m_direction = Vector3D::Down;
line.m_origin = new_translation;
if (curlocation.y > 0) // if not in hell then use the vehicles y location, else you point we want to move to
line.m_origin.y = curlocation.y + 5.0f; // pretty harsh hill! =)
//
// Prepare query
//
Stuff::Normal3D normal;
Entity::CollisionQuery query(&line, &normal, Entity::CanBeWalkedOnFlag, who1);
//
// Cast ray
//
Adept::Entity *entity_hit;
Check_Object(CollisionGrid::Instance);
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
if (entity_hit != NULL)
{
// if we hit ground, great!
line.FindEnd(&new_translation);
}
else
{
// Damnit...then find the ground aggresivly!!!!
line.m_origin = new_translation;
if (curlocation.y > 0) // if not in hell then use the vehicles y location, else you point we want to move to
line.m_origin.y = curlocation.y + 100.0f; // pretty harsh hill! =)
else
line.m_origin.y = new_translation.y + 100.0f;
line.m_length = 1000.0f;
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
if (entity_hit != NULL)
{
line.FindEnd(&new_translation);
}
else // now try up!
{
line.m_direction = Vector3D(0.0f, 1.0f, 0.0f);
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
if (entity_hit != NULL)
{
line.FindEnd(&new_translation);
}
}
// ok stop we are way off the map
}
}
LinearMatrix4D new_local_to_world;
// from here by jcem
if (flags & 2) {
Stuff::Point3D rv(lookpt);
#if 1
LinearMatrix4D mo = who1->GetLocalToWorld();
Point3D new_trans(new_translation);
new_trans.y = rv.y;
mo.BuildTranslation(new_trans);
//LinearMatrix4D mv = mo.Invert();
//mv *= rv;
//rv = mv;
Vector3D vFN;
vFN.Subtract(rv, new_trans);
UnitVector3D vF(vFN);
UnitVector3D vU;
Vector3D vRN;
mo.GetLocalUpInWorld(&vU);
vRN.Cross(vF, vU);
UnitVector3D vR(vRN);
mo(FORWARD_AXIS,X_Axis) = vF.x;
mo(FORWARD_AXIS,Y_Axis) = vF.y;
mo(FORWARD_AXIS,Z_Axis) = vF.z;
mo(RIGHT_AXIS,X_Axis) = vR.x;
mo(RIGHT_AXIS,Y_Axis) = vR.y;
mo(RIGHT_AXIS,Z_Axis) = vR.z;
YawPitchRoll moA(mo);
moA.pitch = 0.0f;
moA.roll = 0.0f;
mo.BuildRotation(moA);
mo.BuildTranslation(new_translation);
new_local_to_world = mo;
#elif 1
LinearMatrix4D mo = who1->GetLocalToWorld();
Stuff::Scalar angle = 3.141592 / (2 * 3);
Stuff::Scalar angle_inc = angle / 2;
YawPitchRoll current_rotation;
Point3D new_trans(new_translation);
new_trans.y = rv.y;
mo.BuildTranslation(new_trans);
int nTimes = (int)(3.141592 * 2.0 / angle_inc) + 1;
while(!MatrixFacesPoint(mo, rv, angle)) {
YawPitchRoll current_rotation;
current_rotation = mo;
current_rotation.yaw += angle_inc;
current_rotation.Normalize();
mo.BuildRotation(current_rotation);
if (nTimes-- <= 0)
break;
}
YawPitchRoll moA(mo);
moA.pitch = 0.0f;
moA.roll = 0.0f;
mo.BuildRotation(moA);
mo.BuildTranslation(new_translation);
new_local_to_world = mo;
#elif 0
LinearMatrix4D mt = who2->GetLocalToWorld();
Point3D pt = (Point3D)mt;
LinearMatrix4D mo = who1->GetLocalToWorld();
Point3D po = (Point3D)mo;
Vector3D vt(new_translation);
LinearMatrix4D mv;
//mv.BuildIdentity();
mv.BuildRotation(vt);
//mv.BuildTranslation(new_translation);
Point3D pppp;
pppp.Multiply(pt, mv);
Vector3D vvv(pppp);
LinearMatrix4D dd;
dd.BuildIdentity();
dd.BuildRotation(vvv);
LinearMatrix4D qq;
qq.Multiply(mv, dd);
YawPitchRoll new_rotation(qq);
new_rotation.yaw.Normalize();
new_rotation.pitch = 0.0f;
new_rotation.roll = 0.0f;
new_local_to_world.BuildRotation(new_rotation);
new_local_to_world.BuildTranslation(new_translation);
#else
Vector3D vdir;
static bool s_bv3d = 1;
if (s_bv3d)
vdir.Subtract(pt, new_translation);
else
vdir.Subtract(new_translation, pt);
#define PIX 3.141592
#define R2D(x) ((((x) * 180.0)) / PIX)
char sz[256];
Vector3D vt(pt);
LinearMatrix4D mv;
mv.BuildIdentity(pt);
mv.BuildRotation(vt);
YawPitchRoll t_rotation(mv);
LinearMatrix4D mx;
mx.BuildIdentity();
mx.BuildRotation(vdir);
LinearMatrix4D inv_mx;
inv_mx.Invert(mx);
YawPitchRoll new_rotation(inv_mx);
sprintf(sz, "t %3.2f, n %3.2f\n", R2D(t_rotation.yaw.angle), R2D(new_rotation.yaw.angle));
::OutputDebugString(sz);
static int s_nAdd = 0;
switch(s_nAdd)
{
case -1:
new_rotation.yaw -= t_rotation.yaw;
break;
case 0:
break;
case +1:
new_rotation.yaw += t_rotation.yaw;
break;
}
static s_nDeg = -1;
switch(s_nDeg)
{
case 0:
new_rotation.yaw += PIX / 2.0;
break;
case 1:
new_rotation.yaw += PIX;
break;
case 2:
new_rotation.yaw += PIX * 3.0 / 2.0;
break;
case 3:
new_rotation.yaw += PIX * 2.0;
break;
}
new_rotation.yaw.Normalize();
new_rotation.pitch = 0.0f;
new_rotation.roll = 0.0f;
inv_mx.BuildRotation(new_rotation);
inv_mx.BuildTranslation(new_translation);
new_local_to_world = inv_mx;
//new_local_to_world.BuildRotation(new_rotation);
#endif
} else { // original...
YawPitchRoll new_rotation;
new_rotation = (YawPitchRoll) who1->GetLocalToWorld ();
//new_rotation.pitch = 0.0f;
new_rotation.roll = 0.0f;
new_local_to_world.BuildRotation(new_rotation);
new_local_to_world.BuildTranslation(new_translation);
}
who1->SetNewLocalToParent(new_local_to_world);
// to here by jcem
who1->SyncMatrices (true);
Map::GetInstance()->UpdateZone (who1);
who1->initialLocalToParent = who1->GetLocalToParent();
who1->initialWorldSpaceVelocity = who1->worldSpaceVelocity,
who1->initialWorldSpaceAcceleration = who1->worldSpaceAcceleration;
}
void Group_TeleportToHell(MWObject *who1)
{
Point3D hpt(Point3D::HellPoint);
TeleportWorker (who1,Point3D::HellPoint,1,hpt);
AI *ai;
ai = who1->GetAI ();
if (ai)
{
ai->Shutdown ();
ai->AlwayActive (false);
// ai->TurnOff ();
if (ai->IsDerivedFrom(MoverAI::DefaultData))
{
MoverAI *move =Cast_Object (MoverAI *,ai);
move->ClearMoveOrder ();
}
if (ai->IsDerivedFrom(CombatAI::DefaultData))
{
CombatAI *combat =Cast_Object (CombatAI *,ai);
combat->OrderStopAttacking ();
}
if (ai->IsDerivedFrom (PlaneAI::DefaultData))
{
PlaneAI *planeai = Cast_Object (PlaneAI *,ai);
planeai->hellteleport ();
}
}
}
TypePtr execteleportToHell (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
if (ObjectIDisGroup(id) == true) {
int group_id = ObjectIDtoGroupID(id);
mwobject_list targets;
GetVehiclesFromGroup(group_id,targets);
{for (mwobject_list::const_iterator i = targets.begin(); i != targets.end(); ++i)
{
Group_TeleportToHell(*i);
}}
} else {
MWObject *who1 = GetMWObjectForID(id);
if (who1) {
Group_TeleportToHell(who1);
}
}
return NULL;
}
TypePtr execteleport (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
Stuff::Point3D tpt = popPoint();
MWObject *who1 = GetMWObjectForID(id);
if (!who1)
return NULL;
Verify (who1);
TeleportWorker (who1,Point3D::HellPoint,0,tpt);
return NULL;
}
TypePtr execteleportAndLook (SymTableNodePtr routineIdPtr) // jcem
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
Stuff::Point3D lookpt = popPoint();
int flags = popInteger ();
Stuff::Point3D tpt = popPoint();
MWObject *who1 = GetMWObjectForID(id);
if (!who1)
return NULL;
Verify (who1);
TeleportWorker (who1,lookpt,flags,tpt);
return NULL;
}
TypePtr execDisableAIJumping (SymTableNodePtr routineIdPtr)
{
MoverAI::DisableAIJumping ();
endFunction ();
return NULL;
}
TypePtr execplayChatter (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
return NULL;
}
TypePtr execplayChatterPriority (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
long priority = popInteger ();
return NULL;
}
TypePtr execkillChatter (SymTableNodePtr routineIdPtr)
{
endFunction ();
// no parameters or return value
return NULL;
}
TypePtr execstartTimer (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT ((objectid >=0),ablERROR ("trying to startTimer on an invalid timer"));
ablREPORT ((objectid <MAX_MISSION_TIMERS),ablERROR ("trying startTimer on an invalid timer"));
mission->Timer (objectid).Start ();
return NULL;
}
TypePtr execkillTimer (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT ((objectid >=0),ablERROR ("trying to killTimer on an invalid timer"));
ablREPORT ((objectid <MAX_MISSION_TIMERS),ablERROR ("trying killTimer on an invalid timer"));
mission->Timer (objectid).Stop ();
return NULL;
}
TypePtr execresetTimer (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT ((objectid >=0),ablERROR ("trying to resetTimer on an invalid timer"));
ablREPORT ((objectid <MAX_MISSION_TIMERS),ablERROR ("trying resetTimer on an invalid timer"));
mission->Timer (objectid).Stop ();
mission->Timer (objectid).Start ();
return NULL;
}
TypePtr execpauseTimer (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger ();
bool pause = popBoolean ();
Check_Object (MechWarrior4::MWMission::GetInstance());
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
ablREPORT ((objectid >=0),ablERROR ("trying to pauseTimer on an invalid timer"));
ablREPORT ((objectid <MAX_MISSION_TIMERS),ablERROR ("trying pauseTimer on an invalid timer"));
mission->Timer (objectid).Pause (pause);
return NULL;
}
//orders
TypePtr execorderDie (SymTableNodePtr routineIdPtr)
{
// no parameters or return value
Check_Pointer(CurWarrior);
CurWarrior->StopScript ();
endFunction ();
return NULL;
}
TypePtr execorderMoveLookOut (SymTableNodePtr routineIdPtr)
{
// no parameters or return value
Check_Pointer(CurMoverAI);
if (CurMoverAI->IsDerivedFrom(PlaneAI::DefaultData) == false)
{
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to lookout on a non mover ai"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("asking to lookout on a dead unit"));
CurMoverAI->orderMoveLookOut ();
}
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
endFunction ();
return NULL;
}
TypePtr execorderFormOnSpot (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long GroupID = popInteger ();
long* loc = popIntegerPtr ();
long* dir = popIntegerPtr ();
long speed = popInteger ();
long form = popInteger ();
long sparse = popInteger ();
bool clear = popBoolean ();
ablREPORT ((ObjectIDisGroup(GroupID)),ablERROR ("trying to form on spot for a non group"));
Verify (loc);
Verify (dir);
std::vector<MoverAI*> list;
GetAIsFromGroup<MoverAI> (ObjectIDtoGroupID(GroupID),list);
speed = ConvertKPHtoMPS (speed);
Form_On_Spot (list,loc,dir,speed,form,sparse,clear);
return NULL;
}
TypePtr execorderFormationMove (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long GroupID = popInteger ();
long PathId = popInteger ();
long speed = popInteger ();
long type = popInteger ();
long form = popInteger ();
long sparse = popInteger ();
bool clear = popBoolean ();
Verify (type >= 0);
Verify (type <= PATROL_SEESAW);
ablREPORT ((ObjectIDisGroup(GroupID)),ablERROR ("trying to formation move for a non group"));
ablREPORT (PathId!=-1,ablERROR ("pathid is invalid"));
Path *path = Cast_Object (Path *,NameTable::GetInstance()->FindData (PathId));
Check_Object (path);
Verify (path->IsDerivedFrom (Path::DefaultData));
std::vector<MoverAI*> list;
GetAIsFromGroup<MoverAI> (ObjectIDtoGroupID(GroupID),list);
speed = ConvertKPHtoMPS (speed);
pushBoolean (Form_Move (list,PathId,speed,type,form,sparse,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveTo (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurMoverAI);
long PathId = popInteger ();
long speed = popInteger ();
long type = popInteger ();
bool forwards = popBoolean ();
bool clear = popBoolean ();
ablREPORT (type >= 1,"Bad move type");
ablREPORT (type <= PATROL_SEESAW,"Bad move type");
ablREPORT (PathId!=-1,ablERROR ("pathid is invalid"));
Path *path = Cast_Object (Path *,NameTable::GetInstance()->FindData (PathId));
Check_Object (path);
ablREPORT (path->IsDerivedFrom (Path::DefaultData),ablERROR ("unknown path in moveto"));
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to move to for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to move to for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushBoolean (CurMoverAI->orderMoveToSemi (path,speed,type,forwards,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveToFree (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurMoverAI);
long PathId = popInteger ();
long speed = popInteger ();
long type = popInteger ();
bool forwards = popBoolean ();
bool clear = popBoolean ();
Verify (type >= 0);
Verify (type <= PATROL_SEESAW);
ablREPORT (PathId!=-1,ablERROR ("pathid is invalid"));
Path *path = Cast_Object (Path *,NameTable::GetInstance()->FindData (PathId));
Check_Object (path);
ablREPORT (path->IsDerivedFrom (Path::DefaultData),ablERROR ("unknown path in moveto"));
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to move to for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to move to for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushBoolean (CurMoverAI->orderMoveTo (path,speed,type,forwards,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveToRigid (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurMoverAI);
long PathId = popInteger ();
long speed = popInteger ();
long type = popInteger ();
bool forwards = popBoolean ();
bool clear = popBoolean ();
Verify (type >= 0);
Verify (type <= PATROL_SEESAW);
ablREPORT (PathId!=-1,ablERROR ("pathid is invalid"));
Path *path = Cast_Object (Path *,NameTable::GetInstance()->FindData (PathId));
Check_Object (path);
ablREPORT (path->IsDerivedFrom (Path::DefaultData),ablERROR ("unknown path in moveto rigid"));
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to move to rigid for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to move to rigid for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushBoolean (CurMoverAI->orderMoveToRigid (path,speed,type,forwards,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveFlee (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurMoverAI);
long objectid = popInteger ();
long speed = popInteger ();
Verify (objectid != -1);
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to flee for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to flee for a dead unit"));
MWObject* who = GetMWObjectForID(objectid);
if (!who)
{
pushInteger (0);
return IntegerTypePtr;
}
Check_Object (who);
Verify (!CurMoverAI->Dead ());
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushInteger (CurMoverAI->orderMoveFlee (who,speed));
return IntegerTypePtr;
}
TypePtr execorderMoveResumePatrolRigid (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
long PathId = popInteger ();
long speed = popInteger ();
long type = popInteger ();
bool forwards = popBoolean ();
bool clear = popBoolean ();
ablREPORT (PathId!=-1,ablERROR ("pathid is invalid"));
Path *path = Cast_Object (Path *,NameTable::GetInstance()->FindData (PathId));
Check_Object (path);
ablREPORT (path->IsDerivedFrom (Path::DefaultData),ablERROR ("unknown path in resume patrol rigid"));
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to resume patrol for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to resume patrol for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushBoolean(CurMoverAI->orderMoveResumePatrolRigid (path,speed,type,forwards,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveResumePatrol (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
long PathId = popInteger ();
long speed = popInteger ();
long type = popInteger ();
bool forwards = popBoolean ();
bool clear = popBoolean ();
ablREPORT (PathId!=-1,ablERROR ("pathid is invalid"));
Path *path = Cast_Object (Path *,NameTable::GetInstance()->FindData (PathId));
Check_Object (path);
ablREPORT (path->IsDerivedFrom (Path::DefaultData),ablERROR ("unknown path in resume patrol"));
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to resume patrol for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to resume patrol for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushBoolean(CurMoverAI->orderMoveResumePatrolSemi (path,speed,type,forwards,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveResumePatrolFree (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
long PathId = popInteger ();
long speed = popInteger ();
long type = popInteger ();
bool forwards = popBoolean ();
bool clear = popBoolean ();
ablREPORT (PathId!=-1,ablERROR ("pathid is invalid"));
Path *path = Cast_Object (Path *,NameTable::GetInstance()->FindData (PathId));
Check_Object (path);
ablREPORT (path->IsDerivedFrom (Path::DefaultData),ablERROR ("unknown path in resume patrol"));
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to resume patrol for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to resume patrol for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushBoolean(CurMoverAI->orderMoveResumePatrol (path,speed,type,forwards,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveFollow (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
long objectid = popInteger ();
long xoffset = popInteger ();
long zoffset = popInteger ();
if ((xoffset > 0) && (xoffset < 30))
xoffset = 30;
if ((zoffset > 0) && (zoffset < 30))
zoffset = 30;
if ((xoffset < 0) && (xoffset > -30))
xoffset = -30;
if ((zoffset < 0) && (zoffset > -30))
zoffset = -30;
Verify (objectid != -1);
MWObject *who = GetMWObjectForID(objectid);
if (!who)
return NULL;
Check_Object (who);
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to follow for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to follow for a dead unit"));
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
CurMoverAI->orderMoveFollow (who,xoffset,zoffset,1000);
return NULL;
}
TypePtr execorderMoveSit (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
bool shutdown = popBoolean ();
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to sit for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to sit for a dead unit"));
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
if (CurMoverAI->IsDerivedFrom(PlaneAI::DefaultData) == false)
{
CurMoverAI->orderMoveSit (shutdown);
}
return NULL;
}
TypePtr execorderMoveToLocPoint (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
Stuff::Point3D loc;
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
baseType(execVariable(idPtr, USE_REFPARAM));
long* waypoint = (long*)(&((StackItemPtr)tos->address)->integer);
Check_Pointer (waypoint);
pop();
loc.x = (float) waypoint[0];
loc.y = (float) waypoint[1];
loc.z = (float) waypoint[2];
long speed = popInteger ();
bool forwards = popBoolean ();
bool clear = popBoolean ();
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to move locpoint for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to move locpoint for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
pushBoolean (CurMoverAI->orderMoveToLocPoint (loc,speed,forwards,clear));
return BooleanTypePtr;
}
TypePtr execorderMoveToObject (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
Check_Object (CurMoverAI);
long objectid = popInteger ();
long speed = popInteger ();
Verify (objectid != -1);
Entity* who = GetObjectForID<Entity>(objectid);
who = ConvertAIToEntity(who);
if (!who)
{
pushBoolean (false);
return BooleanTypePtr;
}
Check_Object (who);
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (MoverAI::DefaultData)),ablERROR ("trying to move object for a non mover"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to move object for a dead unit"));
speed = ConvertKPHtoMPS (speed);
if (CurMoverAI->IsDerivedFrom (CombatAI::DefaultData))
{
CombatAI *combat = Cast_Object (CombatAI *,CurMoverAI);
if (combat->OverridingMovement () && combat->Attacking ())
{
combat->OrderStopAttacking ();
}
}
if (who->IsDerivedFrom (Vehicle::DefaultData))
{
CurMoverAI->orderMoveFollow (who,0,-20,speed);
Check_Object (CurMoverAI->getVehicle ());
pushBoolean(CurMoverAI->getVehicle ()->IsWithin(who,40,true));
}
else
{
pushBoolean (CurMoverAI->orderMoveToObject (who,speed));
}
return BooleanTypePtr;
}
TypePtr execorderAttack (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
bool moveoverride = popBoolean();
CombatAI* combat_ai = GetCombatAIForID(-1);
if (!combat_ai)
{
pushBoolean (false);
return BooleanTypePtr;
}
Verify(!combat_ai->Dead ());
if ((combat_ai->Target() == 0) ||
(combat_ai->Target()->IsDestroyed() == true))
{
pushBoolean(true);
}
else
{
pushBoolean(false);
combat_ai->OrderAttack(moveoverride);
}
return BooleanTypePtr;
}
TypePtr execorderAttackTactic (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
long tactic = popInteger ();
bool moveoverride = popBoolean ();
CombatAI* combat_ai = GetCombatAIForID(-1);
if (!combat_ai)
{
pushBoolean (false);
return BooleanTypePtr;
}
Verify (!combat_ai->Dead ());
if (tactic == MW4AI::Tactics::TACTIC_PICK_BEST)
{
combat_ai->OrderAttack(moveoverride);
}
else
{
combat_ai->OrderAttackTactic((MW4AI::Tactics::TacticID)tactic,moveoverride);
}
if ((combat_ai->Target() == 0) ||
(combat_ai->Target()->IsDestroyed() == true))
{
pushBoolean(true);
}
else
{
pushBoolean(false);
}
return BooleanTypePtr;
}
TypePtr execorderAttackBomb (SymTableNodePtr routineIdPtr)
{
Check_Pointer(CurWarrior);
Verify (!CurWarrior->Dead ());
pushBoolean (true); // TODO
endFunction ();
return BooleanTypePtr;
}
TypePtr execorderStopAttacking(SymTableNodePtr routineIdPtr)
{
Check_Pointer(CurWarrior);
Verify (!CurWarrior->Dead ());
if (CurWarrior->IsDerivedFrom(CombatAI::DefaultData) == false)
{
ablREPORT(0,ablERROR("Cannot orderStopAttacking() on a non-combat-AI"));
}
else
{
CombatAI* combat_ai = Cast_Object(CombatAI*,CurWarrior);
Check_Object(combat_ai);
combat_ai->OrderStopAttacking();
}
endFunction(); // no parameters or return value
return NULL;
}
TypePtr execorderTakeOff (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
int distance = popInteger ();
Check_Object (CurMoverAI);
if (CurMoverAI->IsDerivedFrom(PlaneAI::DefaultData) == false)
{
pushBoolean(true);
return BooleanTypePtr;
}
ablREPORT ((CurMoverAI->IsDerivedFrom (PlaneAI::DefaultData)),ablERROR ("trying to takeoff for a non plane"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to takeoff for a dead unit"));
PlaneAI *plane_ai = Cast_Object(PlaneAI *, CurMoverAI);
pushBoolean (plane_ai->orderTakeOff (distance));
return BooleanTypePtr;
}
TypePtr execorderLand (SymTableNodePtr routineIdPtr)
{
Check_Pointer(CurWarrior);
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (PlaneAI::DefaultData)),ablERROR ("trying to land for a non plane"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to takeoff for a dead unit"));
PlaneAI *plane_ai = Cast_Object(PlaneAI *, CurMoverAI);
pushBoolean (plane_ai->orderLand ());
endFunction ();
return BooleanTypePtr;
}
TypePtr execorderDoorOpen (SymTableNodePtr routineIdPtr)
{
Check_Pointer(CurWarrior);
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (PlaneAI::DefaultData)),ablERROR ("trying to door open for a non dropship"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to door open for a dead unit"));
PlaneAI *plane_ai = Cast_Object(PlaneAI *, CurMoverAI);
pushBoolean (plane_ai->orderDoorOpen ());
endFunction ();
return BooleanTypePtr;
}
TypePtr execorderDoorClose (SymTableNodePtr routineIdPtr)
{
Check_Pointer(CurWarrior);
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (PlaneAI::DefaultData)),ablERROR ("trying to door close for a non dropship"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to door close for a dead unit"));
PlaneAI *plane_ai = Cast_Object(PlaneAI *, CurMoverAI);
pushBoolean (plane_ai->orderDoorClose ());
endFunction ();
return BooleanTypePtr;
}
TypePtr execorderShootPoint (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Pointer(CurWarrior);
getCodeToken();
SymTableNodePtr idPtr = getCodeSymTableNodePtr();
baseType(execVariable(idPtr, USE_REFPARAM));
long* waypoint = (long*)(&((StackItemPtr)tos->address)->integer);
Check_Pointer (waypoint);
pop();
Stuff::Point3D loc((float) waypoint[0],
(float) waypoint[1],
(float) waypoint[2]);
long stretch = popInteger ();
Check_Object (CurMoverAI);
ablREPORT ((CurMoverAI->IsDerivedFrom (CombatAI::DefaultData)),ablERROR ("trying to shootpoint for a non combat"));
ablREPORT ((!CurMoverAI->Dead ()),ablERROR ("trying to shootpoint for a dead unit"));
CombatAI* combat_ai = Cast_Object(CombatAI*,CurMoverAI);
Check_Object(combat_ai);
combat_ai->OrderShootPoint(loc,stretch);
return NULL;
}
void Group_LancemateCommand(Group::identifier group_id, long command)
{
std::vector<CombatAI*> objects;
GetAIsFromGroup<CombatAI>(group_id,objects);
MW4AI::LancemateCommands::lancemate_list l;
{for (std::vector<CombatAI*>::iterator i = objects.begin();
i != objects.end();
++i)
{
l.push_back((*i)->GetSelf().objectID);
}}
if (l.size() > 0)
{
MW4AI::LancemateCommands::Execute((MW4AI::LancemateCommands::ID)command,l);
}
}
TypePtr execlancemateCommand(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long command = popInteger();
if (ObjectIDisGroup(id) == true)
{
Group_LancemateCommand(ObjectIDtoGroupID(id),command);
return NULL;
}
CombatAI *who = GetCombatAIForID(id);
if (who != 0)
{
Check_Object(who);
MW4AI::LancemateCommands::lancemate_list l;
l.push_back(who->GetSelf().objectID);
MW4AI::LancemateCommands::Execute((MW4AI::LancemateCommands::ID)command,l);
}
return NULL;
}
TypePtr execEnableAIStats(SymTableNodePtr routineIdPtr)
{
if (MW4AI::DebugRenderer::GetInstance() != 0)
{
MW4AI::DebugRenderer::GetInstance()->SetAIStatsRendering(MW4AI::DebugRenderer::STATS_ALL);
}
endFunction();
return NULL;
}
TypePtr execDisableAIStats(SymTableNodePtr routineIdPtr)
{
if (MW4AI::DebugRenderer::GetInstance() != 0)
{
MW4AI::DebugRenderer::GetInstance()->SetAIStatsRendering(MW4AI::DebugRenderer::STATS_NONE);
}
endFunction();
return NULL;
}
TypePtr execEnableMoveLines(SymTableNodePtr routineIdPtr)
{
if (MW4AI::DebugRenderer::GetInstance() != 0)
{
MW4AI::DebugRenderer::GetInstance()->SetMovementLineRendering(true);
}
endFunction();
return NULL;
}
TypePtr execDisableMoveLines(SymTableNodePtr routineIdPtr)
{
if (MW4AI::DebugRenderer::GetInstance() != 0)
{
MW4AI::DebugRenderer::GetInstance()->SetMovementLineRendering(false);
}
endFunction();
return NULL;
}
TypePtr execEnableGlobalInvulnerable(SymTableNodePtr routineIdPtr)
{
DamageDispatch::SetGlobalInvulnerability(true);
endFunction();
return NULL;
}
TypePtr execDisableGlobalInvulnerable(SymTableNodePtr routineIdPtr)
{
DamageDispatch::SetGlobalInvulnerability(false);
endFunction();
return NULL;
}
TypePtr execEnableInvulnerable(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
// no longer implemented ...
return NULL;
}
TypePtr execDisableInvulnerable(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
// no longer implemented ...
return NULL;
}
void Group_Destroy(Group::identifier id)
{
if ((Adept::Player::GetInstance() != 0) &&
(Adept::Player::GetInstance()->IsDerivedFrom(MWPlayer::DefaultData) == true))
{
MWPlayer* mwplayer = Cast_Object(MWPlayer*,Adept::Player::GetInstance());
mwobject_list objects;
GetVehiclesFromGroup(id,objects);
{for (mwobject_list::iterator i = objects.begin();
i != objects.end();
++i)
{
mwplayer->AddObjectToDestroy((*i)->objectID);
}}
}
}
TypePtr execDestroy(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
if (ObjectIDisGroup(id) == true)
{
Group_Destroy(ObjectIDtoGroupID(id));
return NULL;
}
MWObject *who = GetMWObjectForID(id);
if ((who) &&
(Adept::Player::GetInstance() != 0) &&
(Adept::Player::GetInstance()->IsDerivedFrom(MWPlayer::DefaultData) == true))
{
MWPlayer* mwplayer = Cast_Object(MWPlayer*,Adept::Player::GetInstance());
mwplayer->AddObjectToDestroy(who->objectID);
}
return NULL;
}
TypePtr execGOSMenuItemExec(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CallDebuggerMenuItem(popStringPtr(),gosMenu_Activated);
return NULL;
}
TypePtr execGOSMenuItemChecked(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
#pragma warning(disable:4800)
bool rv = (bool)CallDebuggerMenuItem(popStringPtr(),gosMenu_CheckMark);
pushBoolean(rv);
#pragma warning(default:4800)
return BooleanTypePtr;
}
void Group_SetTargetDesirability(Group::identifier id, Stuff::Scalar desirability)
{
mwobject_list objects;
GetVehiclesFromGroup(id,objects);
{for (mwobject_list::iterator i = objects.begin();
i != objects.end();
++i)
{
(*i)->SetTargetDesirability(desirability);
}}
}
TypePtr execSetTargetDesirability(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long desirability = popInteger();
Stuff::Scalar real;
if (desirability != -1)
{
// MSL 5.05 Bug Fix
if (desirability > 100)
desirability = 100;
ablREPORT(desirability >= 0,ablERROR ("SetTargetDesirability(): desirability param must be -1 or 0 <= d <= 100"));
ablREPORT(desirability <= 100,ablERROR ("SetTargetDesirability(): desirability param must be -1 or 0 <= d <= 100"));
real = (Stuff::Scalar)desirability / 100;
}
else
{
real = -1;
}
if (ObjectIDisGroup(id) == true)
{
Group_SetTargetDesirability(ObjectIDtoGroupID(id),real);
return NULL;
}
MWObject *who = GetMWObjectForID(id);
if (who)
{
Check_Object(who);
who->SetTargetDesirability(real);
}
return NULL;
}
void Group_SetIsShotRadius(Group::identifier id, Stuff::Scalar radius)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->SetIsShotRadius(radius);
}}
}
TypePtr execSetIsShotRadius(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long radius = popInteger();
ablREPORT(radius >= 0,ablERROR ("Must specify a positive radius or 0 for setIsShotRadius()"));
Stuff::Scalar scalar_radius = (Stuff::Scalar)radius;
if (ObjectIDisGroup(id) == true)
{
Group_SetIsShotRadius(ObjectIDtoGroupID(id),scalar_radius);
return NULL;
}
//
// Use regulare AI pointer here, not CombatAI since trucks, etc.. may call this.
//
AI * aiGuy = GetAIForID(id);
if (aiGuy)
{
Check_Object(aiGuy);
aiGuy->SetIsShotRadius(scalar_radius);
}
return NULL;
}
void Group_SetSquadTargetingRadius(Group::identifier id, Stuff::Scalar radius)
{
std::vector<CombatAI*> ais;
GetAIsFromGroup<CombatAI>(id,ais);
{for (std::vector<CombatAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->SetSquadTargetingRadius(radius);
}}
}
TypePtr execSetSquadTargetingRadius(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long radius = popInteger();
ablREPORT(radius >= 0,ablERROR ("Must specify a positive radius or 0 for SetSquadTargetingRadius()"));
Stuff::Scalar scalar_radius = (Stuff::Scalar)radius;
if (ObjectIDisGroup(id) == true)
{
Group_SetSquadTargetingRadius(ObjectIDtoGroupID(id),scalar_radius);
return NULL;
}
CombatAI* combat_ai = GetCombatAIForID(id);
if (combat_ai)
{
Check_Object(combat_ai);
combat_ai->SetSquadTargetingRadius(scalar_radius);
}
return NULL;
}
void Group_SetSearchLight(Group::identifier id, MW4AI::SearchLightController::State state)
{
std::vector<CombatAI*> ais;
GetAIsFromGroup<CombatAI>(id,ais);
{for (std::vector<CombatAI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->GetSearchLightController().SetState(state);
}}
}
TypePtr execSetSearchLight(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
bool on = popBoolean();
MW4AI::SearchLightController::State state;
if (on == true)
{
state = MW4AI::SearchLightController::ON;
}
else
{
state = MW4AI::SearchLightController::OFF;
}
if (ObjectIDisGroup(id) == true)
{
Group_SetSearchLight(ObjectIDtoGroupID(id),state);
}
else
{
CombatAI* combat_ai = GetCombatAIForID(id);
if (combat_ai)
{
Check_Object(combat_ai);
combat_ai->GetSearchLightController().SetState(state);
}
}
return NULL;
}
TypePtr execSetGroupAI(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Group::identifier group_id = ObjectIDtoGroupID(popInteger());
long group_ai = popInteger();
ablREPORT(group_ai > MW4AI::Squad::GROUPAI_FIRST,ablERROR ("Invalid group AI specified for setGroupAI() -- see MWCONST.ABI"));
ablREPORT(group_ai < MW4AI::Squad::GROUPAI_LAST,ablERROR ("Invalid group AI specified for setGroupAI() -- see MWCONST.ABI"));
Verify(Adept::NameTable::GetInstance() != 0);
GroupContainer& vgc = GetGroupContainer();
ablREPORT(vgc.GroupExists(group_id) == true,ablERROR ("setGroupAI(): the specified group does not exist"));
if (vgc.GroupExists(group_id) == false)
{
return NULL;
}
Group& group = vgc.GetGroup(group_id);
if ((group.HasAI() == false) ||
(group.GetAI()->GetID() != (MW4AI::Squad::ID)group_ai))
{
Stuff::Auto_Ptr<MW4AI::Squad::AI> ai_ptr(MW4AI::Squad::CreateAI((MW4AI::Squad::ID)group_ai));
group.SetSquadAI(ai_ptr);
}
return NULL;
}
TypePtr execGetLancemate(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long lancemate_index = popInteger();
std::vector<MWObject*> lancemates;
MW4AI::Groups::GetLancemates(lancemates,true);
if ((lancemate_index < 0) ||
(lancemate_index >= lancemates.size()))
{
pushInteger(ABL_NO_UNIT);
}
else
{
pushInteger(lancemates[lancemate_index]->objectID);
}
return IntegerTypePtr;
}
TypePtr execNotifyGroupEnemySpotted(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long raw_group_id = popInteger();
ablREPORT(ObjectIDisGroup(raw_group_id) == true,ablERROR("NotifyGroupEnemySpotted(): first parameter must specify a group"));
Group::identifier group_id = ObjectIDtoGroupID(raw_group_id);
long who_spotted = popInteger();
if ((who_spotted == -1) &&
(CurWarrior != 0) &&
(CurWarrior->vehicle != 0))
{
who_spotted = CurWarrior->vehicle->objectID;
}
if (who_spotted == -1)
{
return NULL;
}
ablREPORT(ObjectIDisGroup(who_spotted) == false,ablERROR("NotifyGroupEnemySpotted(): must specify that a single unit (not a group) has been seen"));
GroupContainer& vgc = GetGroupContainer();
ablREPORT(vgc.GroupExists(group_id) == true,ablERROR ("NotifyGroupEnemySpotted(): the specified group does not exist"));
if (vgc.GroupExists(group_id) == false)
{
return NULL;
}
MW4AI::Squad::AI* group_ai = vgc.GetGroup(group_id).GetAI();
if (group_ai != 0)
{
group_ai->NotifyShot(vgc.GetGroup(group_id),who_spotted);
}
else
{
ablREPORT(1 == 0,ablERROR ("NotifyGroupEnemySpotted(): the specified group has no AI attached"));
}
return NULL;
}
TypePtr execTacticIsFinished (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
if (ObjectIDisGroup(id) == true)
{
ablREPORT(1 == 0,ablERROR("Group ID passed in to TacticIsFinished()"));
pushBoolean(false);
}
else
{
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(id);
if (combat_ai == 0)
{
pushBoolean(false);
}
else
{
pushBoolean(combat_ai->TacticIsFinished());
}
}
return (BooleanTypePtr);
}
TypePtr execGroupAllDead(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("asking group all dead for a non group"));
if (ObjectIDisTeam(id) == true)
{
mwobject_list vehicles;
GetVehiclesFromGroup(ObjectIDtoGroupID(id),vehicles);
pushBoolean(vehicles.size() == 0);
return BooleanTypePtr;
}
Group::identifier group_id = ObjectIDtoGroupID(id);
pushBoolean(MW4AI::Groups::AllDead(group_id));
return(BooleanTypePtr);
}
TypePtr execGroupAddObject(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("asking group add object for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(id);
Adept::ObjectID object_id = popInteger();
if (object_id == ABL_NO_UNIT)
{
return NULL;
}
if ((object_id == -1) &&
(CurWarrior != 0) &&
(CurWarrior->vehicle != 0))
{
object_id = CurWarrior->vehicle->objectID;
}
if (object_id >= 0)
{
if (ObjectIDisGroup(object_id) == true) { // jcem - group to group add?
int i, g_id = ObjectIDtoGroupID(object_id);
int nSrcCount = MW4AI::Groups::Size(g_id);
for(i = 0; i < nSrcCount; i++)
{
Adept::ObjectID obj_id;
if (MW4AI::Groups::GetMember(g_id, (unsigned)i, obj_id)) {
//if (!MW4AI::Groups::ContainsObject(obj_id, group_id)) {
MW4AI::Groups::AddObject(obj_id,group_id);
//}
}
}
} else {
MW4AI::Groups::AddObject(object_id,group_id);
}
}
return NULL;
}
TypePtr execGroupRemoveObject(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("asking group remove object for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(id);
Adept::ObjectID object_id = popInteger();
if ((object_id == -1) &&
(CurWarrior != 0) &&
(CurWarrior->vehicle != 0))
{
object_id = CurWarrior->vehicle->objectID;
}
if (object_id >= 0)
{
if (ObjectIDisGroup(object_id) == true) { // jcem - group to group add?
int i, g_id = ObjectIDtoGroupID(object_id);
int nSrcCount = MW4AI::Groups::Size(g_id);
for(i = 0; i < nSrcCount; i++)
{
Adept::ObjectID obj_id;
if (MW4AI::Groups::GetMember(g_id, (unsigned)i, obj_id)) {
MW4AI::Groups::RemoveObject(obj_id,group_id);
}
}
} else {
MW4AI::Groups::RemoveObject(object_id,group_id);
}
}
return NULL;
}
TypePtr execGroupNumDead(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("asking group num dead for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(id);
pushInteger(MW4AI::Groups::NumDead(group_id));
return(IntegerTypePtr);
}
TypePtr execGroupSize(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("asking group size for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(id);
if (ObjectIDisTeam(id) == true)
{
mwobject_list vehicles;
GetVehiclesFromGroup(ObjectIDtoGroupID(id),vehicles);
pushInteger(vehicles.size());
return IntegerTypePtr;
}
pushInteger(MW4AI::Groups::Size(group_id));
return(IntegerTypePtr);
}
TypePtr execGroupContainsObject(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("asking group contains object for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(id);
Adept::ObjectID object_id = popInteger();
if (object_id == ABL_NO_UNIT)
{
pushBoolean(false);
return (BooleanTypePtr);
}
if (ObjectIDisTeam(id) == true)
{
MWObject* object = GetMWObjectForID(object_id);
if (object != 0)
{
mwobject_list vehicles;
GetVehiclesFromGroup(group_id,vehicles);
{for (mwobject_list::const_iterator i = vehicles.begin();
i != vehicles.end();
++i)
{
if ((*i) == object)
{
pushInteger(true);
return IntegerTypePtr;
}
}}
}
pushInteger(false);
return IntegerTypePtr;
}
if ((object_id == -1) &&
(CurWarrior != 0) &&
(CurWarrior->vehicle != 0))
{
object_id = CurWarrior->vehicle->objectID;
}
if (object_id >= 0)
{
pushBoolean(MW4AI::Groups::ContainsObject(object_id,group_id));
}
else
{
pushBoolean(false);
}
return(BooleanTypePtr);
}
TypePtr execGroupGetFirstGroup(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Adept::ObjectID vehicle_id = popInteger();
if ((vehicle_id == -1) &&
(CurWarrior != 0) &&
(CurWarrior->vehicle != 0))
{
vehicle_id = CurWarrior->vehicle->objectID;
}
if (vehicle_id == -1)
{
pushInteger(ABL_NO_UNIT);
}
else
{
Group::identifier group_id;
if (MW4AI::Groups::GetFirstGroup(vehicle_id,group_id) == true)
{
pushInteger(group_id);
}
else
{
pushInteger(ABL_NO_UNIT);
}
}
return(IntegerTypePtr);
}
TypePtr execGroupGetFirstObject(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("asking group get first object for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(id);
if (ObjectIDisTeam(id) == true)
{
mwobject_list vehicles;
GetVehiclesFromGroup(group_id,vehicles);
if (vehicles.size() == 0)
{
pushInteger(ABL_NO_UNIT);
}
else
{
pushInteger((*(vehicles.begin()))->objectID);
}
return IntegerTypePtr;
}
Adept::ObjectID object_id;
if (MW4AI::Groups::GetFirstObject(group_id,object_id) == true)
{
pushInteger(object_id);
}
else
{
pushInteger(ABL_NO_UNIT);
}
return(IntegerTypePtr);
}
TypePtr execGroupGetObject(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long index = popInteger();
ablREPORT ((ObjectIDisGroup(id) == true),ablERROR ("calling GroupGetObject for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(id);
Adept::ObjectID object_id;
if (MW4AI::Groups::GetMember(group_id,index,object_id) == true)
{
pushInteger(object_id);
}
else
{
pushInteger(ABL_NO_UNIT);
}
return (IntegerTypePtr);
}
TypePtr execGroupObjectID(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Group::identifier group_id = popInteger();
Verify(group_id < 0x00FFFFFF);
pushInteger((Adept::NameTable::Groups_Reserved << 24) + group_id);
return(IntegerTypePtr);
}
TypePtr execGroupAllWithin(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long int_group_id = popInteger();
long target_id = popInteger();
Stuff::Scalar range = (Stuff::Scalar)popInteger();
ablREPORT ((ObjectIDisGroup(int_group_id) == true),ablERROR ("asking group all within for a non group"));
Group::identifier group_id = ObjectIDtoGroupID(int_group_id);
mwobject_list objects;
GetVehiclesFromGroup(group_id,objects);
if (objects.size() == 0)
{
pushBoolean(false);
return(BooleanTypePtr);
}
bool all_within = true;
{for (mwobject_list::iterator i = objects.begin();
i != objects.end();
++i)
{
if (ObjectIDisGroup(target_id) == true)
{
mwobject_list target_objects;
GetVehiclesFromGroup(target_id,target_objects);
{for (mwobject_list::iterator i_target = target_objects.begin();
i_target != target_objects.end();
++i_target)
{
if ((*i)->IsWithin(*i_target,range,true) == false)
{
pushBoolean(false);
return(BooleanTypePtr);
}
}}
}
else
{
Adept::Entity* target = GetObjectForID<Entity>(target_id);
if (!target)
{
pushBoolean (false);
return BooleanTypePtr;
}
if ((*i)->IsWithin(target,range,true) == false)
{
pushBoolean(false);
return(BooleanTypePtr);
}
}
}}
pushBoolean(true);
return(BooleanTypePtr);
}
TypePtr execTeamObjectID(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Group::identifier team_id = popInteger();
Verify(team_id < 0x00FFFFFF);
pushInteger((Adept::NameTable::Groups_Reserved << 24) + team_id + 0x00F00000);
return(IntegerTypePtr);
}
TypePtr execcinemaStart (SymTableNodePtr routineIdPtr)
{
endFunction ();
// no parameters or return value
Check_Object(CameraShipManager::Instance);
Verify (Adept::Player::GetInstance()->IsDerivedFrom (MWPlayer::DefaultData));
MWPlayer *player = (MWPlayer *) Adept::Player::GetInstance();
VehicleInterface *inter = player->GetInterface ();
if (inter->cinemaPlaying == false)
{
CameraShipManager::Instance->TurnOnCameras();
inter->SetCinemaPlaying(true);
}
return NULL;
}
TypePtr execcinemaEnd (SymTableNodePtr routineIdPtr)
{
endFunction ();
// no parameters or return value
Check_Object(CameraShipManager::Instance);
CameraShipManager::Instance->TurnOffCameras();
Verify (Adept::Player::GetInstance()->IsDerivedFrom (MWPlayer::DefaultData));
MWPlayer *player = (MWPlayer *) Adept::Player::GetInstance();
VehicleInterface *inter;
inter = player->GetInterface ();
inter->SetCinemaPlaying(false);
MoverAI::g_AlwaysIgnoreObstacles = false;
/*
NameTable *table = NameTable::Instance;
int j,size,current;
size = table->nameTableArray[NameTable::AIArray].GetLength ();
current = 0;
for (j=0;j<size;j++)
{
NameTableEntry *data;
Entity *ent;
AI *ai;
MWObject *obj;
data = &table->nameTableArray [NameTable::AIArray][j];
ent = data->dataPointer->GetCurrent ();
if (!ent)
continue;
ai = Cast_Object (AI *,ent);
if (!ai->IsDerivedFrom (PlayerAI::DefaultData))
{
if (!ai->m_Deactive)
{
ent = ai->getEntity ();
if (ent)
{
ai->m_Deactive = true;
obj = Cast_Object (MWObject *,ent);
obj->TurnOff ();
}
}
}
}
*/
return NULL;
}
TypePtr execSetAlwaysIgnoreObstacles (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MoverAI::g_AlwaysIgnoreObstacles = popBoolean();
return NULL;
}
TypePtr execSetIgnoreFog (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int object_id = popInteger();
bool ignore = popBoolean();
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(object_id);
Verify((long)combat_ai != -1);
if (combat_ai)
{
combat_ai->SetIgnoreFog(ignore);
}
return NULL;
}
TypePtr execplay2DAnim (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long animid = popInteger ();
long priority = popInteger ();
long screenLocX = popInteger ();
long screenLocY = popInteger ();
return NULL;
}
CameraShip *GetCameraShip(long camera_id)
{
int array_index = NameTableEntry::GetArrayIndex(camera_id);
ablREPORT(array_index >= 0,ablERROR ("invalid object id from abl"));
ablREPORT(array_index < NameTable::GetInstance()->TableSize,ablERROR ("invalid object id from abl"));
CameraShip* camera = (CameraShip*) NameTable::GetInstance()->FindData(camera_id);
ablREPORT (camera,ablERROR ("invalid object id from abl"));
ablREPORT (camera->IsDerivedFrom (CameraShip::DefaultData),ablERROR ("tried to convert an objectid to the wrong type of object. Function called needs a Camera type objectid"));
return camera;
}
Entity *GetEntity(long entity_id)
{
int array_index = NameTableEntry::GetArrayIndex(entity_id);
ablREPORT(array_index >= 0,ablERROR ("invalid object id from abl"));
ablREPORT(array_index < NameTable::GetInstance()->TableSize,ablERROR ("invalid object id from abl"));
Entity* entity = (Entity*) NameTable::GetInstance()->FindData(entity_id);
ablREPORT (entity,ablERROR ("invalid object id from abl"));
ablREPORT (entity->IsDerivedFrom (Entity::DefaultData),ablERROR ("tried to convert an objectid to the wrong type of object. Function called needs an Entity type objectid"));
return entity;
}
CameraShip *GetActiveCamera()
{
Check_Object(CameraShipManager::Instance);
return (CameraShipManager::Instance->GetActiveCamera());
}
TypePtr execSetCameraFootShake (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid(popInteger());
long distance(popInteger());
if ((objectid == ABL_NO_UNIT) ||
(distance == 0))
{
objectid = ABL_NO_UNIT;
distance = 0;
}
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->SetFootShakeParams(objectid,distance);
}
return NULL;
}
TypePtr execcinemaskip (SymTableNodePtr routineIdPtr)
{
// DECLARE_ABL_CONTEXT;
if (gos_GetKeyStatus(KEY_SPACE) == KEY_RELEASED)
{
pushBoolean(true);
}
else if (gos_GetKeyStatus(KEY_ESCAPE) == KEY_RELEASED)
{
pushBoolean(true);
}
else
{
pushBoolean(false);
}
endFunction ();
return BooleanTypePtr;
}
TypePtr execsetinternalcamera (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Object(CameraShipManager::Instance);
bool hud_value = popBoolean();
CameraShipManager::Instance->SetInternalCamera(hud_value);
return NULL;
}
TypePtr execsetactivecamera (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Object(CameraShipManager::Instance);
long camera_id = popInteger();
CameraShip *camera = GetCameraShip(camera_id);
CameraShipManager::Instance->SetActiveCamera(camera);
return NULL;
}
TypePtr execsetcameraFOV (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
float fov = popReal ();
float time = popReal ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
float degrees = fov * Radians_Per_Degree;
camera->SetCameraFOV(degrees, time);
}
return NULL;
}
TypePtr execfadetoblack (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
float time = popReal ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->FadeToBlack(time);
}
return NULL;
}
TypePtr execfadefromblack (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
float time = popReal ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->FadeFromBlack(time);
}
return NULL;
}
TypePtr execfadetowhite (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
float time = popReal ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->FadeToWhite(time);
}
return NULL;
}
TypePtr execfadefromwhite (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
float time = popReal ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->FadeFromWhite(time);
}
return NULL;
}
TypePtr execcamerafollowobject (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
long entity_id = popInteger();
Entity *entity = GetEntity(entity_id);
if (camera != 0)
{
camera->CameraFollowObject(entity);
}
return NULL;
}
TypePtr execcamerafollowpath (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
long entity_id = popInteger ();
long speed_kph = popInteger ();
float speed_mps = ConvertKPHtoMPSFloat (speed_kph);
Entity *entity = GetEntity(entity_id);
ablREPORT (entity->IsDerivedFrom (Path::DefaultData),ablERROR ("tried to convert an objectid to the wrong type of object. Function called needs an Entity type objectid"));
Path *path = Cast_Object(Path*, entity);
if (camera != 0)
{
camera->CameraFollowPath(speed_mps, path);
}
return NULL;
}
TypePtr execcameraposition (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
float x = popReal ();
float y = popReal ();
float z = popReal ();
float time = popReal ();
if (camera != 0)
{
camera->CameraPosition(x, y, z, time);
}
return NULL;
}
TypePtr execcameradetach (SymTableNodePtr routineIdPtr)
{
endFunction ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->CameraDetach();
}
return NULL;
}
TypePtr execcameraoffset (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
float x = popReal ();
float y = popReal ();
float z = popReal ();
float time = popReal ();
bool local = popBoolean ();
if (camera != 0)
{
camera->CameraOffset(x,y,z,time, local);
}
return NULL;
}
TypePtr execoverridecamerapitch (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
float deg = popReal ();
float time = popReal ();
float rad = deg * Radians_Per_Degree;
if (camera != 0)
{
camera->OverrideCameraPitch(rad, time);
}
return NULL;
}
TypePtr execoverridecamerayaw (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
float deg = popReal ();
float time = popReal ();
float rad = deg * Radians_Per_Degree;
if (camera != 0)
{
camera->OverrideCameraYaw(rad, time);
}
return NULL;
}
TypePtr execoverridecameraroll (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
float deg = popReal ();
float time = popReal ();
float rad = deg * Radians_Per_Degree;
if (camera != 0)
{
camera->OverrideCameraRoll(rad, time);
}
return NULL;
}
TypePtr execresetcameraoverrides (SymTableNodePtr routineIdPtr)
{
endFunction ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->ResetCameraOverrides();
}
return NULL;
}
TypePtr exectargetfollowobject (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
long entity_id = popInteger();
Entity *entity = GetEntity(entity_id);
if (camera != 0)
{
camera->TargetFollowObject(entity);
}
return NULL;
}
TypePtr exectargetfollowpath (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
long entity_id = popInteger ();
long speed_kph = popInteger ();
float speed_mps = ConvertKPHtoMPSFloat (speed_kph);
Entity *entity = GetEntity(entity_id);
ablREPORT (entity->IsDerivedFrom (Path::DefaultData),ablERROR ("tried to convert an objectid to the wrong type of object. Function called needs an Entity type objectid"));
Path *path = Cast_Object(Path*, entity);
if (camera != 0)
{
camera->TargetFollowPath(speed_mps, path);
}
return NULL;
}
TypePtr exectargetposition (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
float x = popReal ();
float y = popReal ();
float z = popReal ();
float time = popReal ();
if (camera != 0)
{
camera->TargetPosition(x, y, z, time);
}
return NULL;
}
TypePtr exectargetdetach (SymTableNodePtr routineIdPtr)
{
endFunction ();
CameraShip* camera = GetActiveCamera();
if (camera != 0)
{
camera->TargetDetach();
}
return NULL;
}
TypePtr exectargetoffset (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CameraShip* camera = GetActiveCamera();
float x = popReal ();
float y = popReal ();
float z = popReal ();
float time = popReal ();
bool local = popBoolean ();
if (camera != 0)
{
camera->TargetOffset(x,y,z,time, local);
}
return NULL;
}
TypePtr execSetMemoryInteger(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long index = popInteger ();
long value = popInteger ();
if (ObjectIDisGroup(id) == true) { // jcem - set memeory for group added
Group::identifier gid = ObjectIDtoGroupID(id);
std::vector<AI*> ais;
GetAIsFromGroup<AI>(gid,ais);
{for (std::vector<AI*>::iterator i = ais.begin(); i != ais.end(); ++i)
{
(*i)->IntegerMemory (index,value);
}}
} else {
AI* who = GetAIForID(id);
if (!who)
return NULL;
Verify ((long) who != -1);
who->IntegerMemory (index,value);
}
return NULL;
}
TypePtr execSetMemoryReal(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long index = popInteger ();
float value = popReal ();
if (ObjectIDisGroup(id) == true) { // jcem - set memeory for group added
Group::identifier gid = ObjectIDtoGroupID(id);
std::vector<AI*> ais;
GetAIsFromGroup<AI>(gid,ais);
{for (std::vector<AI*>::iterator i = ais.begin(); i != ais.end(); ++i)
{
(*i)->RealMemory (index,value);
}}
} else {
AI* who = GetAIForID(id);
if (!who)
return NULL;
Verify ((long) who != -1);
who->RealMemory (index,value);
}
return NULL;
}
TypePtr execGetMemoryInteger(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long index = popInteger ();
AI* who = GetAIForID(id);
if (who) {
Verify ((long) who != -1);
pushInteger (who->IntegerMemory (index));
} else {
pushInteger (0); // jcem - error actually^^
}
return IntegerTypePtr;
}
TypePtr execGetMemoryReal(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
long index = popInteger ();
AI* who = GetAIForID(id);
if (who) {
Verify ((long) who != -1);
pushReal (who->RealMemory (index));
} else {
pushReal (0.0f); // jcem - error actually^^
}
return RealTypePtr;
}
TypePtr execSetGlobalTrigger(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int index = popInteger();
bool value = popBoolean();
AI::SetGlobalTrigger(index,value);
return NULL;
}
TypePtr execGetGlobalTrigger(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int index = popInteger();
pushBoolean(AI::GetGlobalTrigger(index));
return BooleanTypePtr;
}
void Group_SetSensorVisibility(Group::identifier group_id, bool visible)
{
mwobject_list objects;
GetVehiclesFromGroup(group_id,objects);
{for (mwobject_list::const_iterator i = objects.begin();
i != objects.end();
++i)
{
(*i)->SetVisibleOnSensors(visible);
}}
}
TypePtr execSetSensorVisibility (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger();
bool visible = popBoolean();
if (ObjectIDisGroup(id) == true)
{
Group_SetSensorVisibility(ObjectIDtoGroupID(id),visible);
return NULL;
}
MWObject* object = GetMWObjectForID(id);
if (object != 0)
{
object->SetVisibleOnSensors(visible);
}
return NULL;
}
void Group_SetAutoTargeting(Group::identifier group_id, bool enabled)
{
std::vector<CombatAI*> ais;
GetAIsFromGroup<CombatAI>(group_id,ais);
{for (std::vector<CombatAI*>::const_iterator i = ais.begin();
i != ais.end();
++i)
{
(*i)->SetAutoTargeting(enabled);
}}
}
TypePtr execSetAutoTargeting(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger();
bool enabled = popBoolean();
if (ObjectIDisGroup(id) == true)
{
Group_SetAutoTargeting(ObjectIDtoGroupID(id),enabled);
return NULL;
}
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(id);
if (combat_ai != 0)
{
combat_ai->SetAutoTargeting(enabled);
}
return NULL;
}
TypePtr execEnablePerWeaponRayCasting(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int object_id = popInteger();
bool enable = popBoolean();
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(object_id);
if (combat_ai != 0)
{
combat_ai->EnablePerWeaponRayCasting(enable);
}
return NULL;
}
void Group_execStartup(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if ((*i)->Dead() == false)
{
(*i)->Startup();
}
}}
}
TypePtr execstartup (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execStartup(ObjectIDtoGroupID(id));
}
else
{
AI *who = GetAIForID(id);
if (!who)
return NULL;
ablREPORT ((!who->Dead ()),ablERROR ("asking to startup a dead unit"));
Check_Object (who);
who->Startup ();
}
return NULL;
}
void Group_execShutdown(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
{for (std::vector<AI*>::iterator i = ais.begin();
i != ais.end();
++i)
{
if ((*i)->Dead() == false)
{
(*i)->Shutdown();
}
}}
}
TypePtr execshutDown (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execShutdown(ObjectIDtoGroupID(id));
}
else
{
AI *who = GetAIForID(id);
if (!who)
return NULL;
Check_Object (who);
ablREPORT ((!who->Dead ()),ablERROR ("asking to shutdown a dead unit"));
who->Shutdown ();
}
return NULL;
}
TypePtr execPlayerAI (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Check_Object (Adept::Player::GetInstance());
MWPlayer *player;
long id = popInteger ();
bool run = popBoolean ();
Verify (Adept::Player::GetInstance()->IsDerivedFrom (MWPlayer::DefaultData));
player = (MWPlayer *) Adept::Player::GetInstance();
VehicleInterface *inter;
inter = player->GetInterface ();
Verify (inter);
inter->PlayerAIRun (run);
return NULL;
}
void Group_execStopExecute(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
for (std::vector<AI*>::iterator i = ais.begin(); i != ais.end(); ++i)
{
Check_Object (*i);
(*i)->StopExecute ();
}
}
TypePtr execAddMechInstanceSalvage(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *string = popStringPtr();
if(MWGame::GetInstance())
{
if(MWGame::GetInstance()->m_salvageManager)
{
char *salv_string;
salv_string = strlwr(string);
MWGame::GetInstance()->GetAndAddMechInstance(salv_string);
}
}
return NULL;
}
TypePtr execAddComponentSalvage(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *string = popStringPtr();
int num = popInteger();
if(MWGame::GetInstance())
{
if(MWGame::GetInstance()->m_salvageManager)
{
char *salv_string;
salv_string = strlwr(string);
MWGame::GetInstance()->m_salvageManager->GetAndAddComponentSalvage(salv_string, num);
}
}
return NULL;
}
TypePtr execAddWeaponSalvage(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *string = popStringPtr();
int num = popInteger();
if(MWGame::GetInstance())
{
if(MWGame::GetInstance()->m_salvageManager)
{
char *salv_string;
salv_string = strlwr(string);
MWGame::GetInstance()->m_salvageManager->GetAndAddWeaponSalvage(salv_string, num);
}
}
return NULL;
}
TypePtr execMarkBuildingAsScorable (SymTableNodePtr routineIDPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
MWObject *obj = GetMWObjectForID (id);
// MSL 5.04 Dropship
ablREPORT ( (obj->IsDerivedFrom(Building::DefaultData)
|| obj->IsDerivedFrom(Dropship::DefaultData)
|| obj->IsDerivedFrom(Tank::DefaultData)),
"Tried to mark non building or dropship as scorable");
if (obj->IsDerivedFrom(Building::DefaultData))
{
Building * building;
building = Cast_Object (Building*, obj);
building->m_scoreThisBuilding = true;
}
else if (obj->IsDerivedFrom(Dropship::DefaultData))
{
Dropship * dropship;
dropship = Cast_Object (Dropship*, obj);
dropship->m_scoreThisDropship = true;
}
else if (obj->IsDerivedFrom(Tank::DefaultData))
{
Tank * tank;
tank = Cast_Object (Tank*, obj);
tank->m_scoreThisTank = true;
}
// ablREPORT (obj->IsDerivedFrom(Building::DefaultData), "Tried to mark non building as scorable");
// Building * building;
// building = Cast_Object (Building*, obj);
// building->m_scoreThisBuilding = true;
return NULL;
}
TypePtr execJump (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long time = popInteger();
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(id);
if (combat_ai != 0)
{
combat_ai->OrderJump((Stuff::Scalar)time);
}
return NULL;
}
TypePtr execCrouch (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
MWObject* mwobject = GetMWObjectForID(id);
if ((mwobject != 0) &&
(mwobject->IsDerivedFrom(MWObject::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,mwobject);
mech->CrouchRequest();
}
return NULL;
}
TypePtr execFall (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long fall_type = popInteger();
MWObject* mwobject = GetMWObjectForID(id);
if ((mwobject != 0) &&
(mwobject->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,mwobject);
switch (fall_type)
{
case 0:
{
mech->Test_FallForward();
break;
}
case 1:
{
mech->Test_FallBackward();
break;
}
case 2:
{
mech->Test_FallLeft();
break;
}
default:
{
mech->Test_FallRight();
break;
}
}
}
return NULL;
}
TypePtr execTorsoPitch (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MechWarrior4::CombatAI* who = GetCombatAIForID(popInteger());
float pitch = popReal();
if (who != 0)
{
who->SetGoalPitch(pitch);
}
return NULL;
}
TypePtr execTorsoYaw (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MechWarrior4::CombatAI* who = GetCombatAIForID(popInteger());
float yaw = popReal();
if (who != 0)
{
who->SetGoalYaw(yaw);
}
return NULL;
}
TypePtr execSetGimped (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWObject* mwobject = GetMWObjectForID(popInteger());
bool gimped = popBoolean();
if ((mwobject != 0) &&
(mwobject->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,mwobject);
if (gimped == true)
{
mech->Test_LeftGimp();
}
else
{
mech->SetNoGimp();
}
}
return NULL;
}
void Rotate(MWObject& who, Stuff::Scalar rotation)
{
YawPitchRoll new_rotation(YawPitchRoll::Identity);
new_rotation = (YawPitchRoll) who.GetLocalToWorld();
new_rotation.yaw = rotation;
Point3D new_translation(who.GetLocalToWorld());
LinearMatrix4D new_local_to_world;
new_local_to_world.BuildTranslation(new_translation);
new_local_to_world.BuildRotation(new_rotation);
who.SetNewLocalToParent(new_local_to_world);
who.SyncMatrices(true);
Map::GetInstance()->UpdateZone(&who);
}
TypePtr execSetRotation (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long object_id = popInteger();
long rotation_degrees = popInteger();
MWObject* mwobject = GetMWObjectForID(object_id);
if (mwobject != 0)
{
Rotate(*mwobject,(Scalar)rotation_degrees * Radians_Per_Degree);
}
return NULL;
}
TypePtr execSetHelicoptersIgnoreMissionBounds (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MW4AI::Actions::g_HelicoptersIgnoreMissionBounds = popBoolean();
return NULL;
}
TypePtr execSetTorsoCenteringEnabled (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int src_id = popInteger();
int enabled = popBoolean();
MWObject* src = GetMWObjectForID(src_id);
if ((src != 0) &&
(src->IsDestroyed() == false) &&
(src->vehicleInterface != 0) &&
(src->vehicleInterface->IsDerivedFrom(MechWarrior4::VehicleInterface::DefaultData) == true))
{
MechWarrior4::VehicleInterface* vehicle_interface = Cast_Object(MechWarrior4::VehicleInterface*,src->vehicleInterface);
if (enabled == false)
{
vehicle_interface->SetPerminateTorsoMode(VehicleInterface::LeaveTorsoAlone);
}
else
{
vehicle_interface->SetPerminateTorsoMode(VehicleInterface::CenterLegsToTorso);
}
}
return NULL;
}
TypePtr execSetCompositingEnabled (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
popBoolean();
// functionality intentionally removed ...
return NULL;
}
void Group_execSetSensorMode(Group::identifier group_id, int mode)
{
mwobject_list mwobjects;
GetVehiclesFromTeam(group_id,mwobjects);
{for (mwobject_list::const_iterator i = mwobjects.begin();
i != mwobjects.end();
++i)
{
if ((*i)->GetSensor() != 0)
{
(*i)->GetSensor()->SetSensorMode(mode,(*i)->DoesHaveBeagle());
}
}}
}
TypePtr execSetSensorMode (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
long mode = popInteger();
if (ObjectIDisGroup (id))
{
Group_execSetSensorMode(ObjectIDtoGroupID(id),mode);
}
else
{
MWObject* mwobject = GetMWObjectForID(id);
if ((mwobject != 0) &&
(mwobject->GetSensor() != 0))
{
mwobject->GetSensor()->SetSensorMode(mode,mwobject->DoesHaveBeagle());
}
}
return NULL;
}
TypePtr execGetSensorMode (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger();
MWObject* mwobject = GetMWObjectForID(id);
if ((mwobject != 0) &&
(mwobject->GetSensor() != 0))
{
pushInteger(mwobject->GetSensor()->GetSensorMode());
}
else
{
pushInteger(0);
}
return IntegerTypePtr;
}
TypePtr execSetMinSpeed (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long object_id = popInteger();
long speed = popInteger();
MechWarrior4::CombatAI* who = GetCombatAIForID(object_id);
if (who != 0)
{
Stuff::Scalar s = (Stuff::Scalar)speed;
s *= 0.01f;
who->SetMinSpeed(s);
}
return NULL;
}
TypePtr execStopExecute (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup (id))
{
Group_execStopExecute (ObjectIDtoGroupID (id));
}
else
{
AI *who = GetAIForID(id);
if (!who)
return NULL;
ablREPORT ((!who->Dead ()),ablERROR ("asking to stop execute a dead unit"));
Check_Object (who);
who->StopExecute ();
}
return NULL;
}
void Group_execStartExecute(Group::identifier group_id)
{
std::vector<AI*> ais;
GetAIsFromGroup<AI>(group_id,ais);
for (std::vector<AI*>::iterator i = ais.begin(); i != ais.end(); ++i)
{
Check_Object (*i);
(*i)->StartExecute ();
}
}
TypePtr execStartExecute (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
if (ObjectIDisGroup (id))
{
Group_execStartExecute (ObjectIDtoGroupID (id));
}
else
{
AI *who = GetAIForID(id);
if (!who)
return NULL;
ablREPORT ((!who->Dead ()),ablERROR ("asking to start execute a dead unit"));
Check_Object (who);
who->StartExecute ();
}
return NULL;
}
TypePtr execSetActivationDistance (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long dist = popInteger ();
MWMission *mission;
if (dist > 1200)
{
dist = 1200;
}
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Check_Object (mission);
mission->m_DistanceCheck = (Scalar) dist;
return NULL;
}
TypePtr execFlyBy (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
Entity* who = GetObjectForID<Entity>(id);
who = ConvertAIToEntity(who);
PlaneAI *plane;
Stuff::Point3D loc (who->GetLocalToWorld ());
ablREPORT (CurMoverAI->IsDerivedFrom (PlaneAI::DefaultData),"Tried to issue a fly by order on a non flyer");
plane = Cast_Object (PlaneAI *,CurMoverAI);
pushBoolean (plane->FlyBy (loc));
return BooleanTypePtr;
}
TypePtr execSave (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long id = popInteger ();
return NULL;
}
TypePtr execGetDifficulty (SymTableNodePtr routineIdPtr)
{
pushInteger (MWApplication::GetInstance()->GetDifficultyLevel());
endFunction ();
return IntegerTypePtr;
}
TypePtr execEject (SymTableNodePtr routineIdPtr)
{
long id = popInteger ();
MWObject *obj = GetMWObjectForID (id);
ablREPORT (obj->IsDerivedFrom (Vehicle::DefaultData),"Tried to eject on a non vehicle");
Vehicle *veh;
veh = Cast_Object (Vehicle *,obj);
veh->Eject ();
return NULL;
}
TypePtr execAddBucket (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CBucketManager::Bucket_Type type = (CBucketManager::Bucket_Type) popInteger ();
int id = popInteger ();
int affects = popInteger ();
int mod2 = popInteger ();
ReplicatorID repid;
if (id == -2)
{
repid = ReplicatorID::Null;
}
else
{
MWObject *obj = GetMWObjectForID (id);
repid = obj->GetReplicatorID ();
}
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
pushInteger (mission->m_BucketManager->AddBucket (type,repid,affects,mod2));
return IntegerTypePtr;
}
TypePtr execKillBucket (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->KillBucket (id);
return NULL;
}
TypePtr execShowBucket (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->ShowBucket (id);
return NULL;
}
TypePtr execHideBucket (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->HideBucket (id);
return NULL;
}
TypePtr execGetBucketValue (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
pushInteger(mission->m_BucketManager->BucketValue (id));
return IntegerTypePtr;
}
TypePtr execFindBucketValue (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CBucketManager::Bucket_Type type = (CBucketManager::Bucket_Type) popInteger ();
int id = popInteger ();
ReplicatorID repid;
if (id == -2)
{
repid = ReplicatorID::Null;
}
else
{
MWObject *obj = GetMWObjectForID (id);
repid = obj->GetReplicatorID ();
}
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
pushInteger(mission->m_BucketManager->FindBucketValue (type, repid));
return IntegerTypePtr;
}
TypePtr execSetBucketValue (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
int value = popInteger ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->BucketValue (id,value);
return NULL;
}
TypePtr execTrackBucket (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CBucketManager::Bucket_Type type = (CBucketManager::Bucket_Type) popInteger ();
int mod2 = popInteger ();
bool visible = popBoolean ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->SetupTrack (type,mod2,visible);
return NULL;
}
TypePtr execTrackObjectBucket (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CBucketManager::Bucket_Type type = (CBucketManager::Bucket_Type) popInteger ();
int objid = popInteger ();
int distance = popInteger ();
bool visible = popBoolean ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->SetupTrackObject (type,objid,distance,visible);
return NULL;
}
TypePtr execFindBucket (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
CBucketManager::Bucket_Type type = (CBucketManager::Bucket_Type) popInteger ();
int id = popInteger ();
int affects = popInteger ();
int mod2 = popInteger ();
int objid = popInteger ();
ReplicatorID repid;
if (id == -2)
{
repid = ReplicatorID::Null;
}
else
{
MWObject *obj = GetMWObjectForID (id);
repid = obj->GetReplicatorID ();
}
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
pushInteger (mission->m_BucketManager->FindBucket (type,repid,affects,mod2,objid));
return IntegerTypePtr;
}
TypePtr execAddCustomBucketParameter(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int bucket_type(popInteger());
int bucket_multiplier(popInteger());
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->AddCustomBucketParameter((CBucketManager::Bucket_Type)bucket_type,bucket_multiplier);
return NULL;
}
TypePtr execChatMessage(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *text = popStringPtr();
if (text == 0)
{
return NULL;
}
MWApplication::GetInstance()->SendChat(
Connection::Local->GetID(),
MWApplication::SystemBroadcast,
0,
text);
return NULL;
}
TypePtr execSetCustomBucketName(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *name = popStringPtr();
if (name == 0)
{
return NULL;
}
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->SetCustomBucketName(name);
return NULL;
}
TypePtr execSetCustomBucketNameIndex(SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int bucket_name_index(popInteger());
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
mission->m_BucketManager->SetCustomBucketName(MWApplication::GetInstance()->GetLocString(bucket_name_index));
return NULL;
}
void Group_execAddPoints(Group::identifier group_id, int points, MWMission& mission)
{
mwobject_list objects;
GetVehiclesFromGroup(group_id,objects);
{for (mwobject_list::const_iterator i = objects.begin();
i != objects.end();
++i)
{
mission.m_BucketManager->AddToCustomScore((*i)->GetReplicatorID(),points);
}}
}
TypePtr execAddPoints (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
int points = popInteger ();
MWMission *mission;
Check_Object (MWMission::GetInstance());
mission = Cast_Object (MWMission *,MWMission::GetInstance());
Verify (mission->m_BucketManager);
if (ObjectIDisTeam(id) == true)
{
int team = id & 0xFF;
if (team == 0)
{
team = 8;
}
else
{
--team;
}
mission->m_BucketManager->AddTeamPoints(team,points);
}
else
{
if (ObjectIDisGroup(id))
{
Group_execAddPoints(ObjectIDtoGroupID(id),points,*mission);
}
else
{
MWObject* who = GetMWObjectForID(id);
if (who != 0)
{
mission->m_BucketManager->AddToCustomScore(who->GetReplicatorID(),points);
}
}
}
return NULL;
}
TypePtr execAttachFlag (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
int who = popInteger ();
Flag *flag = GetFlagForID (id);
ablREPORT (flag,"could not find a flag with that id");
if (flag == 0)
{
return NULL;
}
MWObject *obj = GetMWObjectForID (who);
if (obj == 0)
{
return NULL;
}
ablREPORT (obj->IsDerivedFrom (MWObject::DefaultData),"Tried to attach a flag to a non mwobject");
flag->Execute_AttachTo(obj);
return NULL;
}
TypePtr execDropFlag (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
Flag *flag = GetFlagForID (id);
ablREPORT (flag,"could not find a flag with that id");
flag->Execute_Drop();
return NULL;
}
// MSL 5.05 Return Flag Script Command
TypePtr execReturnFlag (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
Flag *flag = GetFlagForID (id);
ablREPORT (flag,"could not find a flag with that id");
flag->Execute_ReturnToOrigin();
return NULL;
}
TypePtr execDeactiveFlag (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
int time = popInteger ();
Flag *flag = GetFlagForID (id);
ablREPORT (flag,"could not find a flag with that id");
flag->DeactiveTime (time);
return NULL;
}
void Group_execSetMaxFlagsCarried(Group::identifier id, int max_flags)
{
mwobject_list objects;
GetVehiclesFromGroup(id,objects);
{for (mwobject_list::const_iterator i = objects.begin();
i != objects.end();
++i)
{
if ((*i)->IsDerivedFrom(Mech::DefaultData) == true)
{
Mech* mech = Cast_Object(Mech*,*i);
mech->SetMaxFlagsCarried(max_flags);
}
}}
}
TypePtr execSetMaxFlagsCarried (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
int max_flags = popInteger ();
if (id == ABL_NO_UNIT)
{
MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance());
mwmission->SetMaxFlagsCarried(max_flags);
}
else
{
if (ObjectIDisGroup(id) == true)
{
Group_execSetMaxFlagsCarried(ObjectIDtoGroupID(id),max_flags);
}
else
{
MWObject *obj = GetMWObjectForID (id);
if ((obj != 0) &&
(obj->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,obj);
mech->SetMaxFlagsCarried(max_flags);
}
}
}
return NULL;
}
TypePtr execSetFlagDropReturnTime (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance());
mwmission->SetFlagDropReturnTime(popInteger());
return NULL;
}
TypePtr execSetFlagCaptureReturnTime (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance());
mwmission->SetFlagCaptureReturnTime(popInteger());
return NULL;
}
TypePtr execSetFlagsEnabled (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance());
mwmission->SetFlagsEnabled((MWMission::FLAG_ENABLE_STATE)popInteger());
return NULL;
}
TypePtr execSetFlagCaptureEnabled (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance());
mwmission->SetFlagCaptureEnabled(popBoolean());
return NULL;
}
TypePtr execShowFlagsAsNavPoints (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance());
mwmission->SetFlagsAsNavPoints(popBoolean());
return NULL;
}
TypePtr execSetViewMode (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long view_mode = popInteger();
VehicleInterface::GetInstance()->SetCameraViewLevel(view_mode);
return NULL;
}
TypePtr execGetViewMode (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWObject* src = GetMWObjectForID(popInteger());
if ((src != 0) &&
(src->IsDestroyed() == false) &&
(src->vehicleInterface != 0) &&
(src->vehicleInterface->IsDerivedFrom(MechWarrior4::VehicleInterface::DefaultData) == true))
{
MechWarrior4::VehicleInterface* vehicle_interface = Cast_Object(MechWarrior4::VehicleInterface*,src->vehicleInterface);
pushInteger(vehicle_interface->GetCameraViewLevel());
}
else
{
pushInteger(0);
}
return IntegerTypePtr;
}
TypePtr execSetInputTypeEnabled (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long type = popInteger();
bool enabled = popBoolean();
InputTrainer::GetInstance()->SetEnabled((InputTrainer::InputType)type,enabled);
return NULL;
}
TypePtr execSetHUDComponentEnabled (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long type = popInteger();
bool enabled = popBoolean();
if (enabled == true)
{
MWGUIManager::GetInstance()->ShowHudComponent((MWGUIManager::HUDELEMENTS)type);
}
else
{
MWGUIManager::GetInstance()->HideHudComponent((MWGUIManager::HUDELEMENTS)type);
}
if (VehicleInterface::GetInstance() != 0)
{
VehicleInterface::GetInstance()->m_AIControlledHUD = true;
}
return NULL;
}
TypePtr execResetAmmo (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWObject* src = GetMWObjectForID(popInteger());
if (src == 0)
{
return NULL;
}
Stuff::ChainIteratorOf<MechWarrior4::Weapon*> i(&(src->weaponChain));
MechWarrior4::Weapon* weapon = 0;
while ((weapon = i.ReadAndNext()) != 0)
{
weapon->encryptedAmmoCount = ENCRYPT(weapon->initialAmmoCount);
}
return (NULL);
}
TypePtr execOverrideHeatOption (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
HeatManager::g_OverrideHeatOption = popBoolean();
return (NULL);
}
TypePtr execSetMissionBounds (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
static_cast<MWMission*>(MWMission::GetInstance())->StoreOriginalBounds(); // jcem
long id_ul = popInteger();
long id_lr = popInteger();
Adept::Entity* object_ul = GetObjectForID<Adept::Entity>(id_ul);
Adept::Entity* object_lr = GetObjectForID<Adept::Entity>(id_lr);
if ((object_ul != 0) &&
(object_lr != 0))
{
Vector2DOf<Scalar> bounds_ul;
bounds_ul.x = ((Stuff::Point3D)(object_ul->GetLocalToWorld())).x;
bounds_ul.y = ((Stuff::Point3D)(object_ul->GetLocalToWorld())).z;
Vector2DOf<Scalar> bounds_lr;
bounds_lr.x = ((Stuff::Point3D)(object_lr->GetLocalToWorld())).x;
bounds_lr.y = ((Stuff::Point3D)(object_lr->GetLocalToWorld())).z;
Vector2DOf<Scalar> bounds_ur(bounds_ul);
bounds_ur.x = bounds_lr.x;
Vector2DOf<Scalar> bounds_ll(bounds_lr);
bounds_ll.x = bounds_ul.x;
DynamicArrayOf<Vector2DOf<Scalar> > bounds_list;
bounds_list.SetLength(4);
bounds_list[0] = bounds_ul;
bounds_list[1] = bounds_ll;
bounds_list[2] = bounds_lr;
bounds_list[3] = bounds_ur;
{for (int i = 0; i < bounds_list.GetLength(); ++i)
{
Map::GetInstance()->WorldToZoneCoords(bounds_list[i].x,bounds_list[i].y);
}}
MWMission* mission = Cast_Object(MWMission*,Adept::Mission::GetInstance());
mission->SetMissionPolygon(bounds_list);
bounds_list[0].x = 0;
bounds_list[0].y = 0;
bounds_list[1].x = 0;
bounds_list[1].y = 0.0001f;
bounds_list[2].x = 0.0001f;
bounds_list[2].y = 0.0001f;
bounds_list[3].x = 0.0001f;
bounds_list[3].y = 0;
mission->SetWarningPolygon(bounds_list);
mission->m_ConstraintTopLeft = (Stuff::Point3D)object_ul->GetLocalToWorld();
mission->m_ConstraintBottomRight = (Stuff::Point3D)object_lr->GetLocalToWorld();
VehicleInterface::GetInstance()->SetBoundsWarningsEnabled(false);
}
return NULL;
}
void Group_execRespawn(Group::identifier id)
{
mwobject_list objects;
GetVehiclesFromGroup(id,objects);
{for (mwobject_list::const_iterator i = objects.begin();
i != objects.end();
++i)
{
if ((*i)->IsDerivedFrom(Mech::DefaultData) == true)
{
Mech* mech = Cast_Object(Mech*,*i);
// mech->Respawn();
}
}}
}
TypePtr execRespawn (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int id = popInteger ();
if (ObjectIDisGroup(id) == true)
{
Group_execRespawn(ObjectIDtoGroupID(id));
}
else
{
MWObject *obj = GetMWObjectForID (id);
if ((obj != 0) &&
(obj->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,obj);
// mech->Respawn();
}
}
return NULL;
}
TypePtr execResetMission (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWApplication* mwapplication = Cast_Object(MWApplication*,MWApplication::GetInstance());
mwapplication->ResetMission();
return NULL;
}
TypePtr execIsTargeted (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MechWarrior4::CombatAI* combat_ai = GetCombatAIForID(popInteger());
Verify((long)combat_ai != -1);
if (combat_ai != 0)
{
if (combat_ai->GetTimeTargetedByEnemy() > 0.5f)
{
pushBoolean(true);
return BooleanTypePtr;
}
}
pushBoolean(false);
return BooleanTypePtr;
}
TypePtr execLookingToward (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
Adept::Entity* at_object = GetObjectForID<Adept::Entity>(popInteger());
if ((at_object != 0) &&
(VehicleInterface::GetInstance() != 0) &&
(VehicleInterface::GetInstance()->vehicle != 0))
{
if (MatrixFacesPoint(VehicleInterface::GetInstance()->vehicle->GetLocalToWorld(),
(Stuff::Point3D)at_object->GetLocalToWorld(),
Stuff::Pi_Over_4) == true)
{
pushBoolean(true);
return BooleanTypePtr;
}
}
pushBoolean(false);
return BooleanTypePtr;
}
TypePtr execFiredWeaponGroup (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int weapon_group = popInteger();
if (weapon_group > 0)
{
--weapon_group;
}
if (VehicleInterface::GetInstance()->GetLastTimeFiredWeaponGroup(weapon_group) + 1.0f > gos_GetElapsedTime())
{
pushBoolean(true);
}
else
{
pushBoolean(false);
}
return BooleanTypePtr;
}
TypePtr execIsSetToNavPoint (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
long objectid = popInteger();
NavPoint *nav_point = Cast_Object(NavPoint *,NameTable::GetInstance()->FindData(objectid));
Check_Object(nav_point);
if ((nav_point != 0) &&
(VehicleInterface::GetInstance()->GetNavPoint() == nav_point))
{
pushBoolean(true);
}
else
{
pushBoolean(false);
}
return BooleanTypePtr;
}
TypePtr execGetDamageRating (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int who = popInteger ();
if (who != ABL_NO_UNIT)
{
MechWarrior4::MWObject* object = GetMWObjectForID(who);
if (object != 0)
{
Scalar damage = MW4AI::Damage::GetDamageRating(*object);
pushInteger((int)damage);
return IntegerTypePtr;
}
}
pushInteger(0);
return IntegerTypePtr;
}
TypePtr execboardDropShip (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int GroupID = popInteger ();
int dropid = popInteger ();
ablREPORT ((ObjectIDisGroup(GroupID)),ablERROR ("trying to board dropship for a non group"));
Dropship *drop = Cast_Object (Dropship *,NameTable::GetInstance()->FindData (dropid));
Check_Object (drop);
Verify (drop->IsDerivedFrom (Dropship::DefaultData));
std::vector<MoverAI*> list;
GetAIsFromGroup<MoverAI> (ObjectIDtoGroupID(GroupID),list);
pushBoolean (BoardDropShip (list,drop));
return BooleanTypePtr;
}
TypePtr execDrop (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int mechID = popInteger ();
MWObject *obj = GetMWObjectForID (mechID);
ablREPORT (obj,"could not find the mech with that id");
Mech *mech = Cast_Object (Mech *,obj);
Check_Object (mech);
Verify (mech->IsDerivedFrom (Mech::DefaultData));
mech->StartDropping ();
return NULL;
}
TypePtr execShowTimer (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int timerid,objid,timeoffset,color;
bool timeonleft,visible;
timerid = popInteger ();
objid = popInteger ();
timeoffset = popInteger ();
timeonleft = popBoolean ();
color = popInteger ();
visible = popBoolean ();
MWGUIManager *gui = MWGUIManager::GetInstance ();
Verify (gui);
gui->ShowTimer (visible);
if (visible)
{
HUDTimer *timer;
timer = Cast_Object (HUDTimer *,gui->Component (MWGUIManager::HUD_TIMER));
timer->Timer (timerid);
timer->TimeOffset (timeoffset);
timer->TimeOnLeft (timeonleft);
timer->Color (color);
Objective *obj=NULL;
if (objid)
{
obj = Cast_Object(Objective *,NameTable::GetInstance()->FindData(objid));
Check_Object (obj);
}
timer->Objective (obj);
}
return NULL;
}
TypePtr execSetHelpArrow (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int rot = popInteger ();
int x = popInteger();
int y = popInteger();
int color = popInteger();
bool visible = popBoolean();
int time = popInteger();
MWGUIManager *gui = MWGUIManager::GetInstance ();
Verify (gui);
gui->ShowHelpArrow (visible);
if (visible)
{
HUDHelpArrow *arrow = Cast_Object (HUDHelpArrow *,gui->Component (MWGUIManager::HUD_HELPARROW));
arrow->SetParams((Scalar)rot * Radians_Per_Degree,(Scalar)x,(Scalar)y,color,time);
}
return NULL;
}
TypePtr execShowHelpArrow (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int rot,color;
long *loc;
bool visible;
rot = popInteger ();
loc = popIntegerPtr ();
color = popInteger ();
visible = popBoolean ();
MWGUIManager *gui = MWGUIManager::GetInstance ();
Verify (gui);
gui->ShowHelpArrow (visible);
if (visible)
{
HUDHelpArrow *arrow;
arrow = Cast_Object (HUDHelpArrow *,gui->Component (MWGUIManager::HUD_HELPARROW));
arrow->SetRot ((Scalar) rot * Radians_Per_Degree);
Point3D locpt;
locpt.x = (Scalar) loc[0];
locpt.y = (Scalar) loc[1];
locpt.z = 0.9f;
arrow->Location (locpt);
arrow->Color (color);
}
return NULL;
}
TypePtr execMakeColor (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int red,green,blue,alpha,toret;
red = popInteger ();
green = popInteger ();
blue = popInteger ();
alpha = popInteger ();
toret = (alpha<<24) + (red<<16) + (green<<8) + (blue);
pushInteger (toret);
return IntegerTypePtr;
}
TypePtr execPlayLancemateSound (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
const char *soundname = popStringPtr ();
int vo_count = popInteger ();
if (vo_count < 1)
{
vo_count = 1;
}
bool played_any = false;
std::vector<MWObject*> lancemates;
MW4AI::Groups::GetLancemates(lancemates);
while (lancemates.size() > 0)
{
int index = gos_rand() % lancemates.size();
std::vector<MWObject*>::iterator i = lancemates.begin();
{for (int j = 0;
j < index;
++j)
{
++i;
}}
if (((*i)->GetAI() != 0) &&
((*i)->GetAI()->getEntity() != 0) &&
((*i)->GetAI()->getEntity()->IsDestroyed() == false) &&
((*i)->GetAI()->GetLancemate() != 0))
{
LancematePlug* plug = (*i)->GetAI()->GetLancemate();
MString audio_command_name(soundname);
audio_command_name += plug->m_TalkerSuffix;
audio_command_name += ".wav{handle}";
MString audio_resource_name("Audio\\");
audio_resource_name += audio_command_name;
Resource r(audio_resource_name);
if (r.DoesResourceExist() == true)
{
AudioCommand *command = AudioCommand::Create(AudioRenderer::VOType,audio_command_name,1.0f,1.0f);
if (command)
{
Check_Object(command);
command->Play();
if (AudioManager::GetInstance() != 0)
{
AudioManager::GetInstance()->AddCommand(command,FindTalkerID (plug->m_TalkerSuffix));
}
}
--vo_count;
played_any = true;
if (vo_count == 0)
{
pushBoolean(true);
return BooleanTypePtr;
}
}
}
lancemates.erase(i);
}
pushBoolean(played_any);
return BooleanTypePtr;
}
TypePtr execPlayVoiceOver (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
const char *soundname = popStringPtr ();
int talker_id = popInteger ();
if ((talker_id == (ELEMENTS(talker_suffixes)-1)) && (!MW4Shell::Instance->m_optionsObject->m_bettyOn))
{
pushBoolean (true);
return BooleanTypePtr;
}
if ((AudioManager::GetInstance() != 0) &&
(IsDead(AudioManager::GetInstance()->TalkerObjectID(talker_id)) == true))
{
pushBoolean (true);
return BooleanTypePtr;
}
if (IsDead(talker_suffixes[talker_id]) == true)
{
pushBoolean(true);
return BooleanTypePtr;
}
MString wav_file(soundname);
Verify((unsigned)talker_id < ELEMENTS(talker_suffixes));
wav_file += talker_suffixes[talker_id];
AudioCommand *command = AudioCommand::Create(AudioRenderer::VOType, wav_file, 1.0f, 1.0f);
if (command)
{
Check_Object(command);
command->Play();
if (AudioManager::GetInstance() != 0)
{
AudioManager::GetInstance()->AddCommand(command,talker_id);
}
}
pushBoolean (false);
return BooleanTypePtr;
}
int GetStringHash(const char* soundname, int talker)
{
int rv = 0;
{for (int i = 0;
i < strlen(soundname);
++i)
{
rv ^= soundname[i] << ((i & 0x03) * 8);
}}
rv ^= strlen(soundname);
rv ^= (talker << 16);
return (rv);
}
TypePtr execPlayVoiceOverOnce (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
const char *soundname = popStringPtr ();
int talker_id = popInteger ();
if ((talker_id == (ELEMENTS(talker_suffixes)-1)) && (!MW4Shell::Instance->m_optionsObject->m_bettyOn)) // this is a betty sound
{
pushBoolean (true);
return BooleanTypePtr;
}
if (AudioManager::GetInstance() != 0)
{
if ((AudioManager::GetInstance()->GetVOPlayed(GetStringHash(soundname,talker_id)) == true) ||
(IsDead(AudioManager::GetInstance()->TalkerObjectID(talker_id)) == true))
{
pushBoolean (true);
return BooleanTypePtr;
}
}
if (IsDead(talker_suffixes[talker_id]) == true)
{
pushBoolean(true);
return BooleanTypePtr;
}
MString wav_file(soundname);
Verify((unsigned)talker_id < ELEMENTS(talker_suffixes));
wav_file += talker_suffixes[talker_id];
AudioCommand *command = AudioCommand::Create(AudioRenderer::VOType, wav_file, 1.0f, 1.0f);
if (command)
{
Check_Object(command);
command->Play();
if (AudioManager::GetInstance() != 0)
{
AudioManager::GetInstance()->AddCommand(command,talker_id);
}
if (AudioManager::GetInstance() != 0)
{
AudioManager::GetInstance()->SetVOPlayed(GetStringHash(soundname,talker_id));
}
}
pushBoolean (false);
return BooleanTypePtr;
}
TypePtr execKillVoiceOvers (SymTableNodePtr routineIdPtr)
{
// DECLARE_ABL_CONTEXT;
if (AudioManager::GetInstance() != 0)
{
AudioManager::GetInstance()->DeleteAllCommands();
}
endFunction ();
return NULL;
}
TypePtr execIsVoiceOverPlaying (SymTableNodePtr routineIdPtr)
{
if (AudioManager::GetInstance() != 0)
{
pushBoolean(AudioManager::GetInstance()->IsVoiceOverPlaying());
}
else
{
pushBoolean(false);
}
endFunction ();
return BooleanTypePtr;
}
TypePtr execStartMusic (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
const char *soundname = popStringPtr ();
float old_timeout = popReal ();
float new_timein = popReal ();
float new_volume = popInteger () / 100.0f;
if (g_MissionMusic)
{
MString wav_file(soundname);
wav_file += "_music.wav{handle}";
AudioCommand *command = AudioCommand::Create(AudioRenderer::MusicType, wav_file, 1, 1);
if ((command) &&
(AudioManager::GetInstance() != 0))
{
AudioManager::GetInstance()->AddMusicCommand(command,old_timeout,new_timein,new_volume);
}
}
return NULL;
}
TypePtr execIsMusicPlaying (SymTableNodePtr routineIdPtr)
{
if (AudioManager::GetInstance() != 0)
{
pushBoolean(AudioManager::GetInstance()->IsMusicPlaying());
}
else
{
pushBoolean(false);
}
endFunction ();
return BooleanTypePtr;
}
TypePtr execPlayBettySound (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int sound_index = popInteger();
Check_Object(VehicleInterface::GetInstance());
VehicleInterface::GetInstance()->ReactToEvent((VehicleInterface::SOUND_TRIGGER)sound_index);
return NULL;
}
TypePtr execPlayTeamBettySound (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int team_number = popInteger();
int sound_index = popInteger();
if ((Network::GetInstance() != 0) &&
(MWApplication::GetInstance() != 0))
{
if ((team_number == 0) ||
(team_number > MWApplication::No_Team))
{
return NULL;
}
--team_number;
DynamicMemoryStream stream;
stream.WriteBytes(&team_number,1);
stream.WriteBytes(&sound_index,1);
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
{
for (int i = 0; i < Maximum_Players; ++i)
{
if ((app->servedConnectionData[i].clientLaunched) &&
(app->servedConnectionData[i].clientPlayer != 0))
{
stream.Rewind();
Network::GetInstance()->SendNetMessage(i, MWApplication::TeamBettyMessageID, &stream, true);
}
}
}
}
return NULL;
}
TypePtr execStartMusicAll (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int sound_index = popInteger();
if (g_MissionMusic &&
(Network::GetInstance() != 0) &&
(MWApplication::GetInstance() != 0))
{
DynamicMemoryStream stream;
stream.WriteBytes(&sound_index,1);
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
{for (int i = 0; i < Maximum_Players; ++i)
{
if ((app->servedConnectionData[i].clientLaunched) &&
(app->servedConnectionData[i].clientPlayer != 0))
{
stream.Rewind();
Network::GetInstance()->SendNetMessage(i,
MWApplication::StartMusicMessageID,
&stream,
true);
}
}}
}
return NULL;
}
TypePtr execTeamSetNav (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int team_number = popInteger();
int nav = popInteger();
if ((Network::GetInstance() != 0) &&
(MWApplication::GetInstance() != 0))
{
if (team_number == 0)
{
team_number = 8;
}
else
{
if ((team_number < 0) ||
(team_number > 8))
{
return NULL;
}
else
{
--team_number;
}
}
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
if (team_number == 8)
{
if (most_recent_no_team_nav == nav)
{
return NULL;
}
}
else
{
if ((app->teams[team_number] != 0) &&
(app->teams[team_number]->GetCurrent() != 0) &&
(app->teams[team_number]->GetCurrent()->m_MostRecentTeamNav == nav))
{
return NULL;
}
}
DynamicMemoryStream stream;
stream.WriteBytes(&team_number,1);
stream.WriteBytes(&nav,4);
{for (int i = 0; i < Maximum_Players; ++i)
{
if ((app->servedConnectionData[i].clientLaunched) &&
(app->servedConnectionData[i].clientPlayer != 0) &&
(app->servedConnectionData[i].clientPlayer->vehicle != 0) &&
(app->servedConnectionData[i].clientPlayer->vehicle->IsDerivedFrom(Vehicle::DefaultData) == true))
{
Vehicle* vehicle = Cast_Object(Vehicle*,app->servedConnectionData[i].clientPlayer->vehicle);
if (vehicle->GetTeam() == team_number)
{
stream.Rewind();
Network::GetInstance()->SendNetMessage(i,
MWApplication::TeamSetNavMessageID,
&stream,
true);
}
}
}}
if (team_number == 8)
{
most_recent_no_team_nav = nav;
}
else
{
if ((app->teams[team_number] != 0) &&
(app->teams[team_number]->GetCurrent() != 0))
{
app->teams[team_number]->GetCurrent()->m_MostRecentTeamNav = nav;
}
}
}
return NULL;
}
TypePtr execSpecifyTalker (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int talker = popInteger();
int object_id = popInteger();
if (AudioManager::GetInstance() != 0)
{
AudioManager::GetInstance()->MapTalker(talker,object_id);
}
return NULL;
}
TypePtr execNavPointReached (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int src_id = popInteger ();
MWObject* src = GetMWObjectForID(src_id);
if ((src != 0) && (src->IsDestroyed() == false) && (src->vehicleInterface != 0))
{
MechWarrior4::VehicleInterface* vehicle_interface = Cast_Object(MechWarrior4::VehicleInterface*,src->vehicleInterface);
vehicle_interface->ReactToEvent (VehicleInterface::NAVPOINT_REACHED);
}
return NULL;
}
TypePtr execStandardRoutineCall (SymTableNodePtr routineIdPtr)
{
TypePtr toret;
if (debugger)
debugger->traceRoutineEntry(routineIdPtr);
long routineKey = routineIdPtr->defn.info.routine.key;
ablREPORT ((*g_ABLFunctions)[routineKey] != NULL,ablERROR ("undefined abl function"));
#ifdef LAB_ONLY
double start_time(gos_GetHiResTime());
#endif
toret = (*g_ABLFunctions)[routineKey]->Execute (routineIdPtr);
#ifdef LAB_ONLY
double execute_time(gos_GetHiResTime() - start_time);
if ((Profiler::Instance() != 0) &&
(CurModule != 0) &&
(Profiler::Instance()->GetActive() == true))
{
Profiler::Instance()->NotifyFunctionCalled(execute_time,
(*g_ABLFunctions)[routineKey]->Name(),
CurModule->getName());
}
#endif
if (debugger)
debugger->traceRoutineExit(routineIdPtr);
return toret;
}
void Group_execSetDmgModifier(Group::identifier group_id, int nIdx, int nDmgFactor)
{
mwobject_list targets;
GetVehiclesFromGroup(group_id,targets,true);
if (targets.size() == 0)
{
return;
}
mwobject_list::iterator best_found = targets.end();
{for (mwobject_list::iterator i = targets.begin(); i != targets.end(); ++i)
{
(*i)->SetDmgModifier(nIdx, nDmgFactor);
}}
}
TypePtr execSetDmgModifier (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int nWho = popInteger();
int nIdx = popInteger(); // 0: default, 1: splash
int nDmgFactor = popInteger(); // should be -1(restore), 0(store), (1 <= && <= 10000)
// real factor = nDmgFactor / 10000.0
if (ObjectIDisGroup(nWho) == true) {
Group_execSetDmgModifier(ObjectIDtoGroupID(nWho), nIdx, nDmgFactor);
} else {
MWObject* src = GetMWObjectForID(nWho);
if (src != 0)
{
src->SetDmgModifier(nIdx, nDmgFactor);
}
}
return (NULL);
}
TypePtr execRestoreOriginalBounds (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
static_cast<MWMission*>(MWMission::GetInstance())->RestoreOriginalBounds();
return (NULL);
}
MechWarrior4::Path& GetPathFromID(int nPathID)
{
if (nPathID < 0) {
ablREPORT (nPathID==-1,ablERROR ("nPathID should >= -1"));
return *(MechWarrior4::Path*)NULL;
} else {
Entity *entity;
MechWarrior4::Path* path;
entity = NameTable::GetInstance()->FindData (nPathID);
ablREPORT (entity->IsDerivedFrom (MechWarrior4::Path::DefaultData),ablERROR ("tried to set bounds using invalid path..."));
return *Cast_Object (MechWarrior4::Path *,entity);
}
}
TypePtr execSetBoundsFromPaths (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int nMiss = popInteger();
int nWarn = popInteger();
static_cast<MWMission*>(MWMission::GetInstance())->SetBoundsFromPaths(GetPathFromID(nMiss), GetPathFromID(nWarn));
return (NULL);
}
TypePtr execRandSelect (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
// group id - dest, group id - src, int nCount
// if (nCount < 0) then move-to-group not add-to-group
long dest = popInteger();
long src = popInteger();
int nCount = popInteger();
ablREPORT ((ObjectIDisGroup(dest) == true),ablERROR ("execRandSelect: group id is required"));
ablREPORT ((ObjectIDisGroup(src) == true),ablERROR ("execRandSelect: group id is required"));
Group::identifier g_dest = ObjectIDtoGroupID(dest);
Group::identifier g_src = ObjectIDtoGroupID(src);
ablREPORT ((g_dest != g_src),ablERROR ("execRandSelect: should be src != dest"));
bool bMove = false;
if (nCount < 0) {
nCount = -nCount;
bMove = true;
}
int i, nSrcCount = MW4AI::Groups::Size(g_src);
Adept::ObjectID* pIDs = new Adept::ObjectID[nSrcCount];
Adept::ObjectID* p = pIDs;
Adept::ObjectID obj_id;
for(i = 0; i < nSrcCount; i++)
{
if (MW4AI::Groups::GetMember(g_src, (unsigned)i, obj_id)) {
if (!MW4AI::Groups::ContainsObject(obj_id, g_dest))
*p++ = obj_id;
}
}
nSrcCount = p - pIDs;
while(0 < nSrcCount)
{
if (nCount <= 0)
break;
int n = Stuff::Random::GetRandomInt() % nSrcCount;
if (0 <= n) {
obj_id = pIDs[n];
nSrcCount--;
if (n < nSrcCount)
memcpy(&pIDs[n], &pIDs[n + 1], sizeof(Adept::ObjectID) * (nSrcCount - n));
if (bMove) {
MW4AI::Groups::RemoveObject(obj_id, g_src);
}
MW4AI::Groups::AddObject(obj_id, g_dest);
nCount--;
}
}
delete [] pIDs;
return (NULL);
}
TypePtr execRespawnPosition (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
// group id - dest, group id - src, int nCount
// if (nCount < 0) then move-to-group not add-to-group
Adept::ObjectID id_who = popInteger();
gosASSERT(id_who == -1); // currently single player only...
Adept::ObjectID id_where = popInteger();
ablREPORT ((ObjectIDisGroup(id_where) != true),ablERROR ("execRespawnPosition: group id is not allowed, only drop id required"));
// see MWApplication::RequestRespawnMessageHandler(int connection, Stuff::MemoryStream *message)
#ifdef _DEBUG
Check_Object(EntityManager::GetInstance());
Adept::DropZone *zone = EntityManager::GetInstance()->GetDropZone(id_where);
Check_Object(zone);
#endif // _DEBUG
MWApplication *app;
app = MWApplication::GetInstance ();
int nSvrID = Connection::Server->GetID();
Check_Object(app->servedConnectionData[nSvrID].clientPlayer);
app->servedConnectionData[nSvrID].clientPlayer->dropZone = id_where;
return (NULL);
}
TypePtr execGetCOOP (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());
gosASSERT(mission);
int nIdx = popInteger();
int nRet = mission->GetCOOP(nIdx);
pushInteger(nRet);
return IntegerTypePtr;
}
TypePtr execSetCOOP (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());
gosASSERT(mission);
int nIdx = popInteger();
int nParam = popInteger();
int nRet = mission->SetCOOP(nIdx, nParam);
pushInteger(nRet);
return IntegerTypePtr;
}
TypePtr execGetTime (SymTableNodePtr routineIdPtr)
{
pushReal (gos_GetElapsedTime());
endFunction ();
return RealTypePtr;
}
TypePtr execGetTimeX (SymTableNodePtr routineIdPtr)
{
pushReal (gos_GetHiResTime());
endFunction ();
return RealTypePtr;
}
TypePtr execIGetTime (SymTableNodePtr routineIdPtr)
{
pushInteger ((int)(gos_GetElapsedTime() * 1000.0f));
endFunction ();
return IntegerTypePtr;
}
TypePtr execIGetTimeX (SymTableNodePtr routineIdPtr)
{
pushInteger ((int)(gos_GetHiResTime() * 1000.0f));
endFunction ();
return IntegerTypePtr;
}
TypePtr execPlaySoundStr (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
char *name = popStringPtr();
AudioCommand *asdf = AudioCommand::Create(AudioRenderer::MechanicalType, name, 1.0f, 1.0f);
if (asdf) {
Check_Object(asdf);
asdf->Play();
}
return NULL;
}
TypePtr execLogMapRespawn (SymTableNodePtr routineIdPtr)
{
endFunction ();
#if defined( STATS2_BUILD )
MW4log2_LocalLogGeneric(va("MapRespawn"));
#else
// MW4log_generic(MW4G_MAPRESPAWN, va("MapRespawn"));
#endif
return NULL;
}
TypePtr execLogDefendingTeam (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int defending_team = popInteger();
defending_team-=1;
#if defined( STATS2_BUILD )
MW4log2_LocalLogGeneric(va("DefendingTeam\t%d",defending_team));
#else
// MW4log_generic(MW4T_DEFENDINGTEAM, va("DefendingTeam\t%d",defending_team));
#endif
return NULL;
}
TypePtr execLogHQDestroyed (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int team_hq = popInteger();
int destroying_team = popInteger();
team_hq-=1;
destroying_team-=1;
#if defined( STATS2_BUILD )
MW4log2_LocalLogGeneric(va("HQDestroyed\t%d\t%d",team_hq,destroying_team));
#else
// MW4log_generic(MW4T_HQDESTROYED, va("HQDestroyed\t%d\t%d",team_hq,destroying_team));
#endif
return NULL;
}
TypePtr execLogDefendTimeAward (SymTableNodePtr routineIdPtr)
{
DECLARE_ABL_CONTEXT;
int team = popInteger();
int award = popInteger();
team-=1;
#if defined( STATS2_BUILD )
MW4log2_LocalLogGeneric(va("DefendTimeAward\t%d\t%d",team,award));
#else
// MW4log_generic(MW4T_HQDESTROYED, va("DefendTimeAward\t%d\t%d",team,award));
#endif
return NULL;
}
int GetEnemyTyps(int id_group, char** ppNames, int* pnCounts, int nMask)
{
gosASSERT(ObjectIDisGroup(id_group) == true);
Group::identifier group_id = ObjectIDtoGroupID(id_group);
mwobject_list targets;
GetVehiclesFromGroup(group_id,targets,true);
MWMission* mission;
if (MWMission::GetInstance())
mission = Cast_Object(MWMission*, MWMission::GetInstance());
else
mission = NULL;
int nSubStageNumber = mission->GetCOOP(MWMission::COOP_SUBSTAGE_NUMBER);
bool bBonusStage = (4 < nSubStageNumber) ? true: false;
int i;
int nMechs = 0;
int nTypes = 0;
struct STypeInfo
{
int m_nCount;
char m_strTypeName[64];
}
aTypeInfos[100];
int nMiscs = 0;
mwobject_list::iterator best_found = targets.end();
MWApplication* app = MWApplication::GetInstance();
{
for (mwobject_list::iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
MWObject* pObj = (*itr);
if (pObj->IsDerivedFrom(Mech::DefaultData))
{
nMechs++;
}
else if (pObj->IsDerivedFrom(Building::DefaultData) || pObj->IsDerivedFrom(Vehicle::DefaultData))
{
const char* pcszName;
if (bBonusStage && !pObj->IsDerivedFrom(Vehicle::DefaultData))
{
pcszName = "Buildings";
}
else
{
const MechWarrior4::MWObject::GameModel* game_model = pObj->GetGameModel();
Check_Object(game_model);
pcszName = app->GetLocString(game_model->m_nameIndex);
}
if (0 < strlen(pcszName))
{
for(i = 0; i < nTypes; i++)
{
if (strcmp(aTypeInfos[i].m_strTypeName, pcszName) == 0)
{
aTypeInfos[i].m_nCount++;
break;
}
}
if (i == nTypes)
{
strcpy(aTypeInfos[nTypes].m_strTypeName, pcszName);
aTypeInfos[nTypes].m_nCount = 1;
nTypes++;
}
}
else
{
nMiscs++;
}
}
else if (pObj->IsDerivedFrom(Mech::DefaultData))
{
nMiscs++;
}
}
}
int nRet = 0;
if (0 < nMechs)
{
FREEANDNULL(*ppNames);
const char* strMech = "Enemy Mechs";
char* psz = (char*)gos_Malloc(strlen(strMech) + 1);
strcpy(psz, strMech);
*ppNames++ = psz;
*pnCounts++ = nMechs;
nRet++;
}
for(i = 0; i < nTypes; i++)
{
FREEANDNULL(*ppNames);
char* psz = (char*)gos_Malloc(strlen(aTypeInfos[i].m_strTypeName) + 1);
strcpy(psz, aTypeInfos[i].m_strTypeName);
*ppNames++ = psz;
*pnCounts++ = aTypeInfos[i].m_nCount;
nRet++;
}
if (0 < nMiscs)
{
FREEANDNULL(*ppNames);
const char* strMisc = "Misc Enemy";
char* psz = (char*)gos_Malloc(strlen(strMisc) + 1);
strcpy(psz, strMisc);
*ppNames++ = psz;
*pnCounts++ = nMiscs;
nRet++;
}
return nRet;
}
//***************************************************************************
}