//*************************************************************************** // // ABLXSTD.CPP // //*************************************************************************** #include "MW4Headers.hpp" #include #include #include #include "ablfuncs.hpp" #include "ablprofiler.hpp" #include #include #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 #include #include #include #include #include "move_formation.hpp" #include "MWCampaign.hpp" #include "AI_Specials.hpp" #include #include "Salvage.hpp" #include "mwapplication.hpp" #include #include "flag.hpp" #include "MWGame.hpp" #include "sensor.hpp" #include "Team.hpp" #include #include #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 #include #include #include "mw4shell.hpp" #include "nglog_mw4.hpp" #pragma warning (disable : 4189) using namespace Stuff; using namespace MW4AI; namespace MW4AI { bool BoardDropShip (stlport::vector& 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 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_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 void GetAIsFromTeam(int team_number, std::vector& 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 void GetAIsFromGroup(Group::identifier group_id, std::vector& ais) { Verify(Adept::NameTable::GetInstance() != 0); if (group_id & 0x00F00000) { GetAIsFromTeam(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;inameTableArray[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;inameTableArray [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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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(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(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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 objects; GetVehiclesFromGroup(group_id,objects); {for (std::vector::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 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 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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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;inameTableArray [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(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(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(object1); Entity* who2 = GetObjectForID(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(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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(id,ais); {for (std::vector::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 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 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(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(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;jnameTableArray [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;jnameTableArray [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 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 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 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 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 list; GetAIsFromGroup (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 list; GetAIsFromGroup (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(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 objects; GetAIsFromGroup(group_id,objects); MW4AI::LancemateCommands::lancemate_list l; {for (std::vector::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 ais; GetAIsFromGroup(id,ais); {for (std::vector::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 ais; GetAIsFromGroup(id,ais); {for (std::vector::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 ais; GetAIsFromGroup(id,ais); {for (std::vector::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 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 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(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;jnameTableArray [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 ais; GetAIsFromGroup(gid,ais); {for (std::vector::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 ais; GetAIsFromGroup(gid,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); {for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); for (std::vector::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 ais; GetAIsFromGroup(group_id,ais); for (std::vector::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(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 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::GetInstance())->StoreOriginalBounds(); // jcem long id_ul = popInteger(); long id_lr = popInteger(); Adept::Entity* object_ul = GetObjectForID(id_ul); Adept::Entity* object_lr = GetObjectForID(id_lr); if ((object_ul != 0) && (object_lr != 0)) { Vector2DOf bounds_ul; bounds_ul.x = ((Stuff::Point3D)(object_ul->GetLocalToWorld())).x; bounds_ul.y = ((Stuff::Point3D)(object_ul->GetLocalToWorld())).z; Vector2DOf bounds_lr; bounds_lr.x = ((Stuff::Point3D)(object_lr->GetLocalToWorld())).x; bounds_lr.y = ((Stuff::Point3D)(object_lr->GetLocalToWorld())).z; Vector2DOf bounds_ur(bounds_ul); bounds_ur.x = bounds_lr.x; Vector2DOf bounds_ll(bounds_lr); bounds_ll.x = bounds_ul.x; DynamicArrayOf > 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(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 list; GetAIsFromGroup (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 lancemates; MW4AI::Groups::GetLancemates(lancemates); while (lancemates.size() > 0) { int index = gos_rand() % lancemates.size(); std::vector::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::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::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; } //*************************************************************************** }