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.
9823 lines
240 KiB
C++
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;
|
|
}
|
|
//***************************************************************************
|
|
|
|
|
|
}
|