From ccf506a68b67857dbf1193a578df0d176c022dde Mon Sep 17 00:00:00 2001 From: nev6502 Date: Sun, 21 Jun 2020 18:45:59 -0600 Subject: [PATCH 1/7] Callback function is now an optional parameter across the various action creation functions, because some times actions are created expressely to be merged into another action to create a 2 action trigger, and thus the standalone action gets discarded. Entering a callback parameter just for the sake of requiring it is not very nice or clean. --- code/REDALERT/MapScript.cpp | 423 +++++++++++++++++++++++++++--------- 1 file changed, 324 insertions(+), 99 deletions(-) diff --git a/code/REDALERT/MapScript.cpp b/code/REDALERT/MapScript.cpp index 4c74838..268528f 100644 --- a/code/REDALERT/MapScript.cpp +++ b/code/REDALERT/MapScript.cpp @@ -1,6 +1,3 @@ -// MapScript.cpp -// - #include "FUNCTION.H" #include "MapScript.h" @@ -1069,7 +1066,13 @@ int houseType = lua_tointeger(L, 1); int in_x = lua_tointeger(L, 2); int in_y = lua_tointeger(L, 3); - const char* in_function = lua_tostring(L, 4); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 4) { + in_function = (char*)lua_tostring(L, 4); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1087,8 +1090,10 @@ // Create instance of trigger type TriggerClass * this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } // Get the cell and set the trigger this_trigger->Cell = XY_Cell(in_x, in_y); @@ -1126,7 +1131,13 @@ int objectID = lua_tointeger(L, 1); int houseType = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } BuildingClass* this_building = Buildings.Ptr(objectID); @@ -1146,8 +1157,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } // Set the building this_building->Trigger = this_trigger; @@ -1184,7 +1197,13 @@ static int Script_ObjectDiscoveryCallback(lua_State* L) { int objectID = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // A house must be specified if (objectID >= 0 ) { @@ -1201,8 +1220,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } Script_SetObjectTrigger(objectID, this_trigger); @@ -1238,7 +1259,13 @@ static int Script_HouseDiscoveredCallback(lua_State* L) { int houseType = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1258,8 +1285,10 @@ TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[PlayerPtr->Class->House].Add(this_trigger); @@ -1293,7 +1322,13 @@ static int Script_ObjectAttackedCallback(lua_State* L) { int objectID = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // An object must be specified if (objectID >= 0) { @@ -1310,8 +1345,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } Script_SetObjectTrigger(objectID, this_trigger); @@ -1345,7 +1382,13 @@ static int Script_ObjectDestroyedCallback(lua_State* L) { int objectID = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // An object must be specified if (objectID >= 0) { @@ -1362,8 +1405,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } Script_SetObjectTrigger(objectID, this_trigger); @@ -1399,8 +1444,12 @@ *=============================================================================================*/ static int Script_AnyEventCallback(lua_State* L) { - const char* in_function = lua_tostring(L, 1); + char* in_function = ""; + // Optional callback function + if (lua_gettop(L) >= 1) { + in_function = (char*)lua_tostring(L, 1); + } // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -1414,8 +1463,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -1444,7 +1495,13 @@ static int Script_AllUnitsDestroyedCallback(lua_State* L) { int houseType = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1462,11 +1519,12 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - - HouseTriggers[(HousesType)houseType].Add(this_trigger); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + HouseTriggers[(HousesType)houseType].Add(this_trigger); // Output the new trigger's ID lua_pushnumber(L, this_trigger->ID); @@ -1498,7 +1556,13 @@ static int Script_AllBuildingsDestroyedCallback(lua_State* L) { int houseType = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1516,12 +1580,13 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[(HousesType)houseType].Add(this_trigger); - // Output the new trigger's ID lua_pushnumber(L, this_trigger->ID); @@ -1552,7 +1617,13 @@ static int Script_AllDestroyedCallback(lua_State* L) { int houseType = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1570,12 +1641,13 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[(HousesType)houseType].Add(this_trigger); - // Output the new trigger's ID lua_pushnumber(L, this_trigger->ID); @@ -1608,7 +1680,13 @@ int houseType = lua_tointeger(L, 1); int in_credits = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1626,12 +1704,13 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[(HousesType)houseType].Add(this_trigger); - // Output the new trigger's ID lua_pushnumber(L, this_trigger->ID); @@ -1662,7 +1741,13 @@ static int Script_TimeReachedCallback(lua_State* L) { int in_time = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -1677,8 +1762,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -1705,7 +1792,12 @@ *=============================================================================================*/ static int Script_MissionTimerCallback(lua_State* L) { - const char* in_function = lua_tostring(L, 1); + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 1) { + in_function = (char*)lua_tostring(L, 1); + } // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -1719,8 +1811,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -1751,7 +1845,13 @@ int houseType = lua_tointeger(L, 1); int in_number = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1769,8 +1869,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[(HousesType)houseType].Add(this_trigger); @@ -1807,7 +1909,13 @@ int houseType = lua_tointeger(L, 1); int in_number = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1825,8 +1933,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[(HousesType)houseType].Add(this_trigger); @@ -1860,7 +1970,13 @@ static int Script_NoFactoriesCallback(lua_State* L) { int houseType = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1878,8 +1994,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[(HousesType)houseType].Add(this_trigger); @@ -1914,8 +2032,14 @@ static int Script_CivilianEscapeCallback(lua_State* L) { int houseType = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); - + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + if (houseType >= 0 && houseType < HouseTypes.Count()) { // Create trigger type @@ -1931,8 +2055,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -1968,7 +2094,13 @@ int houseType = lua_tointeger(L, 1); int objectType = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { @@ -1985,8 +2117,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[houseType].Add(this_trigger); @@ -2025,7 +2159,13 @@ int houseType = lua_tointeger(L, 1); int objectType = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2042,8 +2182,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[houseType].Add(this_trigger); @@ -2082,7 +2224,13 @@ int houseType = lua_tointeger(L, 1); int objectType = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2099,8 +2247,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[houseType].Add(this_trigger); @@ -2139,7 +2289,13 @@ int houseType = lua_tointeger(L, 1); int objectType = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2156,8 +2312,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[houseType].Add(this_trigger); @@ -2192,8 +2350,13 @@ static int Script_TeamLeavesMapCallback(lua_State* L) { int in_team = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } TeamTypeClass* this_team = TeamTypes.Ptr(in_team); if (this_team != NULL) { @@ -2213,8 +2376,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -2257,7 +2422,12 @@ int in_x = lua_tointeger(L, 2); int in_y = lua_tointeger(L, 3); - const char* in_function = lua_tostring(L, 4); + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 4) { + in_function = (char*)lua_tostring(L, 4); + } if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2274,8 +2444,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } // Get the cell and set the trigger this_trigger->Cell = XY_Cell(in_x, in_y); @@ -2318,7 +2490,12 @@ int houseType = lua_tointeger(L, 1); int in_x = lua_tointeger(L,2); - const char* in_function = lua_tostring(L, 3); + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2335,8 +2512,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } // Find a free spot and set the trigger int addY = 0; @@ -2385,7 +2564,12 @@ int houseType = lua_tointeger(L, 1); int in_y = lua_tointeger(L, 2); - const char* in_function = lua_tostring(L, 3); + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2402,8 +2586,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } // Find a free spot and set the trigger int addX = 0; @@ -2447,7 +2633,13 @@ static int Script_GlobalSetCallback(lua_State* L) { int in_global = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -2462,8 +2654,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -2491,7 +2685,13 @@ static int Script_GlobalClearedCallback(lua_State* L) { int in_global = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -2506,8 +2706,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -2535,7 +2737,13 @@ static int Script_LowPowerCallback(lua_State* L) { int houseType = lua_tointeger(L, 1); - const char* in_function = lua_tostring(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } // A house must be specified if (houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2555,8 +2763,10 @@ TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[PlayerPtr->Class->House].Add(this_trigger); @@ -2588,7 +2798,12 @@ *=============================================================================================*/ static int Script_AllBridgesDestroyedCallback(lua_State* L) { - const char* in_function = lua_tostring(L, 1); + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 1) { + in_function = (char*)lua_tostring(L, 1); + } // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -2602,8 +2817,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } LogicTriggers.Add(this_trigger); @@ -2634,7 +2851,13 @@ int buildingType = lua_tointeger(L, 1); int houseType = lua_tointeger(L,2); - const char* in_function = lua_tostring(L,3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } // A house must be specified if (buildingType>=0 && houseType >= 0 && houseType < HouseTypes.Count()) { @@ -2651,8 +2874,10 @@ // Create instance of trigger type TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } HouseTriggers[(HousesType)houseType].Add(this_trigger); From 0ef858bf86651112cc7fa00fa1d7f34b19a68494 Mon Sep 17 00:00:00 2001 From: nev6502 Date: Fri, 26 Jun 2020 00:19:20 -0600 Subject: [PATCH 2/7] More scripting functions (ability to various change object / objectType attributes) and globals for use with them --- code/REDALERT/MapScript.cpp | 424 +++++++++++++++++++++++++++++++++++- code/REDALERT/MapScript.h | 31 +++ scripts/_Global.script | 82 +++++++ 3 files changed, 534 insertions(+), 3 deletions(-) diff --git a/code/REDALERT/MapScript.cpp b/code/REDALERT/MapScript.cpp index 268528f..fa5feb8 100644 --- a/code/REDALERT/MapScript.cpp +++ b/code/REDALERT/MapScript.cpp @@ -969,7 +969,7 @@ } /*********************************************************************************************** - * Script_DesignatePreferredTarget - Gives specified house a repeating special weapon * + * Script_DesignatePreferredTarget - Gives specified house a prefferable type of target * * * * SCRIPT INPUT: houseType (int) - The player (house) index to set targetting for (or -1) * * targetType (int) - The target type index to set to * @@ -3271,7 +3271,415 @@ return -1; } + +/********************************************************************************************** +* Modification Utility Functions * +*=============================================================================================*/ + /********************************************************************************************** + * Script_SetObjectAttribute - Sets attributes for specific objects * + * * + * SCRIPT INPUT: objectID (int) - The ID of the object * + * attribute_type (int) - The attribute to change * + * attribute_value (int) - The value to set the attribute to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetObjectAttribute(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + + + // Get the appropriate technotype + if (this_object != NULL) { + + + + + switch ((MapScriptAttributeType)attribute_type) { + case ATTRIBUTE_STRENGTH: { + + int attribute_value = lua_tointeger(L, 3); + this_object->Strength = attribute_value; + + }break; + default: { + + TechnoTypeClass* this_type_class; + + switch (this_object->RTTI) { + case RTTI_BUILDING: + + this_type_class = BuildingTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_UNIT: + + this_type_class = UnitTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_INFANTRY: + + this_type_class = InfantryTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_VESSEL: + + this_type_class = VesselTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_AIRCRAFT: + + this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); + + break; + } + + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + } + + }break; + + } + + } + + + return -1; + } + + /********************************************************************************************** + * Script_SetBuildingTypeAttribute - Sets attributes for a building types * + * * + * SCRIPT INPUT: buildingTypeID (int) - The ID of the building type class * + * attribute_type (int) - The attribute to change * + * attribute_value (int) - The value to set the attribute to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetBuildingTypeAttribute(lua_State* L) { + + int buildingTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = BuildingTypes.Ptr(buildingTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_SetVehicleTypeAttribute - Sets attributes for vehicle types * + * * + * SCRIPT INPUT: vehicleTypeID (int) - The ID of the vehicle type class * + * attribute_type (int) - The attribute to change * + * attribute_value (int) - The value to set the attribute to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetVehicleTypeAttribute(lua_State* L) { + + int vehicleTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = UnitTypes.Ptr(vehicleTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_SetInfantryTypeAttribute - Sets attributes for infantry types * + * * + * SCRIPT INPUT: infantryTypeID (int) - The ID of the infantry type class * + * attribute_type (int) - The attribute to change * + * attribute_value (int) - The value to set the attribute to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetInfantryTypeAttribute(lua_State* L) { + + int infantryTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = InfantryTypes.Ptr(infantryTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_SetVesselTypeAttribute - Sets attributes for vessel types * + * * + * SCRIPT INPUT: vesselTypeID (int) - The ID of the vessel type class * + * attribute_type (int) - The attribute to change * + * attribute_value (int) - The value to set the attribute to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetVesselTypeAttribute(lua_State* L) { + + int vesselTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = VesselTypes.Ptr(vesselTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_SetAircraftTypeAttribute - Sets attributes for aircraft types * + * * + * SCRIPT INPUT: aircraftTypeID (int) - The ID of the aircraft type class * + * attribute_type (int) - The attribute to change * + * attribute_value (int) - The value to set the attribute to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetAircraftTypeAttribute(lua_State* L) { + + int aircraftTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = AircraftTypes.Ptr(aircraftTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_SetObjectTypeAttribute - Sets attributes for specific object types globally * + * * + * Used internally by MapScript to retrieve input and set attributes for TechnoTypeClass * + * * + * SCRIPT INPUT: this_type_class (TechnoTypeClass*) - The techno type * + * attribute_type (MapScriptAttributeType) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptAttributeType attribute_type) { + + switch (attribute_type) { + case ATTRIBUTE_MAX_STRENGTH: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->MaxStrength = attribute_value; + + }break; + + case ATTRIBUTE_COST: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->Cost = attribute_value; + + }break; + case ATTRIBUTE_SIGHT_RANGE: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->SightRange = attribute_value; + + }break; + case ATTRIBUTE_TECH_LEVEL: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->Level = attribute_value; + + }break; + case ATTRIBUTE_ARMOR: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->Armor = (ArmorType)attribute_value; + + }break; + case ATTRIBUTE_PRIMARY_WEAPON: { + + int attribute_value = lua_tointeger(L, 3); + + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->PrimaryWeapon = this_weapon; + } + + }break; + case ATTRIBUTE_SECONDARY_WEAPON: { + + int attribute_value = lua_tointeger(L, 3); + + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->SecondaryWeapon = this_weapon; + } + + }break; + case ATTRIBUTE_SPEED: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->Speed = (SpeedType)attribute_value; + + }break; + case ATTRIBUTE_MAX_SPEED: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->MaxSpeed = (MPHType)attribute_value; + + }break; + case ATTRIBUTE_MAX_AMMO: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->MaxAmmo = attribute_value; + + }break; + case ATTRIBUTE_ROTATION_SPEED: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->ROT = attribute_value; + + }break; + case ATTRIBUTE_IS_CRUSHABLE: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsCrushable = attribute_value; + + }break; + case ATTRIBUTE_IS_STEALTHY: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsStealthy = attribute_value; + + }break; + case ATTRIBUTE_IS_SELECTABLE: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsSelectable = attribute_value; + + }break; + case ATTRIBUTE_IS_LEGAL_TARGET: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsLegalTarget = attribute_value; + + }break; + case ATTRIBUTE_IS_REPAIRABLE: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsRepairable = attribute_value; + + }break; + case ATTRIBUTE_IS_SELF_HEALING: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsSelfHealing = attribute_value; + + }break; + case ATTRIBUTE_IS_EXPLODING: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsExploding = attribute_value; + + }break; + case ATTRIBUTE_HAS_CREW: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + this_type_class->IsCrew = attribute_value; + + }break; + case ATTRIBUTE_MAX_PASSENGERS: { + + int attribute_value = lua_tointeger(L, 3); + + this_type_class->MaxPassengers = attribute_value; + + }break; + + } + + + return -1; + } /********************************************************************************************** * Mission Utility Functions * @@ -4273,7 +4681,7 @@ } return -1; - } + } /*********************************************************************************************** * MapScript::CallFunction - Calls a given function within the current script * @@ -4472,11 +4880,21 @@ lua_register(L, "SetTriggerCallback", Script_SetTriggerCallback); // Initiates a given [callback] on an existing [trigger] // TODO: Make this work via name OR ID lua_register(L, "TriggerAddCell", Script_TriggerAddCell); // Initiates a given [callback] on an existing [trigger] - lua_register(L, "GetCellObject", Script_GetCellObject); // Gets an object (ID - building/vehicle/aircraft/infantry/vessel), if any, at [Cell/X],[Cell/Y] lua_register(L, "MergeTriggers", Script_MergeTriggers); // Combines the events of two triggers (for multi-event triggers :) lua_register(L, "GetTriggerByName", Script_GetTriggerByName); // Gets the ID of the trigger with a given name lua_register(L, "TriggerSetPersistence", Script_TriggerSetPersistence); // Does a trigger go on and on or just run once? + /********************************************************************************************** + * Object Functions * + *=============================================================================================*/ + lua_register(L, "GetCellObject", Script_GetCellObject); // Gets an object (ID - building/vehicle/aircraft/infantry/vessel), if any, at [Cell/X],[Cell/Y] + lua_register(L, "SetObjectAttribute", Script_SetObjectAttribute); // Sets an object's attributes (strength, etc.) + lua_register(L, "SetBuildingTypeAttribute", Script_SetBuildingTypeAttribute); // Sets the attribute of a Building type + lua_register(L, "SetVehicleTypeAttribute", Script_SetVehicleTypeAttribute); // Sets the attribute of a Vehicle type + lua_register(L, "SetInfantryTypeAttribute", Script_SetInfantryTypeAttribute); // Sets the attribute of an Infantry type + lua_register(L, "SetVesselTypeAttribute", Script_SetVesselTypeAttribute); // Sets the attribute of a Vessel type + lua_register(L, "SetAircraftTypeAttribute", Script_SetAircraftTypeAttribute); // Sets the attribute of an Aircraft type + /********************************************************************************************** * Mission Utility Functions * *=============================================================================================*/ diff --git a/code/REDALERT/MapScript.h b/code/REDALERT/MapScript.h index b3bf2d4..532a61b 100644 --- a/code/REDALERT/MapScript.h +++ b/code/REDALERT/MapScript.h @@ -43,6 +43,34 @@ private: lua_State* L; }; + + +// Enums +typedef enum MapScriptAttributeType : char { + ATTRIBUTE_NONE=0, + ATTRIBUTE_STRENGTH, + ATTRIBUTE_MAX_STRENGTH, + ATTRIBUTE_COST, + ATTRIBUTE_SIGHT_RANGE, + ATTRIBUTE_TECH_LEVEL, + ATTRIBUTE_ARMOR, + ATTRIBUTE_PRIMARY_WEAPON, + ATTRIBUTE_SECONDARY_WEAPON, + ATTRIBUTE_SPEED, + ATTRIBUTE_MAX_SPEED, + ATTRIBUTE_MAX_AMMO, + ATTRIBUTE_ROTATION_SPEED, + ATTRIBUTE_IS_CRUSHABLE, + ATTRIBUTE_IS_STEALTHY, + ATTRIBUTE_IS_SELECTABLE, + ATTRIBUTE_IS_LEGAL_TARGET, + ATTRIBUTE_IS_REPAIRABLE, + ATTRIBUTE_IS_SELF_HEALING, + ATTRIBUTE_IS_EXPLODING, + ATTRIBUTE_HAS_CREW, + ATTRIBUTE_MAX_PASSENGERS +} MapScriptAttributeType; + // Non-Class-Functions bool Script_SetObjectTrigger(int input_object_id, TriggerClass* input_trigger); ObjectClass* Script_GetCacheObject(int input_object_id); @@ -53,4 +81,7 @@ int Script_AircraftIndexFromID(int input_object_id); int Script_InfantryIndexFromID(int input_object_id); int Script_VesselIndexFromID(int input_object_id); +static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptAttributeType attribute_type); + + #endif \ No newline at end of file diff --git a/scripts/_Global.script b/scripts/_Global.script index e266642..230c731 100644 --- a/scripts/_Global.script +++ b/scripts/_Global.script @@ -194,3 +194,85 @@ TRIGGER_VOLATILE=0 TRIGGER_SEMI_PERSISTENT=1 TRIGGER_PERSISTENT=2 + + -- ********************************************************* + -- * * + -- * Attribite Types * + -- * * + -- ********************************************************* + ATTRIBUTE_NONE=0 + ATTRIBUTE_STRENGTH=1 -- Object attribute + ATTRIBUTE_MAX_STRENGTH=2 -- Definition attribute + ATTRIBUTE_COST=3 -- Definition attribute + ATTRIBUTE_SIGHT_RANGE=4 -- Definition attribute + ATTRIBUTE_TECH_LEVEL=5 -- Definition attribute + ATTRIBUTE_ARMOR=6 + ATTRIBUTE_PRIMARY_WEAPON=7 + ATTRIBUTE_SECONDARY_WEAPON=8 + ATTRIBUTE_SPEED=9 + ATTRIBUTE_MAX_SPEED=10 + ATTRIBUTE_MAX_AMMO=11 + ATTRIBUTE_ROTATION_SPEED=12 + ATTRIBUTE_IS_CRUSHABLE=13 + ATTRIBUTE_IS_STEALTHY=14 + ATTRIBUTE_IS_SELECTABLE=15 + ATTRIBUTE_IS_LEGAL_TARGET=16 + ATTRIBUTE_IS_REPAIRABLE=17 + ATTRIBUTE_IS_SELF_HEALING=18 + ATTRIBUTE_IS_EXPLODING=19 + ATTRIBUTE_HAS_CREW=20 + ATTRIBUTE_MAX_PASSENGERS=21 + + -- ********************************************************* + -- * * + -- * Armor Types * + -- * * + -- ********************************************************* + ARMOR_NONE=0 + ARMOR_WOOD=1 + ARMOR_ALUMINUM=2 + ARMOR_STEEL=3 + ARMOR_CONCRETE=4 + + -- ********************************************************* + -- * * + -- * Weapon Types * + -- * * + -- ********************************************************* + WEAPON_COLT45=0 + WEAPON_ACK_ACK=1 + WEAPON_VULCAN=2 + WEAPON_MAVERICK=3 + WEAPON_CAMERA=4 + WEAPON_FIREBALL=5 + WEAPON_RIFLE=6 + WEAPON_CHAIN_GUN=7 + WEAPON_PISTOL=8 + WEAPON_M16=9 + WEAPON_DRAGON=10 + WEAPON_HELLFIRE=11 + WEAPON_GRENADE=12 + WEAPON_75MM=13 + WEAPON_90MM=14 + WEAPON_105MM=15 + WEAPON_120MM=16 + WEAPON_TURRET_GUN=17 + WEAPON_MAMMOTH_TUSK=18 + WEAPON_155MM=19 + WEAPON_M60MG=20 + WEAPON_NAPALM=21 + WEAPON_TESLA_ZAP=22 + WEAPON_NIKE=23 + WEAPON_8INCH=24 + WEAPON_STINGER=25 + WEAPON_TORPEDO=26 + WEAPON_2INCH=27 + WEAPON_DEPTH_CHARGE=28 + WEAPON_PARA_BOMB=29 + WEAPON_DOGJAW=30 + WEAPON_HEAL=31 + WEAPON_SCUD=32 + WEAPON_FLAMER=33 + WEAPON_REDEYE=34 + + \ No newline at end of file From 19569faf2be061562bfa5b9c523d73266adea805 Mon Sep 17 00:00:00 2001 From: nev6502 Date: Sat, 27 Jun 2020 18:16:29 -0600 Subject: [PATCH 3/7] Added ability to change attributes for buildings, units, infantry, aircraft and veseels. Values are restored to default values by cacheing values upon first usage and cleaning up with Deinit(). Revised global header to encapsulate the values within sections, drastically reducing variable counts Mouse frequent click/drag fix --- code/redalert/io/userinput.cpp | 6 + code/redalert/mapscript.cpp | 552 +++++++++++++++++++++++++++++++-- code/redalert/mapscript.h | 57 +++- scripts/_Global.script | 519 +++++++++++++++++-------------- 4 files changed, 875 insertions(+), 259 deletions(-) diff --git a/code/redalert/io/userinput.cpp b/code/redalert/io/userinput.cpp index aadd59c..2f0ea73 100644 --- a/code/redalert/io/userinput.cpp +++ b/code/redalert/io/userinput.cpp @@ -58,6 +58,12 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) Keyboard->Put_Element(KN_LMOUSE); leftMouseProcessed = true; + + // Seems to fix "missed mouse click" bug + if (numFramesLMouse == 0) { + numFramesLMouse++; + return; + } numFramesLMouse++; } else if (event.button.button == SDL_BUTTON_RIGHT) { diff --git a/code/redalert/mapscript.cpp b/code/redalert/mapscript.cpp index fa5feb8..807fe15 100644 --- a/code/redalert/mapscript.cpp +++ b/code/redalert/mapscript.cpp @@ -1,5 +1,5 @@ -#include "FUNCTION.H" -#include "MapScript.h" +#include "function.H" +#include "mapscript.h" /********************************************************************************************** * Red Alert Vanilla Actions * @@ -3306,14 +3306,39 @@ - + // Global attributes / Multi object attributes switch ((MapScriptAttributeType)attribute_type) { + case ATTRIBUTE_TYPE: { + + }break; case ATTRIBUTE_STRENGTH: { int attribute_value = lua_tointeger(L, 3); this_object->Strength = attribute_value; }break; + + case ATTRIBUTE_IS_REPAIRING: { + + int attribute_value = lua_tointeger(L, 3); + + switch (this_object->RTTI) { + case RTTI_BUILDING: { + + BuildingClass* this_building = (BuildingClass*)this_object; + this_building->IsRepairing = attribute_value; + + }break; + case RTTI_VESSEL: { + + VesselClass* this_vessel = (VesselClass*)this_object; + this_vessel->IsSelfRepairing = attribute_value; + + }break; + } + }break; + + // Object Class specific default: { TechnoTypeClass* this_type_class; @@ -3344,7 +3369,7 @@ this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); break; - } + } if (this_type_class != NULL) { @@ -3531,6 +3556,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxStrength); + + // Set the attribute this_type_class->MaxStrength = attribute_value; }break; @@ -3539,6 +3568,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Cost); + + // Set the attribute this_type_class->Cost = attribute_value; }break; @@ -3546,6 +3579,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SightRange); + + // Set the attribute this_type_class->SightRange = attribute_value; }break; @@ -3553,6 +3590,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Level); + + // Set the attribute this_type_class->Level = attribute_value; }break; @@ -3560,6 +3601,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Armor); + + // Set the attribute this_type_class->Armor = (ArmorType)attribute_value; }break; @@ -3567,9 +3612,24 @@ int attribute_value = lua_tointeger(L, 3); - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->PrimaryWeapon = this_weapon; + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->PrimaryWeapon->ID); + }else { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } + + // Set the attribute + if (attribute_value < 0) { + this_type_class->PrimaryWeapon = NULL; + }else { + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->PrimaryWeapon = this_weapon; + }else { + this_type_class->PrimaryWeapon = NULL; + } } }break; @@ -3577,9 +3637,24 @@ int attribute_value = lua_tointeger(L, 3); - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->SecondaryWeapon = this_weapon; + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SecondaryWeapon->ID); + }else { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } + + // Set the attribute + if (attribute_value < 0) { + this_type_class->SecondaryWeapon = NULL; + }else{ + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->SecondaryWeapon = this_weapon; + }else { + this_type_class->SecondaryWeapon = NULL; + } } }break; @@ -3587,6 +3662,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Speed); + + // Set the attribute this_type_class->Speed = (SpeedType)attribute_value; }break; @@ -3594,6 +3673,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxSpeed); + + // Set the attribute this_type_class->MaxSpeed = (MPHType)attribute_value; }break; @@ -3601,6 +3684,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxAmmo); + + // Set the attribute this_type_class->MaxAmmo = attribute_value; }break; @@ -3608,55 +3695,87 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->ROT); + + // Set the attribute this_type_class->ROT = attribute_value; }break; - case ATTRIBUTE_IS_CRUSHABLE: { + case ATTRIBUTE_CRUSHABLE: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrushable); + + // Set the attribute this_type_class->IsCrushable = attribute_value; }break; - case ATTRIBUTE_IS_STEALTHY: { + case ATTRIBUTE_STEALTHY: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsStealthy); + + // Set the attribute this_type_class->IsStealthy = attribute_value; }break; - case ATTRIBUTE_IS_SELECTABLE: { + case ATTRIBUTE_SELECTABLE: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelectable); + + // Set the attribute this_type_class->IsSelectable = attribute_value; }break; - case ATTRIBUTE_IS_LEGAL_TARGET: { + case ATTRIBUTE_LEGAL_TARGET: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsLegalTarget); + + // Set the attribute this_type_class->IsLegalTarget = attribute_value; }break; - case ATTRIBUTE_IS_REPAIRABLE: { + case ATTRIBUTE_REPAIRABLE: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsRepairable); + + // Set the attribute this_type_class->IsRepairable = attribute_value; }break; - case ATTRIBUTE_IS_SELF_HEALING: { + case ATTRIBUTE_SELF_HEALING: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelfHealing); + + // Set the attribute this_type_class->IsSelfHealing = attribute_value; }break; - case ATTRIBUTE_IS_EXPLODING: { + case ATTRIBUTE_EXPLODES: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsExploding); + + // Set the attribute this_type_class->IsExploding = attribute_value; }break; @@ -3664,6 +3783,10 @@ unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrew); + + // Set the attribute this_type_class->IsCrew = attribute_value; }break; @@ -3671,14 +3794,312 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxPassengers); + + // Set the attribute this_type_class->MaxPassengers = attribute_value; }break; + default:{ + + // Object class specific attributes + // Welcome to the web of switches] + + // Type of object + switch (this_type_class->RTTI) { + + // Building Specific + case RTTI_BUILDINGTYPE:{ + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CAPACITY: { + + int attribute_value = lua_tointeger(L, 3); + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Capacity); + + // Set the attribute + this_building_class->Capacity = attribute_value; + + }break; + case ATTRIBUTE_POWER: { + + int attribute_value = lua_tointeger(L, 3); + + // Both power and drain are different variables + // And so we do some trickery here to fill + // the right values based on postivie/negative input + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Power + this_building_class->Drain); + + // Set the attribute + if (attribute_value > 0) { + this_building_class->Power = attribute_value; + this_building_class->Drain = 0; + }else { + this_building_class->Power = 0; + this_building_class->Drain = attribute_value * -1; // Flip negative power input + } + + }break; + case ATTRIBUTE_SELLABLE: { + + int attribute_value = lua_tointeger(L, 3); + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->IsUnsellable *-1); + + // Set the attribute + // Personal opinion; sellable makes more sense than unsellable + // This replacement could be seen as IsUnNonSellable, or... IsSellable + if (attribute_value == 1) { + this_building_class->IsUnsellable = 0; + } + else { + this_building_class->IsUnsellable = 1; + } + + }break; + } + + }break; + + + // Unit Specific + case RTTI_UNITTYPE:{ + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CRATE_GOODIE: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrateGoodie); + + // Set the attribute + this_unit_class->IsCrateGoodie = attribute_value; + + }break; + case ATTRIBUTE_CRUSHER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrusher); + + // Set the attribute + this_unit_class->IsCrusher = attribute_value; + + }break; + case ATTRIBUTE_HARVEST: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsToHarvest); + + // Set the attribute + this_unit_class->IsToHarvest = attribute_value; + + }break; + case ATTRIBUTE_RADAR_EQUIPPED: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsRadarEquipped); + + // Set the attribute + this_unit_class->IsRadarEquipped = attribute_value; + + }break; + case ATTRIBUTE_JAMMER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsJammer); + + // Set the attribute + this_unit_class->IsJammer = attribute_value; + + }break; + case ATTRIBUTE_GAPPER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsGapper); + + // Set the attribute + this_unit_class->IsGapper = attribute_value; + + }break; + } + + }break; + + + // Infantry Specific + case RTTI_INFANTRYTYPE:{ + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_FEMALE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFemale); + + // Set the attribute + this_infantry_class->IsFemale = attribute_value; + + }break; + case ATTRIBUTE_CAPTURE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCapture); + + // Set the attribute + this_infantry_class->IsCapture = attribute_value; + + }break; + case ATTRIBUTE_FRAIDY_CAT: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFraidyCat); + + // Set the attribute + this_infantry_class->IsFraidyCat = attribute_value; + + }break; + case ATTRIBUTE_CIVILIAN: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCivilian); + + // Set the attribute + this_infantry_class->IsCivilian = attribute_value; + + }break; + case ATTRIBUTE_BOMBER: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsBomber); + + // Set the attribute + this_infantry_class->IsBomber = attribute_value; + + }break; + case ATTRIBUTE_DOG: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsDog); + + // Set the attribute + this_infantry_class->IsDog = attribute_value; + + }break; + + } + + }break; + + } // End of object specific switch + + }break; + + } // End of attribute switch + + return -1; + } + + + /*********************************************************************************************** + * Script_CacheDefaultAttribute - Caches an attribute value upon first usage for restoration * + * * + * SCRIPT INPUT: input_rtti (RTTIType) - The RTTI type for the attrtibute * + * input_id (int) - The ID of the typeclass * + * input_attribute (int) - The attribute to cache * + * input_value (int) - The value if the cache item doesn't exist * + * * + * SCRIPT OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + void Script_CacheDefaultAttribute(RTTIType input_rtti, int input_id, MapScriptAttributeType input_attribute, int input_value) { + + bool cache_item_found = false; + for (std::vector::iterator it = Scen.mapScript->DefaultTypeAttributeCache.begin(); it != Scen.mapScript->DefaultTypeAttributeCache.end(); ++it) {//Error 2-4 + + MapScriptDefaultAttribute* cachedAttribute = (MapScriptDefaultAttribute*)(*it); + + if (input_rtti == cachedAttribute->RTTI && input_id == cachedAttribute->ID && input_attribute == cachedAttribute->attribute) { + cache_item_found = true; + break; + } } + // Cached attribute does not exist; let's cache! + if (!cache_item_found) { + + MapScriptDefaultAttribute* cachedAttribute = new MapScriptDefaultAttribute; + cachedAttribute->RTTI = input_rtti; + cachedAttribute->ID = input_id; + cachedAttribute->attribute = input_attribute; + cachedAttribute->value = input_value; + Scen.mapScript->DefaultTypeAttributeCache.push_back(cachedAttribute); + + } - return -1; } /********************************************************************************************** @@ -4744,6 +5165,7 @@ *=============================================================================================*/ void MapScript::Deinit() { + // Remove any cached objects for (int i = 0; i < ObjectCache.size(); ++i) { delete ObjectCache[i]; @@ -4751,6 +5173,92 @@ ObjectCache.clear(); + // Welcome back to the web of switches where we will restore any default + // attributes that were changed in the script + for (std::vector::iterator it = Scen.mapScript->DefaultTypeAttributeCache.begin(); it != Scen.mapScript->DefaultTypeAttributeCache.end(); ++it) {//Error 2-4 + + MapScriptDefaultAttribute* cachedAttribute = (MapScriptDefaultAttribute*)(*it); + + + + + + switch (cachedAttribute->RTTI) { + + case RTTI_BUILDINGTYPE: { + lua_getglobal(L, "SetBuildingTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_UNITTYPE: { + lua_getglobal(L, "SetUnitTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_INFANTRYTYPE: { + lua_getglobal(L, "SetInfantryTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_AIRCRAFTTYPE: { + lua_getglobal(L, "SetAircraftTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_VESSELTYPE: { + lua_getglobal(L, "SetVesselTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + + } + + + } + + + for (int index = 0; index < Warheads.Count(); index++) { + Warheads.Ptr(index)->Read_INI(RuleINI); + } + + for (int proj = 0; proj < BulletTypes.Count(); proj++) { + BulletTypes.Ptr(proj)->Read_INI(RuleINI); + } + + for (int windex = 0; windex < Weapons.Count(); windex++) { + Weapons.Ptr(windex)->Read_INI(RuleINI); + } + + for (int uindex = 0; uindex < UnitTypes.Count(); uindex++) { + UnitTypes.Ptr(uindex)->Read_INI(RuleINI); + } + + for (int iindex = 0; iindex < InfantryTypes.Count(); iindex++) { + InfantryTypes.Ptr(iindex)->Read_INI(RuleINI); + } + + for (int vindex = 0; vindex < VesselTypes.Count(); vindex++) { + VesselTypes.Ptr(vindex)->Read_INI(RuleINI); + } + + for (int aindex = 0; aindex < AircraftTypes.Count(); aindex++) { + AircraftTypes.Ptr(aindex)->Read_INI(RuleINI); + } + + for (int bindex = 0; bindex < BuildingTypes.Count(); bindex++) { + BuildingTypes.Ptr(bindex)->Read_INI(RuleINI); + } + } /*********************************************************************************************** @@ -4776,6 +5284,7 @@ // Load file if (luaL_loadfile(L, scriptName)){ + Console_Printf(lua_tostring(L, -1)); L = NULL; return false; } @@ -4789,6 +5298,7 @@ SetLuaPath(";scripts/?.script;"); if (lua_pcall(L, 0, 0, 0)) { + Console_Printf(lua_tostring(L, -1)); L = NULL; return false; } @@ -4796,6 +5306,9 @@ // Reserve object cache memory ObjectCache.reserve(2000); + // Reserve type attribute cache memory (to restore rules after script) + DefaultTypeAttributeCache.reserve(1000); + /********************************************************************************************** * Red Alert Vanilla Actions * *=============================================================================================*/ @@ -4894,6 +5407,9 @@ lua_register(L, "SetInfantryTypeAttribute", Script_SetInfantryTypeAttribute); // Sets the attribute of an Infantry type lua_register(L, "SetVesselTypeAttribute", Script_SetVesselTypeAttribute); // Sets the attribute of a Vessel type lua_register(L, "SetAircraftTypeAttribute", Script_SetAircraftTypeAttribute); // Sets the attribute of an Aircraft type + + + //lua_register(L, "GetObjectAttribute", Script_SetAircraftTypeAttribute); // Gets the attribute of an object /********************************************************************************************** * Mission Utility Functions * diff --git a/code/redalert/mapscript.h b/code/redalert/mapscript.h index 532a61b..5548a95 100644 --- a/code/redalert/mapscript.h +++ b/code/redalert/mapscript.h @@ -1,4 +1,4 @@ -// MapScript.h +// mapscript.h // #ifndef MAPSCRIPT_H @@ -20,6 +20,15 @@ struct MapScriptObject { RTTIType RTTI; // The type of object }; +// Stores defaults of rules from before +// variables were changed within +struct MapScriptDefaultAttribute { + RTTIType RTTI; // The type of object + int ID=-1; // The index of the object in its heap + int attribute; + int value; +}; + // // MapScript Class @@ -38,6 +47,7 @@ public: void SetLuaPath(const char* input_path); std::vector ObjectCache; + std::vector DefaultTypeAttributeCache; private: lua_State* L; @@ -47,7 +57,9 @@ private: // Enums typedef enum MapScriptAttributeType : char { - ATTRIBUTE_NONE=0, + + // Techno types + ATTRIBUTE_TYPE=0, ATTRIBUTE_STRENGTH, ATTRIBUTE_MAX_STRENGTH, ATTRIBUTE_COST, @@ -60,15 +72,39 @@ typedef enum MapScriptAttributeType : char { ATTRIBUTE_MAX_SPEED, ATTRIBUTE_MAX_AMMO, ATTRIBUTE_ROTATION_SPEED, - ATTRIBUTE_IS_CRUSHABLE, - ATTRIBUTE_IS_STEALTHY, - ATTRIBUTE_IS_SELECTABLE, - ATTRIBUTE_IS_LEGAL_TARGET, - ATTRIBUTE_IS_REPAIRABLE, - ATTRIBUTE_IS_SELF_HEALING, - ATTRIBUTE_IS_EXPLODING, + ATTRIBUTE_CRUSHABLE, + ATTRIBUTE_STEALTHY, + ATTRIBUTE_SELECTABLE, + ATTRIBUTE_LEGAL_TARGET, + ATTRIBUTE_REPAIRABLE, + ATTRIBUTE_SELF_HEALING, + ATTRIBUTE_EXPLODES, ATTRIBUTE_HAS_CREW, - ATTRIBUTE_MAX_PASSENGERS + ATTRIBUTE_MAX_PASSENGERS, + ATTRIBUTE_IS_REPAIRING, + + // Building Specific + ATTRIBUTE_CAPACITY, + ATTRIBUTE_POWER, + ATTRIBUTE_SELLABLE, + + // Unit Specific + ATTRIBUTE_CRATE_GOODIE, + ATTRIBUTE_CRUSHER, + ATTRIBUTE_HARVEST, + ATTRIBUTE_RADAR_EQUIPPED, + ATTRIBUTE_JAMMER, + ATTRIBUTE_GAPPER, + + // Infantry Specific + ATTRIBUTE_FEMALE, + ATTRIBUTE_CAPTURE, + ATTRIBUTE_FRAIDY_CAT, + ATTRIBUTE_CIVILIAN, + ATTRIBUTE_BOMBER, + ATTRIBUTE_DOG + + } MapScriptAttributeType; // Non-Class-Functions @@ -83,5 +119,6 @@ int Script_VesselIndexFromID(int input_object_id); static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptAttributeType attribute_type); +void Script_CacheDefaultAttribute(RTTIType input_rtti, int input_id, MapScriptAttributeType input_attribute, int input_value); #endif \ No newline at end of file diff --git a/scripts/_Global.script b/scripts/_Global.script index 230c731..f848203 100644 --- a/scripts/_Global.script +++ b/scripts/_Global.script @@ -4,115 +4,148 @@ -- * * -- *=======================================================* + -- ********************************************************* + -- * * + -- * Houses (players) * + -- * * + -- ********************************************************* + Houses={ + SPAIN=0, -- YELLOW/GOLD + GREECE=1, -- BLUE-GREY + USSR=2, -- RED + ENGLAND=3, -- GREEN + UKRAINE=4, -- ORANGE + GERMANY=5, -- KHAKI/LIGHT BROWN + FRANCE=6, -- AQUA + TURKEY=7, -- RED-OCHRE + GOODGUY=8, -- BLUE-GREY + BADGUY=9, -- RED + NEUTRAL=10, -- YELLOW/GOLD + SPECIAL=11, -- YELLOW/GOLD + MULTI1=12, -- YELLOW/GOLD + MULTI2=13, -- BLUE-GREY + MULTI3=14, -- RED + MULTI4=15, -- GREEN + MULTI5=16, -- ORANGE + MULTI6=17, -- KHAKI/LIGHT BROWN + MULTI7=18, -- AQUA + MULTI8=19 -- RED-OCHRE + } -- ********************************************************* -- * * -- * Buildings * -- * * -- ********************************************************* - - BUILDING_ATEK=0 -- Allied Technology Centre - BUILDING_IRON=1 -- Iron Curtain - BUILDING_WEAP=2 -- Weapons Factory - BUILDING_PDOX=3 -- Chronosphere - BUILDING_PBOX=4 -- Pillbox - BUILDING_HBOX=5 -- Camouflaged Pillbox - BUILDING_DOME=6 -- Radar Dome - BUILDING_GAP =7 -- Gap Generator - BUILDING_GUN =8 -- Gun Turret - BUILDING_AGUN=9 -- Anti-Aircraft Gun - BUILDING_FTUR=10 -- Flame Turret - BUILDING_FACT=11 -- Construction Yard - BUILDING_PROC=12 -- Ore Refinery - BUILDING_SILO=13 -- Ore Silo - BUILDING_HPAD=14 -- Helicopter Pad - BUILDING_SAM =15 -- SAM Site - BUILDING_AFLD=16 -- Airfield - BUILDING_POWR=17 -- Power Plant - BUILDING_APWR=18 -- Advanced Power Plant - BUILDING_STEK=19 -- Soviet Technology Centre - BUILDING_HOSP=20 -- Hospital - BUILDING_BARR=21 -- Barracks (Allied) - BUILDING_TENT=22 -- Barracks (Soviet) - BUILDING_KENN=23 -- Dog Kennel - BUILDING_FIX =24 -- Service Depot - BUILDING_BIO =25 -- Bio-Research Laboratory - BUILDING_MISS=26 -- Technology Centre/Prison - BUILDING_SYRD=27 -- Ship Yard - BUILDING_SPEN=28 -- Sub Pen - BUILDING_MSLO=29 -- Missile Silo - BUILDING_FCOM=30 -- Forward Command Post - BUILDING_TSLA=31 -- Tesla Coil - BUILDING_WEAF=32 -- Fake Weapons Factory - BUILDING_FACF=33 -- Fake Construction Yard - BUILDING_SYRF=34 -- Fake Ship Yard - BUILDING_SPEF=35 -- Fake Sub Pen - BUILDING_DOMF=36 -- Fake Radar Dome - BUILDING_MINV=43 -- Anti-vehicle mine - BUILDING_MINP=44 -- Anti-personnel mine + + BuildingTypes={ + ATEK=0, -- Allied Technology Centre + IRON=1, -- Iron Curtain + WEAP=2, -- Weapons Factory + PDOX=3, -- Chronosphere + PBOX=4, -- Pillbox + HBOX=5, -- Camouflaged Pillbox + DOME=6, -- Radar Dome + GAP =7, -- Gap Generator + GUN =8, -- Gun Turret + AGUN=9, -- Anti-Aircraft Gun + FTUR=10, -- Flame Turret + FACT=11, -- Construction Yard + PROC=12, -- Ore Refinery + SILO=13, -- Ore Silo + HPAD=14, -- Helicopter Pad + SAM =15, -- SAM Site + AFLD=16, -- Airfield + POWR=17, -- Power Plant + APWR=18, -- Advanced Power Plant + STEK=19, -- Soviet Technology Centre + HOSP=20, -- Hospital + BARR=21, -- Barracks (Allied) + TENT=22, -- Barracks (Soviet) + KENN=23, -- Dog Kennel + FIX =24, -- Service Depot + BIO =25, -- Bio-Research Laboratory + MISS=26, -- Technology Centre/Prison + SYRD=27, -- Ship Yard + SPEN=28, -- Sub Pen + MSLO=29, -- Missile Silo + FCOM=30, -- Forward Command Post + TSLA=31, -- Tesla Coil + WEAF=32, -- Fake Weapons Factory + FACF=33, -- Fake Construction Yard + SYRF=34, -- Fake Ship Yard + SPEF=35, -- Fake Sub Pen + DOMF=36, -- Fake Radar Dome + MINV=43, -- Anti-vehicle mine + MINP=44, -- Anti-personnel mine -- Counterstrike - BUILDING_QUEE=84 -- Queen ant structure - BUILDING_LAR1=85 -- Ant - single ant larva - BUILDING_LAR2=86 -- Ant - two ant larvae - + QUEE=84, -- Queen ant structure + LAR1=85, -- Ant - single ant larva + LAR2=86 -- Ant - two ant larvae + } + -- ********************************************************* -- * * -- * Infantry * -- * * -- ********************************************************* - INFANTRY_E1=0 -- Rifle Infantry - INFANTRY_E2=1 -- Grenadier - INFANTRY_E3=2 -- Rocket Soldier - INFANTRY_E4=3 -- Flamethrower - INFANTRY_E6=4 -- Engineer - INFANTRY_E7=5 -- Tanya - INFANTRY_SPY=6 -- Spy - INFANTRY_THF=7 -- Thief - INFANTRY_MEDI=8 -- Field Medic - INFANTRY_GNRL=9 -- General - INFANTRY_DOG=10 -- Attack Dog - INFANTRY_C1=11 -- Joe - INFANTRY_C2=12 -- Barry - INFANTRY_C3=13 -- Shelly - INFANTRY_C4=14 -- Maria - INFANTRY_C5=15 -- Karen - INFANTRY_C6=16 -- Steve - INFANTRY_C7=17 -- Phil - INFANTRY_C8=18 -- Dwight - INFANTRY_C9=19 -- Erik - INFANTRY_C10=20 -- Scientist - INFANTRY_EINSTEIN=21 -- Prof. Einstein - INFANTRY_DELPHI=22 -- Special 1 - INFANTRY_CHAN=23 -- Special 2 - + InfantryTypes={ + E1=0, -- Rifle Infantry + E2=1, -- Grenadier + E3=2, -- Rocket Soldier + E4=3, -- Flamethrower + E6=4, -- Engineer + E7=5, -- Tanya + SPY=6, -- Spy + THF=7, -- Thief + MEDI=8, -- Field Medic + GNRL=9, -- General + DOG=10, -- Attack Dog + C1=11, -- Joe + C2=12, -- Barry + C3=13, -- Shelly + C4=14, -- Maria + C5=15, -- Karen + C6=16, -- Steve + C7=17, -- Phil + C8=18, -- Dwight + C9=19, -- Erik + C10=20, -- Scientist + EINSTEIN=21, -- Prof. Einstein + DELPHI=22, -- Special 1 + CHAN=23 -- Special 2 + } + -- ********************************************************* -- * * -- * Vehicle * -- * * -- ********************************************************* - VEHICLE_4TNK=0 -- Mammoth Tank - VEHICLE_3TNK=1 -- Heavy Tank - VEHICLE_2TNK=2 -- Medium Tank - VEHICLE_1TNK=3 -- Light Tank - VEHICLE_APC=4 -- Armoured Personnel Carrier - VEHICLE_MNLY=5 -- Mine Layer - VEHICLE_JEEP=6 -- Ranger - VEHICLE_HARV=7 -- Ore Truck - VEHICLE_ARTY=8 -- Artillery - VEHICLE_MRJ=9 -- Mobile Radar Jammer - VEHICLE_MGG=10 -- Mobile Gap Generator - VEHICLE_MCV=11 -- Mobile Construction Vehicle - VEHICLE_2VRL=12 -- V2 Rocket Launcher - VEHICLE_TRUK=13 -- Convoy Truck + VehicleTypes={ + _4TNK=0, -- Mammoth Tank + _3TNK=1, -- Heavy Tank + _2TNK=2, -- Medium Tank + _1TNK=3, -- Light Tank + APC=4, -- Armoured Personnel Carrier + MNLY=5, -- Mine Layer + JEEP=6, -- Ranger + HARV=7, -- Ore Truck + ARTY=8, -- Artillery + MRJ=9, -- Mobile Radar Jammer + MGG=10, -- Mobile Gap Generator + MCV=11, -- Mobile Construction Vehicle + _2VRL=12, -- V2 Rocket Launcher + TRUK=13, -- Convoy Truck -- Counterstrike only: - VEHICLE_ANT1=14 -- First ant type - VEHICLE_ANT2=15 -- Second ant type - VEHICLE_ANT3=16 -- Third ant type + ANT1=14, -- First ant type + ANT2=15, -- Second ant type + ANT3=16 -- Third ant type + } -- ********************************************************* -- * * @@ -120,159 +153,183 @@ -- * * -- ********************************************************* - AIRCRAFT_TRAN=0 -- Chinook Helicopter - AIRCRAFT_BADR=1 -- Badger Bomber - AIRCRAFT_U2=2 -- Spy Plane - AIRCRAFT_MIG=3 -- MIG Attack Plane - AIRCRAFT_YAK=4 -- Yak Attack Plane - AIRCRAFT_HELI=5 -- Longbow Helicopter - AIRCRAFT_HIND=6 -- Hind Helicopter - - -- ********************************************************* - -- * * - -- * Houses (players) * - -- * * - -- ********************************************************* - - HOUSE_SPAIN= 0 -- YELLOW/GOLD - HOUSE_GREECE=1 -- BLUE-GREY - HOUSE_USSR=2 -- RED - HOUSE_ENGLAND=3 -- GREEN - HOUSE_UKRAINE=4 -- ORANGE - HOUSE_GERMANY=5 -- KHAKI/LIGHT BROWN - HOUSE_FRANCE=6 -- AQUA - HOUSE_TURKEY=7 -- RED-OCHRE - HOUSE_GOODGUY=8 -- BLUE-GREY - HOUSE_BADGUY=9 -- RED - HOUSE_NEUTRAL=10 -- YELLOW/GOLD - HOUSE_SPECIAL=11 -- YELLOW/GOLD - HOUSE_MULTI1=12 -- YELLOW/GOLD - HOUSE_MULTI2=13 -- BLUE-GREY - HOUSE_MULTI3=14 -- RED - HOUSE_MULTI4=15 -- GREEN - HOUSE_MULTI5=16 -- ORANGE - HOUSE_MULTI6=17 -- KHAKI/LIGHT BROWN - HOUSE_MULTI7=18 -- AQUA - HOUSE_MULTI8=19 -- RED-OCHRE - - -- ********************************************************* - -- * * - -- * Special weapons * - -- * * - -- ********************************************************* - SPECIAL_WEAPON_SONAR=0 - SPECIAL_WEAPON_NUKE=1 - SPECIAL_WEAPON_CHRONO=2 - SPECIAL_WEAPON_PARABOMB=3 - SPECIAL_WEAPON_PARATROOPS=4 - SPECIAL_WEAPON_SPY_PLANE=5 - SPECIAL_WEAPON_IRON_CURTAIN=6 - SPECIAL_WEAPON_GPS=7 - - -- ********************************************************* - -- * * - -- * Target types (for use with DesignatePreferredTarget) * - -- * * - -- ********************************************************* - TARGET_TYPE_ANYTHING=1 - TARGET_TYPE_BUILDINGS=2 - TARGET_TYPE_HARVESTERS=3 - TARGET_TYPE_INFANTRY=4 - TARGET_TYPE_VEHICLES=5 - TARGET_TYPE_SHIPS=6 - TARGET_TYPE_FACTORIES=7 - TARGET_TYPE_BASE_DEFENCES=8 - TARGET_TYPE_BASE_THREATS=9 - TARGET_TYPE_POWER=10 - TARGET_TYPE_FAKE_BUILDINGS=11 - - -- ********************************************************* - -- * * - -- * Trigger persistance * - -- * * - -- ********************************************************* - TRIGGER_VOLATILE=0 - TRIGGER_SEMI_PERSISTENT=1 - TRIGGER_PERSISTENT=2 - - -- ********************************************************* - -- * * - -- * Attribite Types * - -- * * - -- ********************************************************* - ATTRIBUTE_NONE=0 - ATTRIBUTE_STRENGTH=1 -- Object attribute - ATTRIBUTE_MAX_STRENGTH=2 -- Definition attribute - ATTRIBUTE_COST=3 -- Definition attribute - ATTRIBUTE_SIGHT_RANGE=4 -- Definition attribute - ATTRIBUTE_TECH_LEVEL=5 -- Definition attribute - ATTRIBUTE_ARMOR=6 - ATTRIBUTE_PRIMARY_WEAPON=7 - ATTRIBUTE_SECONDARY_WEAPON=8 - ATTRIBUTE_SPEED=9 - ATTRIBUTE_MAX_SPEED=10 - ATTRIBUTE_MAX_AMMO=11 - ATTRIBUTE_ROTATION_SPEED=12 - ATTRIBUTE_IS_CRUSHABLE=13 - ATTRIBUTE_IS_STEALTHY=14 - ATTRIBUTE_IS_SELECTABLE=15 - ATTRIBUTE_IS_LEGAL_TARGET=16 - ATTRIBUTE_IS_REPAIRABLE=17 - ATTRIBUTE_IS_SELF_HEALING=18 - ATTRIBUTE_IS_EXPLODING=19 - ATTRIBUTE_HAS_CREW=20 - ATTRIBUTE_MAX_PASSENGERS=21 - + AircraftTypes={ + TRAN=0, -- Chinook Helicopter + BADR=1, -- Badger Bomber + U2=2, -- Spy Plane + MIG=3, -- MIG Attack Plane + YAK=4, -- Yak Attack Plane + HELI=5, -- Longbow Helicopter + HIND=6, -- Hind Helicopter + } + -- ********************************************************* -- * * -- * Armor Types * -- * * -- ********************************************************* - ARMOR_NONE=0 - ARMOR_WOOD=1 - ARMOR_ALUMINUM=2 - ARMOR_STEEL=3 - ARMOR_CONCRETE=4 - + ArmorTypes={ + NONE=0, + WOOD=1, + ALUMINUM=2, + STEEL=3, + CONCRETE=4 + } + -- ********************************************************* -- * * -- * Weapon Types * -- * * -- ********************************************************* - WEAPON_COLT45=0 - WEAPON_ACK_ACK=1 - WEAPON_VULCAN=2 - WEAPON_MAVERICK=3 - WEAPON_CAMERA=4 - WEAPON_FIREBALL=5 - WEAPON_RIFLE=6 - WEAPON_CHAIN_GUN=7 - WEAPON_PISTOL=8 - WEAPON_M16=9 - WEAPON_DRAGON=10 - WEAPON_HELLFIRE=11 - WEAPON_GRENADE=12 - WEAPON_75MM=13 - WEAPON_90MM=14 - WEAPON_105MM=15 - WEAPON_120MM=16 - WEAPON_TURRET_GUN=17 - WEAPON_MAMMOTH_TUSK=18 - WEAPON_155MM=19 - WEAPON_M60MG=20 - WEAPON_NAPALM=21 - WEAPON_TESLA_ZAP=22 - WEAPON_NIKE=23 - WEAPON_8INCH=24 - WEAPON_STINGER=25 - WEAPON_TORPEDO=26 - WEAPON_2INCH=27 - WEAPON_DEPTH_CHARGE=28 - WEAPON_PARA_BOMB=29 - WEAPON_DOGJAW=30 - WEAPON_HEAL=31 - WEAPON_SCUD=32 - WEAPON_FLAMER=33 - WEAPON_REDEYE=34 + WeaponTypes={ + NONE=-1, + COLT45=0, + ACK_ACK=1, + VULCAN=2, + MAVERICK=3, + CAMERA=4, + FIREBALL=5, + RIFLE=6, + CHAIN_GUN=7, + PISTOL=8, + M16=9, + DRAGON=10, + HELLFIRE=11, + GRENADE=12, + _75MM=13, + _90MM=14, + _105MM=15, + _120MM=16, + TURRET_GUN=17, + MAMMOTH_TUSK=18, + _155MM=19, + M60MG=20, + NAPALM=21, + TESLA_ZAP=22, + NIKE=23, + _8INCH=24, + STINGER=25, + TORPEDO=26, + _2INCH=27, + DEPTH_CHARGE=28, + PARA_BOMB=29, + DOGJAW=30, + HEAL=31, + SCUD=32, + FLAMER=33, + REDEYE=34 + } + + + + -- ********************************************************* + -- * * + -- * Special weapons * + -- * * + -- ********************************************************* + SpecialWeapons={ + Sonar=0, + Nuke=1, + Chrono=2, + Parabomb=3, + Paratroops=4, + SpyPlane=5, + IronCurtain=6, + GPS=7 + } + + -- ********************************************************* + -- * * + -- * Target types (for use with DesignatePreferredTarget) * + -- * * + -- ********************************************************* + TargetTypes={ + Anything=1, + Buildings=2, + Harvesters=3, + Infantry=4, + Vehicles=5, + Ships=6, + Factories=7, + BaseDefences=8, + BaseThreats=9, + Power=10, + FakeBuildings=11 + } + + -- ********************************************************* + -- * * + -- * Trigger persistance * + -- * * + -- ********************************************************* + PersistenceTypes={ + Volatile=0, + SemiPersistent=1, + Persistent=2 + } + + -- ********************************************************* + -- * * + -- * Attribite Types * + -- * * + -- ********************************************************* + Attributes = { + Type=0, + Strength=1, -- Object attribute + MaxStrength=2, -- Definition attribute + Cost=3, -- Definition attribute + SightRange=4, -- Definition attribute + TechLevel=5, -- Definition attribute + Armor=6, + PrimaryWeapon=7, + SecondaryWeapon=8, + Speed=9, + MaxSpeed=10, + MaxAmmo=11, + RotationSpeed=12, + IsCrushable=13, + IsStealthy=14, + IsSelectable=15, + IsLegalTarget=16, + IsRepairable=17, + IsSelfHealing=18, + Explodes=19, + HasCrew=20, + MaxPassengers=21, + IsRepairing=22, + + -- Building Specific + Capacity=23, + Power=24, + Sellable=25, - \ No newline at end of file + -- Unit Specific + IsCrateGoodie=26, + IsCrusher=27, + IsHarvest=28, + IsRadarEquipped=29, + IsJammer=30, + IsGapper=31, + + -- Infantry Specific + IsFemale=32, + Capture=33, + IsFraidyCat=34, + IsCivilian=35, + IsBomber=36, + IsDog=37 + + } + + -- ********************************************************* + -- * * + -- * Fear Type Attribute Values * + -- * * + -- ********************************************************* + FearTypes={ + None=0, -- No fear at all (default state). + Anxious=10, -- Something makes them scared. + Scared=100, -- Scared enough to take cover. + Panic=200, -- Run away! Run away! + Maximum=255 -- Scared to death. + } \ No newline at end of file From 678d78400424c3a99468defeca5c136035755979 Mon Sep 17 00:00:00 2001 From: nev6502 Date: Sun, 28 Jun 2020 15:35:10 -0600 Subject: [PATCH 4/7] Added To_Float to fixed point class. This is to help with certain house values to/from Lua but may have other uses. Added ability to create objects out of thin air, and force factories to produce units. Added ability to issue movement commands to units. Updated object cache system to use an incremental UID for retrieval / passing ID back to the script, as ID collisions were occuring. --- code/redalert/fixed.cpp | 29 + code/redalert/fixed.h | 5 + code/redalert/mapscript.cpp | 2493 ++++++++++++++++++++++++++++++----- code/redalert/mapscript.h | 66 +- scripts/_Global.script | 64 +- 5 files changed, 2302 insertions(+), 355 deletions(-) diff --git a/code/redalert/fixed.cpp b/code/redalert/fixed.cpp index e8add29..abf18cd 100644 --- a/code/redalert/fixed.cpp +++ b/code/redalert/fixed.cpp @@ -32,6 +32,7 @@ * Functions: * * fixed::As_ASCII -- Returns a pointer (static) of this number as an ASCII string. * * fixed::To_ASCII -- Convert a fixed point number into an ASCII string. * + * fixed::To_Float -- Convert a fixed point number into a float value * * fixed::fixed -- Constructor for fixed integral from ASCII initializer. * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -40,6 +41,7 @@ #include #include #include +#include /* @@ -148,6 +150,33 @@ fixed::fixed(char const * ascii) } +/*********************************************************************************************** + * fixed::To_Float -- Convert a fixed point number into a float * + * * + * Use this routine to convert this fixed point number into a float. This can be lossy for * + * fine values. * + * * + * INPUT: none * + * * + * OUTPUT: Returns with the float value of this fixed point number * + * * + * WARNINGS: none * + * * + * HISTORY: * + * 06/27/2020 JJ : Created. * + *=============================================================================================*/ +float fixed::To_Float() const +{ + + unsigned int whole = Data.Composite.Whole; + unsigned int frac = ((unsigned int)Data.Composite.Fraction * 1000U) / PRECISION; + + float this_raw_value = (whole + (frac * .001)); + + return floor(this_raw_value * 100.0 + 0.5) / 100.0; + +} + /*********************************************************************************************** * fixed::To_ASCII -- Convert a fixed point number into an ASCII string. * * * diff --git a/code/redalert/fixed.h b/code/redalert/fixed.h index b141508..3b2ec81 100644 --- a/code/redalert/fixed.h +++ b/code/redalert/fixed.h @@ -206,6 +206,11 @@ class fixed int To_ASCII(char * buffer, int maxlen=-1) const; char const * As_ASCII(void) const; + /* + ** Helper function to convert fixed point number to float (JJ) + */ + float To_Float() const; + /* ** Helper constants that provide some convenient fixed point values. */ diff --git a/code/redalert/mapscript.cpp b/code/redalert/mapscript.cpp index 807fe15..1489e7f 100644 --- a/code/redalert/mapscript.cpp +++ b/code/redalert/mapscript.cpp @@ -3024,7 +3024,7 @@ return 1; } - MapScriptObject* CacheObject = new MapScriptObject; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); CacheObject->ID = this_object->ID; CacheObject->RTTI = this_object->RTTI; @@ -3054,7 +3054,7 @@ } else { Scen.mapScript->ObjectCache.push_back(CacheObject); - lua_pushnumber(L, CacheObject->ID); // Return index for ultrafast lookup + lua_pushnumber(L, CacheObject->UID); // Return UID for faster lookup } return 1; @@ -3277,7 +3277,7 @@ *=============================================================================================*/ /********************************************************************************************** - * Script_SetObjectAttribute - Sets attributes for specific objects * + * Script_SetObjectAttribute - Sets attributes for specific objects or object types * * * * SCRIPT INPUT: objectID (int) - The ID of the object * * attribute_type (int) - The attribute to change * @@ -3299,15 +3299,11 @@ ObjectClass* this_object = Script_GetCacheObject(objectID); - - // Get the appropriate technotype if (this_object != NULL) { - - // Global attributes / Multi object attributes - switch ((MapScriptAttributeType)attribute_type) { + switch ((MapScriptObjectAttributeType)attribute_type) { case ATTRIBUTE_TYPE: { }break; @@ -3373,7 +3369,7 @@ if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); } }break; @@ -3410,7 +3406,7 @@ TechnoTypeClass* this_type_class = BuildingTypes.Ptr(buildingTypeID); if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); } return -1; @@ -3440,7 +3436,7 @@ TechnoTypeClass* this_type_class = UnitTypes.Ptr(vehicleTypeID); if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); } return -1; @@ -3470,7 +3466,7 @@ TechnoTypeClass* this_type_class = InfantryTypes.Ptr(infantryTypeID); if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); } return -1; @@ -3500,7 +3496,7 @@ TechnoTypeClass* this_type_class = VesselTypes.Ptr(vesselTypeID); if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); } return -1; @@ -3530,343 +3526,1025 @@ TechnoTypeClass* this_type_class = AircraftTypes.Ptr(aircraftTypeID); if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptAttributeType)attribute_type); + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); } return -1; } - + /********************************************************************************************** * Script_SetObjectTypeAttribute - Sets attributes for specific object types globally * * * * Used internally by MapScript to retrieve input and set attributes for TechnoTypeClass * * * * SCRIPT INPUT: this_type_class (TechnoTypeClass*) - The techno type * - * attribute_type (MapScriptAttributeType) - The attribute to change * + * attribute_type (MapScriptObjectAttributeType) - The attribute to change * * * * SCRIPT OUTPUT: void * * * * WARNINGS: ? * * * *=============================================================================================*/ - static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptAttributeType attribute_type) { + static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type) { + + switch (attribute_type) { + case ATTRIBUTE_MAX_STRENGTH: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxStrength); + + // Set the attribute + this_type_class->MaxStrength = attribute_value; + + }break; + + case ATTRIBUTE_COST: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Cost); + + // Set the attribute + this_type_class->Cost = attribute_value; + + }break; + case ATTRIBUTE_SIGHT_RANGE: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SightRange); + + // Set the attribute + this_type_class->SightRange = attribute_value; + + }break; + case ATTRIBUTE_TECH_LEVEL: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Level); + + // Set the attribute + this_type_class->Level = attribute_value; + + }break; + case ATTRIBUTE_ARMOR: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Armor); + + // Set the attribute + this_type_class->Armor = (ArmorType)attribute_value; + + }break; + case ATTRIBUTE_PRIMARY_WEAPON: { + + int attribute_value = lua_tointeger(L, 3); + + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->PrimaryWeapon->ID); + } + else { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } + + // Set the attribute + if (attribute_value < 0) { + this_type_class->PrimaryWeapon = NULL; + } + else { + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->PrimaryWeapon = this_weapon; + } + else { + this_type_class->PrimaryWeapon = NULL; + } + } + + }break; + case ATTRIBUTE_SECONDARY_WEAPON: { + + int attribute_value = lua_tointeger(L, 3); + + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SecondaryWeapon->ID); + } + else { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } + + // Set the attribute + if (attribute_value < 0) { + this_type_class->SecondaryWeapon = NULL; + } + else { + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->SecondaryWeapon = this_weapon; + } + else { + this_type_class->SecondaryWeapon = NULL; + } + } + + }break; + case ATTRIBUTE_SPEED: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Speed); + + // Set the attribute + this_type_class->Speed = (SpeedType)attribute_value; + + }break; + case ATTRIBUTE_MAX_SPEED: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxSpeed); + + // Set the attribute + this_type_class->MaxSpeed = (MPHType)attribute_value; + + }break; + case ATTRIBUTE_MAX_AMMO: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxAmmo); + + // Set the attribute + this_type_class->MaxAmmo = attribute_value; + + }break; + case ATTRIBUTE_ROTATION_SPEED: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->ROT); + + // Set the attribute + this_type_class->ROT = attribute_value; + + }break; + case ATTRIBUTE_CRUSHABLE: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrushable); + + // Set the attribute + this_type_class->IsCrushable = attribute_value; + + }break; + case ATTRIBUTE_STEALTHY: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsStealthy); + + // Set the attribute + this_type_class->IsStealthy = attribute_value; + + }break; + case ATTRIBUTE_SELECTABLE: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelectable); + + // Set the attribute + this_type_class->IsSelectable = attribute_value; + + }break; + case ATTRIBUTE_LEGAL_TARGET: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsLegalTarget); + + // Set the attribute + this_type_class->IsLegalTarget = attribute_value; + + }break; + case ATTRIBUTE_REPAIRABLE: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsRepairable); + + // Set the attribute + this_type_class->IsRepairable = attribute_value; + + }break; + case ATTRIBUTE_SELF_HEALING: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelfHealing); + + // Set the attribute + this_type_class->IsSelfHealing = attribute_value; + + }break; + case ATTRIBUTE_EXPLODES: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsExploding); + + // Set the attribute + this_type_class->IsExploding = attribute_value; + + }break; + case ATTRIBUTE_HAS_CREW: { + + unsigned int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrew); + + // Set the attribute + this_type_class->IsCrew = attribute_value; + + }break; + case ATTRIBUTE_MAX_PASSENGERS: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxPassengers); + + // Set the attribute + this_type_class->MaxPassengers = attribute_value; + + }break; + default: { + + // Object class specific attributes + // Welcome to the web of switches] + + // Type of object + switch (this_type_class->RTTI) { + + // Building Specific + case RTTI_BUILDINGTYPE: { + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CAPACITY: { + + int attribute_value = lua_tointeger(L, 3); + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Capacity); + + // Set the attribute + this_building_class->Capacity = attribute_value; + + }break; + case ATTRIBUTE_POWER: { + + int attribute_value = lua_tointeger(L, 3); + + // Both power and drain are different variables + // And so we do some trickery here to fill + // the right values based on postivie/negative input + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Power - this_building_class->Drain); + + // Set the attribute + if (attribute_value > 0) { + this_building_class->Power = attribute_value; + this_building_class->Drain = 0; + } + else { + this_building_class->Power = 0; + this_building_class->Drain = attribute_value * -1; // Flip negative power input + } + + }break; + case ATTRIBUTE_SELLABLE: { + + int attribute_value = lua_tointeger(L, 3); + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->IsUnsellable * -1); + + // Set the attribute + // Personal opinion; sellable makes more sense than unsellable + // This replacement could be seen as IsUnNonSellable, or... IsSellable + if (attribute_value == 1) { + this_building_class->IsUnsellable = 0; + } + else { + this_building_class->IsUnsellable = 1; + } + + }break; + } + + }break; + + + // Unit Specific + case RTTI_UNITTYPE: { + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CRATE_GOODIE: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrateGoodie); + + // Set the attribute + this_unit_class->IsCrateGoodie = attribute_value; + + }break; + case ATTRIBUTE_CRUSHER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrusher); + + // Set the attribute + this_unit_class->IsCrusher = attribute_value; + + }break; + case ATTRIBUTE_HARVEST: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsToHarvest); + + // Set the attribute + this_unit_class->IsToHarvest = attribute_value; + + }break; + case ATTRIBUTE_RADAR_EQUIPPED: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsRadarEquipped); + + // Set the attribute + this_unit_class->IsRadarEquipped = attribute_value; + + }break; + case ATTRIBUTE_JAMMER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsJammer); + + // Set the attribute + this_unit_class->IsJammer = attribute_value; + + }break; + case ATTRIBUTE_GAPPER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsGapper); + + // Set the attribute + this_unit_class->IsGapper = attribute_value; + + }break; + } + + }break; + + + // Infantry Specific + case RTTI_INFANTRYTYPE: { + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_FEMALE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFemale); + + // Set the attribute + this_infantry_class->IsFemale = attribute_value; + + }break; + case ATTRIBUTE_CAPTURE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCapture); + + // Set the attribute + this_infantry_class->IsCapture = attribute_value; + + }break; + case ATTRIBUTE_FRAIDY_CAT: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFraidyCat); + + // Set the attribute + this_infantry_class->IsFraidyCat = attribute_value; + + }break; + case ATTRIBUTE_CIVILIAN: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCivilian); + + // Set the attribute + this_infantry_class->IsCivilian = attribute_value; + + }break; + case ATTRIBUTE_BOMBER: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsBomber); + + // Set the attribute + this_infantry_class->IsBomber = attribute_value; + + }break; + case ATTRIBUTE_DOG: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsDog); + + // Set the attribute + this_infantry_class->IsDog = attribute_value; + + }break; + + } + + }break; + + } // End of object specific switch + + }break; + + } // End of attribute switch + + return -1; + } + + /********************************************************************************************** + * Script_GetObjectAttribute - Gets attributes for specific objects or object types * + * * + * SCRIPT INPUT: objectID (int) - The ID of the object * + * attribute_type (int) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetObjectAttribute(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + // Get the appropriate technotype + if (this_object != NULL) { + + // Global attributes / Multi object attributes + switch ((MapScriptObjectAttributeType)attribute_type) { + case ATTRIBUTE_TYPE: { + + // Send the attribute + lua_pushinteger(L, this_object->RTTI); + return 1; + + }break; + case ATTRIBUTE_STRENGTH: { + + // Send the attribute + lua_pushinteger(L, this_object->Strength); + return 1; + + }break; + + case ATTRIBUTE_IS_REPAIRING: { + + switch (this_object->RTTI) { + case RTTI_BUILDING: { + + BuildingClass* this_building = (BuildingClass*)this_object; + + // Send the attribute + lua_pushinteger(L, this_building->IsRepairing); + return 1; + + }break; + case RTTI_VESSEL: { + + VesselClass* this_vessel = (VesselClass*)this_object; + + // Send the attribute + lua_pushinteger(L, this_vessel->IsSelfRepairing); + return 1; + + }break; + } + }break; + + // Object Class specific + default: { + + TechnoTypeClass* this_type_class = NULL; + + switch (this_object->RTTI) { + case RTTI_BUILDING: + + this_type_class = BuildingTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_UNIT: + + this_type_class = UnitTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_INFANTRY: + + this_type_class = InfantryTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_VESSEL: + + this_type_class = VesselTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_AIRCRAFT: + + this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); + + break; + } + + // Type attribute retrieval + if (this_type_class != NULL) { + return Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + }break; + + } + + } + + + return -1; + } + + /********************************************************************************************** + * Script_GetBuildingTypeAttribute - Gets attributes for a building types * + * * + * SCRIPT INPUT: buildingTypeID (int) - The ID of the building type class * + * attribute_type (int) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetBuildingTypeAttribute(lua_State* L) { + + int buildingTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = BuildingTypes.Ptr(buildingTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_GetVehicleTypeAttribute - Gets attributes for vehicle types * + * * + * SCRIPT INPUT: vehicleTypeID (int) - The ID of the vehicle type class * + * attribute_type (int) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetVehicleTypeAttribute(lua_State* L) { + + int vehicleTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = UnitTypes.Ptr(vehicleTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_GetInfantryTypeAttribute - Gets attributes for infantry types * + * * + * SCRIPT INPUT: infantryTypeID (int) - The ID of the infantry type class * + * attribute_type (int) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetInfantryTypeAttribute(lua_State* L) { + + int infantryTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = InfantryTypes.Ptr(infantryTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_GetVesselTypeAttribute - Gets attributes for vessel types * + * * + * SCRIPT INPUT: vesselTypeID (int) - The ID of the vessel type class * + * attribute_type (int) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetVesselTypeAttribute(lua_State* L) { + + int vesselTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = VesselTypes.Ptr(vesselTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_GetAircraftTypeAttribute - Gets attributes for aircraft types * + * * + * SCRIPT INPUT: aircraftTypeID (int) - The ID of the aircraft type class * + * attribute_type (int) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetAircraftTypeAttribute(lua_State* L) { + + int aircraftTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = AircraftTypes.Ptr(aircraftTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; + } + + /********************************************************************************************** + * Script_GetObjectTypeAttribute - Gets attributes for specific object types globally * + * * + * Used internally by MapScript to send input and get attributes for TechnoTypeClass * + * * + * SCRIPT INPUT: this_type_class (TechnoTypeClass*) - The techno type * + * attribute_type (MapScriptObjectAttributeType) - The attribute to change * + * * + * SCRIPT OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type) { switch (attribute_type) { case ATTRIBUTE_MAX_STRENGTH: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxStrength); - - // Set the attribute - this_type_class->MaxStrength = attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->MaxStrength); + return 1; }break; case ATTRIBUTE_COST: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Cost); - - // Set the attribute - this_type_class->Cost = attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->Cost); + return 1; }break; case ATTRIBUTE_SIGHT_RANGE: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SightRange); - - // Set the attribute - this_type_class->SightRange = attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->SightRange); + return 1; }break; case ATTRIBUTE_TECH_LEVEL: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Level); - - // Set the attribute - this_type_class->Level = attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->Level); + return 1; }break; case ATTRIBUTE_ARMOR: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Armor); - - // Set the attribute - this_type_class->Armor = (ArmorType)attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->Armor); + return 1; }break; case ATTRIBUTE_PRIMARY_WEAPON: { - int attribute_value = lua_tointeger(L, 3); - if (this_type_class->PrimaryWeapon != NULL) { - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->PrimaryWeapon->ID); - }else { - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + // Send the attribute + lua_pushinteger(L, this_type_class->PrimaryWeapon->ID); + return 1; } - - // Set the attribute - if (attribute_value < 0) { - this_type_class->PrimaryWeapon = NULL; - }else { - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->PrimaryWeapon = this_weapon; - }else { - this_type_class->PrimaryWeapon = NULL; - } + else { + // Send the attribute + lua_pushinteger(L, -1); + return 1; } }break; case ATTRIBUTE_SECONDARY_WEAPON: { - int attribute_value = lua_tointeger(L, 3); - - if (this_type_class->PrimaryWeapon != NULL) { - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SecondaryWeapon->ID); - }else { - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + if (this_type_class->SecondaryWeapon != NULL) { + // Send the attribute + lua_pushinteger(L, this_type_class->SecondaryWeapon->ID); + return 1; } - - // Set the attribute - if (attribute_value < 0) { - this_type_class->SecondaryWeapon = NULL; - }else{ - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->SecondaryWeapon = this_weapon; - }else { - this_type_class->SecondaryWeapon = NULL; - } + else { + // Send the attribute + lua_pushinteger(L, -1); + return 1; } }break; case ATTRIBUTE_SPEED: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Speed); - - // Set the attribute - this_type_class->Speed = (SpeedType)attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->Speed); + return 1; }break; case ATTRIBUTE_MAX_SPEED: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxSpeed); - - // Set the attribute - this_type_class->MaxSpeed = (MPHType)attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->MaxSpeed); + return 1; }break; case ATTRIBUTE_MAX_AMMO: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxAmmo); - - // Set the attribute - this_type_class->MaxAmmo = attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->MaxAmmo); + return 1; }break; case ATTRIBUTE_ROTATION_SPEED: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->ROT); - - // Set the attribute - this_type_class->ROT = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->ROT); + return 1; }break; case ATTRIBUTE_CRUSHABLE: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrushable); - - // Set the attribute - this_type_class->IsCrushable = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsCrushable); + return 1; }break; case ATTRIBUTE_STEALTHY: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsStealthy); - - // Set the attribute - this_type_class->IsStealthy = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsStealthy); + return 1; }break; case ATTRIBUTE_SELECTABLE: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelectable); - - // Set the attribute - this_type_class->IsSelectable = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsSelectable); + return 1; }break; case ATTRIBUTE_LEGAL_TARGET: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsLegalTarget); - - // Set the attribute - this_type_class->IsLegalTarget = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsLegalTarget); + return 1; }break; case ATTRIBUTE_REPAIRABLE: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsRepairable); - - // Set the attribute - this_type_class->IsRepairable = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsRepairable); + return 1; }break; case ATTRIBUTE_SELF_HEALING: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelfHealing); - - // Set the attribute - this_type_class->IsSelfHealing = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsSelfHealing); + return 1; }break; case ATTRIBUTE_EXPLODES: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsExploding); - - // Set the attribute - this_type_class->IsExploding = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsExploding); + return 1; }break; case ATTRIBUTE_HAS_CREW: { - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrew); - - // Set the attribute - this_type_class->IsCrew = attribute_value; + // Send the attribute + lua_pushboolean(L, this_type_class->IsCrew); + return 1; }break; case ATTRIBUTE_MAX_PASSENGERS: { - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxPassengers); - - // Set the attribute - this_type_class->MaxPassengers = attribute_value; + // Send the attribute + lua_pushinteger(L, this_type_class->MaxPassengers); + return 1; }break; - default:{ + default: { // Object class specific attributes // Welcome to the web of switches] - + // Type of object switch (this_type_class->RTTI) { - // Building Specific - case RTTI_BUILDINGTYPE:{ + // Building Specific + case RTTI_BUILDINGTYPE: { // What type of attribute? switch (attribute_type) { case ATTRIBUTE_CAPACITY: { - int attribute_value = lua_tointeger(L, 3); - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Capacity); - - // Set the attribute - this_building_class->Capacity = attribute_value; + // Send the attribute + lua_pushinteger(L, this_building_class->Capacity); + return 1; }break; case ATTRIBUTE_POWER: { - int attribute_value = lua_tointeger(L, 3); - // Both power and drain are different variables // And so we do some trickery here to fill // the right values based on postivie/negative input BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Power + this_building_class->Drain); + int this_value = this_building_class->Power - this_building_class->Drain; - // Set the attribute - if (attribute_value > 0) { - this_building_class->Power = attribute_value; - this_building_class->Drain = 0; - }else { - this_building_class->Power = 0; - this_building_class->Drain = attribute_value * -1; // Flip negative power input - } + // Send the attribute + lua_pushinteger(L, this_value); + return 1; }break; case ATTRIBUTE_SELLABLE: { - int attribute_value = lua_tointeger(L, 3); - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->IsUnsellable *-1); - // Set the attribute // Personal opinion; sellable makes more sense than unsellable // This replacement could be seen as IsUnNonSellable, or... IsSellable - if (attribute_value == 1) { - this_building_class->IsUnsellable = 0; - } - else { - this_building_class->IsUnsellable = 1; + if (this_building_class->IsUnsellable == 1) { + // Send the attribute + lua_pushinteger(L, 0); + return 1; + } else { + // Send the attribute + lua_pushinteger(L, 1); + return 1; } }break; @@ -3876,86 +4554,62 @@ // Unit Specific - case RTTI_UNITTYPE:{ + case RTTI_UNITTYPE: { // What type of attribute? switch (attribute_type) { case ATTRIBUTE_CRATE_GOODIE: { - int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrateGoodie); - - // Set the attribute - this_unit_class->IsCrateGoodie = attribute_value; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsCrateGoodie); + return 1; }break; case ATTRIBUTE_CRUSHER: { - int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrusher); - - // Set the attribute - this_unit_class->IsCrusher = attribute_value; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsCrusher); + return 1; }break; case ATTRIBUTE_HARVEST: { - int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsToHarvest); - - // Set the attribute - this_unit_class->IsToHarvest = attribute_value; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsToHarvest); + return 1; }break; case ATTRIBUTE_RADAR_EQUIPPED: { - int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsRadarEquipped); - - // Set the attribute - this_unit_class->IsRadarEquipped = attribute_value; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsRadarEquipped); + return 1; }break; case ATTRIBUTE_JAMMER: { - int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsJammer); - - // Set the attribute - this_unit_class->IsJammer = attribute_value; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsJammer); + return 1; }break; case ATTRIBUTE_GAPPER: { - int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsGapper); - - // Set the attribute - this_unit_class->IsGapper = attribute_value; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsGapper); + return 1; }break; } @@ -3963,87 +4617,63 @@ }break; - // Infantry Specific - case RTTI_INFANTRYTYPE:{ + // Infantry Specific + case RTTI_INFANTRYTYPE: { // What type of attribute? switch (attribute_type) { case ATTRIBUTE_FEMALE: { - int attribute_value = lua_tointeger(L, 3); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFemale); - - // Set the attribute - this_infantry_class->IsFemale = attribute_value; + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsFemale); + return 1; }break; case ATTRIBUTE_CAPTURE: { - int attribute_value = lua_tointeger(L, 3); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCapture); - - // Set the attribute - this_infantry_class->IsCapture = attribute_value; + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsCapture); + return 1; }break; case ATTRIBUTE_FRAIDY_CAT: { - int attribute_value = lua_tointeger(L, 3); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFraidyCat); - - // Set the attribute - this_infantry_class->IsFraidyCat = attribute_value; + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsFraidyCat); + return 1; }break; case ATTRIBUTE_CIVILIAN: { - int attribute_value = lua_tointeger(L, 3); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCivilian); - - // Set the attribute - this_infantry_class->IsCivilian = attribute_value; + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsCivilian); + return 1; }break; case ATTRIBUTE_BOMBER: { - int attribute_value = lua_tointeger(L, 3); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsBomber); - - // Set the attribute - this_infantry_class->IsBomber = attribute_value; + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsBomber); + return 1; }break; case ATTRIBUTE_DOG: { - int attribute_value = lua_tointeger(L, 3); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - // Cache default value if first time changing this attribute - Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsDog); - - // Set the attribute - this_infantry_class->IsDog = attribute_value; + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsDog); + return 1; }break; @@ -4053,55 +4683,1110 @@ } // End of object specific switch - }break; + }break; } // End of attribute switch + + // Didn't find result return -1; + } + /********************************************************************************************** + * Script_SetHouseAttribute - Sets attributes for specific houses * + * * + * SCRIPT INPUT: houseID (int) - The ID of the house * + * attribute_type (int) - The attribute to change * + * attribute_value (int) - The value to set the attribute to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_SetHouseAttribute(lua_State* L) { - /*********************************************************************************************** - * Script_CacheDefaultAttribute - Caches an attribute value upon first usage for restoration * - * * - * SCRIPT INPUT: input_rtti (RTTIType) - The RTTI type for the attrtibute * - * input_id (int) - The ID of the typeclass * - * input_attribute (int) - The attribute to cache * - * input_value (int) - The value if the cache item doesn't exist * - * * - * SCRIPT OUTPUT: void * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - void Script_CacheDefaultAttribute(RTTIType input_rtti, int input_id, MapScriptAttributeType input_attribute, int input_value) { + int houseID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); - bool cache_item_found = false; - for (std::vector::iterator it = Scen.mapScript->DefaultTypeAttributeCache.begin(); it != Scen.mapScript->DefaultTypeAttributeCache.end(); ++it) {//Error 2-4 + HouseClass* this_house = Houses.Ptr(houseID); - MapScriptDefaultAttribute* cachedAttribute = (MapScriptDefaultAttribute*)(*it); + // Get the appropriate technotype + if (this_house != NULL) { - if (input_rtti == cachedAttribute->RTTI && input_id == cachedAttribute->ID && input_attribute == cachedAttribute->attribute) { - cache_item_found = true; - break; + switch (attribute_type) { + case HOUSE_ATTRIBUTE_IQ: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Control.IQ = attribute_value; + this_house->IQ = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_TECH_LEVEL: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Control.TechLevel = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_IS_HUMAN: { + + int attribute_value = lua_tointeger(L, 3); + + if (attribute_value == 1) { + this_house->IsHuman = 1; + this_house->WasHuman = 1; + }else { + this_house->IsHuman = 0; + } + + + }break; + case HOUSE_ATTRIBUTE_FIREPOWER_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->FirepowerBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].FirepowerBias; + + }break; + case HOUSE_ATTRIBUTE_GROUNDSPEED_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->GroundspeedBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].GroundspeedBias; + + }break; + case HOUSE_ATTRIBUTE_ARMOR_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->ArmorBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].ArmorBias; + + }break; + case HOUSE_ATTRIBUTE_ROF_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->ROFBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].ROFBias; + + }break; + case HOUSE_ATTRIBUTE_COST_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->CostBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].CostBias; + + }break; + case HOUSE_ATTRIBUTE_REPAIR_DELAY: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->RepairDelay = (fixed)attribute_value; + + }break; + case HOUSE_ATTRIBUTE_BUILD_DELAY: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->BuildDelay = (fixed)attribute_value; + + }break; + case HOUSE_ATTRIBUTE_STARTED: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsStarted = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_ALERTED: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsAlerted = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_BASE_BUILDING: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsBaseBuilding = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_DISCOVERED: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsDiscovered = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_CAPACITY: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Capacity = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_TIBERIUM: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Tiberium = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_CREDITS: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Credits = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_ALERT_TIMER: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->AlertTime = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_REPAIR_TIMER: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->RepairTimer = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_POINTS : { + + int attribute_value = lua_tointeger(L, 3); + + this_house->PointTotal = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_BUILDINGS: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_INFANTRY: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VEHICLES: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_AIRCRAFT: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VESSELS: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_CAPTURED_BUILDINGS: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_CRATES: { + + // Non writable + + }break; + + case HOUSE_ATTRIBUTE_BUILDING_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->BuildingFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_UNIT_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->UnitFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_INFANTRY_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->InfantryFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_AIRCRAFT_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->AircraftFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_VESSEL_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->VesselFactories = attribute_value; + + }break; + + case HOUSE_ATTRIBUTE_POWER: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Power = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_DRAIN: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Drain = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_LAST_ATTACKER: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->WhoLastHurtMe = (HousesType)attribute_value; + + }break; } } - // Cached attribute does not exist; let's cache! - if (!cache_item_found) { - MapScriptDefaultAttribute* cachedAttribute = new MapScriptDefaultAttribute; - cachedAttribute->RTTI = input_rtti; - cachedAttribute->ID = input_id; - cachedAttribute->attribute = input_attribute; - cachedAttribute->value = input_value; - Scen.mapScript->DefaultTypeAttributeCache.push_back(cachedAttribute); + return -1; + } + + /********************************************************************************************** + * Script_GetHouseAttribute - Sets attributes for specific houses * + * * + * SCRIPT INPUT: houseID (int) - The ID of the house * + * attribute_type (int) - The attribute to change * + * * + * SCRIPT OUTPUT: (mixed) - The value of the attribute * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_GetHouseAttribute(lua_State* L) { + + int houseID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + HouseClass* this_house = Houses.Ptr(houseID); + + // Get the appropriate technotype + if (this_house != NULL) { + + switch (attribute_type) { + case HOUSE_ATTRIBUTE_IQ: { + + lua_pushnumber(L, this_house->IQ); + return 1; + + }break; + case HOUSE_ATTRIBUTE_TECH_LEVEL: { + + lua_pushnumber(L, this_house->Control.TechLevel); + return 1; + + }break; + case HOUSE_ATTRIBUTE_IS_HUMAN: { + + lua_pushboolean(L, this_house->IsHuman); + return 1; + + }break; + case HOUSE_ATTRIBUTE_FIREPOWER_BIAS: { + + lua_pushnumber(L, (float)this_house->FirepowerBias.To_Float()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_GROUNDSPEED_BIAS: { + + lua_pushnumber(L, (float)this_house->GroundspeedBias.To_Float()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_ARMOR_BIAS: { + + lua_pushnumber(L, (float)this_house->ArmorBias.To_Float()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_ROF_BIAS: { + + lua_pushnumber(L, this_house->ROFBias.To_Float()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_COST_BIAS: { + + lua_pushnumber(L, (float)this_house->CostBias.To_Float()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_REPAIR_DELAY: { + + lua_pushnumber(L, (float)this_house->RepairDelay.To_Float()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_BUILD_DELAY: { + + lua_pushnumber(L, (float)this_house->BuildDelay.To_Float()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_STARTED: { + + lua_pushboolean(L, this_house->IsStarted); + return 1; + + }break; + case HOUSE_ATTRIBUTE_ALERTED: { + + lua_pushboolean(L, this_house->IsAlerted); + return 1; + + }break; + case HOUSE_ATTRIBUTE_BASE_BUILDING: { + + lua_pushboolean(L, this_house->IsBaseBuilding); + return 1; + + }break; + case HOUSE_ATTRIBUTE_DISCOVERED: { + + lua_pushboolean(L, this_house->IsDiscovered); + return 1; + + }break; + case HOUSE_ATTRIBUTE_CAPACITY: { + + lua_pushinteger(L, this_house->Capacity); + return 1; + + }break; + case HOUSE_ATTRIBUTE_TIBERIUM: { + + lua_pushinteger(L, this_house->Tiberium); + return 1; + + }break; + case HOUSE_ATTRIBUTE_CREDITS: { + + lua_pushinteger(L, this_house->Credits); + return 1; + + }break; + case HOUSE_ATTRIBUTE_ALERT_TIMER: { + + lua_pushnumber(L, this_house->AlertTime); + return 1; + + }break; + case HOUSE_ATTRIBUTE_REPAIR_TIMER: { + + lua_pushnumber(L, this_house->RepairTimer); + return 1; + + }break; + case HOUSE_ATTRIBUTE_POINTS: { + + lua_pushinteger(L, this_house->PointTotal); + return 1; + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_BUILDINGS: { + + lua_pushinteger(L, (int)this_house->DestroyedBuildings->Get_All_Totals()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_INFANTRY: { + + lua_pushinteger(L, (int)this_house->DestroyedInfantry->Get_All_Totals()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VEHICLES: { + + lua_pushinteger(L, (int)this_house->DestroyedUnits->Get_All_Totals()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_AIRCRAFT: { + + lua_pushinteger(L, (int)this_house->DestroyedAircraft->Get_All_Totals()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VESSELS: { + + lua_pushinteger(L, (int)this_house->DestroyedVessels->Get_All_Totals()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_CAPTURED_BUILDINGS: { + + lua_pushinteger(L, (int)this_house->CapturedBuildings->Get_All_Totals()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_CRATES: { + + lua_pushinteger(L, (int)this_house->TotalCrates->Get_All_Totals()); + return 1; + + }break; + case HOUSE_ATTRIBUTE_AIRCRAFT_FACTORIES: { + + lua_pushinteger(L, this_house->AircraftFactories); + return 1; + + }break; + case HOUSE_ATTRIBUTE_INFANTRY_FACTORIES: { + + lua_pushinteger(L, this_house->InfantryFactories); + return 1; + + }break; + case HOUSE_ATTRIBUTE_UNIT_FACTORIES: { + + lua_pushinteger(L, this_house->UnitFactories); + return 1; + + }break; + case HOUSE_ATTRIBUTE_VESSEL_FACTORIES: { + + lua_pushinteger(L, this_house->VesselFactories); + return 1; + + }break; + case HOUSE_ATTRIBUTE_BUILDING_FACTORIES: { + + lua_pushinteger(L, this_house->BuildingFactories); + return 1; + + }break; + case HOUSE_ATTRIBUTE_POWER: { + + lua_pushnumber(L, this_house->Power); + return 1; + + }break; + case HOUSE_ATTRIBUTE_DRAIN: { + + lua_pushnumber(L, this_house->Drain); + return 1; + + }break; + case HOUSE_ATTRIBUTE_LAST_ATTACKER: { + + lua_pushnumber(L, this_house->WhoLastHurtMe); + return 1; + + }break; + } } + lua_pushnumber(L, -1); + + return -1; } + /*********************************************************************************************** + * Script_BuildUnit - Builds a given unit in a given factory * + * * + * SCRIPT INPUT: factoryObject (int) - The factory object id * + * * + * unitType (int) - The unit type index for the unit to make (unit in a * + * general sense, not a vehicle) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_BuildUnit(lua_State* L) { + + int factoryObject = lua_tointeger(L, 1); + int unitType = lua_tointeger(L, 2); + + BuildingClass* this_factory = (BuildingClass *)Script_GetCacheObject(factoryObject); + + // Get the appropriate technotype + if (this_factory != NULL && this_factory->IsActive) { + + int result = true; + + switch (this_factory->Class->ID) { + case STRUCT_WEAP: { + + UnitTypeClass* unit_to_place = UnitTypes.Ptr(unitType); + UnitClass *new_unit = (UnitClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_UnitIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + }else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; + case STRUCT_TENT: + case STRUCT_BARRACKS: { + + InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(unitType); + InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_InfantryIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + }else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; + case STRUCT_KENNEL: { + + InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(unitType); + InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_InfantryIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + }else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; + case STRUCT_HELIPAD: + case STRUCT_AIRSTRIP: { + + AircraftTypeClass* unit_to_place = AircraftTypes.Ptr(unitType); + AircraftClass* new_unit = (AircraftClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_AircraftIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + }else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; + case STRUCT_SUB_PEN: + case STRUCT_SHIP_YARD: { + + VesselTypeClass* unit_to_place = VesselTypes.Ptr(unitType); + VesselClass* new_unit = (VesselClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_VesselIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + }else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; + } + + } + + + lua_pushnumber(L, -1); + return 1; + } + + /*********************************************************************************************** + * Script_CreateVehicle - Creates a given unit out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The unit type to create * + * * + * houseType (int) - The player (house) index to create the unit for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_CreateVehicle(lua_State* L) { + + int objectIndex = lua_tointeger(L,1); + int houseType = lua_tointeger(L,2); + int in_x = lua_tointeger(L,3); + int in_y = lua_tointeger(L,4); + + HouseClass *this_house = Houses.Ptr(houseType); + + UnitTypeClass *unit_to_place = UnitTypes.Ptr(objectIndex); + + if (this_house != NULL && unit_to_place != NULL) { + UnitClass* new_unit = (UnitClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { + + bool new_unit_placed = false; + + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if(!new_unit_placed){ + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell))) { + new_unit_placed = true; + } + } + + + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_UnitIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + } + } + } + + lua_pushnumber(L, -1); + return 1; + } + + + /*********************************************************************************************** + * Script_CreateInfantry - Creates a given Infantry out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The Infantry type to create * + * * + * houseType (int) - The player (house) index to create the Infantry for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_CreateInfantry(lua_State* L) { + + int objectIndex = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + int in_x = lua_tointeger(L, 3); + int in_y = lua_tointeger(L, 4); + + HouseClass* this_house = Houses.Ptr(houseType); + + InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(objectIndex); + + if (this_house != NULL && unit_to_place != NULL) { + InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { + + bool new_unit_placed = false; + + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)),DIR_S)) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if (!new_unit_placed) { + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell),DIR_S)) { + new_unit_placed = true; + } + } + + + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_InfantryIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + } + } + } + + lua_pushnumber(L, -1); + return 1; + } + + /*********************************************************************************************** + * Script_CreateAircraft - Creates a given Aircraft out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The Aircraft type to create * + * * + * houseType (int) - The player (house) index to create the Aircraft for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_CreateAircraft(lua_State* L) { + + int objectIndex = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + int in_x = lua_tointeger(L, 3); + int in_y = lua_tointeger(L, 4); + + HouseClass* this_house = Houses.Ptr(houseType); + + AircraftTypeClass* unit_to_place = AircraftTypes.Ptr(objectIndex); + + if (this_house != NULL && unit_to_place != NULL) { + AircraftClass* new_unit = (AircraftClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { + + bool new_unit_placed = false; + + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if (!new_unit_placed) { + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell))) { + new_unit_placed = true; + } + } + + + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_AircraftIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + } + } + } + + lua_pushnumber(L, -1); + return 1; + } + + /*********************************************************************************************** + * Script_CreateVessel - Creates a given Vessel out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The Vessel type to create * + * * + * houseType (int) - The player (house) index to create the Vessel for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_CreateVessel(lua_State* L) { + + int objectIndex = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + int in_x = lua_tointeger(L, 3); + int in_y = lua_tointeger(L, 4); + + HouseClass* this_house = Houses.Ptr(houseType); + + VesselTypeClass* unit_to_place = VesselTypes.Ptr(objectIndex); + + if (this_house != NULL && unit_to_place != NULL) { + VesselClass* new_unit = (VesselClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { + + bool new_unit_placed = false; + + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if (!new_unit_placed) { + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell))) { + new_unit_placed = true; + } + } + + + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_VesselIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + } + } + } + + lua_pushnumber(L, -1); + return 1; + } + + +/********************************************************************************************** +* Object Orders Functions * +*=============================================================================================*/ + +/*********************************************************************************************** + * Script_MoveObjectTo - Assigns a movement order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (int) - X location to move object to * + * * + * in_y (int) - Y location to move object to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_MoveObjectTo(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + int in_x = lua_tointeger(L, 2); + int in_y = lua_tointeger(L, 3); + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + switch (this_object->RTTI) { + case RTTI_UNIT: { + + UnitClass* thisUnit = (UnitClass*)this_object; + + Queue_Mission(TargetClass(thisUnit), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + + lua_pushnumber(L, 1); + return 1; + + }break; + case RTTI_INFANTRY: { + + InfantryClass* thisInfantry = (InfantryClass*)this_object; + + Queue_Mission(TargetClass(thisInfantry), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + + lua_pushnumber(L, 1); + return 1; + + }break; + case RTTI_AIRCRAFT: { + + AircraftClass* thisAircraft = (AircraftClass*)this_object; + + Queue_Mission(TargetClass(thisAircraft), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + + lua_pushnumber(L, 1); + return 1; + + }break; + case RTTI_VESSEL: { + + VesselClass* thisVessel = (VesselClass*)this_object; + + Queue_Mission(TargetClass(thisVessel), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + + lua_pushnumber(L, 1); + return 1; + + }break; + } + } + + lua_pushnumber(L, -1); + return 1; + + } + + /********************************************************************************************** * Mission Utility Functions * *=============================================================================================*/ @@ -4754,6 +6439,34 @@ return -1; } +/********************************************************************************************** +* Special / Debug Functions * +*=============================================================================================*/ + +/*********************************************************************************************** + * Script_Console_Print - Prints text to the console * + * * + * SCRIPT INPUT: inputText (string) - The text to print to the console * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_Console_Print(lua_State* L) { + + const char* inputText = lua_tostring(L, -1); // grab path string from top of stack + + Console_Printf(inputText); + + return -1; + } + + /********************************************************************************************** * MapScript Internal Functions * *=============================================================================================*/ @@ -4780,7 +6493,7 @@ MapScriptObject* thisCacheObject = (MapScriptObject*)(*it); // Here it is - if (thisCacheObject->ID == input_object_id) { + if (thisCacheObject->UID == input_object_id) { // Determine type of object and return it from cache. If it doesn't exist any longer, remove it from cache switch (thisCacheObject->RTTI) { @@ -4842,7 +6555,7 @@ // Not found in cache; let's find the object by ID the hard way... If scripting is done well, this doesn't get hit int _objectIndex = -1; - MapScriptObject* CacheObject = new MapScriptObject; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); CacheObject->ID = -1; _objectIndex = Script_BuildingIndexFromID(input_object_id); @@ -5104,6 +6817,47 @@ return -1; } + /*********************************************************************************************** + * Script_CacheDefaultAttribute - Caches an attribute value upon first usage for restoration * + * * + * SCRIPT INPUT: input_rtti (RTTIType) - The RTTI type for the attrtibute * + * input_id (int) - The ID of the typeclass * + * input_attribute (int) - The attribute to cache * + * input_value (int) - The value if the cache item doesn't exist * + * * + * SCRIPT OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + void Script_CacheDefaultObjectTypeAttribute(RTTIType input_rtti, int input_id, MapScriptObjectAttributeType input_attribute, int input_value) { + + bool cache_item_found = false; + for (std::vector::iterator it = Scen.mapScript->DefaultObjectTypeAttributeCache.begin(); it != Scen.mapScript->DefaultObjectTypeAttributeCache.end(); ++it) {//Error 2-4 + + MapScriptDefaultObjectAttribute* cachedAttribute = (MapScriptDefaultObjectAttribute*)(*it); + + if (input_rtti == cachedAttribute->RTTI && input_id == cachedAttribute->ID && input_attribute == cachedAttribute->attribute) { + cache_item_found = true; + break; + } + + } + + // Cached attribute does not exist; let's cache! + if (!cache_item_found) { + + MapScriptDefaultObjectAttribute* cachedAttribute = new MapScriptDefaultObjectAttribute; + cachedAttribute->RTTI = input_rtti; + cachedAttribute->ID = input_id; + cachedAttribute->attribute = input_attribute; + cachedAttribute->value = input_value; + Scen.mapScript->DefaultObjectTypeAttributeCache.push_back(cachedAttribute); + + } + + } + /*********************************************************************************************** * MapScript::CallFunction - Calls a given function within the current script * * * @@ -5153,6 +6907,27 @@ lua_pop(L, 1); } + /*********************************************************************************************** + * MapScript::CreateCacheObject -- Initializes a cached object for a new cache entry * + * * + * INPUT: mapName - The script path * + * * + * OUTPUT: bool; did the map script load and initialize? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ + MapScriptObject* MapScript::CreateCacheObject() { + + MapScriptObject* CacheObject = new MapScriptObject; + + cUID++; + CacheObject->UID = cUID; + + return CacheObject; + + } + /*********************************************************************************************** * MapScript::Deinit - Deinitialize/free any data used by MapScript (used within destructor) * * * @@ -5173,15 +6948,10 @@ ObjectCache.clear(); - // Welcome back to the web of switches where we will restore any default - // attributes that were changed in the script - for (std::vector::iterator it = Scen.mapScript->DefaultTypeAttributeCache.begin(); it != Scen.mapScript->DefaultTypeAttributeCache.end(); ++it) {//Error 2-4 - - MapScriptDefaultAttribute* cachedAttribute = (MapScriptDefaultAttribute*)(*it); - - - + // We will now restore any default Object attributes that were changed in the script + for (std::vector::iterator it = DefaultObjectTypeAttributeCache.begin(); it != DefaultObjectTypeAttributeCache.end(); ++it) {//Error 2-4 + MapScriptDefaultObjectAttribute* cachedAttribute = (MapScriptDefaultObjectAttribute*)(*it); switch (cachedAttribute->RTTI) { @@ -5223,9 +6993,16 @@ } - } + // Remove any cached Object Attributes + for (int i = 0; i < DefaultObjectTypeAttributeCache.size(); ++i) + { + delete DefaultObjectTypeAttributeCache[i]; + } + + DefaultObjectTypeAttributeCache.clear(); + for (int index = 0; index < Warheads.Count(); index++) { Warheads.Ptr(index)->Read_INI(RuleINI); @@ -5261,6 +7038,7 @@ } + /*********************************************************************************************** * MapScript::Init -- Loads and initializes script for a given map * * * @@ -5274,6 +7052,9 @@ * * *=============================================================================================*/ bool MapScript::Init(const char* mapName) { + + this->cUID = 0; + char scriptName[256]; // Build map path @@ -5307,7 +7088,7 @@ ObjectCache.reserve(2000); // Reserve type attribute cache memory (to restore rules after script) - DefaultTypeAttributeCache.reserve(1000); + DefaultObjectTypeAttributeCache.reserve(1000); /********************************************************************************************** * Red Alert Vanilla Actions * @@ -5401,6 +7182,7 @@ * Object Functions * *=============================================================================================*/ lua_register(L, "GetCellObject", Script_GetCellObject); // Gets an object (ID - building/vehicle/aircraft/infantry/vessel), if any, at [Cell/X],[Cell/Y] + lua_register(L, "SetObjectAttribute", Script_SetObjectAttribute); // Sets an object's attributes (strength, etc.) lua_register(L, "SetBuildingTypeAttribute", Script_SetBuildingTypeAttribute); // Sets the attribute of a Building type lua_register(L, "SetVehicleTypeAttribute", Script_SetVehicleTypeAttribute); // Sets the attribute of a Vehicle type @@ -5408,8 +7190,27 @@ lua_register(L, "SetVesselTypeAttribute", Script_SetVesselTypeAttribute); // Sets the attribute of a Vessel type lua_register(L, "SetAircraftTypeAttribute", Script_SetAircraftTypeAttribute); // Sets the attribute of an Aircraft type + lua_register(L, "GetObjectAttribute", Script_GetObjectAttribute); // Sets an object's attributes (strength, etc.) + lua_register(L, "GetBuildingTypeAttribute", Script_GetBuildingTypeAttribute); // Sets the attribute of a Building type + lua_register(L, "GetVehicleTypeAttribute", Script_GetVehicleTypeAttribute); // Sets the attribute of a Vehicle type + lua_register(L, "GetInfantryTypeAttribute", Script_GetInfantryTypeAttribute); // Sets the attribute of an Infantry type + lua_register(L, "GetVesselTypeAttribute", Script_GetVesselTypeAttribute); // Sets the attribute of a Vessel type + lua_register(L, "GetAircraftTypeAttribute", Script_GetAircraftTypeAttribute); // Sets the attribute of an Aircraft type - //lua_register(L, "GetObjectAttribute", Script_SetAircraftTypeAttribute); // Gets the attribute of an object + lua_register(L, "SetHouseAttribute", Script_SetHouseAttribute); // Sets a house's attributes + lua_register(L, "GetHouseAttribute", Script_GetHouseAttribute); // Gets a house's attributes + + lua_register(L, "BuildUnit", Script_BuildUnit); // Builds a unit in a given factory / barracks / naval yard / etc + lua_register(L, "CreateVehicle", Script_CreateVehicle); // Creates a unit out of thin air + lua_register(L, "CreateInfantry", Script_CreateInfantry); // Creates a unit out of thin air + lua_register(L, "CreateAircraft", Script_CreateAircraft); // Creates a unit out of thin air + lua_register(L, "CreateVessel", Script_CreateVessel); // Creates a unit out of thin air + + /********************************************************************************************** + * Object Orders Functions * + *=============================================================================================*/ + + lua_register(L, "MoveObjectTo", Script_MoveObjectTo); // Assigns a movement order to the object /********************************************************************************************** * Mission Utility Functions * @@ -5432,7 +7233,13 @@ lua_register(L, "GetWaypointX", Script_GetWaypointX); // Get Cell/X of waypoint lua_register(L, "GetWaypointY", Script_GetWaypointY); // Get Cell/Y of waypoint - + + /********************************************************************************************** + * Special / Debug Functions * + *=============================================================================================*/ + + lua_register(L, "PrintConsole", Script_Console_Print); // Print text to console + /********************************************************************************************** * Script Globals * *=============================================================================================*/ diff --git a/code/redalert/mapscript.h b/code/redalert/mapscript.h index 5548a95..3b914f5 100644 --- a/code/redalert/mapscript.h +++ b/code/redalert/mapscript.h @@ -15,27 +15,30 @@ extern "C" { // Object Cache Item // Stores an id lookup table struct MapScriptObject { + + int UID; // The UID of the object (to prevent ID collisions) + int ID=-1; // The object's "Global ID" int classIndex=-1; // The object's "Global ID" RTTIType RTTI; // The type of object + }; -// Stores defaults of rules from before -// variables were changed within -struct MapScriptDefaultAttribute { +// Stores defaults of object attributes whenever they are changed for the first time (for later restoration) +struct MapScriptDefaultObjectAttribute { RTTIType RTTI; // The type of object int ID=-1; // The index of the object in its heap int attribute; int value; }; - // // MapScript Class // class MapScript { public: + int cUID = 0; ~MapScript() { Deinit(); }; @@ -43,11 +46,13 @@ public: bool Init(const char* mapName); void Deinit(); + MapScriptObject* CreateCacheObject(); + void CallFunction(const char* functionName); void SetLuaPath(const char* input_path); std::vector ObjectCache; - std::vector DefaultTypeAttributeCache; + std::vector DefaultObjectTypeAttributeCache; private: lua_State* L; @@ -56,7 +61,7 @@ private: // Enums -typedef enum MapScriptAttributeType : char { +typedef enum MapScriptObjectAttributeType : char { // Techno types ATTRIBUTE_TYPE=0, @@ -105,7 +110,49 @@ typedef enum MapScriptAttributeType : char { ATTRIBUTE_DOG -} MapScriptAttributeType; +} MapScriptObjectAttributeType; + +// Enums +typedef enum MapScriptHouseAttributeType : char { + + // Techno types + HOUSE_ATTRIBUTE_IQ = 0, + HOUSE_ATTRIBUTE_TECH_LEVEL, + HOUSE_ATTRIBUTE_IS_HUMAN, + HOUSE_ATTRIBUTE_FIREPOWER_BIAS, + HOUSE_ATTRIBUTE_GROUNDSPEED_BIAS, + HOUSE_ATTRIBUTE_ARMOR_BIAS, + HOUSE_ATTRIBUTE_ROF_BIAS, + HOUSE_ATTRIBUTE_COST_BIAS, + HOUSE_ATTRIBUTE_REPAIR_DELAY, + HOUSE_ATTRIBUTE_BUILD_DELAY, + HOUSE_ATTRIBUTE_STARTED, + HOUSE_ATTRIBUTE_ALERTED, + HOUSE_ATTRIBUTE_BASE_BUILDING, + HOUSE_ATTRIBUTE_DISCOVERED, + HOUSE_ATTRIBUTE_CAPACITY, + HOUSE_ATTRIBUTE_TIBERIUM, + HOUSE_ATTRIBUTE_CREDITS, + HOUSE_ATTRIBUTE_ALERT_TIMER, + HOUSE_ATTRIBUTE_REPAIR_TIMER, + HOUSE_ATTRIBUTE_POINTS, + HOUSE_ATTRIBUTE_DESTROYED_BUILDINGS, + HOUSE_ATTRIBUTE_DESTROYED_VEHICLES, + HOUSE_ATTRIBUTE_DESTROYED_INFANTRY, + HOUSE_ATTRIBUTE_DESTROYED_AIRCRAFT, + HOUSE_ATTRIBUTE_DESTROYED_VESSELS, + HOUSE_ATTRIBUTE_CAPTURED_BUILDINGS, + HOUSE_ATTRIBUTE_CRATES, + HOUSE_ATTRIBUTE_BUILDING_FACTORIES, + HOUSE_ATTRIBUTE_UNIT_FACTORIES, + HOUSE_ATTRIBUTE_INFANTRY_FACTORIES, + HOUSE_ATTRIBUTE_AIRCRAFT_FACTORIES, + HOUSE_ATTRIBUTE_VESSEL_FACTORIES, + HOUSE_ATTRIBUTE_POWER, + HOUSE_ATTRIBUTE_DRAIN, + HOUSE_ATTRIBUTE_LAST_ATTACKER + +} MapScriptHouseAttributeType; // Non-Class-Functions bool Script_SetObjectTrigger(int input_object_id, TriggerClass* input_trigger); @@ -117,8 +164,9 @@ int Script_AircraftIndexFromID(int input_object_id); int Script_InfantryIndexFromID(int input_object_id); int Script_VesselIndexFromID(int input_object_id); -static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptAttributeType attribute_type); +static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type); +static int Script_GetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type); -void Script_CacheDefaultAttribute(RTTIType input_rtti, int input_id, MapScriptAttributeType input_attribute, int input_value); +void Script_CacheDefaultObjectTypeAttribute(RTTIType input_rtti, int input_id, MapScriptObjectAttributeType input_attribute, int input_value); #endif \ No newline at end of file diff --git a/scripts/_Global.script b/scripts/_Global.script index f848203..6b4a09b 100644 --- a/scripts/_Global.script +++ b/scripts/_Global.script @@ -160,7 +160,21 @@ MIG=3, -- MIG Attack Plane YAK=4, -- Yak Attack Plane HELI=5, -- Longbow Helicopter - HIND=6, -- Hind Helicopter + HIND=6 -- Hind Helicopter + } + + -- ********************************************************* + -- * * + -- * Vessels * + -- * * + -- ********************************************************* + + VesselTypes={ + SS=0, -- Submarine + DD=1, -- Destroyer + CA=2, -- Cruiser + LST=3, -- Land Sea Tank (transport) + PT=4 -- Gun Boat } -- ********************************************************* @@ -270,10 +284,10 @@ -- ********************************************************* -- * * - -- * Attribite Types * + -- * Obejct Attributes * -- * * -- ********************************************************* - Attributes = { + ObjectAttributes = { Type=0, Strength=1, -- Object attribute MaxStrength=2, -- Definition attribute @@ -320,6 +334,50 @@ IsDog=37 } + + -- ********************************************************* + -- * * + -- * House Attributes * + -- * * + -- ********************************************************* + HouseAttributes = { + IQ = 0, + TechLevel =1, + IsHuman=2, + FirepowerBias=3, + GroundspeedBias=4, + ArmorBias=5, + ROFBias=6, + CostBias=7, + RepairDelay=8, + BuildDelay=9, + Started=10, + Alerted=11, + BaseBuilding=12, + Discovered=13, + Capacity=14, + Tiberium=15, + Credits=16, + AlertTimer=17, + RepairTimer=18, + Points=19, + DestroyedBuildings=20, + DestroyedVehicles=21, + DestroyedInfantry=22, + DestroyedAircraft=23, + DestroyedVessels=24, + CapturedBuildings=25, + Crates=26, + BuildingFactories=27, + VehicleFactories=28, + InfantryFactories=29, + AircraftFactories=30, + VesselFactories=31, + + Power=32, + Drain=33, + LastAttacker=34 + } -- ********************************************************* -- * * From 9b237d8fdad3b2796af954a0a866c55c2141cc76 Mon Sep 17 00:00:00 2001 From: nev6502 Date: Sun, 28 Jun 2020 17:57:57 -0600 Subject: [PATCH 5/7] Added several unit orders --- code/redalert/mapscript.cpp | 388 ++++++++++++++++++++++++++++++++---- 1 file changed, 351 insertions(+), 37 deletions(-) diff --git a/code/redalert/mapscript.cpp b/code/redalert/mapscript.cpp index 1489e7f..1253edb 100644 --- a/code/redalert/mapscript.cpp +++ b/code/redalert/mapscript.cpp @@ -5711,7 +5711,7 @@ *=============================================================================================*/ /*********************************************************************************************** - * Script_MoveObjectTo - Assigns a movement order to an object * + * Script_OrderMove - Assigns a movement order to an object * * * * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * * * @@ -5728,7 +5728,7 @@ * WARNINGS: ? * * * *=============================================================================================*/ - static int Script_MoveObjectTo(lua_State* L) { + static int Script_OrderMove(lua_State* L) { int objectID = lua_tointeger(L, 1); int in_x = lua_tointeger(L, 2); @@ -5737,48 +5737,108 @@ ObjectClass* this_object = Script_GetCacheObject(objectID); if (this_object != NULL) { - switch (this_object->RTTI) { - case RTTI_UNIT: { - UnitClass* thisUnit = (UnitClass*)this_object; + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, As_Target(XY_Cell(in_x, in_y))); - Queue_Mission(TargetClass(thisUnit), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + lua_pushnumber(L, 1); + return 1; - lua_pushnumber(L, 1); - return 1; + } - }break; - case RTTI_INFANTRY: { + lua_pushnumber(L, -1); + return 1; - InfantryClass* thisInfantry = (InfantryClass*)this_object; + } - Queue_Mission(TargetClass(thisInfantry), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + /*********************************************************************************************** + * Script_OrderAttackCell - Assigns an attack order to an object for a specific cell * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (int) - X location to attack * + * * + * in_y (int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_OrderAttackCell(lua_State* L) { - lua_pushnumber(L, 1); - return 1; + int objectID = lua_tointeger(L, 1); - }break; - case RTTI_AIRCRAFT: { + int in_x = lua_tointeger(L, 2); + int in_y = lua_tointeger(L, 3); - AircraftClass* thisAircraft = (AircraftClass*)this_object; + ObjectClass* this_object = Script_GetCacheObject(objectID); - Queue_Mission(TargetClass(thisAircraft), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + if (this_object != NULL) { - lua_pushnumber(L, 1); - return 1; - - }break; - case RTTI_VESSEL: { - - VesselClass* thisVessel = (VesselClass*)this_object; - - Queue_Mission(TargetClass(thisVessel), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); - - lua_pushnumber(L, 1); - return 1; - - }break; + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, this_target, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + + } + + /*********************************************************************************************** + * Script_OrderAttack - Assigns an attack order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (int) - X location to attack * + * * + * in_y (int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_OrderAttack(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + + lua_pushnumber(L, 1); + return 1; + } lua_pushnumber(L, -1); @@ -5786,6 +5846,255 @@ } + /*********************************************************************************************** + * Script_OrderHunt - Assigns a hunt order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to attack * + * * + * in_y (opt)(int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_OrderHunt(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + + } + + /*********************************************************************************************** + * Script_OrderGuard - Assigns a guard order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to attack * + * * + * in_y (opt)(int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_OrderGuard(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + + } + + /*********************************************************************************************** + * Script_OrderRetreat - Assigns a retreat order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to attack * + * * + * in_y (opt)(int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_OrderRetreat(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + + } + + /*********************************************************************************************** + * Script_OrderEnter - Assigns an enter order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to enter (building / unit) * + * * + * in_y (opt)(int) - Y location to enter (building / unit) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_OrderEnter(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ENTER, this_target, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + + } + + /*********************************************************************************************** + * Script_OrderCapture - Assigns a capture order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to capture (building) * + * * + * in_y (opt)(int) - Y location to capture (building) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + static int Script_OrderCapture(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_CAPTURE, this_target, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + + } /********************************************************************************************** * Mission Utility Functions * @@ -7201,16 +7510,21 @@ lua_register(L, "GetHouseAttribute", Script_GetHouseAttribute); // Gets a house's attributes lua_register(L, "BuildUnit", Script_BuildUnit); // Builds a unit in a given factory / barracks / naval yard / etc - lua_register(L, "CreateVehicle", Script_CreateVehicle); // Creates a unit out of thin air - lua_register(L, "CreateInfantry", Script_CreateInfantry); // Creates a unit out of thin air - lua_register(L, "CreateAircraft", Script_CreateAircraft); // Creates a unit out of thin air - lua_register(L, "CreateVessel", Script_CreateVessel); // Creates a unit out of thin air + lua_register(L, "CreateVehicle", Script_CreateVehicle); // Creates a unit out of thin air + lua_register(L, "CreateInfantry", Script_CreateInfantry); // Creates a unit out of thin air + lua_register(L, "CreateAircraft", Script_CreateAircraft); // Creates a unit out of thin air + lua_register(L, "CreateVessel", Script_CreateVessel); // Creates a unit out of thin air /********************************************************************************************** * Object Orders Functions * *=============================================================================================*/ - lua_register(L, "MoveObjectTo", Script_MoveObjectTo); // Assigns a movement order to the object + lua_register(L, "OrderMove", Script_OrderMove); // Assigns a movement order to the object + lua_register(L, "OrderAttack", Script_OrderAttack); // Assigns an attack order to the object + lua_register(L, "OrderHunt", Script_OrderHunt); // Assigns a hunt order to the object + lua_register(L, "OrderGuard", Script_OrderGuard); // Assigns a guard order to the object + lua_register(L, "OrderEnter", Script_OrderEnter); // Assigns a enter order to the object + lua_register(L, "OrderCapture", Script_OrderCapture); // Assigns a capture order to the object /********************************************************************************************** * Mission Utility Functions * From 9770771f5c8f5b9e852b43b50f9945f8e1a75f1a Mon Sep 17 00:00:00 2001 From: nev6502 Date: Sun, 28 Jun 2020 19:50:53 -0600 Subject: [PATCH 6/7] Fixes several small issues --- code/redalert/mapscript.cpp | 13461 +++++++++++++++++----------------- 1 file changed, 6734 insertions(+), 6727 deletions(-) diff --git a/code/redalert/mapscript.cpp b/code/redalert/mapscript.cpp index 1253edb..8e1a841 100644 --- a/code/redalert/mapscript.cpp +++ b/code/redalert/mapscript.cpp @@ -5,1451 +5,1208 @@ * Red Alert Vanilla Actions * *=============================================================================================*/ - /*********************************************************************************************** - * Script_Win - The specified player wins * - * * - * SCRIPT INPUT: houseType (int) - The player (house that wins) * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_Win(lua_State* L) { - - int houseType = lua_tointeger(L, -1); +/*********************************************************************************************** + * Script_Win - The specified player wins * + * * + * SCRIPT INPUT: houseType (int) - The player (house that wins) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_Win(lua_State* L) { - if (houseType != HOUSE_NONE) { + int houseType = lua_tointeger(L, -1); - HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); + if (houseType != HOUSE_NONE) { - if (this_house != NULL) { + HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); - if (this_house->ID == PlayerPtr->Class->House) { - PlayerPtr->Flag_To_Win(); - } - else { - PlayerPtr->Flag_To_Lose(); - } + if (this_house != NULL) { - bool success = this_house->Fire_Sale(); - lua_pushboolean(L, int(success)); + if (this_house->ID == PlayerPtr->Class->House) { + PlayerPtr->Flag_To_Win(); } - } - - return 1; - } - - /*********************************************************************************************** - * Script_Lose - The specified player loses * - * * - * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_Lose(lua_State* L) { - - int houseType = lua_tointeger(L, -1); - - if (houseType != HOUSE_NONE) { - - HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); - - if (this_house != NULL) { - - if (this_house->ID == PlayerPtr->Class->House) { - PlayerPtr->Flag_To_Lose(); - } - else { - PlayerPtr->Flag_To_Win(); - } - - lua_pushboolean(L, 1); - } - } - - return 1; - } - - /*********************************************************************************************** - * Script_BeginProduction - This will enable production to begin for the house specified * - * * - * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_BeginProduction(lua_State* L) { - - int houseType = lua_tointeger(L, -1); - - if (houseType != HOUSE_NONE) { - - HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); - - if (this_house != NULL) { - this_house->Begin_Production(); - } - } - - return 1; - } - - /*********************************************************************************************** - * Script_CreateTeam - Attempts to create team (as defined in map) * - * * - * SCRIPT INPUT: teamType (int) - The team index to attempt to create * - * * - * SCRIPT OUTPUT: success (bool) - Did a team get created? * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CreateTeam(lua_State* L) { - - const char* teamType = lua_tostring(L, 1); - - TeamTypeClass* teamPtr = TeamTypeClass::From_Name(teamType); - - if (teamPtr != NULL) { - ScenarioInit++; - - bool success = false; - - TeamClass* new_team = teamPtr->Create_One_Of(); - - if (new_team != NULL) { - success = true; + else { + PlayerPtr->Flag_To_Lose(); } - lua_pushboolean(L, int(success)); - - ScenarioInit--; - } - - return 1; - } - - /*********************************************************************************************** - * Script_DestroyTeam - Destroy all teams of the type specified * - * * - * SCRIPT INPUT: teamType (int) - The team index to attempt to destroy * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_DestroyTeam(lua_State* L) { - - const char* teamType = lua_tostring(L, 1); - - TeamTypeClass* teamPtr = TeamTypeClass::From_Name(teamType); - - if (teamPtr != NULL) { - - teamPtr->Destroy_All_Of(); - - } - - return 1; - } - - /*********************************************************************************************** - * Script_AllHunt - Force all units of specified house to go into hunt mode * - * * - * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AllHunt(lua_State* L) { - - int houseType = lua_tointeger(L, -1); - - if (houseType != HOUSE_NONE) { - - HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); - - if (this_house != NULL) { - this_house->Do_All_To_Hunt(); - } - } - - return 1; - } - - /*********************************************************************************************** - * Script_Reinforcements - Attempts to create reinforcements as defined by team * - * * - * SCRIPT INPUT: teamType (int) - The team index to attempt to create * - * * - * SCRIPT OUTPUT: success (bool) - Did Do_Reinforcements return true? * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_Reinforcements(lua_State* L) { - - const char* teamType = lua_tostring(L, 1); - - TeamTypeClass* teamPtr = TeamTypeClass::From_Name(teamType); - - if (teamPtr != NULL) { - bool success = Do_Reinforcements(teamPtr); + bool success = this_house->Fire_Sale(); lua_pushboolean(L, int(success)); } - else { - lua_pushboolean(L, 0); - } - - return 1; } - /*********************************************************************************************** - * Script_DropZoneFlare - Places drop down smoke at specified waypoint location * - * * - * SCRIPT INPUT: in_x (int) - The Cell/X location to drop the smoke * - * in_y (int) - The Cell/Y location to drop the smoke * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_DropZoneFlare(lua_State* L) { + return 1; +} - int in_x = lua_tointeger(L, 1); - int in_y = lua_tointeger(L, 2); +/*********************************************************************************************** + * Script_Lose - The specified player loses * + * * + * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_Lose(lua_State* L) { - new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(XY_Cell(in_x,in_y))); + int houseType = lua_tointeger(L, -1); - return 1; - } + if (houseType != HOUSE_NONE) { - /*********************************************************************************************** - * Script_FireSale - Make AI house give up, selling everything and going all in on attack * - * * - * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * - * * - * SCRIPT OUTPUT: success (bool) - Did the action get performed? * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_FireSale(lua_State* L) { + HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); - int houseType = lua_tointeger(L, -1); + if (this_house != NULL) { - if (houseType != HOUSE_NONE) { - - HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); - - if (this_house != NULL) { - bool success = this_house->Fire_Sale(); - lua_pushboolean(L, int(success)); + if (this_house->ID == PlayerPtr->Class->House) { + PlayerPtr->Flag_To_Lose(); } - } - - return 1; - } - - /*********************************************************************************************** - * Script_PlayMovie - Plays the given movie * - * * - * SCRIPT INPUT: ret (int) - The movie index of which to play * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_PlayMovie(lua_State* L) { - int ret = lua_tointeger(L, -1); - Play_Movie((VQType)ret); - return 1; - } - - /*********************************************************************************************** - * Script_TriggerText - Triggers text to display in-game * - * * - * SCRIPT INPUT: textIndex (int) - The text index to display (from tutorial.ini) * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_TriggerText(lua_State* L) { - int textIndex = lua_tointeger(L, -1); - - // TODO: Implement colors / flags - - // JJQUESTION: This appears right but doesn't do anything. Is text broken at the moment? - if (textIndex > 0 && textIndex < sizeof(TutorialText)) { - - Session.Messages.Add_Message(NULL, textIndex, (char*)TutorialText[textIndex], PCOLOR_GREEN, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, Rule.MessageDelay * TICKS_PER_MINUTE); - } - - return 1; - } - - /*********************************************************************************************** - * Script_DestroyTrigger - Destroys a given trigger * - * * - * SCRIPT INPUT: ret (int) - The index/id of the trigger of which to destroy * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_DestroyTrigger(lua_State* L) { - - int triggerIndex = lua_tointeger(L, -1); - - TriggerClass* this_trigger = Triggers.Ptr(triggerIndex); - - if (this_trigger != NULL) { - Detach_This_From_All(this_trigger->As_Target()); - delete Triggers.Ptr(triggerIndex); - } - - return 1; - } - - /*********************************************************************************************** - * Script_AutoCreate - Allows house AI to begin creating autocreate teams * - * * - * Autocreation means that instead of a teamtype being * - * manually created by a Create Team trigger action, that * - * it will be subject to the autocreate function. Each * - * computer country can have its autocreation function * - * turned on through a trigger action, after which the * - * creation of the teamtypes that have autocreation turned * - * on will be subject to being created, at the whim of the * - * autocreate function. See [TeamTypes] Section for more * - * details. * - * - The Red Alert Single Player Mission Creation Guide * - * * - * * - * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow autocreate for * - * createEnables (bool, default yes) - Allow autocreate on/off * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AutoCreate(lua_State* L) { - - int houseType = 0; - bool autoCreateEnabled = true; - - houseType = lua_tointeger(L, 1); - - // If there is a second argument given, process it - if (lua_gettop(L) == 2) { - autoCreateEnabled = lua_toboolean(L, 2); - } - - if (houseType != HOUSE_NONE) { - - HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); - - if (this_house != NULL) { - - // If we are enabling auto creation by the house, clear alert - if (autoCreateEnabled) { - this_house->AlertTime = 0; // TODO - don't assume successful pointer - } - - // Now set the parameter - this_house->IsAlerted = autoCreateEnabled; - + else { + PlayerPtr->Flag_To_Win(); } + lua_pushboolean(L, 1); } - - return 1; } - /*********************************************************************************************** - * Script_AllowWin - Allows a win * - * * - * Used when you want a specific objective * - * to be met before the mission is accomplished. In other words, if the * - * trigger with this action assigned to it hasn't been fired, but the * - * actual WIN trigger has been fired, the mission will not end until this * - * "allow win" trigger is fired. * - * * - * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AllowWin(lua_State* L) { + return 1; +} - int houseType = lua_tointeger(L, -1); +/*********************************************************************************************** + * Script_BeginProduction - This will enable production to begin for the house specified * + * * + * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_BeginProduction(lua_State* L) { - if (houseType != HOUSE_NONE) { + int houseType = lua_tointeger(L, -1); - HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); + if (houseType != HOUSE_NONE) { - if (this_house != NULL) { - this_house->Blockage++; + HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); + + if (this_house != NULL) { + this_house->Begin_Production(); + } + } + + return 1; +} + +/*********************************************************************************************** + * Script_CreateTeam - Attempts to create team (as defined in map) * + * * + * SCRIPT INPUT: teamType (int) - The team index to attempt to create * + * * + * SCRIPT OUTPUT: success (bool) - Did a team get created? * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CreateTeam(lua_State* L) { + + const char* teamType = lua_tostring(L, 1); + + TeamTypeClass* teamPtr = TeamTypeClass::From_Name(teamType); + + if (teamPtr != NULL) { + ScenarioInit++; + + bool success = false; + + TeamClass* new_team = teamPtr->Create_One_Of(); + + if (new_team != NULL) { + success = true; + } + + lua_pushboolean(L, int(success)); + + ScenarioInit--; + } + + return 1; +} + +/*********************************************************************************************** + * Script_DestroyTeam - Destroy all teams of the type specified * + * * + * SCRIPT INPUT: teamType (int) - The team index to attempt to destroy * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_DestroyTeam(lua_State* L) { + + const char* teamType = lua_tostring(L, 1); + + TeamTypeClass* teamPtr = TeamTypeClass::From_Name(teamType); + + if (teamPtr != NULL) { + + teamPtr->Destroy_All_Of(); + + } + + return 1; +} + +/*********************************************************************************************** + * Script_AllHunt - Force all units of specified house to go into hunt mode * + * * + * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AllHunt(lua_State* L) { + + int houseType = lua_tointeger(L, -1); + + if (houseType != HOUSE_NONE) { + + HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); + + if (this_house != NULL) { + this_house->Do_All_To_Hunt(); + } + } + + return 1; +} + +/*********************************************************************************************** + * Script_Reinforcements - Attempts to create reinforcements as defined by team * + * * + * SCRIPT INPUT: teamType (int) - The team index to attempt to create * + * * + * SCRIPT OUTPUT: success (bool) - Did Do_Reinforcements return true? * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_Reinforcements(lua_State* L) { + + const char* teamType = lua_tostring(L, 1); + + TeamTypeClass* teamPtr = TeamTypeClass::From_Name(teamType); + + if (teamPtr != NULL) { + bool success = Do_Reinforcements(teamPtr); + lua_pushboolean(L, int(success)); + } + else { + lua_pushboolean(L, 0); + } + + return 1; +} + +/*********************************************************************************************** + * Script_DropZoneFlare - Places drop down smoke at specified waypoint location * + * * + * SCRIPT INPUT: in_x (int) - The Cell/X location to drop the smoke * + * in_y (int) - The Cell/Y location to drop the smoke * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_DropZoneFlare(lua_State* L) { + + int in_x = lua_tointeger(L, 1); + int in_y = lua_tointeger(L, 2); + + new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(XY_Cell(in_x, in_y))); + + return 1; +} + +/*********************************************************************************************** + * Script_FireSale - Make AI house give up, selling everything and going all in on attack * + * * + * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * + * * + * SCRIPT OUTPUT: success (bool) - Did the action get performed? * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_FireSale(lua_State* L) { + + int houseType = lua_tointeger(L, -1); + + if (houseType != HOUSE_NONE) { + + HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); + + if (this_house != NULL) { + bool success = this_house->Fire_Sale(); + lua_pushboolean(L, int(success)); + } + } + + return 1; +} + +/*********************************************************************************************** + * Script_PlayMovie - Plays the given movie * + * * + * SCRIPT INPUT: ret (int) - The movie index of which to play * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_PlayMovie(lua_State* L) { + int ret = lua_tointeger(L, -1); + Play_Movie((VQType)ret); + return 1; +} + +/*********************************************************************************************** + * Script_TriggerText - Triggers text to display in-game * + * * + * SCRIPT INPUT: textIndex (int) - The text index to display (from tutorial.ini) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_TriggerText(lua_State* L) { + int textIndex = lua_tointeger(L, -1); + + // TODO: Implement colors / flags + + // JJQUESTION: This appears right but doesn't do anything. Is text broken at the moment? + if (textIndex > 0 && textIndex < sizeof(TutorialText)) { + + Session.Messages.Add_Message(NULL, textIndex, (char*)TutorialText[textIndex], PCOLOR_GREEN, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, Rule.MessageDelay * TICKS_PER_MINUTE); + } + + return 1; +} + +/*********************************************************************************************** + * Script_DestroyTrigger - Destroys a given trigger * + * * + * SCRIPT INPUT: ret (int) - The index/id of the trigger of which to destroy * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_DestroyTrigger(lua_State* L) { + + int triggerIndex = lua_tointeger(L, -1); + + TriggerClass* this_trigger = Triggers.Ptr(triggerIndex); + + if (this_trigger != NULL) { + Detach_This_From_All(this_trigger->As_Target()); + delete Triggers.Ptr(triggerIndex); + } + + return 1; +} + +/*********************************************************************************************** + * Script_AutoCreate - Allows house AI to begin creating autocreate teams * + * * + * Autocreation means that instead of a teamtype being * + * manually created by a Create Team trigger action, that * + * it will be subject to the autocreate function. Each * + * computer country can have its autocreation function * + * turned on through a trigger action, after which the * + * creation of the teamtypes that have autocreation turned * + * on will be subject to being created, at the whim of the * + * autocreate function. See [TeamTypes] Section for more * + * details. * + * - The Red Alert Single Player Mission Creation Guide * + * * + * * + * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow autocreate for * + * createEnables (bool, default yes) - Allow autocreate on/off * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AutoCreate(lua_State* L) { + + int houseType = 0; + bool autoCreateEnabled = true; + + houseType = lua_tointeger(L, 1); + + // If there is a second argument given, process it + if (lua_gettop(L) == 2) { + autoCreateEnabled = lua_toboolean(L, 2); + } + + if (houseType != HOUSE_NONE) { + + HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); + + if (this_house != NULL) { + + // If we are enabling auto creation by the house, clear alert + if (autoCreateEnabled) { + this_house->AlertTime = 0; // TODO - don't assume successful pointer } + + // Now set the parameter + this_house->IsAlerted = autoCreateEnabled; + } - return 1; } - /*********************************************************************************************** - * Script_RevealAll - Reveals the entire map TODO: input player * - * * - * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_RevealAll(lua_State* L) { - if (!PlayerPtr->IsVisionary) { - PlayerPtr->IsVisionary = true; - for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { + return 1; +} + +/*********************************************************************************************** + * Script_AllowWin - Allows a win * + * * + * Used when you want a specific objective * + * to be met before the mission is accomplished. In other words, if the * + * trigger with this action assigned to it hasn't been fired, but the * + * actual WIN trigger has been fired, the mission will not end until this * + * "allow win" trigger is fired. * + * * + * SCRIPT INPUT: houseType (int) - The AI player (house) index to allow winning for * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AllowWin(lua_State* L) { + + int houseType = lua_tointeger(L, -1); + + if (houseType != HOUSE_NONE) { + + HouseClass* this_house = HouseClass::As_Pointer((HousesType)houseType); + + if (this_house != NULL) { + this_house->Blockage++; + } + } + + return 1; +} + +/*********************************************************************************************** + * Script_RevealAll - Reveals the entire map TODO: input player * + * * + * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_RevealAll(lua_State* L) { + if (!PlayerPtr->IsVisionary) { + PlayerPtr->IsVisionary = true; + for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { + Map.Map_Cell(cell, PlayerPtr); + } + } + + return 1; +} + +/*********************************************************************************************** + * Script_RevealCell - Reveals map around given waypoint TODO: input player * + * * + * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_RevealCell(lua_State* L) { + int ret = lua_tointeger(L, -1); + + if (!PlayerPtr->IsVisionary) { + Map.Sight_From(Scen.Waypoint[ret], Rule.GapShroudRadius, PlayerPtr, false); + } + + return 1; +} + +/*********************************************************************************************** + * Script_RevealZone - Reveals area of map around given waypoint TODO: input player * + * * + * Reveal all cells of the zone that the specified waypoint is located in. This can be * + * used to reveal whole islands or bodies of water * + * * + * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_RevealZone(lua_State* L) { + int ret = lua_tointeger(L, -1); + + if (!PlayerPtr->IsVisionary) { + int zone = Map[Scen.Waypoint[ret]].Zones[MZONE_CRUSHER]; + + for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { + if (Map[cell].Zones[MZONE_CRUSHER] == zone) { Map.Map_Cell(cell, PlayerPtr); } } - return 1; } - /*********************************************************************************************** - * Script_RevealCell - Reveals map around given waypoint TODO: input player * - * * - * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_RevealCell(lua_State* L) { - int ret = lua_tointeger(L, -1); + return 1; +} - if (!PlayerPtr->IsVisionary) { - Map.Sight_From(Scen.Waypoint[ret], Rule.GapShroudRadius, PlayerPtr, false); - } +/*********************************************************************************************** + * Script_PlaySound - Plays the given Sound * + * * + * SCRIPT INPUT: ret (int) - The sound index of which to play * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_PlaySound(lua_State* L) { + int ret = lua_tointeger(L, -1); - return 1; + Sound_Effect((VocType)ret); + + return 1; +} + +/*********************************************************************************************** + * Script_PlayMusic - Plays the given Music score. * + * * + * Plays music score at given index. Negative numbers stop any music playing. * + * * + * SCRIPT INPUT: ret (int) - The music index of which to play * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_PlayMusic(lua_State* L) { + int ret = lua_tointeger(L, -1); + + if (ret < 0) { + Theme.Stop(); + } + else { + Theme.Play_Song((ThemeType)ret); } - /*********************************************************************************************** - * Script_RevealZone - Reveals area of map around given waypoint TODO: input player * - * * - * Reveal all cells of the zone that the specified waypoint is located in. This can be * - * used to reveal whole islands or bodies of water * - * * - * SCRIPT INPUT: ret (int) - The waypoint index of which to reveal * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_RevealZone(lua_State* L) { - int ret = lua_tointeger(L, -1); + return 1; +} - if (!PlayerPtr->IsVisionary) { - int zone = Map[Scen.Waypoint[ret]].Zones[MZONE_CRUSHER]; +/*********************************************************************************************** + * Script_PlaySpeech - Plays the given Speech audio * + * * + * SCRIPT INPUT: ret (int) - The speech index of which to play * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_PlaySpeech(lua_State* L) { + int ret = lua_tointeger(L, -1); + Speak((VoxType)ret); + return 1; +} - for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { - if (Map[cell].Zones[MZONE_CRUSHER] == zone) { - Map.Map_Cell(cell, PlayerPtr); - } - } +/*********************************************************************************************** + * Script_StartMissionTimer - Starts the in-game mission timer * + * * + * SCRIPT INPUT: none * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_StartMissionTimer(lua_State* L) { + Scen.MissionTimer.Start(); + Map.Redraw_Tab(); + return 1; +} - } +/*********************************************************************************************** + * Script_StopMissionTimer - Stops the in-game mission timer * + * * + * SCRIPT INPUT: none * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_StopMissionTimer(lua_State* L) { + Scen.MissionTimer.Stop(); + return 1; +} - return 1; +/*********************************************************************************************** + * Script_IncreaseMissionTimer - Increases the mission timer by the given amount * + * * + * SCRIPT INPUT: ret (int) - amount of time in tenths of a minute to increase by * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_IncreaseMissionTimer(lua_State* L) { + int ret = lua_tointeger(L, -1); + Scen.MissionTimer = Scen.MissionTimer + (ret * (TICKS_PER_MINUTE / 10)); + Map.Redraw_Tab(); + return 1; +} + +/*********************************************************************************************** + * Script_DecreaseMissionTimer - Decreases the mission timer by the given amount * + * * + * SCRIPT INPUT: ret (int) - amount of time in tenths of a minute to decrease by * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_DecreaseMissionTimer(lua_State* L) { + int ret = lua_tointeger(L, -1); + Scen.MissionTimer = Scen.MissionTimer - (ret * (TICKS_PER_MINUTE / 10)); + if (Scen.MissionTimer < 0) { Scen.MissionTimer = 0; } + Map.Redraw_Tab(); + return 1; +} + +/*********************************************************************************************** + * Script_SetMissionTimer - Sets and starts the in-game mission timer * + * * + * SCRIPT INPUT: ret (int) - amount of time in tenths of a minute * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_SetMissionTimer(lua_State* L) { + int ret = lua_tointeger(L, -1); + Scen.MissionTimer = Scen.MissionTimer + (ret * (TICKS_PER_MINUTE / 10)); + Scen.MissionTimer.Start(); + Map.Redraw_Tab(); + return 1; +} + +/*********************************************************************************************** + * Script_SetGlobalValue - Sets the global value to "set" position (on) * + * * + * SCRIPT INPUT: global_value (int) - The global to set to "set" * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_SetGlobalValue(lua_State* L) { + int global_value = lua_tointeger(L, -1); + Scen.Set_Global_To(global_value, true); + return 1; +} + +/*********************************************************************************************** + * Script_ClearGlobalValue - Sets the global value to "clear" position (off) * + * * + * SCRIPT INPUT: global_value (int) - The global to set to "off" * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_ClearGlobalValue(lua_State* L) { + int global_value = lua_tointeger(L, -1); + Scen.Set_Global_To(global_value, false); + return 1; +} + +/*********************************************************************************************** + * Script_AutoBaseBuilding - Sets AI basebuilding on/off for given house * + * * + * SCRIPT INPUT: houseType (int) - The player (house) index of the AI * + * on_off (bool) - Enable / disable auto base building * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AutoBaseBuilding(lua_State* L) { + int houseType = lua_tointeger(L, 1); + bool on_off = lua_toboolean(L, 2); + + HouseClass* this_house = Houses.Ptr(houseType); + if (this_house != NULL) { + this_house->IsBaseBuilding = on_off; } - /*********************************************************************************************** - * Script_PlaySound - Plays the given Sound * - * * - * SCRIPT INPUT: ret (int) - The sound index of which to play * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_PlaySound(lua_State* L) { - int ret = lua_tointeger(L, -1); + return 1; +} - Sound_Effect((VocType)ret); +/*********************************************************************************************** + * Script_StopMissionTimer - Stops the in-game mission timer * + * * + * SCRIPT INPUT: none * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CreepShadow(lua_State* L) { + Map.Encroach_Shadow(PlayerPtr); + return 1; +} - return 1; - } +/*********************************************************************************************** + * Script_DestroyTriggerBuilding - Stops the in-game mission timer * + * * + * SCRIPT INPUT: triggerIndex (int) - The index of the trigger previously created * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_DestroyTriggerBuilding(lua_State* L) { + int triggerIndex = lua_tointeger(L, -1); - /*********************************************************************************************** - * Script_PlayMusic - Plays the given Music score. * - * * - * Plays music score at given index. Negative numbers stop any music playing. * - * * - * SCRIPT INPUT: ret (int) - The music index of which to play * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_PlayMusic(lua_State* L) { - int ret = lua_tointeger(L, -1); + TriggerClass* this_trigger = Triggers.Ptr(triggerIndex); - if (ret < 0) { - Theme.Stop(); - } - else { - Theme.Play_Song((ThemeType)ret); - } - - return 1; - } - - /*********************************************************************************************** - * Script_PlaySpeech - Plays the given Speech audio * - * * - * SCRIPT INPUT: ret (int) - The speech index of which to play * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_PlaySpeech(lua_State* L) { - int ret = lua_tointeger(L, -1); - Speak((VoxType)ret); - return 1; - } - - /*********************************************************************************************** - * Script_StartMissionTimer - Starts the in-game mission timer * - * * - * SCRIPT INPUT: none * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_StartMissionTimer(lua_State* L) { - Scen.MissionTimer.Start(); - Map.Redraw_Tab(); - return 1; - } - - /*********************************************************************************************** - * Script_StopMissionTimer - Stops the in-game mission timer * - * * - * SCRIPT INPUT: none * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_StopMissionTimer(lua_State* L) { - Scen.MissionTimer.Stop(); - return 1; - } - - /*********************************************************************************************** - * Script_IncreaseMissionTimer - Increases the mission timer by the given amount * - * * - * SCRIPT INPUT: ret (int) - amount of time in tenths of a minute to increase by * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_IncreaseMissionTimer(lua_State* L) { - int ret = lua_tointeger(L, -1); - Scen.MissionTimer = Scen.MissionTimer + (ret * (TICKS_PER_MINUTE / 10)); - Map.Redraw_Tab(); - return 1; - } - - /*********************************************************************************************** - * Script_DecreaseMissionTimer - Decreases the mission timer by the given amount * - * * - * SCRIPT INPUT: ret (int) - amount of time in tenths of a minute to decrease by * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_DecreaseMissionTimer(lua_State* L) { - int ret = lua_tointeger(L, -1); - Scen.MissionTimer = Scen.MissionTimer - (ret * (TICKS_PER_MINUTE / 10)); - if (Scen.MissionTimer < 0) { Scen.MissionTimer = 0; } - Map.Redraw_Tab(); - return 1; - } - - /*********************************************************************************************** - * Script_SetMissionTimer - Sets and starts the in-game mission timer * - * * - * SCRIPT INPUT: ret (int) - amount of time in tenths of a minute * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetMissionTimer(lua_State* L) { - int ret = lua_tointeger(L, -1); - Scen.MissionTimer = Scen.MissionTimer + (ret * (TICKS_PER_MINUTE / 10)); - Scen.MissionTimer.Start(); - Map.Redraw_Tab(); - return 1; - } - - /*********************************************************************************************** - * Script_SetGlobalValue - Sets the global value to "set" position (on) * - * * - * SCRIPT INPUT: global_value (int) - The global to set to "set" * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetGlobalValue(lua_State* L) { - int global_value = lua_tointeger(L, -1); - Scen.Set_Global_To(global_value, true); - return 1; - } - - /*********************************************************************************************** - * Script_ClearGlobalValue - Sets the global value to "clear" position (off) * - * * - * SCRIPT INPUT: global_value (int) - The global to set to "off" * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_ClearGlobalValue(lua_State* L) { - int global_value = lua_tointeger(L, -1); - Scen.Set_Global_To(global_value, false); - return 1; - } - - /*********************************************************************************************** - * Script_AutoBaseBuilding - Sets AI basebuilding on/off for given house * - * * - * SCRIPT INPUT: houseType (int) - The player (house) index of the AI * - * on_off (bool) - Enable / disable auto base building * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AutoBaseBuilding(lua_State* L) { - int houseType = lua_tointeger(L, 1); - bool on_off = lua_toboolean(L, 2); - - HouseClass* this_house = Houses.Ptr(houseType); - if (this_house != NULL) { - this_house->IsBaseBuilding = on_off; - } - - return 1; - } - - /*********************************************************************************************** - * Script_StopMissionTimer - Stops the in-game mission timer * - * * - * SCRIPT INPUT: none * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CreepShadow(lua_State* L) { - Map.Encroach_Shadow(PlayerPtr); - return 1; - } - - /*********************************************************************************************** - * Script_DestroyTriggerBuilding - Stops the in-game mission timer * - * * - * SCRIPT INPUT: triggerIndex (int) - The index of the trigger previously created * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_DestroyTriggerBuilding(lua_State* L) { - int triggerIndex = lua_tointeger(L, -1); - - TriggerClass* this_trigger = Triggers.Ptr(triggerIndex); - - if(this_trigger != NULL){ - for (int index = 0; index < Buildings.Count(); index++) { - - BuildingClass* this_building = Buildings.Ptr(index); - - if (this_building->Trigger == this_trigger && this_building->Strength > 0) { - int damage = this_building->Strength; - this_building->Take_Damage(damage, 0, WARHEAD_AP, 0, true); - } - - } - } - - return 1; - } - - /*********************************************************************************************** - * Script_GiveOneTimeSpecialWeapon - Gives specified house a one time special weapon * - * * - * SCRIPT INPUT: weaponType (int) - The special weapon type to give * - * houseType (int) - The player (house) index to give this to (-1 for all) * - * immediate(bool) - should the weapon be fully charged? * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GiveOneTimeSpecialWeapon(lua_State* L) { - - int weaponType = lua_tointeger(L, 1); - - int houseType = -1; - bool immediate = -1; - - // Optional houseType parameter - if (lua_gettop(L) >= 2) { - houseType = lua_tointeger(L, 2); - } - - // Optional immediate parameter - if (lua_gettop(L) >= 2) { - immediate = lua_toboolean(L, 3); - } - - for (int h_index = 0; h_index < Houses.Count(); h_index++) { - - HouseClass* house = Houses.Ptr(h_index); - - if (house->ID == houseType || houseType == -1) { - - house->SuperWeapon[weaponType].Enable(TACTION_1_SPECIAL, true); - - if (immediate) { - house->SuperWeapon[weaponType].Forced_Charge(true); - } - - if (PlayerPtr == house) { - Map.Add(RTTI_SPECIAL, weaponType); - Map.Column[1].Flag_To_Redraw(); - } - - if (houseType >= 0) { - break; - } - } - - } - - return 1; - } - - /*********************************************************************************************** - * Script_GiveSpecialWeapon - Gives specified house a repeating special weapon * - * * - * SCRIPT INPUT: weaponType (int) - The special weapon type to give * - * houseType (int) - The player (house) index to give this to (-1 for all) * - * immediate(bool) - should the weapon be fully charged? * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GiveSpecialWeapon(lua_State* L) { - - int weaponType = lua_tointeger(L, 1); - - int houseType = -1; - bool immediate = -1; - - // Optional houseType parameter - if (lua_gettop(L) >= 2) { - houseType = lua_tointeger(L, 2); - } - - // Optional immediate parameter - if (lua_gettop(L) ==3) { - immediate = lua_toboolean(L, 3); - } - - for (int h_index = 0; h_index < Houses.Count(); h_index++) { - - HouseClass* house = Houses.Ptr(h_index); - - if (house->ID == houseType || houseType == -1) { - - house->SuperWeapon[weaponType].Enable(TACTION_FULL_SPECIAL, true); - - if (immediate) { - house->SuperWeapon[weaponType].Forced_Charge(true); - } - - if (PlayerPtr == house) { - Map.Add(RTTI_SPECIAL, weaponType); - Map.Column[1].Flag_To_Redraw(); - } - - if (houseType >= 0) { - break; - } - } - - } - - return 1; - } - - /*********************************************************************************************** - * Script_DesignatePreferredTarget - Gives specified house a prefferable type of target * - * * - * SCRIPT INPUT: houseType (int) - The player (house) index to set targetting for (or -1) * - * targetType (int) - The target type index to set to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_DesignatePreferredTarget(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - unsigned char targetType = lua_tointeger(L, 2); - - if(targetType >= 1 && targetType <= 11){ - - for (int h_index = 0; h_index < Houses.Count(); h_index++) { - - HouseClass* house = Houses.Ptr(h_index); - - if (house->ID == houseType || houseType == -1) { - - house->PreferredTarget = (QuarryType)targetType; - - // Discontinue giving out free cash if a specific house was specified - if (houseType >= 0) { - break; - } - - } - - } - - } - - return 1; - } - - /*********************************************************************************************** - * Script_LaunchFakeNukes - All nuke silos begin launching duds * - * * - * SCRIPT INPUT: none * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_LaunchFakeNukes(lua_State* L) { - + if (this_trigger != NULL) { for (int index = 0; index < Buildings.Count(); index++) { - BuildingClass* bldg = Buildings.Ptr(index); - if (*bldg == STRUCT_MSLO) { - bldg->Assign_Mission(MISSION_MISSILE); + + BuildingClass* this_building = Buildings.Ptr(index); + + if (this_building->Trigger == this_trigger && this_building->Strength > 0) { + int damage = this_building->Strength; + this_building->Take_Damage(damage, 0, WARHEAD_AP, 0, true); + } + + } + } + + return 1; +} + +/*********************************************************************************************** + * Script_GiveOneTimeSpecialWeapon - Gives specified house a one time special weapon * + * * + * SCRIPT INPUT: weaponType (int) - The special weapon type to give * + * houseType (int) - The player (house) index to give this to (-1 for all) * + * immediate(bool) - should the weapon be fully charged? * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GiveOneTimeSpecialWeapon(lua_State* L) { + + int weaponType = lua_tointeger(L, 1); + + int houseType = -1; + bool immediate = -1; + + // Optional houseType parameter + if (lua_gettop(L) >= 2) { + houseType = lua_tointeger(L, 2); + } + + // Optional immediate parameter + if (lua_gettop(L) >= 2) { + immediate = lua_toboolean(L, 3); + } + + for (int h_index = 0; h_index < Houses.Count(); h_index++) { + + HouseClass* house = Houses.Ptr(h_index); + + if (house->ID == houseType || houseType == -1) { + + house->SuperWeapon[weaponType].Enable(TACTION_1_SPECIAL, true); + + if (immediate) { + house->SuperWeapon[weaponType].Forced_Charge(true); + } + + if (PlayerPtr == house) { + Map.Add(RTTI_SPECIAL, weaponType); + Map.Column[1].Flag_To_Redraw(); + } + + if (houseType >= 0) { + break; } } - return 1; } + return 1; +} + +/*********************************************************************************************** + * Script_GiveSpecialWeapon - Gives specified house a repeating special weapon * + * * + * SCRIPT INPUT: weaponType (int) - The special weapon type to give * + * houseType (int) - The player (house) index to give this to (-1 for all) * + * immediate(bool) - should the weapon be fully charged? * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GiveSpecialWeapon(lua_State* L) { + + int weaponType = lua_tointeger(L, 1); + + int houseType = -1; + bool immediate = -1; + + // Optional houseType parameter + if (lua_gettop(L) >= 2) { + houseType = lua_tointeger(L, 2); + } + + // Optional immediate parameter + if (lua_gettop(L) == 3) { + immediate = lua_toboolean(L, 3); + } + + for (int h_index = 0; h_index < Houses.Count(); h_index++) { + + HouseClass* house = Houses.Ptr(h_index); + + if (house->ID == houseType || houseType == -1) { + + house->SuperWeapon[weaponType].Enable(TACTION_FULL_SPECIAL, true); + + if (immediate) { + house->SuperWeapon[weaponType].Forced_Charge(true); + } + + if (PlayerPtr == house) { + Map.Add(RTTI_SPECIAL, weaponType); + Map.Column[1].Flag_To_Redraw(); + } + + if (houseType >= 0) { + break; + } + } + + } + + return 1; +} + +/*********************************************************************************************** + * Script_DesignatePreferredTarget - Gives specified house a prefferable type of target * + * * + * SCRIPT INPUT: houseType (int) - The player (house) index to set targetting for (or -1) * + * targetType (int) - The target type index to set to * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_DesignatePreferredTarget(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + unsigned char targetType = lua_tointeger(L, 2); + + if (targetType >= 1 && targetType <= 11) { + + for (int h_index = 0; h_index < Houses.Count(); h_index++) { + + HouseClass* house = Houses.Ptr(h_index); + + if (house->ID == houseType || houseType == -1) { + + house->PreferredTarget = (QuarryType)targetType; + + // Discontinue giving out free cash if a specific house was specified + if (houseType >= 0) { + break; + } + + } + + } + + } + + return 1; +} + +/*********************************************************************************************** + * Script_LaunchFakeNukes - All nuke silos begin launching duds * + * * + * SCRIPT INPUT: none * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_LaunchFakeNukes(lua_State* L) { + + for (int index = 0; index < Buildings.Count(); index++) { + BuildingClass* bldg = Buildings.Ptr(index); + if (*bldg == STRUCT_MSLO) { + bldg->Assign_Mission(MISSION_MISSILE); + } + } + + return 1; +} + /********************************************************************************************** * Red Alert Vanilla Events * *=============================================================================================*/ - /*********************************************************************************************** - * Script_CreateCellCallback - Creates an ENTERED_BY trigger and attaches a callback * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index to test for entry * - * in_x (int) - The cell/X location of the cell to test * - * in_y (int) - The cell/Y location of the cell to test * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CellCallback(lua_State* L) { +/*********************************************************************************************** + * Script_CreateCellCallback - Creates an ENTERED_BY trigger and attaches a callback * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index to test for entry * + * in_x (int) - The cell/X location of the cell to test * + * in_y (int) - The cell/Y location of the cell to test * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CellCallback(lua_State* L) { - // TODO: option 6 arguments to allow x2,y2 (for a rect) + // TODO: option 6 arguments to allow x2,y2 (for a rect) - int houseType = lua_tointeger(L, 1); - int in_x = lua_tointeger(L, 2); - int in_y = lua_tointeger(L, 3); + int houseType = lua_tointeger(L, 1); + int in_x = lua_tointeger(L, 2); + int in_y = lua_tointeger(L, 3); - char* in_function = ""; + char* in_function = ""; - // Optional callback function - if (lua_gettop(L) >= 4) { - in_function = (char*)lua_tostring(L, 4); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_PLAYER_ENTERED; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass * this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - // Get the cell and set the trigger - this_trigger->Cell = XY_Cell(in_x, in_y); - Map[XY_Cell(in_x, in_y)].Trigger = this_trigger; - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; + // Optional callback function + if (lua_gettop(L) >= 4) { + in_function = (char*)lua_tostring(L, 4); } - /*********************************************************************************************** - * Script_CreateSpiedByCallback - Creates a SPIED_BY trigger and attaches a callback * - * * - * SCRIPT INPUT: objectID (int) - The building ID being spied * - * houseType (int) - The house (player) index doing the spying * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SpiedByCallback(lua_State* L) { + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { - int objectID = lua_tointeger(L, 1); - int houseType = lua_tointeger(L, 2); - - char* in_function = ""; + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); + this_trigger_type->Event1 = TEVENT_PLAYER_ENTERED; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); } - BuildingClass* this_building = Buildings.Ptr(objectID); + // Get the cell and set the trigger + this_trigger->Cell = XY_Cell(in_x, in_y); + Map[XY_Cell(in_x, in_y)].Trigger = this_trigger; - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count() && this_building != NULL) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)this_building->House->ID; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_SPIED; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - // Set the building - this_building->Trigger = this_trigger; - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); return 1; + } - /*********************************************************************************************** - * Script_CreateDiscoveryCallback - Creates a TEVENT_DISCOVERED trigger and attaches a callback* - * * - * Trigger is sprung when the given object is discovered * - * * - * SCRIPT INPUT: objectID (int) - The object's ID being discovered * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_ObjectDiscoveryCallback(lua_State* L) { + lua_pushnumber(L, -1); - int objectID = lua_tointeger(L, 1); + return 1; +} - char* in_function = ""; +/*********************************************************************************************** + * Script_CreateSpiedByCallback - Creates a SPIED_BY trigger and attaches a callback * + * * + * SCRIPT INPUT: objectID (int) - The building ID being spied * + * houseType (int) - The house (player) index doing the spying * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_SpiedByCallback(lua_State* L) { - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); + int objectID = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + BuildingClass* this_building = Buildings.Ptr(objectID); + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count() && this_building != NULL) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)this_building->House->ID; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_SPIED; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); } - // A house must be specified - if (objectID >= 0 ) { + // Set the building + this_building->Trigger = this_trigger; - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HousesType::HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_DISCOVERED; - this_trigger_type->EventControl = MULTI_ONLY; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - Script_SetObjectTrigger(objectID, this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); return 1; + } - /*********************************************************************************************** - * Script_HouseDiscoveredCallback - Initiates when given house is discovered * - * * - * Trigger is sprung when an object belonging to the given house is discovered * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index that has been discovered * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_HouseDiscoveredCallback(lua_State* L) { + lua_pushnumber(L, -1); - int houseType = lua_tointeger(L, 1); + return 1; +} - char* in_function = ""; +/*********************************************************************************************** + * Script_CreateDiscoveryCallback - Creates a TEVENT_DISCOVERED trigger and attaches a callback* + * * + * Trigger is sprung when the given object is discovered * + * * + * SCRIPT INPUT: objectID (int) - The object's ID being discovered * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_ObjectDiscoveryCallback(lua_State* L) { - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } + int objectID = lua_tointeger(L, 1); - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { + char* in_function = ""; - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::VOLATILE; - - this_trigger_type->Event1 = TEVENT_HOUSE_DISCOVERED; - this_trigger_type->EventControl = MULTI_ONLY; - - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[PlayerPtr->Class->House].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); } - /*********************************************************************************************** - * Script_ObjectAttackedCallback - Trigger that springs when object is attacked by anyone * - * * - * SCRIPT INPUT: objectID (int) - The object's ID being discovered * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_ObjectAttackedCallback(lua_State* L) { - - int objectID = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // An object must be specified - if (objectID >= 0) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HousesType::HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_ATTACKED; - this_trigger_type->EventControl = MULTI_ONLY; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - Script_SetObjectTrigger(objectID, this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_ObjectDestroyedCallback - Trigger that springs when object is destroyed by anyone * - * * - * SCRIPT INPUT: objectID (int) - The object's ID being discovered * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_ObjectDestroyedCallback(lua_State* L) { - - int objectID = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // An object must be specified - if (objectID >= 0) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HousesType::HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_DESTROYED; - this_trigger_type->EventControl = MULTI_ONLY; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - Script_SetObjectTrigger(objectID, this_trigger); - - - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_AnyEventCallback - * - * * - * SCRIPT INPUT: objectID (int) - The object's ID being discovered * - * houseType (int) - The house (player) index * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AnyEventCallback(lua_State* L) { - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 1) { - in_function = (char*)lua_tostring(L, 1); - } + // A house must be specified + if (objectID >= 0) { // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -1457,7 +1214,7 @@ this_trigger_type->IsActive = 1; this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - this_trigger_type->Event1 = TEVENT_ANY; + this_trigger_type->Event1 = TEVENT_DISCOVERED; this_trigger_type->EventControl = MULTI_ONLY; // Create instance of trigger type @@ -1468,7 +1225,7 @@ strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); } - LogicTriggers.Add(this_trigger); + Script_SetObjectTrigger(objectID, this_trigger); // Output the new trigger's ID lua_pushnumber(L, this_trigger->ID); @@ -1477,289 +1234,55 @@ } - /*********************************************************************************************** - * Script_AllUnitsDestroyedCallback - Called when all of a house's units are destroyed * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index owner of said units * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AllUnitsDestroyedCallback(lua_State* L) { + lua_pushnumber(L, -1); - int houseType = lua_tointeger(L, 1); - - char* in_function = ""; + return 1; +} - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } +/*********************************************************************************************** + * Script_HouseDiscoveredCallback - Initiates when given house is discovered * + * * + * Trigger is sprung when an object belonging to the given house is discovered * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index that has been discovered * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_HouseDiscoveredCallback(lua_State* L) { - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { + int houseType = lua_tointeger(L, 1); - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HousesType::HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + char* in_function = ""; - this_trigger_type->Event1 = TEVENT_UNITS_DESTROYED; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); } - /*********************************************************************************************** - * Script_AllBuildingsDestroyedCallback - Called when all of a house's buildings are destroyed* - * * - * SCRIPT INPUT: houseType (int) - The house (player) index owner of said buildings * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AllBuildingsDestroyedCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HousesType::HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_BUILDINGS_DESTROYED; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_AllDestroyedCallback - Called when everything belonging to a house is destyroyed * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index that got pwned * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AllDestroyedCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HousesType::HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_ALL_DESTROYED; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_CreditsReachedCallback - Called when given house meets given amount of credits * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index to test against * - * in_credits (int) - The amount of credits * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CreditsReachedCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int in_credits = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_CREDITS; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value= in_credits; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_TimeReachedCallback - Called when the given amount of time has elapsed * - * * - * SCRIPT INPUT: in_time (int) - The time (in tenths of a second) that was reached * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_TimeReachedCallback(lua_State* L) { - - int in_time = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); this_trigger_type->House = HOUSE_NONE; this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + this_trigger_type->IsPersistant = TriggerTypeClass::VOLATILE; - this_trigger_type->Event1 = TEVENT_TIME; + this_trigger_type->Event1 = TEVENT_HOUSE_DISCOVERED; this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = in_time; + + this_trigger_type->Event1.Data.House = (HousesType)houseType; // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); if (in_function[0] != '\0') { @@ -1767,7 +1290,7 @@ strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); } - LogicTriggers.Add(this_trigger); + HouseTriggers[PlayerPtr->Class->House].Add(this_trigger); // Output the new trigger's ID lua_pushnumber(L, this_trigger->ID); @@ -1776,1034 +1299,39 @@ } - /*********************************************************************************************** - * Script_MissionTimerCallback - Called when the mission timer has expired * - * * - * SCRIPT INPUT: in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_MissionTimerCallback(lua_State* L) { + lua_pushnumber(L, -1); - char* in_function = ""; + return 1; +} - // Optional callback function - if (lua_gettop(L) >= 1) { - in_function = (char*)lua_tostring(L, 1); - } +/*********************************************************************************************** + * Script_ObjectAttackedCallback - Trigger that springs when object is attacked by anyone * + * * + * SCRIPT INPUT: objectID (int) - The object's ID being discovered * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_ObjectAttackedCallback(lua_State* L) { - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + int objectID = lua_tointeger(L, 1); - this_trigger_type->Event1 = TEVENT_MISSION_TIMER_EXPIRED; - this_trigger_type->EventControl = MULTI_ONLY; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - LogicTriggers.Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; + char* in_function = ""; + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); } - /*********************************************************************************************** - * Script_UnitsDestroyedCallback - Called when given number of a house's units are destroyed * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index owner of said units * - * in_number (int) - The number of units that have must be destroyed * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_UnitsDestroyedCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int in_number = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_NUNITS_DESTROYED; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = in_number; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /************************************************************************************************ - * Script_BuildingsDestroyedCallback - Called when number of a house's buildings are destroyed * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index owner of said buildings * - * in_number (int) - The number of buildings that have must be destroyed * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *==============================================================================================*/ - static int Script_BuildingsDestroyedCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int in_number = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_NBUILDINGS_DESTROYED; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = in_number; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_NoFactoriesCallback - Called when no more factories exist for a house * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index that got pwned * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_NoFactoriesCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_NOFACTORIES; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = -1; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_CivilianEscapeCallback - Called when civilians get evacuated from map * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner of civilians escaped * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CivilianEscapeCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_EVAC_CIVILIAN; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = -1; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - LogicTriggers.Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_BuildingBuiltCallback - Called when a specified house builds a specified building * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner that built the building * - * objectType (int) - The index / building type to check for * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_BuildingBuiltCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int objectType = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_BUILD; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = objectType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_UnitBuiltCallback - Called when a specified house builds a specified unit * - * * - * Does not trigger for units that spawn with buildings (ie. ore truck) * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner that built the unit * - * objectType (int) - The index / unit type to check for * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_UnitBuiltCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int objectType = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_BUILD_UNIT; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = objectType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_InfantryBuiltCallback - Called when a specified house builds a specified infantry * - * * - * Does not trigger for infantry gained by selling a building * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner that built the infantry * - * objectType (int) - The index / infantry type to check for * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_InfantryBuiltCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int objectType = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_BUILD_INFANTRY; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = objectType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_AircraftBuiltCallback - Called when a specified house builds a specified aircraft * - * * - * Does not trigger for units that spawn with buildings * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner that built the unit * - * objectType (int) - The index / unit type to check for * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AircraftBuiltCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int objectType = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_BUILD_AIRCRAFT; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = objectType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_TeamLeavesMapCallback - Called when the specified team leaves the map * - * * - * SCRIPT INPUT: in_team (int) - The team index that has left the map * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_TeamLeavesMapCallback(lua_State* L) { - - int in_team = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - TeamTypeClass* this_team = TeamTypes.Ptr(in_team); - - if (this_team != NULL) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = this_team->House; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_LEAVES_MAP; - this_trigger_type->EventControl = MULTI_ONLY; - - - this_trigger_type->Event1.Team = this_team; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - LogicTriggers.Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - // Output the new trigger's ID - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_ZoneEntryCallback - Called when a specified house enters zone of given position * - * * - * Does not trigger for units that spawn with buildings * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner that built the unit * - * in_x (int) - The cell/X location of the cell to test * - * in_y (int) - The cell/Y location of the cell to test * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_ZoneEntryCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int in_x = lua_tointeger(L, 2); - int in_y = lua_tointeger(L, 3); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 4) { - in_function = (char*)lua_tostring(L, 4); - } - - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_ENTERS_ZONE; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - // Get the cell and set the trigger - this_trigger->Cell = XY_Cell(in_x, in_y); - MapTriggers.Add(this_trigger); - - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_HorizontalCrossCallback - Called when a specified house's units cross the given X * - * * - * Does not trigger for units that spawn with buildings * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner that owns the unit * - * in_x (int) - The cell/X location that must be crossed * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_HorizontalCrossCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int in_x = lua_tointeger(L,2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_CROSS_VERTICAL; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - // Find a free spot and set the trigger - int addY = 0; - for (addY = 0; addY < Map.MapCellHeight; addY++) { - TriggerClass* trigger = Map[XY_Cell(in_x, Map.MapCellY + addY)].Trigger; - if (trigger == NULL) { - this_trigger->Cell = XY_Cell(in_x, Map.MapCellY + addY); - Map[XY_Cell(in_x, Map.MapCellY + addY)].Trigger = this_trigger; - break; - } - } - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_VerticalCrossCallback - Called when a specified house's units cross the given Y * - * * - * Does not trigger for units that spawn with buildings * - * * - * SCRIPT INPUT: houseType (int) - The house (player) owner that owns the unit * - * in_y (int) - The cell/Y location that must be crossed * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_VerticalCrossCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - int in_y = lua_tointeger(L, 2); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); - } - - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_CROSS_HORIZONTAL; // <- Their description doesn't make sense, not mine - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - // Find a free spot and set the trigger - int addX = 0; - for (addX = 0; addX < Map.MapCellWidth; addX++) { - TriggerClass* trigger = Map[XY_Cell(Map.MapCellX + addX, in_y)].Trigger; - if (trigger == NULL) { - this_trigger->Cell = XY_Cell(Map.MapCellX+ addX, in_y); - Map[XY_Cell(Map.MapCellX+ addX, in_y)].Trigger = this_trigger; - break; - } - } - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - - } - - /*********************************************************************************************** - * Script_GlobalSetCallback - activated when the global value is in the "set" poisition * - * * - * SCRIPT INPUT: in_global - The global value to set * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GlobalSetCallback(lua_State* L) { - - int in_global = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_GLOBAL_SET; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = in_global; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - LogicTriggers.Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - } - - /*********************************************************************************************** - * Script_GlobalSetCallback - activated when the global value is in the "cleared" poisition * - * * - * SCRIPT INPUT: in_global - The global value to set to "cleared" * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GlobalClearedCallback(lua_State* L) { - - int in_global = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - - this_trigger_type->Event1 = TEVENT_GLOBAL_CLEAR; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = in_global; - - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - LogicTriggers.Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - } - - /*********************************************************************************************** - * Script_LowPowerCallback - Initiates when given house becomes low on power * - * * - * SCRIPT INPUT: houseType (int) - The house (player) index that has been discovered * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_LowPowerCallback(lua_State* L) { - - int houseType = lua_tointeger(L, 1); - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 2) { - in_function = (char*)lua_tostring(L, 2); - } - - // A house must be specified - if (houseType >= 0 && houseType < HouseTypes.Count()) { - - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = HOUSE_NONE; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::VOLATILE; - - this_trigger_type->Event1 = TEVENT_LOW_POWER; - this_trigger_type->EventControl = MULTI_ONLY; - - this_trigger_type->Event1.Data.House = (HousesType)houseType; - - // Create instance of trigger type - - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[PlayerPtr->Class->House].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); - - return 1; - } - - /*********************************************************************************************** - * Script_AllBridgesDestroyedCallback - Called when all map's bridges have been destroyed * - * * - * SCRIPT INPUT: in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_AllBridgesDestroyedCallback(lua_State* L) { - - char* in_function = ""; - - // Optional callback function - if (lua_gettop(L) >= 1) { - in_function = (char*)lua_tostring(L, 1); - } + // An object must be specified + if (objectID >= 0) { // Create trigger type TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); @@ -2811,7 +1339,7 @@ this_trigger_type->IsActive = 1; this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; - this_trigger_type->Event1 = TEVENT_ALL_BRIDGES_DESTROYED; + this_trigger_type->Event1 = TEVENT_ATTACKED; this_trigger_type->EventControl = MULTI_ONLY; // Create instance of trigger type @@ -2822,6 +1350,1037 @@ strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); } + Script_SetObjectTrigger(objectID, this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_ObjectDestroyedCallback - Trigger that springs when object is destroyed by anyone * + * * + * SCRIPT INPUT: objectID (int) - The object's ID being discovered * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_ObjectDestroyedCallback(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // An object must be specified + if (objectID >= 0) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HousesType::HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_DESTROYED; + this_trigger_type->EventControl = MULTI_ONLY; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + Script_SetObjectTrigger(objectID, this_trigger); + + + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_AnyEventCallback - * + * * + * SCRIPT INPUT: objectID (int) - The object's ID being discovered * + * houseType (int) - The house (player) index * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AnyEventCallback(lua_State* L) { + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 1) { + in_function = (char*)lua_tostring(L, 1); + } + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HousesType::HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_ANY; + this_trigger_type->EventControl = MULTI_ONLY; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + LogicTriggers.Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + +} + +/*********************************************************************************************** + * Script_AllUnitsDestroyedCallback - Called when all of a house's units are destroyed * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index owner of said units * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AllUnitsDestroyedCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HousesType::HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_UNITS_DESTROYED; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_AllBuildingsDestroyedCallback - Called when all of a house's buildings are destroyed* + * * + * SCRIPT INPUT: houseType (int) - The house (player) index owner of said buildings * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AllBuildingsDestroyedCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HousesType::HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_BUILDINGS_DESTROYED; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_AllDestroyedCallback - Called when everything belonging to a house is destyroyed * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index that got pwned * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AllDestroyedCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HousesType::HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_ALL_DESTROYED; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_CreditsReachedCallback - Called when given house meets given amount of credits * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index to test against * + * in_credits (int) - The amount of credits * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CreditsReachedCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int in_credits = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_CREDITS; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = in_credits; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_TimeReachedCallback - Called when the given amount of time has elapsed * + * * + * SCRIPT INPUT: in_time (int) - The time (in tenths of a second) that was reached * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_TimeReachedCallback(lua_State* L) { + + int in_time = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_TIME; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = in_time; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + LogicTriggers.Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + +} + +/*********************************************************************************************** + * Script_MissionTimerCallback - Called when the mission timer has expired * + * * + * SCRIPT INPUT: in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_MissionTimerCallback(lua_State* L) { + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 1) { + in_function = (char*)lua_tostring(L, 1); + } + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_MISSION_TIMER_EXPIRED; + this_trigger_type->EventControl = MULTI_ONLY; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + LogicTriggers.Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + +} + +/*********************************************************************************************** + * Script_UnitsDestroyedCallback - Called when given number of a house's units are destroyed * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index owner of said units * + * in_number (int) - The number of units that have must be destroyed * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_UnitsDestroyedCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int in_number = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_NUNITS_DESTROYED; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = in_number; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/************************************************************************************************ + * Script_BuildingsDestroyedCallback - Called when number of a house's buildings are destroyed * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index owner of said buildings * + * in_number (int) - The number of buildings that have must be destroyed * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *==============================================================================================*/ +static int Script_BuildingsDestroyedCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int in_number = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_NBUILDINGS_DESTROYED; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = in_number; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_NoFactoriesCallback - Called when no more factories exist for a house * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index that got pwned * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_NoFactoriesCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_NOFACTORIES; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = -1; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_CivilianEscapeCallback - Called when civilians get evacuated from map * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner of civilians escaped * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CivilianEscapeCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_EVAC_CIVILIAN; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = -1; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + LogicTriggers.Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + } + + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_BuildingBuiltCallback - Called when a specified house builds a specified building * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner that built the building * + * objectType (int) - The index / building type to check for * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_BuildingBuiltCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int objectType = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_BUILD; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = objectType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_UnitBuiltCallback - Called when a specified house builds a specified unit * + * * + * Does not trigger for units that spawn with buildings (ie. ore truck) * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner that built the unit * + * objectType (int) - The index / unit type to check for * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_UnitBuiltCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int objectType = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_BUILD_UNIT; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = objectType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_InfantryBuiltCallback - Called when a specified house builds a specified infantry * + * * + * Does not trigger for infantry gained by selling a building * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner that built the infantry * + * objectType (int) - The index / infantry type to check for * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_InfantryBuiltCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int objectType = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_BUILD_INFANTRY; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = objectType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_AircraftBuiltCallback - Called when a specified house builds a specified aircraft * + * * + * Does not trigger for units that spawn with buildings * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner that built the unit * + * objectType (int) - The index / unit type to check for * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AircraftBuiltCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int objectType = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + if (objectType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_BUILD_AIRCRAFT; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = objectType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_TeamLeavesMapCallback - Called when the specified team leaves the map * + * * + * SCRIPT INPUT: in_team (int) - The team index that has left the map * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_TeamLeavesMapCallback(lua_State* L) { + + int in_team = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + TeamTypeClass* this_team = TeamTypes.Ptr(in_team); + + if (this_team != NULL) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = this_team->House; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_LEAVES_MAP; + this_trigger_type->EventControl = MULTI_ONLY; + + + this_trigger_type->Event1.Team = this_team; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + LogicTriggers.Add(this_trigger); // Output the new trigger's ID @@ -2831,315 +2390,784 @@ } - /*********************************************************************************************** - * Script_BuildingExistsCallback - Called if a given building exists for a given house * - * * - * SCRIPT INPUT: buildingType (int) - The building type to check for * - * houseType (int) - The house (player) index owner of said building * - * in_function (string) - The callback function to execute upon trigger * - * * - * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_BuildingExistsCallback(lua_State* L) { + // Output the new trigger's ID + lua_pushnumber(L, -1); - int buildingType = lua_tointeger(L, 1); - int houseType = lua_tointeger(L,2); + return 1; - char* in_function = ""; +} - // Optional callback function - if (lua_gettop(L) >= 3) { - in_function = (char*)lua_tostring(L, 3); +/*********************************************************************************************** + * Script_ZoneEntryCallback - Called when a specified house enters zone of given position * + * * + * Does not trigger for units that spawn with buildings * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner that built the unit * + * in_x (int) - The cell/X location of the cell to test * + * in_y (int) - The cell/Y location of the cell to test * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_ZoneEntryCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int in_x = lua_tointeger(L, 2); + int in_y = lua_tointeger(L, 3); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 4) { + in_function = (char*)lua_tostring(L, 4); + } + + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_ENTERS_ZONE; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); } - // A house must be specified - if (buildingType>=0 && houseType >= 0 && houseType < HouseTypes.Count()) { + // Get the cell and set the trigger + this_trigger->Cell = XY_Cell(in_x, in_y); + MapTriggers.Add(this_trigger); - // Create trigger type - TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); - this_trigger_type->House = (HousesType)houseType; - this_trigger_type->IsActive = 1; - this_trigger_type->IsPersistant = TriggerTypeClass::VOLATILE; - this_trigger_type->Event1 = TEVENT_BUILDING_EXISTS; - this_trigger_type->EventControl = MULTI_ONLY; - this_trigger_type->Event1.Data.Value = buildingType; - // Create instance of trigger type - TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); - - if (in_function[0] != '\0') { - // Copy the callback function into the trigger - strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); - } - - HouseTriggers[(HousesType)houseType].Add(this_trigger); - - // Output the new trigger's ID - lua_pushnumber(L, this_trigger->ID); - - return 1; - - } - - lua_pushnumber(L, -1); + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); return 1; + } + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_HorizontalCrossCallback - Called when a specified house's units cross the given X * + * * + * Does not trigger for units that spawn with buildings * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner that owns the unit * + * in_x (int) - The cell/X location that must be crossed * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_HorizontalCrossCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int in_x = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_CROSS_VERTICAL; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + // Find a free spot and set the trigger + int addY = 0; + for (addY = 0; addY < Map.MapCellHeight; addY++) { + TriggerClass* trigger = Map[XY_Cell(in_x, Map.MapCellY + addY)].Trigger; + if (trigger == NULL) { + this_trigger->Cell = XY_Cell(in_x, Map.MapCellY + addY); + Map[XY_Cell(in_x, Map.MapCellY + addY)].Trigger = this_trigger; + break; + } + } + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_VerticalCrossCallback - Called when a specified house's units cross the given Y * + * * + * Does not trigger for units that spawn with buildings * + * * + * SCRIPT INPUT: houseType (int) - The house (player) owner that owns the unit * + * in_y (int) - The cell/Y location that must be crossed * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_VerticalCrossCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + int in_y = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_CROSS_HORIZONTAL; // <- Their description doesn't make sense, not mine + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + // Find a free spot and set the trigger + int addX = 0; + for (addX = 0; addX < Map.MapCellWidth; addX++) { + TriggerClass* trigger = Map[XY_Cell(Map.MapCellX + addX, in_y)].Trigger; + if (trigger == NULL) { + this_trigger->Cell = XY_Cell(Map.MapCellX + addX, in_y); + Map[XY_Cell(Map.MapCellX + addX, in_y)].Trigger = this_trigger; + break; + } + } + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; + +} + +/*********************************************************************************************** + * Script_GlobalSetCallback - activated when the global value is in the "set" poisition * + * * + * SCRIPT INPUT: in_global - The global value to set * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GlobalSetCallback(lua_State* L) { + + int in_global = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_GLOBAL_SET; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = in_global; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + LogicTriggers.Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; +} + +/*********************************************************************************************** + * Script_GlobalSetCallback - activated when the global value is in the "cleared" poisition * + * * + * SCRIPT INPUT: in_global - The global value to set to "cleared" * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GlobalClearedCallback(lua_State* L) { + + int in_global = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_GLOBAL_CLEAR; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = in_global; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + LogicTriggers.Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; +} + +/*********************************************************************************************** + * Script_LowPowerCallback - Initiates when given house becomes low on power * + * * + * SCRIPT INPUT: houseType (int) - The house (player) index that has been discovered * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_LowPowerCallback(lua_State* L) { + + int houseType = lua_tointeger(L, 1); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 2) { + in_function = (char*)lua_tostring(L, 2); + } + + // A house must be specified + if (houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::VOLATILE; + + this_trigger_type->Event1 = TEVENT_LOW_POWER; + this_trigger_type->EventControl = MULTI_ONLY; + + this_trigger_type->Event1.Data.House = (HousesType)houseType; + + // Create instance of trigger type + + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[PlayerPtr->Class->House].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + +/*********************************************************************************************** + * Script_AllBridgesDestroyedCallback - Called when all map's bridges have been destroyed * + * * + * SCRIPT INPUT: in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_AllBridgesDestroyedCallback(lua_State* L) { + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 1) { + in_function = (char*)lua_tostring(L, 1); + } + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = HousesType::HOUSE_NONE; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::PERSISTANT; + + this_trigger_type->Event1 = TEVENT_ALL_BRIDGES_DESTROYED; + this_trigger_type->EventControl = MULTI_ONLY; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + LogicTriggers.Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + +} + +/*********************************************************************************************** + * Script_BuildingExistsCallback - Called if a given building exists for a given house * + * * + * SCRIPT INPUT: buildingType (int) - The building type to check for * + * houseType (int) - The house (player) index owner of said building * + * in_function (string) - The callback function to execute upon trigger * + * * + * SCRIPT OUTPUT: triggerID - The ID of the trigger created for use with Trigger Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_BuildingExistsCallback(lua_State* L) { + + int buildingType = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + + char* in_function = ""; + + // Optional callback function + if (lua_gettop(L) >= 3) { + in_function = (char*)lua_tostring(L, 3); + } + + // A house must be specified + if (buildingType >= 0 && houseType >= 0 && houseType < HouseTypes.Count()) { + + // Create trigger type + TriggerTypeClass* this_trigger_type = new TriggerTypeClass(); + this_trigger_type->House = (HousesType)houseType; + this_trigger_type->IsActive = 1; + this_trigger_type->IsPersistant = TriggerTypeClass::VOLATILE; + this_trigger_type->Event1 = TEVENT_BUILDING_EXISTS; + this_trigger_type->EventControl = MULTI_ONLY; + this_trigger_type->Event1.Data.Value = buildingType; + + // Create instance of trigger type + TriggerClass* this_trigger = Find_Or_Make(this_trigger_type); + + if (in_function[0] != '\0') { + // Copy the callback function into the trigger + strncpy(this_trigger->MapScriptCallback, in_function, sizeof(this_trigger->MapScriptCallback) - 1); + } + + HouseTriggers[(HousesType)houseType].Add(this_trigger); + + // Output the new trigger's ID + lua_pushnumber(L, this_trigger->ID); + + return 1; + + } + + lua_pushnumber(L, -1); + + return 1; +} + /********************************************************************************************** * Trigger Utility Functions * *=============================================================================================*/ - /*********************************************************************************************** - * Script_Script_TriggerAddCell - Adds a cell to any cell based callback * - * * - * The map editor will always be the fastest way to do this, but here in case it's needed * - * * - * SCRIPT INPUT: triggerIndex (int) - The trigger ID of which to add a cell * - * in_x (int) - The Cell/X location of the new cell * - * in_y (int) - The Cell/Y location of the new cell * - * in_x2 (int) (opt. gr. 2) - The second Cell/X location (for bounding box) * - * in_y2 (int) (opt. gr. 2) - The second Cell/Y location (for bounding box) * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_TriggerAddCell(lua_State* L) { +/*********************************************************************************************** + * Script_Script_TriggerAddCell - Adds a cell to any cell based callback * + * * + * The map editor will always be the fastest way to do this, but here in case it's needed * + * * + * SCRIPT INPUT: triggerIndex (int) - The trigger ID of which to add a cell * + * in_x (int) - The Cell/X location of the new cell * + * in_y (int) - The Cell/Y location of the new cell * + * in_x2 (int) (opt. gr. 2) - The second Cell/X location (for bounding box) * + * in_y2 (int) (opt. gr. 2) - The second Cell/Y location (for bounding box) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_TriggerAddCell(lua_State* L) { - int triggerIndex = lua_tointeger(L, 1); + int triggerIndex = lua_tointeger(L, 1); - int in_x = lua_tointeger(L, 2); - int in_y = lua_tointeger(L, 3); + int in_x = lua_tointeger(L, 2); + int in_y = lua_tointeger(L, 3); - int in_x2=in_x; - int in_y2=in_y; + int in_x2 = in_x; + int in_y2 = in_y; - // Optional secondary group bounding box parameter - if (lua_gettop(L) == 5) { - in_x2 = lua_tointeger(L, 4); - in_y2 = lua_tointeger(L, 5); - } + // Optional secondary group bounding box parameter + if (lua_gettop(L) == 5) { + in_x2 = lua_tointeger(L, 4); + in_y2 = lua_tointeger(L, 5); + } - TriggerClass* this_trigger = Triggers.Ptr(triggerIndex); + TriggerClass* this_trigger = Triggers.Ptr(triggerIndex); - if(this_trigger != NULL){ - for (int _x = in_x; _x <= in_x2; _x++) { - for (int _y = in_y; _y <= in_y2; _y++) { - Map[XY_Cell(_x, _y)].Trigger = this_trigger; - } + if (this_trigger != NULL) { + for (int _x = in_x; _x <= in_x2; _x++) { + for (int _y = in_y; _y <= in_y2; _y++) { + Map[XY_Cell(_x, _y)].Trigger = this_trigger; } } - - + } + + + return 1; +} + +/*********************************************************************************************** + * Script_SetTriggerCallback - Adds a lua callback to an existing trigger * + * * + * SCRIPT INPUT: triggerIndex (int) - The trigger of which to get * + * * + * callbackName (string) - The function name to be called when the * + * actions have been met * + * * + * actionIndex (int) (opt.) - 0: always callback on any of the given paths * + * of the trigger * + * 1: only callback on first action * + * 2: only callback on second action * + * * + * SCRIPT OUTPUT: result (number) - The amount of matching buildings for that player * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_SetTriggerCallback(lua_State* L) { + + int triggerIndex = lua_tointeger(L, 1); + + const char* callbackName = lua_tostring(L, 2); + char actionIndex = 0; + + // Optional actionIndex parameter + if (lua_gettop(L) == 3) { + actionIndex = lua_tointeger(L, 2); + } + + TriggerClass* trigger = Triggers.Ptr(triggerIndex); + + if (trigger != NULL) { + + strncpy(trigger->MapScriptCallback, callbackName, sizeof(trigger->MapScriptCallback) - 1); + trigger->MapScriptActionIndex = actionIndex; + + } + + return 1; +} + +/*********************************************************************************************** + * Script_GetCellObject - Gets an object (if any) on a cell and returns the ID * + * * + * SCRIPT INPUT: in_x (int) - The cell/X location of the cell to pick from * + * in_y (int) - The cell/Y location of the cell to pick from * + * * + * SCRIPT OUTPUT: result (number) - The ID of the building on the cell, or -1 if none * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GetCellObject(lua_State* L) { + + int in_x = lua_tointeger(L, 1); + int in_y = lua_tointeger(L, 2); + + long result = -1; + + ObjectClass* this_object = Map[XY_Cell(in_x, in_y)].Cell_Object(); + + if (this_object == NULL) { + + lua_pushnumber(L, -1); return 1; } - /*********************************************************************************************** - * Script_SetTriggerCallback - Adds a lua callback to an existing trigger * - * * - * SCRIPT INPUT: triggerIndex (int) - The trigger of which to get * - * * - * callbackName (string) - The function name to be called when the * - * actions have been met * - * * - * actionIndex (int) (opt.) - 0: always callback on any of the given paths * - * of the trigger * - * 1: only callback on first action * - * 2: only callback on second action * - * * - * SCRIPT OUTPUT: result (number) - The amount of matching buildings for that player * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetTriggerCallback(lua_State* L) { + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - int triggerIndex = lua_tointeger(L, 1); + CacheObject->ID = this_object->ID; + CacheObject->RTTI = this_object->RTTI; + CacheObject->classIndex = -1; - const char* callbackName = lua_tostring(L, 2); - char actionIndex = 0; - - // Optional actionIndex parameter - if (lua_gettop(L) == 3) { - actionIndex = lua_tointeger(L, 2); - } - - TriggerClass* trigger = Triggers.Ptr(triggerIndex); - - if (trigger != NULL) { - - strncpy(trigger->MapScriptCallback, callbackName, sizeof(trigger->MapScriptCallback) - 1); - trigger->MapScriptActionIndex = actionIndex; - - } - - return 1; + switch (this_object->RTTI) { + case RTTI_BUILDING: { + CacheObject->classIndex = Script_BuildingIndexFromID(this_object->ID); + }break; + case RTTI_UNIT: { + CacheObject->classIndex = Script_UnitIndexFromID(this_object->ID); + }break; + case RTTI_AIRCRAFT: { + CacheObject->classIndex = Script_AircraftIndexFromID(this_object->ID); + }break; + case RTTI_INFANTRY: { + CacheObject->classIndex = Script_InfantryIndexFromID(this_object->ID); + }break; + case RTTI_VESSEL: { + CacheObject->classIndex = Script_VesselIndexFromID(this_object->ID); + }break; } - /*********************************************************************************************** - * Script_GetCellObject - Gets an object (if any) on a cell and returns the ID * - * * - * SCRIPT INPUT: in_x (int) - The cell/X location of the cell to pick from * - * in_y (int) - The cell/Y location of the cell to pick from * - * * - * SCRIPT OUTPUT: result (number) - The ID of the building on the cell, or -1 if none * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetCellObject(lua_State* L) { - - int in_x = lua_tointeger(L, 1); - int in_y = lua_tointeger(L, 2); - - long result = -1; - - ObjectClass* this_object = Map[XY_Cell(in_x, in_y)].Cell_Object(); - - if (this_object == NULL) { - - lua_pushnumber(L, -1); - return 1; - } - - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - - CacheObject->ID = this_object->ID; - CacheObject->RTTI = this_object->RTTI; - CacheObject->classIndex = -1; - - switch (this_object->RTTI) { - case RTTI_BUILDING: { - CacheObject->classIndex = Script_BuildingIndexFromID(this_object->ID); - }break; - case RTTI_UNIT: { - CacheObject->classIndex = Script_UnitIndexFromID(this_object->ID); - }break; - case RTTI_AIRCRAFT: { - CacheObject->classIndex = Script_AircraftIndexFromID(this_object->ID); - }break; - case RTTI_INFANTRY: { - CacheObject->classIndex = Script_InfantryIndexFromID(this_object->ID); - }break; - case RTTI_VESSEL: { - CacheObject->classIndex = Script_VesselIndexFromID(this_object->ID); - }break; - } - - if (CacheObject->classIndex == -1 || CacheObject->ID < 0) { - delete CacheObject; - lua_pushnumber(L, -1); - } - else { - Scen.mapScript->ObjectCache.push_back(CacheObject); - lua_pushnumber(L, CacheObject->UID); // Return UID for faster lookup - } - - return 1; + if (CacheObject->classIndex == -1 || CacheObject->ID < 0) { + delete CacheObject; + lua_pushnumber(L, -1); + } + else { + Scen.mapScript->ObjectCache.push_back(CacheObject); + lua_pushnumber(L, CacheObject->UID); // Return UID for faster lookup } - /*********************************************************************************************** - * Script_Merge_Triggers - Adds the event from trigger 2 to trigger 1 and discards trigger 2 * - * * - * SCRIPT INPUT: triggerIndex (int) - The trigger ID of which will be the result * - * mergeTriggerIndex (int)- The trigger ID of which is being merged * - * * - * SCRIPT OUTPUT: result (number) - The amount of matching buildings for that player * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_MergeTriggers(lua_State* L) { + return 1; +} - int triggerIndex = lua_tointeger(L, 1); - int mergeTriggerIndex = lua_tointeger(L, 2); +/*********************************************************************************************** + * Script_Merge_Triggers - Adds the event from trigger 2 to trigger 1 and discards trigger 2 * + * * + * SCRIPT INPUT: triggerIndex (int) - The trigger ID of which will be the result * + * mergeTriggerIndex (int)- The trigger ID of which is being merged * + * * + * SCRIPT OUTPUT: result (number) - The amount of matching buildings for that player * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_MergeTriggers(lua_State* L) { - TriggerClass* resulting_trigger = Triggers.Ptr(triggerIndex); - TriggerTypeClass* resulting_trigger_type = resulting_trigger->Class; - TriggerClass* merge_trigger = Triggers.Ptr(mergeTriggerIndex); + int triggerIndex = lua_tointeger(L, 1); + int mergeTriggerIndex = lua_tointeger(L, 2); - if (resulting_trigger != NULL && merge_trigger != NULL) { + TriggerClass* resulting_trigger = Triggers.Ptr(triggerIndex); + TriggerTypeClass* resulting_trigger_type = resulting_trigger->Class; + TriggerClass* merge_trigger = Triggers.Ptr(mergeTriggerIndex); - // Set event 2 to event 1 of the merge trigger - resulting_trigger_type->Event2.Event = (TEventType)merge_trigger->Class->Event1.Event; - resulting_trigger_type->Event2.Data.Value = (long)merge_trigger->Class->Event1.Data.Value; - resulting_trigger_type->Event2.Team = (TeamTypeClass*)merge_trigger->Class->Event1.Team; + if (resulting_trigger != NULL && merge_trigger != NULL) { - // Make this an "AND" coniditional trigger (event 1 AND event 2) - resulting_trigger->Class->EventControl = MULTI_AND; - resulting_trigger->Class->ActionControl = MULTI_ONLY; + // Set event 2 to event 1 of the merge trigger + resulting_trigger_type->Event2.Event = (TEventType)merge_trigger->Class->Event1.Event; + resulting_trigger_type->Event2.Data.Value = (long)merge_trigger->Class->Event1.Data.Value; + resulting_trigger_type->Event2.Team = (TeamTypeClass*)merge_trigger->Class->Event1.Team; - // TODO: only do these individual cleanups for actions that they represent (for efficiency) + // Make this an "AND" coniditional trigger (event 1 AND event 2) + resulting_trigger->Class->EventControl = MULTI_AND; + resulting_trigger->Class->ActionControl = MULTI_ONLY; - // Now switch over any LogicTrigger references (we're getting rid of the second trigger) - for (int t_index = 0; t_index < LogicTriggers.Count(); t_index++) { + // TODO: only do these individual cleanups for actions that they represent (for efficiency) - TriggerClass* _trigger = LogicTriggers[t_index]; + // Now switch over any LogicTrigger references (we're getting rid of the second trigger) + for (int t_index = 0; t_index < LogicTriggers.Count(); t_index++) { + TriggerClass* _trigger = LogicTriggers[t_index]; + + if (_trigger == merge_trigger) { + + LogicTriggers.Delete(t_index); + + bool find_existing_result; + for (int t2_index = 0; t2_index < LogicTriggers.Count(); t2_index++) { + if (LogicTriggers[t2_index] == resulting_trigger) { + find_existing_result = true; + break; + } + } + if (!find_existing_result) { + LogicTriggers.Add(resulting_trigger); + } + + break; + } + + } + + // Now switch over any MapTrigger references (we're getting rid of the second trigger) + for (int t_index = 0; t_index < MapTriggers.Count(); t_index++) { + TriggerClass* _trigger = MapTriggers[t_index]; + + if (_trigger != NULL) { if (_trigger == merge_trigger) { - LogicTriggers.Delete(t_index); + MapTriggers.Delete(t_index); bool find_existing_result; - for (int t2_index = 0; t2_index < LogicTriggers.Count(); t2_index++) { - if (LogicTriggers[t2_index] == resulting_trigger) { + for (int t2_index = 0; t2_index < MapTriggers.Count(); t2_index++) { + if (MapTriggers[t2_index] == resulting_trigger) { find_existing_result = true; break; } } if (!find_existing_result) { - LogicTriggers.Add(resulting_trigger); + MapTriggers.Add(resulting_trigger); } break; } - } - // Now switch over any MapTrigger references (we're getting rid of the second trigger) - for (int t_index = 0; t_index < MapTriggers.Count(); t_index++) { - TriggerClass* _trigger = MapTriggers[t_index]; + } + + // Now switch over any HouseTrigger references (we're getting rid of the second trigger) + for (int h_index = 0; h_index < Houses.Count(); h_index++) { + for (int t_index = 0; t_index < HouseTriggers[h_index].Count(); t_index++) { + + TriggerClass* _trigger = HouseTriggers[h_index][t_index]; if (_trigger != NULL) { if (_trigger == merge_trigger) { - MapTriggers.Delete(t_index); + HouseTriggers[h_index].Delete(t_index); bool find_existing_result; - for (int t2_index = 0; t2_index < MapTriggers.Count(); t2_index++) { - if (MapTriggers[t2_index] == resulting_trigger) { + for (int t2_index = 0; t2_index < HouseTriggers[h_index].Count(); t2_index++) { + if (HouseTriggers[h_index][t2_index] == resulting_trigger) { find_existing_result = true; break; } } if (!find_existing_result) { - MapTriggers.Add(resulting_trigger); + HouseTriggers[h_index].Add(resulting_trigger); } break; @@ -3147,2564 +3175,2543 @@ } } - - // Now switch over any HouseTrigger references (we're getting rid of the second trigger) - for (int h_index = 0; h_index < Houses.Count(); h_index++) { - for (int t_index = 0; t_index < HouseTriggers[h_index].Count(); t_index++) { - - TriggerClass* _trigger = HouseTriggers[h_index][t_index]; - - if(_trigger != NULL){ - if (_trigger == merge_trigger) { - - HouseTriggers[h_index].Delete(t_index); - - bool find_existing_result; - for (int t2_index = 0; t2_index < HouseTriggers[h_index].Count(); t2_index++) { - if (HouseTriggers[h_index][t2_index] == resulting_trigger) { - find_existing_result = true; - break; - } - } - if (!find_existing_result) { - HouseTriggers[h_index].Add(resulting_trigger); - } - - break; - } - } - - } - } - - // Go through the map and replace any celltriggers - for (int _x = Map.MapCellX; _x <= Map.MapCellX + Map.MapCellWidth; _x++) { - for (int _y = Map.MapCellY; _y <= Map.MapCellY + Map.MapCellHeight; _y++) { - if (Map[XY_Cell(_x, _y)].Trigger == merge_trigger) { - Map[XY_Cell(_x, _y)].Trigger = resulting_trigger; - } - } - } - - // Now that we've merged the contents, and it's no longer being referred to, we can safely delete the merge trigger - Detach_This_From_All(merge_trigger->As_Target()); - delete merge_trigger; } - return 1; - } - - /*********************************************************************************************** - * Script_GetTriggerByName - Gets the trigger with a given name * - * * - * SCRIPT INPUT: triggerName (string); The input trigger name * - * * - * SCRIPT OUTPUT: triggerID (int) - The index of the trigger with this name * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetTriggerByName(lua_State* L) { - - const char* triggerName= lua_tostring(L, 1); - - // Find the trigger and set up callback - for (int t_index = 0; t_index < Triggers.Count(); t_index++) { - TriggerClass* trigger = Triggers.Ptr(t_index); - - if (trigger != NULL) { - - if (strcmp(trigger->Name(), triggerName) == 0) { - - TriggerTypeClass* this_type = trigger->Class; - lua_pushnumber(L, t_index); - - return 1; - - break; + // Go through the map and replace any celltriggers + for (int _x = Map.MapCellX; _x <= Map.MapCellX + Map.MapCellWidth; _x++) { + for (int _y = Map.MapCellY; _y <= Map.MapCellY + Map.MapCellHeight; _y++) { + if (Map[XY_Cell(_x, _y)].Trigger == merge_trigger) { + Map[XY_Cell(_x, _y)].Trigger = resulting_trigger; } - } - } - lua_pushnumber(L, -1); - - return -1; + // Now that we've merged the contents, and it's no longer being referred to, we can safely delete the merge trigger + Detach_This_From_All(merge_trigger->As_Target()); + delete merge_trigger; } - /*********************************************************************************************** - * Script_TriggerSetPersistence - Sets whether a trigger runs once or indefinitely * - * * - * SCRIPT INPUT: triggerIndex (int) - The trigger ID of which this will apply * - * isPersistent (int) - The persistence value * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_TriggerSetPersistence(lua_State* L) { + return 1; +} - int triggerIndex = lua_tointeger(L, 1); - unsigned char isPersistent = lua_tointeger(L, 2); +/*********************************************************************************************** + * Script_GetTriggerByName - Gets the trigger with a given name * + * * + * SCRIPT INPUT: triggerName (string); The input trigger name * + * * + * SCRIPT OUTPUT: triggerID (int) - The index of the trigger with this name * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GetTriggerByName(lua_State* L) { - TriggerClass* trigger = Triggers.Ptr(triggerIndex); + const char* triggerName = lua_tostring(L, 1); + + // Find the trigger and set up callback + for (int t_index = 0; t_index < Triggers.Count(); t_index++) { + TriggerClass* trigger = Triggers.Ptr(t_index); if (trigger != NULL) { - TriggerTypeClass* trigger_type = trigger->Class; + if (strcmp(trigger->Name(), triggerName) == 0) { - trigger_type->IsPersistant = (TriggerTypeClass::PersistantType)isPersistent; + TriggerTypeClass* this_type = trigger->Class; + lua_pushnumber(L, t_index); + return 1; + + break; + } } - return -1; } + lua_pushnumber(L, -1); + + return -1; +} + +/*********************************************************************************************** + * Script_TriggerSetPersistence - Sets whether a trigger runs once or indefinitely * + * * + * SCRIPT INPUT: triggerIndex (int) - The trigger ID of which this will apply * + * isPersistent (int) - The persistence value * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_TriggerSetPersistence(lua_State* L) { + + int triggerIndex = lua_tointeger(L, 1); + unsigned char isPersistent = lua_tointeger(L, 2); + + TriggerClass* trigger = Triggers.Ptr(triggerIndex); + + if (trigger != NULL) { + + TriggerTypeClass* trigger_type = trigger->Class; + + trigger_type->IsPersistant = (TriggerTypeClass::PersistantType)isPersistent; + + + } + + return -1; +} + /********************************************************************************************** * Modification Utility Functions * *=============================================================================================*/ - - /********************************************************************************************** - * Script_SetObjectAttribute - Sets attributes for specific objects or object types * - * * - * SCRIPT INPUT: objectID (int) - The ID of the object * - * attribute_type (int) - The attribute to change * - * attribute_value (int) - The value to set the attribute to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetObjectAttribute(lua_State* L) { - int objectID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); +/********************************************************************************************** +* Script_SetObjectAttribute - Sets attributes for specific objects or object types * +* * +* SCRIPT INPUT: objectID (int) - The ID of the object * +* attribute_type (int) - The attribute to change * +* attribute_value (int) - The value to set the attribute to * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetObjectAttribute(lua_State* L) { - ObjectClass* this_object = Script_GetCacheObject(objectID); + int objectID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); - // Get the appropriate technotype - if (this_object != NULL) { + ObjectClass* this_object = Script_GetCacheObject(objectID); - // Global attributes / Multi object attributes - switch ((MapScriptObjectAttributeType)attribute_type) { - case ATTRIBUTE_TYPE: { + // Get the appropriate technotype + if (this_object != NULL) { - }break; - case ATTRIBUTE_STRENGTH: { + // Global attributes / Multi object attributes + switch ((MapScriptObjectAttributeType)attribute_type) { + case ATTRIBUTE_TYPE: { - int attribute_value = lua_tointeger(L, 3); - this_object->Strength = attribute_value; + }break; + case ATTRIBUTE_STRENGTH: { - }break; + int attribute_value = lua_tointeger(L, 3); + this_object->Strength = attribute_value; - case ATTRIBUTE_IS_REPAIRING: { + }break; - int attribute_value = lua_tointeger(L, 3); + case ATTRIBUTE_IS_REPAIRING: { - switch (this_object->RTTI) { - case RTTI_BUILDING: { + int attribute_value = lua_tointeger(L, 3); - BuildingClass* this_building = (BuildingClass*)this_object; - this_building->IsRepairing = attribute_value; + switch (this_object->RTTI) { + case RTTI_BUILDING: { - }break; - case RTTI_VESSEL: { + BuildingClass* this_building = (BuildingClass*)this_object; + this_building->IsRepairing = attribute_value; - VesselClass* this_vessel = (VesselClass*)this_object; - this_vessel->IsSelfRepairing = attribute_value; + }break; + case RTTI_VESSEL: { - }break; - } - }break; - - // Object Class specific - default: { - - TechnoTypeClass* this_type_class; - - switch (this_object->RTTI) { - case RTTI_BUILDING: - - this_type_class = BuildingTypes.Ptr(this_object->Class_Of().ID); - - break; - case RTTI_UNIT: - - this_type_class = UnitTypes.Ptr(this_object->Class_Of().ID); - - break; - case RTTI_INFANTRY: - - this_type_class = InfantryTypes.Ptr(this_object->Class_Of().ID); - - break; - case RTTI_VESSEL: - - this_type_class = VesselTypes.Ptr(this_object->Class_Of().ID); - - break; - case RTTI_AIRCRAFT: - - this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); - - break; - } - - - if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - }break; + VesselClass* this_vessel = (VesselClass*)this_object; + this_vessel->IsSelfRepairing = attribute_value; + }break; } - - } - - - return -1; - } - - /********************************************************************************************** - * Script_SetBuildingTypeAttribute - Sets attributes for a building types * - * * - * SCRIPT INPUT: buildingTypeID (int) - The ID of the building type class * - * attribute_type (int) - The attribute to change * - * attribute_value (int) - The value to set the attribute to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetBuildingTypeAttribute(lua_State* L) { - - int buildingTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = BuildingTypes.Ptr(buildingTypeID); - - if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_SetVehicleTypeAttribute - Sets attributes for vehicle types * - * * - * SCRIPT INPUT: vehicleTypeID (int) - The ID of the vehicle type class * - * attribute_type (int) - The attribute to change * - * attribute_value (int) - The value to set the attribute to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetVehicleTypeAttribute(lua_State* L) { - - int vehicleTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = UnitTypes.Ptr(vehicleTypeID); - - if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_SetInfantryTypeAttribute - Sets attributes for infantry types * - * * - * SCRIPT INPUT: infantryTypeID (int) - The ID of the infantry type class * - * attribute_type (int) - The attribute to change * - * attribute_value (int) - The value to set the attribute to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetInfantryTypeAttribute(lua_State* L) { - - int infantryTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = InfantryTypes.Ptr(infantryTypeID); - - if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_SetVesselTypeAttribute - Sets attributes for vessel types * - * * - * SCRIPT INPUT: vesselTypeID (int) - The ID of the vessel type class * - * attribute_type (int) - The attribute to change * - * attribute_value (int) - The value to set the attribute to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetVesselTypeAttribute(lua_State* L) { - - int vesselTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = VesselTypes.Ptr(vesselTypeID); - - if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_SetAircraftTypeAttribute - Sets attributes for aircraft types * - * * - * SCRIPT INPUT: aircraftTypeID (int) - The ID of the aircraft type class * - * attribute_type (int) - The attribute to change * - * attribute_value (int) - The value to set the attribute to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetAircraftTypeAttribute(lua_State* L) { - - int aircraftTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = AircraftTypes.Ptr(aircraftTypeID); - - if (this_type_class != NULL) { - Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_SetObjectTypeAttribute - Sets attributes for specific object types globally * - * * - * Used internally by MapScript to retrieve input and set attributes for TechnoTypeClass * - * * - * SCRIPT INPUT: this_type_class (TechnoTypeClass*) - The techno type * - * attribute_type (MapScriptObjectAttributeType) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type) { - - switch (attribute_type) { - case ATTRIBUTE_MAX_STRENGTH: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxStrength); - - // Set the attribute - this_type_class->MaxStrength = attribute_value; - }break; - case ATTRIBUTE_COST: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Cost); - - // Set the attribute - this_type_class->Cost = attribute_value; - - }break; - case ATTRIBUTE_SIGHT_RANGE: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SightRange); - - // Set the attribute - this_type_class->SightRange = attribute_value; - - }break; - case ATTRIBUTE_TECH_LEVEL: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Level); - - // Set the attribute - this_type_class->Level = attribute_value; - - }break; - case ATTRIBUTE_ARMOR: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Armor); - - // Set the attribute - this_type_class->Armor = (ArmorType)attribute_value; - - }break; - case ATTRIBUTE_PRIMARY_WEAPON: { - - int attribute_value = lua_tointeger(L, 3); - - if (this_type_class->PrimaryWeapon != NULL) { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->PrimaryWeapon->ID); - } - else { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); - } - - // Set the attribute - if (attribute_value < 0) { - this_type_class->PrimaryWeapon = NULL; - } - else { - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->PrimaryWeapon = this_weapon; - } - else { - this_type_class->PrimaryWeapon = NULL; - } - } - - }break; - case ATTRIBUTE_SECONDARY_WEAPON: { - - int attribute_value = lua_tointeger(L, 3); - - if (this_type_class->PrimaryWeapon != NULL) { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SecondaryWeapon->ID); - } - else { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); - } - - // Set the attribute - if (attribute_value < 0) { - this_type_class->SecondaryWeapon = NULL; - } - else { - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->SecondaryWeapon = this_weapon; - } - else { - this_type_class->SecondaryWeapon = NULL; - } - } - - }break; - case ATTRIBUTE_SPEED: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Speed); - - // Set the attribute - this_type_class->Speed = (SpeedType)attribute_value; - - }break; - case ATTRIBUTE_MAX_SPEED: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxSpeed); - - // Set the attribute - this_type_class->MaxSpeed = (MPHType)attribute_value; - - }break; - case ATTRIBUTE_MAX_AMMO: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxAmmo); - - // Set the attribute - this_type_class->MaxAmmo = attribute_value; - - }break; - case ATTRIBUTE_ROTATION_SPEED: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->ROT); - - // Set the attribute - this_type_class->ROT = attribute_value; - - }break; - case ATTRIBUTE_CRUSHABLE: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrushable); - - // Set the attribute - this_type_class->IsCrushable = attribute_value; - - }break; - case ATTRIBUTE_STEALTHY: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsStealthy); - - // Set the attribute - this_type_class->IsStealthy = attribute_value; - - }break; - case ATTRIBUTE_SELECTABLE: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelectable); - - // Set the attribute - this_type_class->IsSelectable = attribute_value; - - }break; - case ATTRIBUTE_LEGAL_TARGET: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsLegalTarget); - - // Set the attribute - this_type_class->IsLegalTarget = attribute_value; - - }break; - case ATTRIBUTE_REPAIRABLE: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsRepairable); - - // Set the attribute - this_type_class->IsRepairable = attribute_value; - - }break; - case ATTRIBUTE_SELF_HEALING: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelfHealing); - - // Set the attribute - this_type_class->IsSelfHealing = attribute_value; - - }break; - case ATTRIBUTE_EXPLODES: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsExploding); - - // Set the attribute - this_type_class->IsExploding = attribute_value; - - }break; - case ATTRIBUTE_HAS_CREW: { - - unsigned int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrew); - - // Set the attribute - this_type_class->IsCrew = attribute_value; - - }break; - case ATTRIBUTE_MAX_PASSENGERS: { - - int attribute_value = lua_tointeger(L, 3); - - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxPassengers); - - // Set the attribute - this_type_class->MaxPassengers = attribute_value; - - }break; + // Object Class specific default: { - // Object class specific attributes - // Welcome to the web of switches] + TechnoTypeClass* this_type_class; - // Type of object - switch (this_type_class->RTTI) { + switch (this_object->RTTI) { + case RTTI_BUILDING: - // Building Specific - case RTTI_BUILDINGTYPE: { + this_type_class = BuildingTypes.Ptr(this_object->Class_Of().ID); - // What type of attribute? - switch (attribute_type) { - case ATTRIBUTE_CAPACITY: { + break; + case RTTI_UNIT: - int attribute_value = lua_tointeger(L, 3); + this_type_class = UnitTypes.Ptr(this_object->Class_Of().ID); - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + break; + case RTTI_INFANTRY: - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Capacity); + this_type_class = InfantryTypes.Ptr(this_object->Class_Of().ID); - // Set the attribute - this_building_class->Capacity = attribute_value; + break; + case RTTI_VESSEL: + + this_type_class = VesselTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_AIRCRAFT: + + this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); - }break; - case ATTRIBUTE_POWER: { + break; + } - int attribute_value = lua_tointeger(L, 3); - // Both power and drain are different variables - // And so we do some trickery here to fill - // the right values based on postivie/negative input + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + }break; - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Power - this_building_class->Drain); + } - // Set the attribute - if (attribute_value > 0) { - this_building_class->Power = attribute_value; - this_building_class->Drain = 0; - } - else { - this_building_class->Power = 0; - this_building_class->Drain = attribute_value * -1; // Flip negative power input - } + } + + + return -1; +} + +/********************************************************************************************** +* Script_SetBuildingTypeAttribute - Sets attributes for a building types * +* * +* SCRIPT INPUT: buildingTypeID (int) - The ID of the building type class * +* attribute_type (int) - The attribute to change * +* attribute_value (int) - The value to set the attribute to * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetBuildingTypeAttribute(lua_State* L) { + + int buildingTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = BuildingTypes.Ptr(buildingTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_SetVehicleTypeAttribute - Sets attributes for vehicle types * +* * +* SCRIPT INPUT: vehicleTypeID (int) - The ID of the vehicle type class * +* attribute_type (int) - The attribute to change * +* attribute_value (int) - The value to set the attribute to * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetVehicleTypeAttribute(lua_State* L) { + + int vehicleTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = UnitTypes.Ptr(vehicleTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_SetInfantryTypeAttribute - Sets attributes for infantry types * +* * +* SCRIPT INPUT: infantryTypeID (int) - The ID of the infantry type class * +* attribute_type (int) - The attribute to change * +* attribute_value (int) - The value to set the attribute to * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetInfantryTypeAttribute(lua_State* L) { + + int infantryTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = InfantryTypes.Ptr(infantryTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_SetVesselTypeAttribute - Sets attributes for vessel types * +* * +* SCRIPT INPUT: vesselTypeID (int) - The ID of the vessel type class * +* attribute_type (int) - The attribute to change * +* attribute_value (int) - The value to set the attribute to * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetVesselTypeAttribute(lua_State* L) { + + int vesselTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = VesselTypes.Ptr(vesselTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_SetAircraftTypeAttribute - Sets attributes for aircraft types * +* * +* SCRIPT INPUT: aircraftTypeID (int) - The ID of the aircraft type class * +* attribute_type (int) - The attribute to change * +* attribute_value (int) - The value to set the attribute to * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetAircraftTypeAttribute(lua_State* L) { + + int aircraftTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = AircraftTypes.Ptr(aircraftTypeID); + + if (this_type_class != NULL) { + Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_SetObjectTypeAttribute - Sets attributes for specific object types globally * +* * +* Used internally by MapScript to retrieve input and set attributes for TechnoTypeClass * +* * +* SCRIPT INPUT: this_type_class (TechnoTypeClass*) - The techno type * +* attribute_type (MapScriptObjectAttributeType) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type) { + + switch (attribute_type) { + case ATTRIBUTE_MAX_STRENGTH: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxStrength); + + // Set the attribute + this_type_class->MaxStrength = attribute_value; + + }break; + + case ATTRIBUTE_COST: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Cost); + + // Set the attribute + this_type_class->Cost = attribute_value; + + }break; + case ATTRIBUTE_SIGHT_RANGE: { + + int attribute_value = lua_tointeger(L, 3); + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SightRange); + + // Set the attribute + this_type_class->SightRange = attribute_value; + + }break; + case ATTRIBUTE_TECH_LEVEL: { + + int attribute_value = lua_tointeger(L, 3); - }break; - case ATTRIBUTE_SELLABLE: { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Level); - int attribute_value = lua_tointeger(L, 3); + // Set the attribute + this_type_class->Level = attribute_value; - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + }break; + case ATTRIBUTE_ARMOR: { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->IsUnsellable * -1); + int attribute_value = lua_tointeger(L, 3); - // Set the attribute - // Personal opinion; sellable makes more sense than unsellable - // This replacement could be seen as IsUnNonSellable, or... IsSellable - if (attribute_value == 1) { - this_building_class->IsUnsellable = 0; - } - else { - this_building_class->IsUnsellable = 1; - } + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Armor); - }break; - } + // Set the attribute + this_type_class->Armor = (ArmorType)attribute_value; - }break; + }break; + case ATTRIBUTE_PRIMARY_WEAPON: { + int attribute_value = lua_tointeger(L, 3); - // Unit Specific - case RTTI_UNITTYPE: { + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->PrimaryWeapon->ID); + } + else { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } - // What type of attribute? - switch (attribute_type) { - case ATTRIBUTE_CRATE_GOODIE: { + // Set the attribute + if (attribute_value < 0) { + this_type_class->PrimaryWeapon = NULL; + } + else { + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->PrimaryWeapon = this_weapon; + } + else { + this_type_class->PrimaryWeapon = NULL; + } + } - int attribute_value = lua_tointeger(L, 3); + }break; + case ATTRIBUTE_SECONDARY_WEAPON: { - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + int attribute_value = lua_tointeger(L, 3); - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrateGoodie); + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SecondaryWeapon->ID); + } + else { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } - // Set the attribute - this_unit_class->IsCrateGoodie = attribute_value; + // Set the attribute + if (attribute_value < 0) { + this_type_class->SecondaryWeapon = NULL; + } + else { + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->SecondaryWeapon = this_weapon; + } + else { + this_type_class->SecondaryWeapon = NULL; + } + } - }break; - case ATTRIBUTE_CRUSHER: { + }break; + case ATTRIBUTE_SPEED: { - int attribute_value = lua_tointeger(L, 3); + int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Speed); - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrusher); + // Set the attribute + this_type_class->Speed = (SpeedType)attribute_value; - // Set the attribute - this_unit_class->IsCrusher = attribute_value; + }break; + case ATTRIBUTE_MAX_SPEED: { - }break; - case ATTRIBUTE_HARVEST: { + int attribute_value = lua_tointeger(L, 3); - int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxSpeed); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + // Set the attribute + this_type_class->MaxSpeed = (MPHType)attribute_value; - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsToHarvest); + }break; + case ATTRIBUTE_MAX_AMMO: { - // Set the attribute - this_unit_class->IsToHarvest = attribute_value; + int attribute_value = lua_tointeger(L, 3); - }break; - case ATTRIBUTE_RADAR_EQUIPPED: { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxAmmo); - int attribute_value = lua_tointeger(L, 3); + // Set the attribute + this_type_class->MaxAmmo = attribute_value; - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + }break; + case ATTRIBUTE_ROTATION_SPEED: { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsRadarEquipped); + int attribute_value = lua_tointeger(L, 3); - // Set the attribute - this_unit_class->IsRadarEquipped = attribute_value; + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->ROT); - }break; - case ATTRIBUTE_JAMMER: { + // Set the attribute + this_type_class->ROT = attribute_value; - int attribute_value = lua_tointeger(L, 3); + }break; + case ATTRIBUTE_CRUSHABLE: { - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + unsigned int attribute_value = lua_tointeger(L, 3); - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsJammer); + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrushable); - // Set the attribute - this_unit_class->IsJammer = attribute_value; + // Set the attribute + this_type_class->IsCrushable = attribute_value; - }break; - case ATTRIBUTE_GAPPER: { + }break; + case ATTRIBUTE_STEALTHY: { - int attribute_value = lua_tointeger(L, 3); + unsigned int attribute_value = lua_tointeger(L, 3); - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsStealthy); - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsGapper); + // Set the attribute + this_type_class->IsStealthy = attribute_value; - // Set the attribute - this_unit_class->IsGapper = attribute_value; + }break; + case ATTRIBUTE_SELECTABLE: { - }break; - } + unsigned int attribute_value = lua_tointeger(L, 3); - }break; + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelectable); + // Set the attribute + this_type_class->IsSelectable = attribute_value; - // Infantry Specific - case RTTI_INFANTRYTYPE: { + }break; + case ATTRIBUTE_LEGAL_TARGET: { - // What type of attribute? - switch (attribute_type) { - case ATTRIBUTE_FEMALE: { + unsigned int attribute_value = lua_tointeger(L, 3); - int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsLegalTarget); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + // Set the attribute + this_type_class->IsLegalTarget = attribute_value; - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFemale); + }break; + case ATTRIBUTE_REPAIRABLE: { - // Set the attribute - this_infantry_class->IsFemale = attribute_value; + unsigned int attribute_value = lua_tointeger(L, 3); - }break; - case ATTRIBUTE_CAPTURE: { + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsRepairable); - int attribute_value = lua_tointeger(L, 3); + // Set the attribute + this_type_class->IsRepairable = attribute_value; - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + }break; + case ATTRIBUTE_SELF_HEALING: { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCapture); + unsigned int attribute_value = lua_tointeger(L, 3); - // Set the attribute - this_infantry_class->IsCapture = attribute_value; + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelfHealing); - }break; - case ATTRIBUTE_FRAIDY_CAT: { + // Set the attribute + this_type_class->IsSelfHealing = attribute_value; - int attribute_value = lua_tointeger(L, 3); + }break; + case ATTRIBUTE_EXPLODES: { - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + unsigned int attribute_value = lua_tointeger(L, 3); - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFraidyCat); + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsExploding); - // Set the attribute - this_infantry_class->IsFraidyCat = attribute_value; + // Set the attribute + this_type_class->IsExploding = attribute_value; - }break; - case ATTRIBUTE_CIVILIAN: { + }break; + case ATTRIBUTE_HAS_CREW: { - int attribute_value = lua_tointeger(L, 3); + unsigned int attribute_value = lua_tointeger(L, 3); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrew); - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCivilian); + // Set the attribute + this_type_class->IsCrew = attribute_value; - // Set the attribute - this_infantry_class->IsCivilian = attribute_value; + }break; + case ATTRIBUTE_MAX_PASSENGERS: { - }break; - case ATTRIBUTE_BOMBER: { + int attribute_value = lua_tointeger(L, 3); - int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxPassengers); - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + // Set the attribute + this_type_class->MaxPassengers = attribute_value; - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsBomber); + }break; + default: { - // Set the attribute - this_infantry_class->IsBomber = attribute_value; + // Object class specific attributes + // Welcome to the web of switches] - }break; - case ATTRIBUTE_DOG: { + // Type of object + switch (this_type_class->RTTI) { - int attribute_value = lua_tointeger(L, 3); + // Building Specific + case RTTI_BUILDINGTYPE: { - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CAPACITY: { - // Cache default value if first time changing this attribute - Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsDog); + int attribute_value = lua_tointeger(L, 3); - // Set the attribute - this_infantry_class->IsDog = attribute_value; + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; - }break; + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Capacity); - } + // Set the attribute + this_building_class->Capacity = attribute_value; - }break; + }break; + case ATTRIBUTE_POWER: { - } // End of object specific switch + int attribute_value = lua_tointeger(L, 3); + + // Both power and drain are different variables + // And so we do some trickery here to fill + // the right values based on postivie/negative input + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Power - this_building_class->Drain); + + // Set the attribute + if (attribute_value > 0) { + this_building_class->Power = attribute_value; + this_building_class->Drain = 0; + } + else { + this_building_class->Power = 0; + this_building_class->Drain = attribute_value * -1; // Flip negative power input + } + + }break; + case ATTRIBUTE_SELLABLE: { + + int attribute_value = lua_tointeger(L, 3); + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->IsUnsellable * -1); + + // Set the attribute + // Personal opinion; sellable makes more sense than unsellable + // This replacement could be seen as IsUnNonSellable, or... IsSellable + if (attribute_value == 1) { + this_building_class->IsUnsellable = 0; + } + else { + this_building_class->IsUnsellable = 1; + } + + }break; + } + + }break; + + + // Unit Specific + case RTTI_UNITTYPE: { + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CRATE_GOODIE: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrateGoodie); + + // Set the attribute + this_unit_class->IsCrateGoodie = attribute_value; + + }break; + case ATTRIBUTE_CRUSHER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrusher); + + // Set the attribute + this_unit_class->IsCrusher = attribute_value; + + }break; + case ATTRIBUTE_HARVEST: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsToHarvest); + + // Set the attribute + this_unit_class->IsToHarvest = attribute_value; + + }break; + case ATTRIBUTE_RADAR_EQUIPPED: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsRadarEquipped); + + // Set the attribute + this_unit_class->IsRadarEquipped = attribute_value; + + }break; + case ATTRIBUTE_JAMMER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsJammer); + + // Set the attribute + this_unit_class->IsJammer = attribute_value; + + }break; + case ATTRIBUTE_GAPPER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsGapper); + + // Set the attribute + this_unit_class->IsGapper = attribute_value; + + }break; + } + + }break; + + + // Infantry Specific + case RTTI_INFANTRYTYPE: { + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_FEMALE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFemale); + + // Set the attribute + this_infantry_class->IsFemale = attribute_value; + + }break; + case ATTRIBUTE_CAPTURE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCapture); + + // Set the attribute + this_infantry_class->IsCapture = attribute_value; + + }break; + case ATTRIBUTE_FRAIDY_CAT: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFraidyCat); + + // Set the attribute + this_infantry_class->IsFraidyCat = attribute_value; + + }break; + case ATTRIBUTE_CIVILIAN: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCivilian); + + // Set the attribute + this_infantry_class->IsCivilian = attribute_value; + + }break; + case ATTRIBUTE_BOMBER: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsBomber); + + // Set the attribute + this_infantry_class->IsBomber = attribute_value; + + }break; + case ATTRIBUTE_DOG: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultObjectTypeAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsDog); + + // Set the attribute + this_infantry_class->IsDog = attribute_value; }break; - } // End of attribute switch + } + + }break; + + } // End of object specific switch + + }break; + + } // End of attribute switch + + return -1; +} + +/********************************************************************************************** +* Script_GetObjectAttribute - Gets attributes for specific objects or object types * +* * +* SCRIPT INPUT: objectID (int) - The ID of the object * +* attribute_type (int) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetObjectAttribute(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + // Get the appropriate technotype + if (this_object != NULL) { + + // Global attributes / Multi object attributes + switch ((MapScriptObjectAttributeType)attribute_type) { + case ATTRIBUTE_TYPE: { + + // Send the attribute + lua_pushinteger(L, this_object->RTTI); + return 1; + + }break; + case ATTRIBUTE_STRENGTH: { + + // Send the attribute + lua_pushinteger(L, this_object->Strength); + return 1; + + }break; + + case ATTRIBUTE_IS_REPAIRING: { + + switch (this_object->RTTI) { + case RTTI_BUILDING: { + + BuildingClass* this_building = (BuildingClass*)this_object; + + // Send the attribute + lua_pushinteger(L, this_building->IsRepairing); + return 1; + + }break; + case RTTI_VESSEL: { + + VesselClass* this_vessel = (VesselClass*)this_object; + + // Send the attribute + lua_pushinteger(L, this_vessel->IsSelfRepairing); + return 1; + + }break; + } + }break; + + // Object Class specific + default: { + + TechnoTypeClass* this_type_class = NULL; + + switch (this_object->RTTI) { + case RTTI_BUILDING: + + this_type_class = BuildingTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_UNIT: + + this_type_class = UnitTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_INFANTRY: + + this_type_class = InfantryTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_VESSEL: + + this_type_class = VesselTypes.Ptr(this_object->Class_Of().ID); + + break; + case RTTI_AIRCRAFT: + + this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); + + break; + } + + // Type attribute retrieval + if (this_type_class != NULL) { + return Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + }break; + + } - return -1; } - /********************************************************************************************** - * Script_GetObjectAttribute - Gets attributes for specific objects or object types * - * * - * SCRIPT INPUT: objectID (int) - The ID of the object * - * attribute_type (int) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetObjectAttribute(lua_State* L) { - int objectID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); + return -1; +} - ObjectClass* this_object = Script_GetCacheObject(objectID); +/********************************************************************************************** +* Script_GetBuildingTypeAttribute - Gets attributes for a building types * +* * +* SCRIPT INPUT: buildingTypeID (int) - The ID of the building type class * +* attribute_type (int) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetBuildingTypeAttribute(lua_State* L) { - // Get the appropriate technotype - if (this_object != NULL) { + int buildingTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); - // Global attributes / Multi object attributes - switch ((MapScriptObjectAttributeType)attribute_type) { - case ATTRIBUTE_TYPE: { + TechnoTypeClass* this_type_class = BuildingTypes.Ptr(buildingTypeID); + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_GetVehicleTypeAttribute - Gets attributes for vehicle types * +* * +* SCRIPT INPUT: vehicleTypeID (int) - The ID of the vehicle type class * +* attribute_type (int) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetVehicleTypeAttribute(lua_State* L) { + + int vehicleTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = UnitTypes.Ptr(vehicleTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_GetInfantryTypeAttribute - Gets attributes for infantry types * +* * +* SCRIPT INPUT: infantryTypeID (int) - The ID of the infantry type class * +* attribute_type (int) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetInfantryTypeAttribute(lua_State* L) { + + int infantryTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = InfantryTypes.Ptr(infantryTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_GetVesselTypeAttribute - Gets attributes for vessel types * +* * +* SCRIPT INPUT: vesselTypeID (int) - The ID of the vessel type class * +* attribute_type (int) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetVesselTypeAttribute(lua_State* L) { + + int vesselTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = VesselTypes.Ptr(vesselTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_GetAircraftTypeAttribute - Gets attributes for aircraft types * +* * +* SCRIPT INPUT: aircraftTypeID (int) - The ID of the aircraft type class * +* attribute_type (int) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetAircraftTypeAttribute(lua_State* L) { + + int aircraftTypeID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); + + TechnoTypeClass* this_type_class = AircraftTypes.Ptr(aircraftTypeID); + + if (this_type_class != NULL) { + return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); + } + + return -1; +} + +/********************************************************************************************** +* Script_GetObjectTypeAttribute - Gets attributes for specific object types globally * +* * +* Used internally by MapScript to send input and get attributes for TechnoTypeClass * +* * +* SCRIPT INPUT: this_type_class (TechnoTypeClass*) - The techno type * +* attribute_type (MapScriptObjectAttributeType) - The attribute to change * +* * +* SCRIPT OUTPUT: void * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type) { + + switch (attribute_type) { + case ATTRIBUTE_MAX_STRENGTH: { + + // Send the attribute + lua_pushinteger(L, this_type_class->MaxStrength); + return 1; + + }break; + + case ATTRIBUTE_COST: { + + // Send the attribute + lua_pushinteger(L, this_type_class->Cost); + return 1; + + }break; + case ATTRIBUTE_SIGHT_RANGE: { + + // Send the attribute + lua_pushinteger(L, this_type_class->SightRange); + return 1; + + }break; + case ATTRIBUTE_TECH_LEVEL: { + + // Send the attribute + lua_pushinteger(L, this_type_class->Level); + return 1; + + }break; + case ATTRIBUTE_ARMOR: { + + // Send the attribute + lua_pushinteger(L, this_type_class->Armor); + return 1; + + }break; + case ATTRIBUTE_PRIMARY_WEAPON: { + + if (this_type_class->PrimaryWeapon != NULL) { + // Send the attribute + lua_pushinteger(L, this_type_class->PrimaryWeapon->ID); + return 1; + } + else { + // Send the attribute + lua_pushinteger(L, -1); + return 1; + } + + }break; + case ATTRIBUTE_SECONDARY_WEAPON: { + + if (this_type_class->SecondaryWeapon != NULL) { + // Send the attribute + lua_pushinteger(L, this_type_class->SecondaryWeapon->ID); + return 1; + } + else { + // Send the attribute + lua_pushinteger(L, -1); + return 1; + } + + }break; + case ATTRIBUTE_SPEED: { + + // Send the attribute + lua_pushinteger(L, this_type_class->Speed); + return 1; + + }break; + case ATTRIBUTE_MAX_SPEED: { + + // Send the attribute + lua_pushinteger(L, this_type_class->MaxSpeed); + return 1; + + }break; + case ATTRIBUTE_MAX_AMMO: { + + // Send the attribute + lua_pushinteger(L, this_type_class->MaxAmmo); + return 1; + + }break; + case ATTRIBUTE_ROTATION_SPEED: { + + // Send the attribute + lua_pushboolean(L, this_type_class->ROT); + return 1; + + }break; + case ATTRIBUTE_CRUSHABLE: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsCrushable); + return 1; + + }break; + case ATTRIBUTE_STEALTHY: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsStealthy); + return 1; + + }break; + case ATTRIBUTE_SELECTABLE: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsSelectable); + return 1; + + }break; + case ATTRIBUTE_LEGAL_TARGET: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsLegalTarget); + return 1; + + }break; + case ATTRIBUTE_REPAIRABLE: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsRepairable); + return 1; + + }break; + case ATTRIBUTE_SELF_HEALING: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsSelfHealing); + return 1; + + }break; + case ATTRIBUTE_EXPLODES: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsExploding); + return 1; + + }break; + case ATTRIBUTE_HAS_CREW: { + + // Send the attribute + lua_pushboolean(L, this_type_class->IsCrew); + return 1; + + }break; + case ATTRIBUTE_MAX_PASSENGERS: { + + // Send the attribute + lua_pushinteger(L, this_type_class->MaxPassengers); + return 1; + + }break; + default: { + + // Object class specific attributes + // Welcome to the web of switches] + + // Type of object + switch (this_type_class->RTTI) { + + // Building Specific + case RTTI_BUILDINGTYPE: { + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CAPACITY: { + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Send the attribute + lua_pushinteger(L, this_building_class->Capacity); + return 1; + + }break; + case ATTRIBUTE_POWER: { + + // Both power and drain are different variables + // And so we do some trickery here to fill + // the right values based on postivie/negative input + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + int this_value = this_building_class->Power - this_building_class->Drain; + + // Send the attribute + lua_pushinteger(L, this_value); + return 1; + + }break; + case ATTRIBUTE_SELLABLE: { + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Set the attribute + // Personal opinion; sellable makes more sense than unsellable + // This replacement could be seen as IsUnNonSellable, or... IsSellable + if (this_building_class->IsUnsellable == 1) { // Send the attribute - lua_pushinteger(L, this_object->RTTI); + lua_pushinteger(L, 0); return 1; - - }break; - case ATTRIBUTE_STRENGTH: { - + } + else { // Send the attribute - lua_pushinteger(L, this_object->Strength); + lua_pushinteger(L, 1); return 1; + } - }break; + }break; + } - case ATTRIBUTE_IS_REPAIRING: { + }break; - switch (this_object->RTTI) { - case RTTI_BUILDING: { - BuildingClass* this_building = (BuildingClass*)this_object; + // Unit Specific + case RTTI_UNITTYPE: { - // Send the attribute - lua_pushinteger(L, this_building->IsRepairing); - return 1; + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CRATE_GOODIE: { - }break; - case RTTI_VESSEL: { + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - VesselClass* this_vessel = (VesselClass*)this_object; - - // Send the attribute - lua_pushinteger(L, this_vessel->IsSelfRepairing); - return 1; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsCrateGoodie); + return 1; - }break; - } - }break; + }break; + case ATTRIBUTE_CRUSHER: { - // Object Class specific - default: { + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - TechnoTypeClass* this_type_class = NULL; + // Send the attribute + lua_pushboolean(L, this_unit_class->IsCrusher); + return 1; - switch (this_object->RTTI) { - case RTTI_BUILDING: + }break; + case ATTRIBUTE_HARVEST: { - this_type_class = BuildingTypes.Ptr(this_object->Class_Of().ID); + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - break; - case RTTI_UNIT: + // Send the attribute + lua_pushboolean(L, this_unit_class->IsToHarvest); + return 1; - this_type_class = UnitTypes.Ptr(this_object->Class_Of().ID); + }break; + case ATTRIBUTE_RADAR_EQUIPPED: { - break; - case RTTI_INFANTRY: + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - this_type_class = InfantryTypes.Ptr(this_object->Class_Of().ID); + // Send the attribute + lua_pushboolean(L, this_unit_class->IsRadarEquipped); + return 1; - break; - case RTTI_VESSEL: + }break; + case ATTRIBUTE_JAMMER: { - this_type_class = VesselTypes.Ptr(this_object->Class_Of().ID); + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - break; - case RTTI_AIRCRAFT: + // Send the attribute + lua_pushboolean(L, this_unit_class->IsJammer); + return 1; - this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); + }break; + case ATTRIBUTE_GAPPER: { - break; - } + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - // Type attribute retrieval - if (this_type_class != NULL) { - return Script_SetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } + // Send the attribute + lua_pushboolean(L, this_unit_class->IsGapper); + return 1; - }break; + }break; + } + + }break; + + + // Infantry Specific + case RTTI_INFANTRYTYPE: { + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_FEMALE: { + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsFemale); + return 1; + + }break; + case ATTRIBUTE_CAPTURE: { + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsCapture); + return 1; + + }break; + case ATTRIBUTE_FRAIDY_CAT: { + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsFraidyCat); + return 1; + + }break; + case ATTRIBUTE_CIVILIAN: { + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsCivilian); + return 1; + + }break; + case ATTRIBUTE_BOMBER: { + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsBomber); + return 1; + + }break; + case ATTRIBUTE_DOG: { + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Send the attribute + lua_pushboolean(L, this_infantry_class->IsDog); + return 1; + + }break; } - } + }break; + + } // End of object specific switch + + }break; + + } // End of attribute switch - return -1; - } + // Didn't find result + return -1; - /********************************************************************************************** - * Script_GetBuildingTypeAttribute - Gets attributes for a building types * - * * - * SCRIPT INPUT: buildingTypeID (int) - The ID of the building type class * - * attribute_type (int) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetBuildingTypeAttribute(lua_State* L) { +} - int buildingTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); +/********************************************************************************************** +* Script_SetHouseAttribute - Sets attributes for specific houses * +* * +* SCRIPT INPUT: houseID (int) - The ID of the house * +* attribute_type (int) - The attribute to change * +* attribute_value (int) - The value to set the attribute to * +* * +* SCRIPT OUTPUT: void * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_SetHouseAttribute(lua_State* L) { - TechnoTypeClass* this_type_class = BuildingTypes.Ptr(buildingTypeID); + int houseID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); - if (this_type_class != NULL) { - return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } + HouseClass* this_house = Houses.Ptr(houseID); - return -1; - } - - /********************************************************************************************** - * Script_GetVehicleTypeAttribute - Gets attributes for vehicle types * - * * - * SCRIPT INPUT: vehicleTypeID (int) - The ID of the vehicle type class * - * attribute_type (int) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetVehicleTypeAttribute(lua_State* L) { - - int vehicleTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = UnitTypes.Ptr(vehicleTypeID); - - if (this_type_class != NULL) { - return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_GetInfantryTypeAttribute - Gets attributes for infantry types * - * * - * SCRIPT INPUT: infantryTypeID (int) - The ID of the infantry type class * - * attribute_type (int) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetInfantryTypeAttribute(lua_State* L) { - - int infantryTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = InfantryTypes.Ptr(infantryTypeID); - - if (this_type_class != NULL) { - return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_GetVesselTypeAttribute - Gets attributes for vessel types * - * * - * SCRIPT INPUT: vesselTypeID (int) - The ID of the vessel type class * - * attribute_type (int) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetVesselTypeAttribute(lua_State* L) { - - int vesselTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = VesselTypes.Ptr(vesselTypeID); - - if (this_type_class != NULL) { - return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_GetAircraftTypeAttribute - Gets attributes for aircraft types * - * * - * SCRIPT INPUT: aircraftTypeID (int) - The ID of the aircraft type class * - * attribute_type (int) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetAircraftTypeAttribute(lua_State* L) { - - int aircraftTypeID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - TechnoTypeClass* this_type_class = AircraftTypes.Ptr(aircraftTypeID); - - if (this_type_class != NULL) { - return Script_GetObjectTypeAttribute(L, this_type_class, (MapScriptObjectAttributeType)attribute_type); - } - - return -1; - } - - /********************************************************************************************** - * Script_GetObjectTypeAttribute - Gets attributes for specific object types globally * - * * - * Used internally by MapScript to send input and get attributes for TechnoTypeClass * - * * - * SCRIPT INPUT: this_type_class (TechnoTypeClass*) - The techno type * - * attribute_type (MapScriptObjectAttributeType) - The attribute to change * - * * - * SCRIPT OUTPUT: void * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptObjectAttributeType attribute_type) { + // Get the appropriate technotype + if (this_house != NULL) { switch (attribute_type) { - case ATTRIBUTE_MAX_STRENGTH: { + case HOUSE_ATTRIBUTE_IQ: { - // Send the attribute - lua_pushinteger(L, this_type_class->MaxStrength); - return 1; + int attribute_value = lua_tointeger(L, 3); - }break; + this_house->Control.IQ = attribute_value; + this_house->IQ = attribute_value; - case ATTRIBUTE_COST: { + }break; + case HOUSE_ATTRIBUTE_TECH_LEVEL: { - // Send the attribute - lua_pushinteger(L, this_type_class->Cost); - return 1; + int attribute_value = lua_tointeger(L, 3); - }break; - case ATTRIBUTE_SIGHT_RANGE: { + this_house->Control.TechLevel = attribute_value; - // Send the attribute - lua_pushinteger(L, this_type_class->SightRange); - return 1; + }break; + case HOUSE_ATTRIBUTE_IS_HUMAN: { - }break; - case ATTRIBUTE_TECH_LEVEL: { + int attribute_value = lua_tointeger(L, 3); - // Send the attribute - lua_pushinteger(L, this_type_class->Level); - return 1; - - }break; - case ATTRIBUTE_ARMOR: { - - // Send the attribute - lua_pushinteger(L, this_type_class->Armor); - return 1; - - }break; - case ATTRIBUTE_PRIMARY_WEAPON: { - - if (this_type_class->PrimaryWeapon != NULL) { - // Send the attribute - lua_pushinteger(L, this_type_class->PrimaryWeapon->ID); - return 1; - } - else { - // Send the attribute - lua_pushinteger(L, -1); - return 1; - } - - }break; - case ATTRIBUTE_SECONDARY_WEAPON: { - - if (this_type_class->SecondaryWeapon != NULL) { - // Send the attribute - lua_pushinteger(L, this_type_class->SecondaryWeapon->ID); - return 1; - } - else { - // Send the attribute - lua_pushinteger(L, -1); - return 1; - } - - }break; - case ATTRIBUTE_SPEED: { - - // Send the attribute - lua_pushinteger(L, this_type_class->Speed); - return 1; - - }break; - case ATTRIBUTE_MAX_SPEED: { - - // Send the attribute - lua_pushinteger(L, this_type_class->MaxSpeed); - return 1; - - }break; - case ATTRIBUTE_MAX_AMMO: { - - // Send the attribute - lua_pushinteger(L, this_type_class->MaxAmmo); - return 1; - - }break; - case ATTRIBUTE_ROTATION_SPEED: { - - // Send the attribute - lua_pushboolean(L, this_type_class->ROT); - return 1; - - }break; - case ATTRIBUTE_CRUSHABLE: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsCrushable); - return 1; - - }break; - case ATTRIBUTE_STEALTHY: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsStealthy); - return 1; - - }break; - case ATTRIBUTE_SELECTABLE: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsSelectable); - return 1; - - }break; - case ATTRIBUTE_LEGAL_TARGET: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsLegalTarget); - return 1; - - }break; - case ATTRIBUTE_REPAIRABLE: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsRepairable); - return 1; - - }break; - case ATTRIBUTE_SELF_HEALING: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsSelfHealing); - return 1; - - }break; - case ATTRIBUTE_EXPLODES: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsExploding); - return 1; - - }break; - case ATTRIBUTE_HAS_CREW: { - - // Send the attribute - lua_pushboolean(L, this_type_class->IsCrew); - return 1; - - }break; - case ATTRIBUTE_MAX_PASSENGERS: { - - // Send the attribute - lua_pushinteger(L, this_type_class->MaxPassengers); - return 1; - - }break; - default: { - - // Object class specific attributes - // Welcome to the web of switches] - - // Type of object - switch (this_type_class->RTTI) { - - // Building Specific - case RTTI_BUILDINGTYPE: { - - // What type of attribute? - switch (attribute_type) { - case ATTRIBUTE_CAPACITY: { - - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; - - // Send the attribute - lua_pushinteger(L, this_building_class->Capacity); - return 1; - - }break; - case ATTRIBUTE_POWER: { - - // Both power and drain are different variables - // And so we do some trickery here to fill - // the right values based on postivie/negative input - - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; - - int this_value = this_building_class->Power - this_building_class->Drain; - - // Send the attribute - lua_pushinteger(L, this_value); - return 1; - - }break; - case ATTRIBUTE_SELLABLE: { - - BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; - - // Set the attribute - // Personal opinion; sellable makes more sense than unsellable - // This replacement could be seen as IsUnNonSellable, or... IsSellable - if (this_building_class->IsUnsellable == 1) { - // Send the attribute - lua_pushinteger(L, 0); - return 1; - } else { - // Send the attribute - lua_pushinteger(L, 1); - return 1; - } - - }break; - } - - }break; - - - // Unit Specific - case RTTI_UNITTYPE: { - - // What type of attribute? - switch (attribute_type) { - case ATTRIBUTE_CRATE_GOODIE: { - - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_unit_class->IsCrateGoodie); - return 1; - - }break; - case ATTRIBUTE_CRUSHER: { - - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_unit_class->IsCrusher); - return 1; - - }break; - case ATTRIBUTE_HARVEST: { - - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_unit_class->IsToHarvest); - return 1; - - }break; - case ATTRIBUTE_RADAR_EQUIPPED: { - - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_unit_class->IsRadarEquipped); - return 1; - - }break; - case ATTRIBUTE_JAMMER: { - - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_unit_class->IsJammer); - return 1; - - }break; - case ATTRIBUTE_GAPPER: { - - UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_unit_class->IsGapper); - return 1; - - }break; - } - - }break; - - - // Infantry Specific - case RTTI_INFANTRYTYPE: { - - // What type of attribute? - switch (attribute_type) { - case ATTRIBUTE_FEMALE: { - - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_infantry_class->IsFemale); - return 1; - - }break; - case ATTRIBUTE_CAPTURE: { - - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_infantry_class->IsCapture); - return 1; - - }break; - case ATTRIBUTE_FRAIDY_CAT: { - - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_infantry_class->IsFraidyCat); - return 1; - - }break; - case ATTRIBUTE_CIVILIAN: { - - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_infantry_class->IsCivilian); - return 1; - - }break; - case ATTRIBUTE_BOMBER: { - - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_infantry_class->IsBomber); - return 1; - - }break; - case ATTRIBUTE_DOG: { - - InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; - - // Send the attribute - lua_pushboolean(L, this_infantry_class->IsDog); - return 1; - - }break; - - } - - }break; - - } // End of object specific switch - - }break; - - } // End of attribute switch - - - // Didn't find result - return -1; - - } - - /********************************************************************************************** - * Script_SetHouseAttribute - Sets attributes for specific houses * - * * - * SCRIPT INPUT: houseID (int) - The ID of the house * - * attribute_type (int) - The attribute to change * - * attribute_value (int) - The value to set the attribute to * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetHouseAttribute(lua_State* L) { - - int houseID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); - - HouseClass* this_house = Houses.Ptr(houseID); - - // Get the appropriate technotype - if (this_house != NULL) { - - switch (attribute_type) { - case HOUSE_ATTRIBUTE_IQ: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->Control.IQ = attribute_value; - this_house->IQ = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_TECH_LEVEL: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->Control.TechLevel = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_IS_HUMAN: { - - int attribute_value = lua_tointeger(L, 3); - - if (attribute_value == 1) { - this_house->IsHuman = 1; - this_house->WasHuman = 1; - }else { - this_house->IsHuman = 0; - } - - - }break; - case HOUSE_ATTRIBUTE_FIREPOWER_BIAS: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->FirepowerBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].FirepowerBias; - - }break; - case HOUSE_ATTRIBUTE_GROUNDSPEED_BIAS: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->GroundspeedBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].GroundspeedBias; - - }break; - case HOUSE_ATTRIBUTE_ARMOR_BIAS: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->ArmorBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].ArmorBias; - - }break; - case HOUSE_ATTRIBUTE_ROF_BIAS: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->ROFBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].ROFBias; - - }break; - case HOUSE_ATTRIBUTE_COST_BIAS: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->CostBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].CostBias; - - }break; - case HOUSE_ATTRIBUTE_REPAIR_DELAY: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->RepairDelay = (fixed)attribute_value; - - }break; - case HOUSE_ATTRIBUTE_BUILD_DELAY: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->BuildDelay = (fixed)attribute_value; - - }break; - case HOUSE_ATTRIBUTE_STARTED: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->IsStarted = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_ALERTED: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->IsAlerted = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_BASE_BUILDING: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->IsBaseBuilding = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_DISCOVERED: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->IsDiscovered = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_CAPACITY: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->Capacity = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_TIBERIUM: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->Tiberium = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_CREDITS: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->Credits = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_ALERT_TIMER: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->AlertTime = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_REPAIR_TIMER: { - - float attribute_value = lua_tonumber(L, 3); - - this_house->RepairTimer = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_POINTS : { - - int attribute_value = lua_tointeger(L, 3); - - this_house->PointTotal = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_DESTROYED_BUILDINGS: { - - // Non writable - - }break; - case HOUSE_ATTRIBUTE_DESTROYED_INFANTRY: { - - // Non writable - - }break; - case HOUSE_ATTRIBUTE_DESTROYED_VEHICLES: { - - // Non writable - - }break; - case HOUSE_ATTRIBUTE_DESTROYED_AIRCRAFT: { - - // Non writable - - }break; - case HOUSE_ATTRIBUTE_DESTROYED_VESSELS: { - - // Non writable - - }break; - case HOUSE_ATTRIBUTE_CAPTURED_BUILDINGS: { - - // Non writable - - }break; - case HOUSE_ATTRIBUTE_CRATES: { - - // Non writable - - }break; - - case HOUSE_ATTRIBUTE_BUILDING_FACTORIES: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->BuildingFactories = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_UNIT_FACTORIES: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->UnitFactories = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_INFANTRY_FACTORIES: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->InfantryFactories = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_AIRCRAFT_FACTORIES: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->AircraftFactories = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_VESSEL_FACTORIES: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->VesselFactories = attribute_value; - - }break; - - case HOUSE_ATTRIBUTE_POWER: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->Power = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_DRAIN: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->Drain = attribute_value; - - }break; - case HOUSE_ATTRIBUTE_LAST_ATTACKER: { - - int attribute_value = lua_tointeger(L, 3); - - this_house->WhoLastHurtMe = (HousesType)attribute_value; - - }break; + if (attribute_value == 1) { + this_house->IsHuman = 1; + this_house->WasHuman = 1; + } + else { + this_house->IsHuman = 0; } + + }break; + case HOUSE_ATTRIBUTE_FIREPOWER_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->FirepowerBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].FirepowerBias; + + }break; + case HOUSE_ATTRIBUTE_GROUNDSPEED_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->GroundspeedBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].GroundspeedBias; + + }break; + case HOUSE_ATTRIBUTE_ARMOR_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->ArmorBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].ArmorBias; + + }break; + case HOUSE_ATTRIBUTE_ROF_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->ROFBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].ROFBias; + + }break; + case HOUSE_ATTRIBUTE_COST_BIAS: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->CostBias = (fixed)attribute_value * Rule.Diff[this_house->Difficulty].CostBias; + + }break; + case HOUSE_ATTRIBUTE_REPAIR_DELAY: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->RepairDelay = (fixed)attribute_value; + + }break; + case HOUSE_ATTRIBUTE_BUILD_DELAY: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->BuildDelay = (fixed)attribute_value; + + }break; + case HOUSE_ATTRIBUTE_STARTED: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsStarted = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_ALERTED: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsAlerted = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_BASE_BUILDING: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsBaseBuilding = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_DISCOVERED: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->IsDiscovered = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_CAPACITY: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Capacity = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_TIBERIUM: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Tiberium = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_CREDITS: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Credits = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_ALERT_TIMER: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->AlertTime = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_REPAIR_TIMER: { + + float attribute_value = lua_tonumber(L, 3); + + this_house->RepairTimer = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_POINTS: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->PointTotal = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_BUILDINGS: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_INFANTRY: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VEHICLES: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_AIRCRAFT: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VESSELS: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_CAPTURED_BUILDINGS: { + + // Non writable + + }break; + case HOUSE_ATTRIBUTE_CRATES: { + + // Non writable + + }break; + + case HOUSE_ATTRIBUTE_BUILDING_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->BuildingFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_UNIT_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->UnitFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_INFANTRY_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->InfantryFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_AIRCRAFT_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->AircraftFactories = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_VESSEL_FACTORIES: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->VesselFactories = attribute_value; + + }break; + + case HOUSE_ATTRIBUTE_POWER: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Power = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_DRAIN: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->Drain = attribute_value; + + }break; + case HOUSE_ATTRIBUTE_LAST_ATTACKER: { + + int attribute_value = lua_tointeger(L, 3); + + this_house->WhoLastHurtMe = (HousesType)attribute_value; + + }break; } - - return -1; } - /********************************************************************************************** - * Script_GetHouseAttribute - Sets attributes for specific houses * - * * - * SCRIPT INPUT: houseID (int) - The ID of the house * - * attribute_type (int) - The attribute to change * - * * - * SCRIPT OUTPUT: (mixed) - The value of the attribute * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetHouseAttribute(lua_State* L) { - int houseID = lua_tointeger(L, 1); - int attribute_type = lua_tointeger(L, 2); + return -1; +} - HouseClass* this_house = Houses.Ptr(houseID); +/********************************************************************************************** +* Script_GetHouseAttribute - Sets attributes for specific houses * +* * +* SCRIPT INPUT: houseID (int) - The ID of the house * +* attribute_type (int) - The attribute to change * +* * +* SCRIPT OUTPUT: (mixed) - The value of the attribute * +* * +* INPUT: lua_State - The current Lua state * +* * +* OUTPUT: int; Did the function run successfully? Return 1 * +* * +* WARNINGS: ? * +* * +*=============================================================================================*/ +static int Script_GetHouseAttribute(lua_State* L) { - // Get the appropriate technotype - if (this_house != NULL) { + int houseID = lua_tointeger(L, 1); + int attribute_type = lua_tointeger(L, 2); - switch (attribute_type) { - case HOUSE_ATTRIBUTE_IQ: { + HouseClass* this_house = Houses.Ptr(houseID); - lua_pushnumber(L, this_house->IQ); - return 1; + // Get the appropriate technotype + if (this_house != NULL) { - }break; - case HOUSE_ATTRIBUTE_TECH_LEVEL: { + switch (attribute_type) { + case HOUSE_ATTRIBUTE_IQ: { - lua_pushnumber(L, this_house->Control.TechLevel); - return 1; + lua_pushnumber(L, this_house->IQ); + return 1; - }break; - case HOUSE_ATTRIBUTE_IS_HUMAN: { + }break; + case HOUSE_ATTRIBUTE_TECH_LEVEL: { - lua_pushboolean(L, this_house->IsHuman); - return 1; + lua_pushnumber(L, this_house->Control.TechLevel); + return 1; - }break; - case HOUSE_ATTRIBUTE_FIREPOWER_BIAS: { + }break; + case HOUSE_ATTRIBUTE_IS_HUMAN: { - lua_pushnumber(L, (float)this_house->FirepowerBias.To_Float()); - return 1; + lua_pushboolean(L, this_house->IsHuman); + return 1; - }break; - case HOUSE_ATTRIBUTE_GROUNDSPEED_BIAS: { - - lua_pushnumber(L, (float)this_house->GroundspeedBias.To_Float()); - return 1; + }break; + case HOUSE_ATTRIBUTE_FIREPOWER_BIAS: { - }break; - case HOUSE_ATTRIBUTE_ARMOR_BIAS: { + lua_pushnumber(L, (float)this_house->FirepowerBias.To_Float()); + return 1; - lua_pushnumber(L, (float)this_house->ArmorBias.To_Float()); - return 1; + }break; + case HOUSE_ATTRIBUTE_GROUNDSPEED_BIAS: { - }break; - case HOUSE_ATTRIBUTE_ROF_BIAS: { + lua_pushnumber(L, (float)this_house->GroundspeedBias.To_Float()); + return 1; - lua_pushnumber(L, this_house->ROFBias.To_Float()); - return 1; + }break; + case HOUSE_ATTRIBUTE_ARMOR_BIAS: { - }break; - case HOUSE_ATTRIBUTE_COST_BIAS: { + lua_pushnumber(L, (float)this_house->ArmorBias.To_Float()); + return 1; - lua_pushnumber(L, (float)this_house->CostBias.To_Float()); - return 1; + }break; + case HOUSE_ATTRIBUTE_ROF_BIAS: { - }break; - case HOUSE_ATTRIBUTE_REPAIR_DELAY: { + lua_pushnumber(L, this_house->ROFBias.To_Float()); + return 1; - lua_pushnumber(L, (float)this_house->RepairDelay.To_Float()); - return 1; + }break; + case HOUSE_ATTRIBUTE_COST_BIAS: { - }break; - case HOUSE_ATTRIBUTE_BUILD_DELAY: { + lua_pushnumber(L, (float)this_house->CostBias.To_Float()); + return 1; - lua_pushnumber(L, (float)this_house->BuildDelay.To_Float()); - return 1; + }break; + case HOUSE_ATTRIBUTE_REPAIR_DELAY: { - }break; - case HOUSE_ATTRIBUTE_STARTED: { + lua_pushnumber(L, (float)this_house->RepairDelay.To_Float()); + return 1; - lua_pushboolean(L, this_house->IsStarted); - return 1; + }break; + case HOUSE_ATTRIBUTE_BUILD_DELAY: { - }break; - case HOUSE_ATTRIBUTE_ALERTED: { + lua_pushnumber(L, (float)this_house->BuildDelay.To_Float()); + return 1; - lua_pushboolean(L, this_house->IsAlerted); - return 1; + }break; + case HOUSE_ATTRIBUTE_STARTED: { - }break; - case HOUSE_ATTRIBUTE_BASE_BUILDING: { + lua_pushboolean(L, this_house->IsStarted); + return 1; - lua_pushboolean(L, this_house->IsBaseBuilding); - return 1; + }break; + case HOUSE_ATTRIBUTE_ALERTED: { - }break; - case HOUSE_ATTRIBUTE_DISCOVERED: { + lua_pushboolean(L, this_house->IsAlerted); + return 1; - lua_pushboolean(L, this_house->IsDiscovered); - return 1; + }break; + case HOUSE_ATTRIBUTE_BASE_BUILDING: { - }break; - case HOUSE_ATTRIBUTE_CAPACITY: { + lua_pushboolean(L, this_house->IsBaseBuilding); + return 1; - lua_pushinteger(L, this_house->Capacity); - return 1; + }break; + case HOUSE_ATTRIBUTE_DISCOVERED: { - }break; - case HOUSE_ATTRIBUTE_TIBERIUM: { + lua_pushboolean(L, this_house->IsDiscovered); + return 1; - lua_pushinteger(L, this_house->Tiberium); - return 1; + }break; + case HOUSE_ATTRIBUTE_CAPACITY: { - }break; - case HOUSE_ATTRIBUTE_CREDITS: { + lua_pushinteger(L, this_house->Capacity); + return 1; - lua_pushinteger(L, this_house->Credits); - return 1; + }break; + case HOUSE_ATTRIBUTE_TIBERIUM: { - }break; - case HOUSE_ATTRIBUTE_ALERT_TIMER: { + lua_pushinteger(L, this_house->Tiberium); + return 1; - lua_pushnumber(L, this_house->AlertTime); - return 1; + }break; + case HOUSE_ATTRIBUTE_CREDITS: { - }break; - case HOUSE_ATTRIBUTE_REPAIR_TIMER: { + lua_pushinteger(L, this_house->Credits); + return 1; - lua_pushnumber(L, this_house->RepairTimer); - return 1; + }break; + case HOUSE_ATTRIBUTE_ALERT_TIMER: { - }break; - case HOUSE_ATTRIBUTE_POINTS: { + lua_pushnumber(L, this_house->AlertTime); + return 1; - lua_pushinteger(L, this_house->PointTotal); - return 1; + }break; + case HOUSE_ATTRIBUTE_REPAIR_TIMER: { - }break; - case HOUSE_ATTRIBUTE_DESTROYED_BUILDINGS: { + lua_pushnumber(L, this_house->RepairTimer); + return 1; - lua_pushinteger(L, (int)this_house->DestroyedBuildings->Get_All_Totals()); - return 1; + }break; + case HOUSE_ATTRIBUTE_POINTS: { - }break; - case HOUSE_ATTRIBUTE_DESTROYED_INFANTRY: { + lua_pushinteger(L, this_house->PointTotal); + return 1; - lua_pushinteger(L, (int)this_house->DestroyedInfantry->Get_All_Totals()); - return 1; + }break; + case HOUSE_ATTRIBUTE_DESTROYED_BUILDINGS: { - }break; - case HOUSE_ATTRIBUTE_DESTROYED_VEHICLES: { + lua_pushinteger(L, (int)this_house->DestroyedBuildings->Get_All_Totals()); + return 1; - lua_pushinteger(L, (int)this_house->DestroyedUnits->Get_All_Totals()); - return 1; + }break; + case HOUSE_ATTRIBUTE_DESTROYED_INFANTRY: { - }break; - case HOUSE_ATTRIBUTE_DESTROYED_AIRCRAFT: { + lua_pushinteger(L, (int)this_house->DestroyedInfantry->Get_All_Totals()); + return 1; - lua_pushinteger(L, (int)this_house->DestroyedAircraft->Get_All_Totals()); - return 1; + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VEHICLES: { - }break; - case HOUSE_ATTRIBUTE_DESTROYED_VESSELS: { + lua_pushinteger(L, (int)this_house->DestroyedUnits->Get_All_Totals()); + return 1; - lua_pushinteger(L, (int)this_house->DestroyedVessels->Get_All_Totals()); - return 1; + }break; + case HOUSE_ATTRIBUTE_DESTROYED_AIRCRAFT: { - }break; - case HOUSE_ATTRIBUTE_CAPTURED_BUILDINGS: { + lua_pushinteger(L, (int)this_house->DestroyedAircraft->Get_All_Totals()); + return 1; - lua_pushinteger(L, (int)this_house->CapturedBuildings->Get_All_Totals()); - return 1; + }break; + case HOUSE_ATTRIBUTE_DESTROYED_VESSELS: { - }break; - case HOUSE_ATTRIBUTE_CRATES: { + lua_pushinteger(L, (int)this_house->DestroyedVessels->Get_All_Totals()); + return 1; - lua_pushinteger(L, (int)this_house->TotalCrates->Get_All_Totals()); - return 1; + }break; + case HOUSE_ATTRIBUTE_CAPTURED_BUILDINGS: { - }break; - case HOUSE_ATTRIBUTE_AIRCRAFT_FACTORIES: { + lua_pushinteger(L, (int)this_house->CapturedBuildings->Get_All_Totals()); + return 1; - lua_pushinteger(L, this_house->AircraftFactories); - return 1; + }break; + case HOUSE_ATTRIBUTE_CRATES: { - }break; - case HOUSE_ATTRIBUTE_INFANTRY_FACTORIES: { + lua_pushinteger(L, (int)this_house->TotalCrates->Get_All_Totals()); + return 1; - lua_pushinteger(L, this_house->InfantryFactories); - return 1; + }break; + case HOUSE_ATTRIBUTE_AIRCRAFT_FACTORIES: { - }break; - case HOUSE_ATTRIBUTE_UNIT_FACTORIES: { + lua_pushinteger(L, this_house->AircraftFactories); + return 1; - lua_pushinteger(L, this_house->UnitFactories); - return 1; + }break; + case HOUSE_ATTRIBUTE_INFANTRY_FACTORIES: { - }break; - case HOUSE_ATTRIBUTE_VESSEL_FACTORIES: { + lua_pushinteger(L, this_house->InfantryFactories); + return 1; - lua_pushinteger(L, this_house->VesselFactories); - return 1; + }break; + case HOUSE_ATTRIBUTE_UNIT_FACTORIES: { - }break; - case HOUSE_ATTRIBUTE_BUILDING_FACTORIES: { + lua_pushinteger(L, this_house->UnitFactories); + return 1; - lua_pushinteger(L, this_house->BuildingFactories); - return 1; + }break; + case HOUSE_ATTRIBUTE_VESSEL_FACTORIES: { - }break; - case HOUSE_ATTRIBUTE_POWER: { + lua_pushinteger(L, this_house->VesselFactories); + return 1; - lua_pushnumber(L, this_house->Power); - return 1; + }break; + case HOUSE_ATTRIBUTE_BUILDING_FACTORIES: { - }break; - case HOUSE_ATTRIBUTE_DRAIN: { + lua_pushinteger(L, this_house->BuildingFactories); + return 1; - lua_pushnumber(L, this_house->Drain); - return 1; + }break; + case HOUSE_ATTRIBUTE_POWER: { - }break; - case HOUSE_ATTRIBUTE_LAST_ATTACKER: { + lua_pushnumber(L, this_house->Power); + return 1; - lua_pushnumber(L, this_house->WhoLastHurtMe); - return 1; + }break; + case HOUSE_ATTRIBUTE_DRAIN: { - }break; + lua_pushnumber(L, this_house->Drain); + return 1; + + }break; + case HOUSE_ATTRIBUTE_LAST_ATTACKER: { + + lua_pushnumber(L, this_house->WhoLastHurtMe); + return 1; + + }break; + } + + } + + lua_pushnumber(L, -1); + + return -1; +} + +/*********************************************************************************************** + * Script_BuildUnit - Builds a given unit in a given factory * + * * + * SCRIPT INPUT: factoryObject (int) - The factory object id * + * * + * unitType (int) - The unit type index for the unit to make (unit in a * + * general sense, not a vehicle) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_BuildUnit(lua_State* L) { + + int factoryObject = lua_tointeger(L, 1); + int unitType = lua_tointeger(L, 2); + + BuildingClass* this_factory = (BuildingClass*)Script_GetCacheObject(factoryObject); + + // Get the appropriate technotype + if (this_factory != NULL && this_factory->IsActive) { + + int result = true; + + switch (this_factory->Class->ID) { + case STRUCT_WEAP: { + + UnitTypeClass* unit_to_place = UnitTypes.Ptr(unitType); + UnitClass* new_unit = (UnitClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_UnitIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + } + else { + delete new_unit; } - } + lua_pushnumber(L, -1); + return 1; - lua_pushnumber(L, -1); + }break; + case STRUCT_TENT: + case STRUCT_BARRACKS: { - return -1; - } + InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(unitType); + InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_factory->House); - /*********************************************************************************************** - * Script_BuildUnit - Builds a given unit in a given factory * - * * - * SCRIPT INPUT: factoryObject (int) - The factory object id * - * * - * unitType (int) - The unit type index for the unit to make (unit in a * - * general sense, not a vehicle) * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_BuildUnit(lua_State* L) { + if (this_factory->Exit_Object(new_unit)) { - int factoryObject = lua_tointeger(L, 1); - int unitType = lua_tointeger(L, 2); + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; - BuildingClass* this_factory = (BuildingClass *)Script_GetCacheObject(factoryObject); - - // Get the appropriate technotype - if (this_factory != NULL && this_factory->IsActive) { + _objectIndex = Script_InfantryIndexFromID(new_unit->ID); - int result = true; + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); - switch (this_factory->Class->ID) { - case STRUCT_WEAP: { + lua_pushnumber(L, CacheObject->UID); + return 1; - UnitTypeClass* unit_to_place = UnitTypes.Ptr(unitType); - UnitClass *new_unit = (UnitClass*)unit_to_place->Create_One_Of(this_factory->House); - - if (this_factory->Exit_Object(new_unit)) { - - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; - - _objectIndex = Script_UnitIndexFromID(new_unit->ID); - - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - lua_pushnumber(L, CacheObject->UID); - return 1; - - }else { - delete new_unit; - } - - lua_pushnumber(L, -1); - return 1; - - }break; - case STRUCT_TENT: - case STRUCT_BARRACKS: { - - InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(unitType); - InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_factory->House); - - if (this_factory->Exit_Object(new_unit)) { - - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; - - _objectIndex = Script_InfantryIndexFromID(new_unit->ID); - - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - lua_pushnumber(L, CacheObject->UID); - return 1; - - }else { - delete new_unit; - } - - lua_pushnumber(L, -1); - return 1; - - }break; - case STRUCT_KENNEL: { - - InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(unitType); - InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_factory->House); - - if (this_factory->Exit_Object(new_unit)) { - - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; - - _objectIndex = Script_InfantryIndexFromID(new_unit->ID); - - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - lua_pushnumber(L, CacheObject->UID); - return 1; - - }else { - delete new_unit; - } - - lua_pushnumber(L, -1); - return 1; - - }break; - case STRUCT_HELIPAD: - case STRUCT_AIRSTRIP: { - - AircraftTypeClass* unit_to_place = AircraftTypes.Ptr(unitType); - AircraftClass* new_unit = (AircraftClass*)unit_to_place->Create_One_Of(this_factory->House); - - if (this_factory->Exit_Object(new_unit)) { - - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; - - _objectIndex = Script_AircraftIndexFromID(new_unit->ID); - - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - lua_pushnumber(L, CacheObject->UID); - return 1; - - }else { - delete new_unit; - } - - lua_pushnumber(L, -1); - return 1; - - }break; - case STRUCT_SUB_PEN: - case STRUCT_SHIP_YARD: { - - VesselTypeClass* unit_to_place = VesselTypes.Ptr(unitType); - VesselClass* new_unit = (VesselClass*)unit_to_place->Create_One_Of(this_factory->House); - - if (this_factory->Exit_Object(new_unit)) { - - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; - - _objectIndex = Script_VesselIndexFromID(new_unit->ID); - - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - lua_pushnumber(L, CacheObject->UID); - return 1; - - }else { - delete new_unit; - } - - lua_pushnumber(L, -1); - return 1; - - }break; + } + else { + delete new_unit; } + lua_pushnumber(L, -1); + return 1; + + }break; + case STRUCT_KENNEL: { + + InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(unitType); + InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_InfantryIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + } + else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; + case STRUCT_HELIPAD: + case STRUCT_AIRSTRIP: { + + AircraftTypeClass* unit_to_place = AircraftTypes.Ptr(unitType); + AircraftClass* new_unit = (AircraftClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_AircraftIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + } + else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; + case STRUCT_SUB_PEN: + case STRUCT_SHIP_YARD: { + + VesselTypeClass* unit_to_place = VesselTypes.Ptr(unitType); + VesselClass* new_unit = (VesselClass*)unit_to_place->Create_One_Of(this_factory->House); + + if (this_factory->Exit_Object(new_unit)) { + + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; + + _objectIndex = Script_VesselIndexFromID(new_unit->ID); + + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + lua_pushnumber(L, CacheObject->UID); + return 1; + + } + else { + delete new_unit; + } + + lua_pushnumber(L, -1); + return 1; + + }break; } - - lua_pushnumber(L, -1); - return 1; } - /*********************************************************************************************** - * Script_CreateVehicle - Creates a given unit out of thin air * - * * - * SCRIPT INPUT: objectIndex(int) - The unit type to create * - * * - * houseType (int) - The player (house) index to create the unit for * - * * - * in_x (int) - X location to create object * - * * - * in_y (int) - Y location to create object * - * * - * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CreateVehicle(lua_State* L) { - int objectIndex = lua_tointeger(L,1); - int houseType = lua_tointeger(L,2); - int in_x = lua_tointeger(L,3); - int in_y = lua_tointeger(L,4); + lua_pushnumber(L, -1); + return 1; +} - HouseClass *this_house = Houses.Ptr(houseType); +/*********************************************************************************************** + * Script_CreateVehicle - Creates a given unit out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The unit type to create * + * * + * houseType (int) - The player (house) index to create the unit for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CreateVehicle(lua_State* L) { - UnitTypeClass *unit_to_place = UnitTypes.Ptr(objectIndex); + int objectIndex = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + int in_x = lua_tointeger(L, 3); + int in_y = lua_tointeger(L, 4); - if (this_house != NULL && unit_to_place != NULL) { - UnitClass* new_unit = (UnitClass*)unit_to_place->Create_One_Of(this_house); - if (new_unit != NULL) { - - bool new_unit_placed = false; + HouseClass* this_house = Houses.Ptr(houseType); - if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + UnitTypeClass* unit_to_place = UnitTypes.Ptr(objectIndex); + if (this_house != NULL && unit_to_place != NULL) { + UnitClass* new_unit = (UnitClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { + + bool new_unit_placed = false; + + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if (!new_unit_placed) { + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell))) { new_unit_placed = true; } - - /* - ** Try to place the object into a nearby cell if something is preventing - ** placement at the given location. - */ - if(!new_unit_placed){ - CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); - if (new_unit->Unlimbo(::Cell_Coord(cell))) { - new_unit_placed = true; - } - } + } - if (new_unit_placed) { - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; - _objectIndex = Script_UnitIndexFromID(new_unit->ID); + _objectIndex = Script_UnitIndexFromID(new_unit->ID); - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); - lua_pushnumber(L, CacheObject->UID); - return 1; - } + lua_pushnumber(L, CacheObject->UID); + return 1; } } - - lua_pushnumber(L, -1); - return 1; } + lua_pushnumber(L, -1); + return 1; +} - /*********************************************************************************************** - * Script_CreateInfantry - Creates a given Infantry out of thin air * - * * - * SCRIPT INPUT: objectIndex(int) - The Infantry type to create * - * * - * houseType (int) - The player (house) index to create the Infantry for * - * * - * in_x (int) - X location to create object * - * * - * in_y (int) - Y location to create object * - * * - * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CreateInfantry(lua_State* L) { - int objectIndex = lua_tointeger(L, 1); - int houseType = lua_tointeger(L, 2); - int in_x = lua_tointeger(L, 3); - int in_y = lua_tointeger(L, 4); +/*********************************************************************************************** + * Script_CreateInfantry - Creates a given Infantry out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The Infantry type to create * + * * + * houseType (int) - The player (house) index to create the Infantry for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CreateInfantry(lua_State* L) { - HouseClass* this_house = Houses.Ptr(houseType); + int objectIndex = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + int in_x = lua_tointeger(L, 3); + int in_y = lua_tointeger(L, 4); - InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(objectIndex); + HouseClass* this_house = Houses.Ptr(houseType); - if (this_house != NULL && unit_to_place != NULL) { - InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_house); - if (new_unit != NULL) { + InfantryTypeClass* unit_to_place = InfantryTypes.Ptr(objectIndex); - bool new_unit_placed = false; + if (this_house != NULL && unit_to_place != NULL) { + InfantryClass* new_unit = (InfantryClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { - if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)),DIR_S)) { + bool new_unit_placed = false; + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)), DIR_S)) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if (!new_unit_placed) { + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell), DIR_S)) { new_unit_placed = true; } - - /* - ** Try to place the object into a nearby cell if something is preventing - ** placement at the given location. - */ - if (!new_unit_placed) { - CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); - if (new_unit->Unlimbo(::Cell_Coord(cell),DIR_S)) { - new_unit_placed = true; - } - } + } - if (new_unit_placed) { - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; - _objectIndex = Script_InfantryIndexFromID(new_unit->ID); + _objectIndex = Script_InfantryIndexFromID(new_unit->ID); - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); - lua_pushnumber(L, CacheObject->UID); - return 1; - } + lua_pushnumber(L, CacheObject->UID); + return 1; } } - - lua_pushnumber(L, -1); - return 1; } - /*********************************************************************************************** - * Script_CreateAircraft - Creates a given Aircraft out of thin air * - * * - * SCRIPT INPUT: objectIndex(int) - The Aircraft type to create * - * * - * houseType (int) - The player (house) index to create the Aircraft for * - * * - * in_x (int) - X location to create object * - * * - * in_y (int) - Y location to create object * - * * - * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CreateAircraft(lua_State* L) { + lua_pushnumber(L, -1); + return 1; +} - int objectIndex = lua_tointeger(L, 1); - int houseType = lua_tointeger(L, 2); - int in_x = lua_tointeger(L, 3); - int in_y = lua_tointeger(L, 4); +/*********************************************************************************************** + * Script_CreateAircraft - Creates a given Aircraft out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The Aircraft type to create * + * * + * houseType (int) - The player (house) index to create the Aircraft for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CreateAircraft(lua_State* L) { - HouseClass* this_house = Houses.Ptr(houseType); + int objectIndex = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + int in_x = lua_tointeger(L, 3); + int in_y = lua_tointeger(L, 4); - AircraftTypeClass* unit_to_place = AircraftTypes.Ptr(objectIndex); + HouseClass* this_house = Houses.Ptr(houseType); - if (this_house != NULL && unit_to_place != NULL) { - AircraftClass* new_unit = (AircraftClass*)unit_to_place->Create_One_Of(this_house); - if (new_unit != NULL) { + AircraftTypeClass* unit_to_place = AircraftTypes.Ptr(objectIndex); - bool new_unit_placed = false; + if (this_house != NULL && unit_to_place != NULL) { + AircraftClass* new_unit = (AircraftClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { - if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + bool new_unit_placed = false; + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if (!new_unit_placed) { + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell))) { new_unit_placed = true; } - - /* - ** Try to place the object into a nearby cell if something is preventing - ** placement at the given location. - */ - if (!new_unit_placed) { - CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); - if (new_unit->Unlimbo(::Cell_Coord(cell))) { - new_unit_placed = true; - } - } + } - if (new_unit_placed) { - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; - _objectIndex = Script_AircraftIndexFromID(new_unit->ID); + _objectIndex = Script_AircraftIndexFromID(new_unit->ID); - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); - lua_pushnumber(L, CacheObject->UID); - return 1; - } + lua_pushnumber(L, CacheObject->UID); + return 1; } } - - lua_pushnumber(L, -1); - return 1; } - /*********************************************************************************************** - * Script_CreateVessel - Creates a given Vessel out of thin air * - * * - * SCRIPT INPUT: objectIndex(int) - The Vessel type to create * - * * - * houseType (int) - The player (house) index to create the Vessel for * - * * - * in_x (int) - X location to create object * - * * - * in_y (int) - Y location to create object * - * * - * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CreateVessel(lua_State* L) { + lua_pushnumber(L, -1); + return 1; +} - int objectIndex = lua_tointeger(L, 1); - int houseType = lua_tointeger(L, 2); - int in_x = lua_tointeger(L, 3); - int in_y = lua_tointeger(L, 4); +/*********************************************************************************************** + * Script_CreateVessel - Creates a given Vessel out of thin air * + * * + * SCRIPT INPUT: objectIndex(int) - The Vessel type to create * + * * + * houseType (int) - The player (house) index to create the Vessel for * + * * + * in_x (int) - X location to create object * + * * + * in_y (int) - Y location to create object * + * * + * SCRIPT OUTPUT: (int) the cached object ID for use with Mapscript Functions * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CreateVessel(lua_State* L) { - HouseClass* this_house = Houses.Ptr(houseType); + int objectIndex = lua_tointeger(L, 1); + int houseType = lua_tointeger(L, 2); + int in_x = lua_tointeger(L, 3); + int in_y = lua_tointeger(L, 4); - VesselTypeClass* unit_to_place = VesselTypes.Ptr(objectIndex); + HouseClass* this_house = Houses.Ptr(houseType); - if (this_house != NULL && unit_to_place != NULL) { - VesselClass* new_unit = (VesselClass*)unit_to_place->Create_One_Of(this_house); - if (new_unit != NULL) { + VesselTypeClass* unit_to_place = VesselTypes.Ptr(objectIndex); - bool new_unit_placed = false; + if (this_house != NULL && unit_to_place != NULL) { + VesselClass* new_unit = (VesselClass*)unit_to_place->Create_One_Of(this_house); + if (new_unit != NULL) { - if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + bool new_unit_placed = false; + if (new_unit->Unlimbo(Cell_Coord(XY_Cell(in_x, in_y)))) { + + new_unit_placed = true; + } + + /* + ** Try to place the object into a nearby cell if something is preventing + ** placement at the given location. + */ + if (!new_unit_placed) { + CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); + if (new_unit->Unlimbo(::Cell_Coord(cell))) { new_unit_placed = true; } - - /* - ** Try to place the object into a nearby cell if something is preventing - ** placement at the given location. - */ - if (!new_unit_placed) { - CELL cell = Map.Nearby_Location(Cell_Coord(XY_Cell(in_x, in_y)), new_unit->Class->Speed); - if (new_unit->Unlimbo(::Cell_Coord(cell))) { - new_unit_placed = true; - } - } + } - if (new_unit_placed) { - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; + if (new_unit_placed) { + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; - _objectIndex = Script_VesselIndexFromID(new_unit->ID); + _objectIndex = Script_VesselIndexFromID(new_unit->ID); - CacheObject->ID = new_unit->ID; - CacheObject->RTTI = new_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); + CacheObject->ID = new_unit->ID; + CacheObject->RTTI = new_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); - lua_pushnumber(L, CacheObject->UID); - return 1; - } + lua_pushnumber(L, CacheObject->UID); + return 1; } } - - lua_pushnumber(L, -1); - return 1; } - + + lua_pushnumber(L, -1); + return 1; +} + /********************************************************************************************** * Object Orders Functions * @@ -5713,7 +5720,7 @@ /*********************************************************************************************** * Script_OrderMove - Assigns a movement order to an object * * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * * * * in_x (int) - X location to move object to * * * @@ -5728,1025 +5735,1025 @@ * WARNINGS: ? * * * *=============================================================================================*/ - static int Script_OrderMove(lua_State* L) { +static int Script_OrderMove(lua_State* L) { - int objectID = lua_tointeger(L, 1); - int in_x = lua_tointeger(L, 2); - int in_y = lua_tointeger(L, 3); + int objectID = lua_tointeger(L, 1); + int in_x = lua_tointeger(L, 2); + int in_y = lua_tointeger(L, 3); - ObjectClass* this_object = Script_GetCacheObject(objectID); + ObjectClass* this_object = Script_GetCacheObject(objectID); - if (this_object != NULL) { + if (this_object != NULL) { - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, As_Target(XY_Cell(in_x, in_y))); + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, As_Target(XY_Cell(in_x, in_y))); - lua_pushnumber(L, 1); - return 1; - - } - - lua_pushnumber(L, -1); + lua_pushnumber(L, 1); return 1; } - /*********************************************************************************************** - * Script_OrderAttackCell - Assigns an attack order to an object for a specific cell * - * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * - * * - * in_x (int) - X location to attack * - * * - * in_y (int) - Y location to attack * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_OrderAttackCell(lua_State* L) { + lua_pushnumber(L, -1); + return 1; - int objectID = lua_tointeger(L, 1); +} - int in_x = lua_tointeger(L, 2); - int in_y = lua_tointeger(L, 3); +/*********************************************************************************************** + * Script_OrderAttackCell - Assigns an attack order to an object for a specific cell * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (int) - X location to attack * + * * + * in_y (int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_OrderAttackCell(lua_State* L) { - ObjectClass* this_object = Script_GetCacheObject(objectID); + int objectID = lua_tointeger(L, 1); - if (this_object != NULL) { + int in_x = lua_tointeger(L, 2); + int in_y = lua_tointeger(L, 3); - TARGET this_target = 0; - if (in_x >= 0 && in_y >= 0) { - this_target = As_Target(XY_Cell(in_x, in_y)); - } + ObjectClass* this_object = Script_GetCacheObject(objectID); - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, this_target, this_target); - - lua_pushnumber(L, 1); - return 1; + if (this_object != NULL) { + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); } - lua_pushnumber(L, -1); - return 1; + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, this_target, this_target); - } - - /*********************************************************************************************** - * Script_OrderAttack - Assigns an attack order to an object * - * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * - * * - * in_x (int) - X location to attack * - * * - * in_y (int) - Y location to attack * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_OrderAttack(lua_State* L) { - - int objectID = lua_tointeger(L, 1); - - int in_x = -1; - int in_y = -1; - if (lua_gettop(L) == 3) { - in_x = lua_tointeger(L, 2); - in_y = lua_tointeger(L, 3); - } - - ObjectClass* this_object = Script_GetCacheObject(objectID); - - if (this_object != NULL) { - - TARGET this_target = 0; - if (in_x >= 0 && in_y >= 0) { - this_target = As_Target(XY_Cell(in_x, in_y)); - } - - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); - - lua_pushnumber(L, 1); - return 1; - - } - - lua_pushnumber(L, -1); - return 1; - - } - - /*********************************************************************************************** - * Script_OrderHunt - Assigns a hunt order to an object * - * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * - * * - * in_x (opt)(int) - X location to attack * - * * - * in_y (opt)(int) - Y location to attack * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_OrderHunt(lua_State* L) { - - int objectID = lua_tointeger(L, 1); - - int in_x = -1; - int in_y = -1; - if (lua_gettop(L) == 3) { - in_x = lua_tointeger(L, 2); - in_y = lua_tointeger(L, 3); - } - - ObjectClass* this_object = Script_GetCacheObject(objectID); - - if (this_object != NULL) { - - TARGET this_target = 0; - if (in_x >= 0 && in_y >= 0) { - this_target = As_Target(XY_Cell(in_x, in_y)); - } - - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); - - lua_pushnumber(L, 1); - return 1; - - } - - lua_pushnumber(L, -1); - return 1; - - } - - /*********************************************************************************************** - * Script_OrderGuard - Assigns a guard order to an object * - * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * - * * - * in_x (opt)(int) - X location to attack * - * * - * in_y (opt)(int) - Y location to attack * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_OrderGuard(lua_State* L) { - - int objectID = lua_tointeger(L, 1); - - int in_x = -1; - int in_y = -1; - if (lua_gettop(L) == 3) { - in_x = lua_tointeger(L, 2); - in_y = lua_tointeger(L, 3); - } - - ObjectClass* this_object = Script_GetCacheObject(objectID); - - if (this_object != NULL) { - - TARGET this_target = 0; - if (in_x >= 0 && in_y >= 0) { - this_target = As_Target(XY_Cell(in_x, in_y)); - } - - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); - - lua_pushnumber(L, 1); - return 1; - - } - - lua_pushnumber(L, -1); - return 1; - - } - - /*********************************************************************************************** - * Script_OrderRetreat - Assigns a retreat order to an object * - * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * - * * - * in_x (opt)(int) - X location to attack * - * * - * in_y (opt)(int) - Y location to attack * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_OrderRetreat(lua_State* L) { - - int objectID = lua_tointeger(L, 1); - - int in_x = -1; - int in_y = -1; - if (lua_gettop(L) == 3) { - in_x = lua_tointeger(L, 2); - in_y = lua_tointeger(L, 3); - } - - ObjectClass* this_object = Script_GetCacheObject(objectID); - - if (this_object != NULL) { - - TARGET this_target = 0; - if (in_x >= 0 && in_y >= 0) { - this_target = As_Target(XY_Cell(in_x, in_y)); - } - - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); - - lua_pushnumber(L, 1); - return 1; - - } - - lua_pushnumber(L, -1); - return 1; - - } - - /*********************************************************************************************** - * Script_OrderEnter - Assigns an enter order to an object * - * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * - * * - * in_x (opt)(int) - X location to enter (building / unit) * - * * - * in_y (opt)(int) - Y location to enter (building / unit) * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_OrderEnter(lua_State* L) { - - int objectID = lua_tointeger(L, 1); - - int in_x = -1; - int in_y = -1; - if (lua_gettop(L) == 3) { - in_x = lua_tointeger(L, 2); - in_y = lua_tointeger(L, 3); - } - - ObjectClass* this_object = Script_GetCacheObject(objectID); - - if (this_object != NULL) { - - TARGET this_target = 0; - if (in_x >= 0 && in_y >= 0) { - this_target = As_Target(XY_Cell(in_x, in_y)); - } - - Queue_Mission(TargetClass(this_object), MISSION_ENTER, this_target, this_target); - - lua_pushnumber(L, 1); - return 1; - - } - - lua_pushnumber(L, -1); + lua_pushnumber(L, 1); return 1; } - /*********************************************************************************************** - * Script_OrderCapture - Assigns a capture order to an object * - * * - * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * - * * - * in_x (opt)(int) - X location to capture (building) * - * * - * in_y (opt)(int) - Y location to capture (building) * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_OrderCapture(lua_State* L) { + lua_pushnumber(L, -1); + return 1; - int objectID = lua_tointeger(L, 1); +} - int in_x = -1; - int in_y = -1; - if (lua_gettop(L) == 3) { - in_x = lua_tointeger(L, 2); - in_y = lua_tointeger(L, 3); +/*********************************************************************************************** + * Script_OrderAttack - Assigns an attack order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (int) - X location to attack * + * * + * in_y (int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_OrderAttack(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); } - ObjectClass* this_object = Script_GetCacheObject(objectID); + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); - if (this_object != NULL) { - - TARGET this_target = 0; - if (in_x >= 0 && in_y >= 0) { - this_target = As_Target(XY_Cell(in_x, in_y)); - } - - Queue_Mission(TargetClass(this_object), MISSION_CAPTURE, this_target, this_target); - - lua_pushnumber(L, 1); - return 1; - - } - - lua_pushnumber(L, -1); + lua_pushnumber(L, 1); return 1; } + lua_pushnumber(L, -1); + return 1; + +} + +/*********************************************************************************************** + * Script_OrderHunt - Assigns a hunt order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to attack * + * * + * in_y (opt)(int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_OrderHunt(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + +} + +/*********************************************************************************************** + * Script_OrderGuard - Assigns a guard order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to attack * + * * + * in_y (opt)(int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_OrderGuard(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + +} + +/*********************************************************************************************** + * Script_OrderRetreat - Assigns a retreat order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to attack * + * * + * in_y (opt)(int) - Y location to attack * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_OrderRetreat(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + +} + +/*********************************************************************************************** + * Script_OrderEnter - Assigns an enter order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to enter (building / unit) * + * * + * in_y (opt)(int) - Y location to enter (building / unit) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_OrderEnter(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_ENTER, this_target, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + +} + +/*********************************************************************************************** + * Script_OrderCapture - Assigns a capture order to an object * + * * + * SCRIPT INPUT: objectID (int) - The object ID (retrieved via MS functions) * + * * + * in_x (opt)(int) - X location to capture (building) * + * * + * in_y (opt)(int) - Y location to capture (building) * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_OrderCapture(lua_State* L) { + + int objectID = lua_tointeger(L, 1); + + int in_x = -1; + int in_y = -1; + if (lua_gettop(L) == 3) { + in_x = lua_tointeger(L, 2); + in_y = lua_tointeger(L, 3); + } + + ObjectClass* this_object = Script_GetCacheObject(objectID); + + if (this_object != NULL) { + + TARGET this_target = 0; + if (in_x >= 0 && in_y >= 0) { + this_target = As_Target(XY_Cell(in_x, in_y)); + } + + Queue_Mission(TargetClass(this_object), MISSION_CAPTURE, this_target, this_target); + + lua_pushnumber(L, 1); + return 1; + + } + + lua_pushnumber(L, -1); + return 1; + +} + /********************************************************************************************** * Mission Utility Functions * *=============================================================================================*/ - /*********************************************************************************************** - * Script_SetBriefingText - Sets the text on the mission briefing screen * - * * - * SCRIPT INPUT: (char*); The input text * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_SetBriefingText(lua_State* L) { - strcpy(Scen.BriefingText, lua_tostring(L, -1)); - return -1; - } +/*********************************************************************************************** + * Script_SetBriefingText - Sets the text on the mission briefing screen * + * * + * SCRIPT INPUT: (char*); The input text * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_SetBriefingText(lua_State* L) { + strcpy(Scen.BriefingText, lua_tostring(L, -1)); + return -1; +} /********************************************************************************************** * Status / Location Utility Functions * *=============================================================================================*/ - /*********************************************************************************************** - * Script_GiveCredits - Gives or takes a given amount of credits to / from a player * - * * - * SCRIPT INPUT: cashToGive (int) - The amount of cold hard credits to give the player. * - * Negative numbers may be used to *take* money * - * * - * houseType (int) - The player (house) index to complete this transaction * - * for, or -1 to give to all players * - * * - * SCRIPT OUTPUT: void * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - * HISTORY: * - * 6/11/2020 - JM Created * - * 6/12/2020 - JJ Added player (house) index input * - *=============================================================================================*/ - static int Script_GiveCredits(lua_State* L) { +/*********************************************************************************************** + * Script_GiveCredits - Gives or takes a given amount of credits to / from a player * + * * + * SCRIPT INPUT: cashToGive (int) - The amount of cold hard credits to give the player. * + * Negative numbers may be used to *take* money * + * * + * houseType (int) - The player (house) index to complete this transaction * + * for, or -1 to give to all players * + * * + * SCRIPT OUTPUT: void * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + * HISTORY: * + * 6/11/2020 - JM Created * + * 6/12/2020 - JJ Added player (house) index input * + *=============================================================================================*/ +static int Script_GiveCredits(lua_State* L) { - int cashToGive = lua_tointeger(L, 1); + int cashToGive = lua_tointeger(L, 1); - int houseType = -1; + int houseType = -1; - // Optional houseType parameter - if (lua_gettop(L) == 2) { - houseType = lua_tointeger(L, 2); - } - - for (int h_index = 0; h_index < Houses.Count(); h_index++) { - - HouseClass* house = Houses.Ptr(h_index); - - if (house->ID == houseType || houseType == -1) { - - if (cashToGive < 0) { - house->Spend_Money(max(0, cashToGive * -1)); - } - else { - house->Refund_Money(cashToGive); - } - - // Discontinue giving out free cash if a specific house was specified - if (houseType >= 0) { - break; - } - } - - } - - return 1; + // Optional houseType parameter + if (lua_gettop(L) == 2) { + houseType = lua_tointeger(L, 2); } - /*********************************************************************************************** - * Script_GetCredits - Gets how many credits the given player has * - * * - * SCRIPT INPUT: houseType (int) - The player (house) index to get credits for * - * * - * SCRIPT OUTPUT: result (number) - The amount of credits the player has * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetCredits(lua_State* L) { + for (int h_index = 0; h_index < Houses.Count(); h_index++) { - int houseType = lua_tointeger(L, -1); + HouseClass* house = Houses.Ptr(h_index); - long result = -1; + if (house->ID == houseType || houseType == -1) { - for (int h_index = 0; h_index < Houses.Count(); h_index++) { - - HouseClass* house = Houses.Ptr(h_index); - - if (house->ID == houseType || houseType == -1) { - result = house->Credits; + if (cashToGive < 0) { + house->Spend_Money(max(0, cashToGive * -1)); + } + else { + house->Refund_Money(cashToGive); + } + // Discontinue giving out free cash if a specific house was specified + if (houseType >= 0) { break; } - } - lua_pushnumber(L, result); - - return 1; } - /*********************************************************************************************** - * Script_CountBuildings - Returns the amount of specific buildings for a player * - * * - * Optionally, you can return only building at a particular cell or in a rectangular area * - * using the two groups of optional coordinate inputs * - * * - * SCRIPT INPUT: structType (int) - The structure index to count buildings for * - * or -1 for all structures * - * * - * houseType (int) - The player (house) index to count buildings for * - * or -1 to for all players * - * * - * NOTE: -1 for either index input acts as ALL * - * * - * in_x1 (int) (optional A) - Only include buildings at or beginning at this * - * Cell/X location * - * * - * in_y1 (int) (optional A) - Only include buildings at or beginning at this * - * Cell/Y location * - * * - * in_x2 (int) (optional B) - Only include buildings at or before this Cell/X * - * location * - * * - * in_y2 (int) (optional B) - Only include buildings at or before this Cell/Y * - * location * - * * - * SCRIPT OUTPUT: result (number) - The amount of matching buildings for that player * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CountBuildings(lua_State* L) { - int structType = lua_tointeger(L, 1); + return 1; +} - int houseType = -1; +/*********************************************************************************************** + * Script_GetCredits - Gets how many credits the given player has * + * * + * SCRIPT INPUT: houseType (int) - The player (house) index to get credits for * + * * + * SCRIPT OUTPUT: result (number) - The amount of credits the player has * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GetCredits(lua_State* L) { - // Optional houseType parameter - if (lua_gettop(L) == 2) { - houseType = lua_tointeger(L, 2); + int houseType = lua_tointeger(L, -1); + + long result = -1; + + for (int h_index = 0; h_index < Houses.Count(); h_index++) { + + HouseClass* house = Houses.Ptr(h_index); + + if (house->ID == houseType || houseType == -1) { + result = house->Credits; + + break; } - // Optional search area - bool within_area = false; - int in_x1, in_x2, in_y1, in_y2; - if (lua_gettop(L) == 4) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = in_x1; - in_y2 = in_y1; - within_area = true; - } - else if (lua_gettop(L) == 6) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = lua_tointeger(L, 5); - in_y2 = lua_tointeger(L, 6); - within_area = true; - } + } - int result = 0; - for (int b_index = 0; b_index < Buildings.Count(); b_index++) { - BuildingClass* building = Buildings.Ptr(b_index); + lua_pushnumber(L, result); - if (building->Owner() == houseType || houseType == -1) { - if (building->Class->Type == structType || structType == -1) { + return 1; +} - // Count, in general - if (within_area == false) { - result++; +/*********************************************************************************************** + * Script_CountBuildings - Returns the amount of specific buildings for a player * + * * + * Optionally, you can return only building at a particular cell or in a rectangular area * + * using the two groups of optional coordinate inputs * + * * + * SCRIPT INPUT: structType (int) - The structure index to count buildings for * + * or -1 for all structures * + * * + * houseType (int) - The player (house) index to count buildings for * + * or -1 to for all players * + * * + * NOTE: -1 for either index input acts as ALL * + * * + * in_x1 (int) (optional A) - Only include buildings at or beginning at this * + * Cell/X location * + * * + * in_y1 (int) (optional A) - Only include buildings at or beginning at this * + * Cell/Y location * + * * + * in_x2 (int) (optional B) - Only include buildings at or before this Cell/X * + * location * + * * + * in_y2 (int) (optional B) - Only include buildings at or before this Cell/Y * + * location * + * * + * SCRIPT OUTPUT: result (number) - The amount of matching buildings for that player * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CountBuildings(lua_State* L) { + int structType = lua_tointeger(L, 1); - // Within search area - } - else { + int houseType = -1; - int this_x = Cell_X(Coord_Cell(building->Coord)); - int this_y = Cell_Y(Coord_Cell(building->Coord)); + // Optional houseType parameter + if (lua_gettop(L) == 2) { + houseType = lua_tointeger(L, 2); + } - if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { - result++; - } - } + // Optional search area + bool within_area = false; + int in_x1, in_x2, in_y1, in_y2; + if (lua_gettop(L) == 4) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = in_x1; + in_y2 = in_y1; + within_area = true; + } + else if (lua_gettop(L) == 6) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = lua_tointeger(L, 5); + in_y2 = lua_tointeger(L, 6); + within_area = true; + } + int result = 0; + for (int b_index = 0; b_index < Buildings.Count(); b_index++) { + BuildingClass* building = Buildings.Ptr(b_index); + + if (building->Owner() == houseType || houseType == -1) { + if (building->Class->Type == structType || structType == -1) { + + // Count, in general + if (within_area == false) { + result++; + + // Within search area } + else { + + int this_x = Cell_X(Coord_Cell(building->Coord)); + int this_y = Cell_Y(Coord_Cell(building->Coord)); + + if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { + result++; + } + } + } } - - lua_pushnumber(L, result); - return 1; } - /*********************************************************************************************** - * Script_CountAircraft - Returns the amount of specific aircraft for a player * - * * - * Optionally, you can return only aircraft at a particular cell or in a rectangular area * - * using the two groups of optional coordinate inputs * - * * - * SCRIPT INPUT: aircraftType (int) - The aircraft index to count aircraft for * - * or -1 for all aircraft * - * * - * houseType (int) - The player (house) index to count aircraft for * - * or -1 for all players * - * * - * NOTE: -1 for either index input acts as ALL * - * * - * in_x1 (int) (optional A) - Only include aircraft at or beginning at this * - * Cell/X location * - * * - * in_y1 (int) (optional A) - Only include aircraft at or beginning at this * - * Cell/Y location * - * * - * in_x2 (int) (optional B) - Only include aircraft at or before this Cell/X * - * location * - * * - * in_y2 (int) (optional B) - Only include aircraft at or before this Cell/Y * - * location * - * * - * SCRIPT OUTPUT: result (number) - The amount of matching aircraft for that player * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CountAircraft(lua_State* L) { - int aircraftType = lua_tointeger(L, 1); + lua_pushnumber(L, result); + return 1; +} - int houseType = -1; +/*********************************************************************************************** + * Script_CountAircraft - Returns the amount of specific aircraft for a player * + * * + * Optionally, you can return only aircraft at a particular cell or in a rectangular area * + * using the two groups of optional coordinate inputs * + * * + * SCRIPT INPUT: aircraftType (int) - The aircraft index to count aircraft for * + * or -1 for all aircraft * + * * + * houseType (int) - The player (house) index to count aircraft for * + * or -1 for all players * + * * + * NOTE: -1 for either index input acts as ALL * + * * + * in_x1 (int) (optional A) - Only include aircraft at or beginning at this * + * Cell/X location * + * * + * in_y1 (int) (optional A) - Only include aircraft at or beginning at this * + * Cell/Y location * + * * + * in_x2 (int) (optional B) - Only include aircraft at or before this Cell/X * + * location * + * * + * in_y2 (int) (optional B) - Only include aircraft at or before this Cell/Y * + * location * + * * + * SCRIPT OUTPUT: result (number) - The amount of matching aircraft for that player * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CountAircraft(lua_State* L) { + int aircraftType = lua_tointeger(L, 1); - // Optional houseType parameter - if (lua_gettop(L) == 2) { - houseType = lua_tointeger(L, 2); - } + int houseType = -1; - // Optional search area - bool within_area = false; - int in_x1, in_x2, in_y1, in_y2; - if (lua_gettop(L) == 4) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = in_x1; - in_y2 = in_y1; - within_area = true; - } - else if (lua_gettop(L) == 6) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = lua_tointeger(L, 5); - in_y2 = lua_tointeger(L, 6); - within_area = true; - } + // Optional houseType parameter + if (lua_gettop(L) == 2) { + houseType = lua_tointeger(L, 2); + } - int result = 0; - for (int a_index = 0; a_index < Aircraft.Count(); a_index++) { - AircraftClass* aircraft = Aircraft.Ptr(a_index); + // Optional search area + bool within_area = false; + int in_x1, in_x2, in_y1, in_y2; + if (lua_gettop(L) == 4) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = in_x1; + in_y2 = in_y1; + within_area = true; + } + else if (lua_gettop(L) == 6) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = lua_tointeger(L, 5); + in_y2 = lua_tointeger(L, 6); + within_area = true; + } - if (aircraft->Owner() == houseType || houseType == -1) { - if (aircraft->Class->Type == aircraftType || aircraftType == -1) { + int result = 0; + for (int a_index = 0; a_index < Aircraft.Count(); a_index++) { + AircraftClass* aircraft = Aircraft.Ptr(a_index); - // Count, in general - if (within_area == false) { - result++; + if (aircraft->Owner() == houseType || houseType == -1) { + if (aircraft->Class->Type == aircraftType || aircraftType == -1) { - // Within search area - } - else { - - int this_x = Cell_X(Coord_Cell(aircraft->Coord)); - int this_y = Cell_Y(Coord_Cell(aircraft->Coord)); - - if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { - result++; - } - } + // Count, in general + if (within_area == false) { + result++; + // Within search area } + else { + + int this_x = Cell_X(Coord_Cell(aircraft->Coord)); + int this_y = Cell_Y(Coord_Cell(aircraft->Coord)); + + if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { + result++; + } + } + } } - - lua_pushnumber(L, result); - return 1; } - /*********************************************************************************************** - * Script_CountUnits - Returns the amount of specific units for a player * - * * - * Optionally, you can return only units at a particular cell or in a rectangular area * - * using the two groups of optional coordinate inputs * - * * - * SCRIPT INPUT: unitType (int) - The unit index to count units for * - * or -1 for all units * - * * - * houseType (int) - The player (house) index to count units for * - * or -1 for all players * - * * - * NOTE: -1 for either index input acts as ALL * - * * - * in_x1 (int) (optional A) - Only include units at or beginning at this * - * Cell/X location * - * * - * in_y1 (int) (optional A) - Only include units at or beginning at this * - * Cell/Y location * - * * - * in_x2 (int) (optional B) - Only include units at or before this Cell/X * - * location * - * * - * in_y2 (int) (optional B) - Only include units at or before this Cell/Y * - * location * - * * - * SCRIPT OUTPUT: result (number) - The amount of matching units for that player * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CountUnits(lua_State* L) { - int unitType = lua_tointeger(L, 1); + lua_pushnumber(L, result); + return 1; +} - int houseType = -1; +/*********************************************************************************************** + * Script_CountUnits - Returns the amount of specific units for a player * + * * + * Optionally, you can return only units at a particular cell or in a rectangular area * + * using the two groups of optional coordinate inputs * + * * + * SCRIPT INPUT: unitType (int) - The unit index to count units for * + * or -1 for all units * + * * + * houseType (int) - The player (house) index to count units for * + * or -1 for all players * + * * + * NOTE: -1 for either index input acts as ALL * + * * + * in_x1 (int) (optional A) - Only include units at or beginning at this * + * Cell/X location * + * * + * in_y1 (int) (optional A) - Only include units at or beginning at this * + * Cell/Y location * + * * + * in_x2 (int) (optional B) - Only include units at or before this Cell/X * + * location * + * * + * in_y2 (int) (optional B) - Only include units at or before this Cell/Y * + * location * + * * + * SCRIPT OUTPUT: result (number) - The amount of matching units for that player * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CountUnits(lua_State* L) { + int unitType = lua_tointeger(L, 1); - // Optional houseType parameter - if (lua_gettop(L) == 2) { - houseType = lua_tointeger(L, 2); - } + int houseType = -1; - // Optional search area - bool within_area = false; - int in_x1, in_x2, in_y1, in_y2; - if (lua_gettop(L) == 4) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = in_x1; - in_y2 = in_y1; - within_area = true; - } - else if (lua_gettop(L) == 6) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = lua_tointeger(L, 5); - in_y2 = lua_tointeger(L, 6); - within_area = true; - } + // Optional houseType parameter + if (lua_gettop(L) == 2) { + houseType = lua_tointeger(L, 2); + } - int result = 0; - for (int u_index = 0; u_index < Units.Count(); u_index++) { - UnitClass* unit = Units.Ptr(u_index); + // Optional search area + bool within_area = false; + int in_x1, in_x2, in_y1, in_y2; + if (lua_gettop(L) == 4) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = in_x1; + in_y2 = in_y1; + within_area = true; + } + else if (lua_gettop(L) == 6) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = lua_tointeger(L, 5); + in_y2 = lua_tointeger(L, 6); + within_area = true; + } - if (unit->Owner() == houseType || houseType == -1) { - if (unit->Class->Type == unitType || unitType == -1) { + int result = 0; + for (int u_index = 0; u_index < Units.Count(); u_index++) { + UnitClass* unit = Units.Ptr(u_index); - // Count, in general - if (within_area == false) { - result++; + if (unit->Owner() == houseType || houseType == -1) { + if (unit->Class->Type == unitType || unitType == -1) { - // Within search area - } - else { - - int this_x = Cell_X(Coord_Cell(unit->Coord)); - int this_y = Cell_Y(Coord_Cell(unit->Coord)); - - if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { - result++; - } - } + // Count, in general + if (within_area == false) { + result++; + // Within search area } + else { + + int this_x = Cell_X(Coord_Cell(unit->Coord)); + int this_y = Cell_Y(Coord_Cell(unit->Coord)); + + if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { + result++; + } + } + } } - - lua_pushnumber(L, result); - return 1; } - /*********************************************************************************************** - * Script_CountInfantry - Returns the amount of specific infantry for a player * - * * - * Optionally, you can return only infantry at a particular cell or in a rectangular area * - * using the two groups of optional coordinate inputs * - * * - * SCRIPT INPUT: infantryType (int) - The infantry index to count infantry for * - * or -1 for all infantry * - * * - * houseType (int) - The player (house) index to count infantry for * - * or -1 for all players * - * * - * NOTE: -1 for either index input acts as ALL * - * * - * in_x1 (int) (optional A) - Only include infantry at or beginning at this * - * Cell/X location * - * * - * in_y1 (int) (optional A) - Only include infantry at or beginning at this * - * Cell/Y location * - * * - * in_x2 (int) (optional B) - Only include infantry at or before this Cell/X * - * location * - * * - * in_y2 (int) (optional B) - Only include infantry at or before this Cell/Y * - * location * - * * - * SCRIPT OUTPUT: result (number) - The amount of matching infantry for that player * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CountInfantry(lua_State* L) { - int infantryType = lua_tointeger(L, 1); + lua_pushnumber(L, result); + return 1; +} - int houseType = -1; +/*********************************************************************************************** + * Script_CountInfantry - Returns the amount of specific infantry for a player * + * * + * Optionally, you can return only infantry at a particular cell or in a rectangular area * + * using the two groups of optional coordinate inputs * + * * + * SCRIPT INPUT: infantryType (int) - The infantry index to count infantry for * + * or -1 for all infantry * + * * + * houseType (int) - The player (house) index to count infantry for * + * or -1 for all players * + * * + * NOTE: -1 for either index input acts as ALL * + * * + * in_x1 (int) (optional A) - Only include infantry at or beginning at this * + * Cell/X location * + * * + * in_y1 (int) (optional A) - Only include infantry at or beginning at this * + * Cell/Y location * + * * + * in_x2 (int) (optional B) - Only include infantry at or before this Cell/X * + * location * + * * + * in_y2 (int) (optional B) - Only include infantry at or before this Cell/Y * + * location * + * * + * SCRIPT OUTPUT: result (number) - The amount of matching infantry for that player * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CountInfantry(lua_State* L) { + int infantryType = lua_tointeger(L, 1); - // Optional houseType parameter - if (lua_gettop(L) == 2) { - houseType = lua_tointeger(L, 2); - } + int houseType = -1; - // Optional search area - bool within_area = false; - int in_x1, in_x2, in_y1, in_y2; - if (lua_gettop(L) == 4) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = in_x1; - in_y2 = in_y1; - within_area = true; - } - else if (lua_gettop(L) == 6) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = lua_tointeger(L, 5); - in_y2 = lua_tointeger(L, 6); - within_area = true; - } + // Optional houseType parameter + if (lua_gettop(L) == 2) { + houseType = lua_tointeger(L, 2); + } - int result = 0; - for (int u_index = 0; u_index < Infantry.Count(); u_index++) { - InfantryClass* infantry = Infantry.Ptr(u_index); + // Optional search area + bool within_area = false; + int in_x1, in_x2, in_y1, in_y2; + if (lua_gettop(L) == 4) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = in_x1; + in_y2 = in_y1; + within_area = true; + } + else if (lua_gettop(L) == 6) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = lua_tointeger(L, 5); + in_y2 = lua_tointeger(L, 6); + within_area = true; + } - if (infantry->Owner() == houseType || houseType == -1) { - if (infantry->Class->Type == infantryType || infantryType == -1) { + int result = 0; + for (int u_index = 0; u_index < Infantry.Count(); u_index++) { + InfantryClass* infantry = Infantry.Ptr(u_index); - // Count, in general - if (within_area == false) { - result++; + if (infantry->Owner() == houseType || houseType == -1) { + if (infantry->Class->Type == infantryType || infantryType == -1) { - // Within search area - } - else { - - int this_x = Cell_X(Coord_Cell(infantry->Coord)); - int this_y = Cell_Y(Coord_Cell(infantry->Coord)); - - if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { - result++; - } - } + // Count, in general + if (within_area == false) { + result++; + // Within search area } + else { + + int this_x = Cell_X(Coord_Cell(infantry->Coord)); + int this_y = Cell_Y(Coord_Cell(infantry->Coord)); + + if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { + result++; + } + } + } } - - lua_pushnumber(L, result); - return 1; } - /*********************************************************************************************** - * Script_CountVessels - Returns the amount of specific vessels for a player * - * * - * Optionally, you can return only vessels at a particular cell or in a rectangular area * - * using the two groups of optional coordinate inputs * - * * - * SCRIPT INPUT: vesselType (int) - The vessel index to count vessels for * - * or -1 for all vessels * - * * - * houseType (int) - The player (house) index to count vessels for * - * or -1 for all players * - * * - * NOTE: -1 for either index input acts as ALL * - * * - * in_x1 (int) (optional A) - Only include vessels at or beginning at this * - * Cell/X location * - * * - * in_y1 (int) (optional A) - Only include vessels at or beginning at this * - * Cell/Y location * - * * - * in_x2 (int) (optional B) - Only include vessels at or before this Cell/X * - * location * - * * - * in_y2 (int) (optional B) - Only include vessels at or before this Cell/X * - * location * - * * - * SCRIPT OUTPUT: result (number) - The amount of matching vessels for that player * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_CountVessels(lua_State* L) { - int vesselType = lua_tointeger(L, 1); + lua_pushnumber(L, result); + return 1; +} - int houseType = -1; +/*********************************************************************************************** + * Script_CountVessels - Returns the amount of specific vessels for a player * + * * + * Optionally, you can return only vessels at a particular cell or in a rectangular area * + * using the two groups of optional coordinate inputs * + * * + * SCRIPT INPUT: vesselType (int) - The vessel index to count vessels for * + * or -1 for all vessels * + * * + * houseType (int) - The player (house) index to count vessels for * + * or -1 for all players * + * * + * NOTE: -1 for either index input acts as ALL * + * * + * in_x1 (int) (optional A) - Only include vessels at or beginning at this * + * Cell/X location * + * * + * in_y1 (int) (optional A) - Only include vessels at or beginning at this * + * Cell/Y location * + * * + * in_x2 (int) (optional B) - Only include vessels at or before this Cell/X * + * location * + * * + * in_y2 (int) (optional B) - Only include vessels at or before this Cell/X * + * location * + * * + * SCRIPT OUTPUT: result (number) - The amount of matching vessels for that player * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_CountVessels(lua_State* L) { + int vesselType = lua_tointeger(L, 1); - // Optional houseType parameter - if (lua_gettop(L) == 2) { - houseType = lua_tointeger(L, 2); - } + int houseType = -1; - // Optional search area - bool within_area = false; - int in_x1, in_x2, in_y1, in_y2; - if (lua_gettop(L) == 4) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = in_x1; - in_y2 = in_y1; - within_area = true; - } - else if (lua_gettop(L) == 6) { - in_x1 = lua_tointeger(L, 3); - in_y1 = lua_tointeger(L, 4); - in_x2 = lua_tointeger(L, 5); - in_y2 = lua_tointeger(L, 6); - within_area = true; - } + // Optional houseType parameter + if (lua_gettop(L) == 2) { + houseType = lua_tointeger(L, 2); + } - int result = 0; - for (int u_index = 0; u_index < Vessels.Count(); u_index++) { - VesselClass* vessel = Vessels.Ptr(u_index); + // Optional search area + bool within_area = false; + int in_x1, in_x2, in_y1, in_y2; + if (lua_gettop(L) == 4) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = in_x1; + in_y2 = in_y1; + within_area = true; + } + else if (lua_gettop(L) == 6) { + in_x1 = lua_tointeger(L, 3); + in_y1 = lua_tointeger(L, 4); + in_x2 = lua_tointeger(L, 5); + in_y2 = lua_tointeger(L, 6); + within_area = true; + } - if (vessel->Owner() == houseType || houseType == -1) { - if (vessel->Class->Type == vesselType || vesselType == -1) { + int result = 0; + for (int u_index = 0; u_index < Vessels.Count(); u_index++) { + VesselClass* vessel = Vessels.Ptr(u_index); - // Count, in general - if (within_area == false) { - result++; + if (vessel->Owner() == houseType || houseType == -1) { + if (vessel->Class->Type == vesselType || vesselType == -1) { - // Within search area - } - else { - - int this_x = Cell_X(Coord_Cell(vessel->Coord)); - int this_y = Cell_Y(Coord_Cell(vessel->Coord)); - - if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { - result++; - } - } + // Count, in general + if (within_area == false) { + result++; + // Within search area } + else { + + int this_x = Cell_X(Coord_Cell(vessel->Coord)); + int this_y = Cell_Y(Coord_Cell(vessel->Coord)); + + if (this_x >= in_x1 && this_x <= in_x2 && this_y >= in_y1 && this_y <= in_y2) { + result++; + } + } + } } + } + + lua_pushnumber(L, result); + return 1; +} + +/*********************************************************************************************** + * Script_GetWaypointX - Gets the Cell/X Coordinate of Waypoint * + * * + * SCRIPT INPUT: waypointIndex (int) - The waypoint's index to grab the X coordinate for * + * * + * SCRIPT OUTPUT: outX (int) - The Cell/X coordinate of the waypoint * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GetWaypointX(lua_State* L) { + + int ret = lua_tointeger(L, -1); + + if (ret > 0 && ret < sizeof(Scen.Waypoint)) { + + lua_pushnumber(L, Cell_X(Scen.Waypoint[ret])); - lua_pushnumber(L, result); return 1; + } - /*********************************************************************************************** - * Script_GetWaypointX - Gets the Cell/X Coordinate of Waypoint * - * * - * SCRIPT INPUT: waypointIndex (int) - The waypoint's index to grab the X coordinate for * - * * - * SCRIPT OUTPUT: outX (int) - The Cell/X coordinate of the waypoint * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetWaypointX(lua_State* L) { + lua_pushnumber(L, -1); - int ret = lua_tointeger(L, -1); + return -1; +} - if (ret > 0 && ret < sizeof(Scen.Waypoint)) { +/*********************************************************************************************** + * Script_GetWaypointY - Gets the Cell/Y Coordinate of Waypoint * + * * + * SCRIPT INPUT: waypointIndex (int) - The waypoint's index to grab the Y coordinate for * + * * + * SCRIPT OUTPUT: outX (int) - The Cell/Y coordinate of the waypoint * + * * + * INPUT: lua_State - The current Lua state * + * * + * OUTPUT: int; Did the function run successfully? Return 1 * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +static int Script_GetWaypointY(lua_State* L) { - lua_pushnumber(L, Cell_X(Scen.Waypoint[ret])); + int ret = lua_tointeger(L, -1); - return 1; + if (ret > 0 && ret < sizeof(Scen.Waypoint)) { - } + lua_pushnumber(L, Cell_Y(Scen.Waypoint[ret])); - lua_pushnumber(L, -1); + return 1; - return -1; } - /*********************************************************************************************** - * Script_GetWaypointY - Gets the Cell/Y Coordinate of Waypoint * - * * - * SCRIPT INPUT: waypointIndex (int) - The waypoint's index to grab the Y coordinate for * - * * - * SCRIPT OUTPUT: outX (int) - The Cell/Y coordinate of the waypoint * - * * - * INPUT: lua_State - The current Lua state * - * * - * OUTPUT: int; Did the function run successfully? Return 1 * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - static int Script_GetWaypointY(lua_State* L) { + lua_pushnumber(L, -1); - int ret = lua_tointeger(L, -1); - - if (ret > 0 && ret < sizeof(Scen.Waypoint)) { - - lua_pushnumber(L, Cell_Y(Scen.Waypoint[ret])); - - return 1; - - } - - lua_pushnumber(L, -1); - - return -1; - } + return -1; +} /********************************************************************************************** * Special / Debug Functions * @@ -6766,801 +6773,801 @@ * WARNINGS: ? * * * *=============================================================================================*/ - static int Script_Console_Print(lua_State* L) { +static int Script_Console_Print(lua_State* L) { - const char* inputText = lua_tostring(L, -1); // grab path string from top of stack + const char* inputText = lua_tostring(L, -1); // grab path string from top of stack - Console_Printf(inputText); + Console_Printf(inputText); + + return -1; +} - return -1; - } - /********************************************************************************************** * MapScript Internal Functions * *=============================================================================================*/ - /*********************************************************************************************** - * MapScript::GetCacheObject -- Returns ObjectClass from cache with given ID * - * * - * INPUT: input_object_id (int) - Input object ID * - * * - * OUTPUT: this_object (ObjectClass*) - The object with the ID or NULL * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - ObjectClass* Script_GetCacheObject(int input_object_id) { - - if (input_object_id < 0) { - return false; - } - - // Look through cache for object with ID, and return it - for (std::vector::iterator it = Scen.mapScript->ObjectCache.begin(); it != Scen.mapScript->ObjectCache.end(); ++it) {//Error 2-4 - - MapScriptObject* thisCacheObject = (MapScriptObject*)(*it); - - // Here it is - if (thisCacheObject->UID == input_object_id) { - - // Determine type of object and return it from cache. If it doesn't exist any longer, remove it from cache - switch (thisCacheObject->RTTI) { - case RTTI_BUILDING: { - BuildingClass* this_building = Buildings.Ptr(thisCacheObject->classIndex); - if (this_building != NULL) { - return this_building; - } - else { - it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache - return NULL; - } - }break; - case RTTI_UNIT: { - UnitClass* this_unit = Units.Ptr(thisCacheObject->classIndex); - if (this_unit != NULL) { - return this_unit; - } - else { - it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache - return NULL; - } - }break; - case RTTI_AIRCRAFT: { - AircraftClass* this_aircraft = Aircraft.Ptr(thisCacheObject->classIndex); - if (this_aircraft != NULL) { - return this_aircraft; - } - else { - it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache - return NULL; - } - }break; - case RTTI_INFANTRY: { - InfantryClass* this_infantry = Infantry.Ptr(thisCacheObject->classIndex); - if (this_infantry != NULL) { - return this_infantry; - } - else { - it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache - return NULL; - } - }break; - case RTTI_VESSEL: { - VesselClass* this_vessel = Vessels.Ptr(thisCacheObject->classIndex); - if (this_vessel != NULL) { - return this_vessel; - } - else { - it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache - return NULL; - } - }break; - } - - } - - } - - // Not found in cache; let's find the object by ID the hard way... If scripting is done well, this doesn't get hit - int _objectIndex = -1; - MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); - CacheObject->ID = -1; - - _objectIndex = Script_BuildingIndexFromID(input_object_id); - BuildingClass* this_building = Buildings.Ptr(_objectIndex); - if (this_building != NULL) { - - CacheObject->ID = this_building->ID; - CacheObject->RTTI = this_building->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - return this_building; - - } - else { - _objectIndex = Script_UnitIndexFromID(input_object_id); - UnitClass* this_unit = Units.Ptr(_objectIndex); - if (this_unit != NULL) { - - CacheObject->ID = this_unit->ID; - CacheObject->RTTI = this_unit->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - return this_unit; - - } - else { - _objectIndex = Script_AircraftIndexFromID(input_object_id); - AircraftClass* this_aircraft = Aircraft.Ptr(_objectIndex); - if (this_aircraft != NULL) { - - CacheObject->ID = this_aircraft->ID; - CacheObject->RTTI = this_aircraft->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - return this_aircraft; - - } - else { - _objectIndex = Script_VesselIndexFromID(input_object_id); - VesselClass* this_vessel = Vessels.Ptr(_objectIndex); - if (this_vessel != NULL) { - - CacheObject->ID = this_vessel->ID; - CacheObject->RTTI = this_vessel->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - return this_vessel; - - } - else { - _objectIndex = Script_InfantryIndexFromID(input_object_id); - InfantryClass* this_infantry = Infantry.Ptr(_objectIndex); - if (this_infantry != NULL) { - - CacheObject->ID = this_infantry->ID; - CacheObject->RTTI = this_infantry->RTTI; - CacheObject->classIndex = _objectIndex; - Scen.mapScript->ObjectCache.push_back(CacheObject); - - return this_infantry; - - } - } - } - } - } - - // Looks like we didn't find anything. They probably shouldn't have gotten this far in the first place so it was worth a try. - delete CacheObject; - - return NULL; - } - - /*********************************************************************************************** - * Script_SetObjectTrigger -- Figures out what kind of object is given and sets up trigger * - * * - * INPUT: input_object (ObjectClass*) - Input object * - * input_trigger (TriggerClass*) - Input Trigger * - * * - * OUTPUT: bool; Was the object found? Does the trigger exist? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - bool Script_SetObjectTrigger(int input_object_id, TriggerClass* input_trigger) { - - if (input_object_id < 0) { - return false; - } - - if (input_trigger == NULL) { - return false; - } - - ObjectClass* this_object = Script_GetCacheObject(input_object_id); - - if (this_object != NULL) { - - switch (this_object->RTTI) { - case RTTI_BUILDING:{ - input_trigger->Class->Event1.Data.Structure = dynamic_cast(this_object)->Class->Type; - dynamic_cast(this_object)->Trigger = input_trigger; - }break; - case RTTI_UNIT:{ - input_trigger->Class->Event1.Data.Unit = dynamic_cast(this_object)->Class->Type; - dynamic_cast(this_object)->Trigger = input_trigger; - }break; - case RTTI_AIRCRAFT:{ - input_trigger->Class->Event1.Data.Aircraft = dynamic_cast(this_object)->Class->Type; - dynamic_cast(this_object)->Trigger = input_trigger; - }break; - case RTTI_INFANTRY:{ - input_trigger->Class->Event1.Data.Infantry = dynamic_cast(this_object)->Class->Type; - dynamic_cast(this_object)->Trigger = input_trigger; - }break; - } - - } +/*********************************************************************************************** + * MapScript::GetCacheObject -- Returns ObjectClass from cache with given ID * + * * + * INPUT: input_object_id (int) - Input object ID * + * * + * OUTPUT: this_object (ObjectClass*) - The object with the ID or NULL * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +ObjectClass* Script_GetCacheObject(int input_object_id) { + if (input_object_id < 0) { return false; } - /*********************************************************************************************** - * Script_BuildingIndexFromID -- Returns BuildingClass or NULL depending on the input * - * * - * INPUT: input_object_id (int) - Input object ID * - * * - * OUTPUT: bool; Was the object found? Does the trigger exist? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - int Script_BuildingIndexFromID(int input_object_id) { + // Look through cache for object with ID, and return it + for (std::vector::iterator it = Scen.mapScript->ObjectCache.begin(); it != Scen.mapScript->ObjectCache.end(); ++it) {//Error 2-4 - if (input_object_id < 0) { - return false; - } + MapScriptObject* thisCacheObject = (MapScriptObject*)(*it); - for (int _index = 0; _index < Buildings.Count(); _index++) { - BuildingClass* _object = Buildings.Ptr(_index); + // Here it is + if (thisCacheObject->UID == input_object_id) { - if (_object->ID == input_object_id) { - return _index; + // Determine type of object and return it from cache. If it doesn't exist any longer, remove it from cache + switch (thisCacheObject->RTTI) { + case RTTI_BUILDING: { + BuildingClass* this_building = Buildings.Ptr(thisCacheObject->classIndex); + if (this_building != NULL) { + return this_building; + } + else { + it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache + return NULL; + } + }break; + case RTTI_UNIT: { + UnitClass* this_unit = Units.Ptr(thisCacheObject->classIndex); + if (this_unit != NULL) { + return this_unit; + } + else { + it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache + return NULL; + } + }break; + case RTTI_AIRCRAFT: { + AircraftClass* this_aircraft = Aircraft.Ptr(thisCacheObject->classIndex); + if (this_aircraft != NULL) { + return this_aircraft; + } + else { + it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache + return NULL; + } + }break; + case RTTI_INFANTRY: { + InfantryClass* this_infantry = Infantry.Ptr(thisCacheObject->classIndex); + if (this_infantry != NULL) { + return this_infantry; + } + else { + it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache + return NULL; + } + }break; + case RTTI_VESSEL: { + VesselClass* this_vessel = Vessels.Ptr(thisCacheObject->classIndex); + if (this_vessel != NULL) { + return this_vessel; + } + else { + it = Scen.mapScript->ObjectCache.erase(it); // Cache item exists but is invalidated; remove from cache + return NULL; + } + }break; } - } - - return -1; - } - - /*********************************************************************************************** - * Script_UnitIndexFromID -- Returns UnitClass* or NULL depending on the input * - * * - * INPUT: input_unit_id (int) - Input Unit ID * - * * - * OUTPUT: bool; Was the object found? Does the trigger exist? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - int Script_UnitIndexFromID(int input_object_id) { - - if (input_object_id < 0) { - return false; - } - - for (int _index = 0; _index < Units.Count(); _index++) { - UnitClass* _object = Units.Ptr(_index); - - if (_object->ID == input_object_id) { - return _index; - } - } - - return -1; - } - - /*********************************************************************************************** - * Script_AircraftIndexFromID -- Returns AircraftClass* or NULL depending on the input * - * * - * INPUT: input_object_id (int) - Input object ID * - * * - * OUTPUT: bool; Was the object found? Does the trigger exist? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - int Script_AircraftIndexFromID(int input_object_id) { - - if (input_object_id < 0) { - return false; - } - - for (int _index = 0; _index < Aircraft.Count(); _index++) { - AircraftClass* _object = Aircraft.Ptr(_index); - - if (_object->ID == input_object_id) { - return _index; - } - } - - return -1; - } - - /*********************************************************************************************** - * Script_InfantryIndexFromID -- Returns InfantryClass* or NULL depending on the input * - * * - * INPUT: input_unit_id (int) - Input Infantry ID * - * * - * OUTPUT: bool; Was the object found? Does the trigger exist? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - int Script_InfantryIndexFromID(int input_object_id) { - - if (input_object_id < 0) { - return false; - } - - for (int _index = 0; _index < Infantry.Count(); _index++) { - InfantryClass* _object = Infantry.Ptr(_index); - - if (_object->ID == input_object_id) { - return _index; - } - } - - return -1; - } - - /*********************************************************************************************** - * Script_VesselIndexFromID -- Returns VesselClass* or NULL depending on the input * - * * - * INPUT: input_unit_id (int) - Input vessel ID * - * * - * OUTPUT: bool; Was the object found? Does the trigger exist? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - int Script_VesselIndexFromID(int input_object_id) { - - if (input_object_id < 0) { - return false; - } - - for (int _index = 0; _index < Vessels.Count(); _index++) { - VesselClass* _object = Vessels.Ptr(_index); - - if (_object->ID == input_object_id) { - return _index; - } - } - - return -1; - } - - /*********************************************************************************************** - * Script_CacheDefaultAttribute - Caches an attribute value upon first usage for restoration * - * * - * SCRIPT INPUT: input_rtti (RTTIType) - The RTTI type for the attrtibute * - * input_id (int) - The ID of the typeclass * - * input_attribute (int) - The attribute to cache * - * input_value (int) - The value if the cache item doesn't exist * - * * - * SCRIPT OUTPUT: void * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - void Script_CacheDefaultObjectTypeAttribute(RTTIType input_rtti, int input_id, MapScriptObjectAttributeType input_attribute, int input_value) { - - bool cache_item_found = false; - for (std::vector::iterator it = Scen.mapScript->DefaultObjectTypeAttributeCache.begin(); it != Scen.mapScript->DefaultObjectTypeAttributeCache.end(); ++it) {//Error 2-4 - - MapScriptDefaultObjectAttribute* cachedAttribute = (MapScriptDefaultObjectAttribute*)(*it); - - if (input_rtti == cachedAttribute->RTTI && input_id == cachedAttribute->ID && input_attribute == cachedAttribute->attribute) { - cache_item_found = true; - break; - } - - } - - // Cached attribute does not exist; let's cache! - if (!cache_item_found) { - - MapScriptDefaultObjectAttribute* cachedAttribute = new MapScriptDefaultObjectAttribute; - cachedAttribute->RTTI = input_rtti; - cachedAttribute->ID = input_id; - cachedAttribute->attribute = input_attribute; - cachedAttribute->value = input_value; - Scen.mapScript->DefaultObjectTypeAttributeCache.push_back(cachedAttribute); } } - /*********************************************************************************************** - * MapScript::CallFunction - Calls a given function within the current script * - * * - * INPUT: functionName - The name of the function to call * - * * - * OUTPUT: void * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - void MapScript::CallFunction(const char* functionName) { + // Not found in cache; let's find the object by ID the hard way... If scripting is done well, this doesn't get hit + int _objectIndex = -1; + MapScriptObject* CacheObject = Scen.mapScript->CreateCacheObject(); + CacheObject->ID = -1; - lua_getglobal(L, functionName); - lua_pcall(L, 0, 0, 0); - - } + _objectIndex = Script_BuildingIndexFromID(input_object_id); + BuildingClass* this_building = Buildings.Ptr(_objectIndex); + if (this_building != NULL) { - /*********************************************************************************************** - * MapScript::setLuaPath - Sets Lua's path / extensions to search for scripts * - * * - * This helps Lua know where/how to look for files when using require(), otherwise we could * - * hard code path/extension as we did previously * - * * - * INPUT: pathvalue - See lua documentation RE: LUA_PATH to know how to deal with this * - * * - * OUTPUT: void * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - void MapScript::SetLuaPath( const char* input_path) + CacheObject->ID = this_building->ID; + CacheObject->RTTI = this_building->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + return this_building; + + } + else { + _objectIndex = Script_UnitIndexFromID(input_object_id); + UnitClass* this_unit = Units.Ptr(_objectIndex); + if (this_unit != NULL) { + + CacheObject->ID = this_unit->ID; + CacheObject->RTTI = this_unit->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + return this_unit; + + } + else { + _objectIndex = Script_AircraftIndexFromID(input_object_id); + AircraftClass* this_aircraft = Aircraft.Ptr(_objectIndex); + if (this_aircraft != NULL) { + + CacheObject->ID = this_aircraft->ID; + CacheObject->RTTI = this_aircraft->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + return this_aircraft; + + } + else { + _objectIndex = Script_VesselIndexFromID(input_object_id); + VesselClass* this_vessel = Vessels.Ptr(_objectIndex); + if (this_vessel != NULL) { + + CacheObject->ID = this_vessel->ID; + CacheObject->RTTI = this_vessel->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + return this_vessel; + + } + else { + _objectIndex = Script_InfantryIndexFromID(input_object_id); + InfantryClass* this_infantry = Infantry.Ptr(_objectIndex); + if (this_infantry != NULL) { + + CacheObject->ID = this_infantry->ID; + CacheObject->RTTI = this_infantry->RTTI; + CacheObject->classIndex = _objectIndex; + Scen.mapScript->ObjectCache.push_back(CacheObject); + + return this_infantry; + + } + } + } + } + } + + // Looks like we didn't find anything. They probably shouldn't have gotten this far in the first place so it was worth a try. + delete CacheObject; + + return NULL; +} + +/*********************************************************************************************** + * Script_SetObjectTrigger -- Figures out what kind of object is given and sets up trigger * + * * + * INPUT: input_object (ObjectClass*) - Input object * + * input_trigger (TriggerClass*) - Input Trigger * + * * + * OUTPUT: bool; Was the object found? Does the trigger exist? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +bool Script_SetObjectTrigger(int input_object_id, TriggerClass* input_trigger) { + + if (input_object_id < 0) { + return false; + } + + if (input_trigger == NULL) { + return false; + } + + ObjectClass* this_object = Script_GetCacheObject(input_object_id); + + if (this_object != NULL) { + + switch (this_object->RTTI) { + case RTTI_BUILDING: { + input_trigger->Class->Event1.Data.Structure = dynamic_cast(this_object)->Class->Type; + dynamic_cast(this_object)->Trigger = input_trigger; + }break; + case RTTI_UNIT: { + input_trigger->Class->Event1.Data.Unit = dynamic_cast(this_object)->Class->Type; + dynamic_cast(this_object)->Trigger = input_trigger; + }break; + case RTTI_AIRCRAFT: { + input_trigger->Class->Event1.Data.Aircraft = dynamic_cast(this_object)->Class->Type; + dynamic_cast(this_object)->Trigger = input_trigger; + }break; + case RTTI_INFANTRY: { + input_trigger->Class->Event1.Data.Infantry = dynamic_cast(this_object)->Class->Type; + dynamic_cast(this_object)->Trigger = input_trigger; + }break; + } + + } + + return false; +} + +/*********************************************************************************************** + * Script_BuildingIndexFromID -- Returns BuildingClass or NULL depending on the input * + * * + * INPUT: input_object_id (int) - Input object ID * + * * + * OUTPUT: bool; Was the object found? Does the trigger exist? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +int Script_BuildingIndexFromID(int input_object_id) { + + if (input_object_id < 0) { + return false; + } + + for (int _index = 0; _index < Buildings.Count(); _index++) { + BuildingClass* _object = Buildings.Ptr(_index); + + if (_object->ID == input_object_id) { + return _index; + } + } + + return -1; +} + +/*********************************************************************************************** + * Script_UnitIndexFromID -- Returns UnitClass* or NULL depending on the input * + * * + * INPUT: input_unit_id (int) - Input Unit ID * + * * + * OUTPUT: bool; Was the object found? Does the trigger exist? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +int Script_UnitIndexFromID(int input_object_id) { + + if (input_object_id < 0) { + return false; + } + + for (int _index = 0; _index < Units.Count(); _index++) { + UnitClass* _object = Units.Ptr(_index); + + if (_object->ID == input_object_id) { + return _index; + } + } + + return -1; +} + +/*********************************************************************************************** + * Script_AircraftIndexFromID -- Returns AircraftClass* or NULL depending on the input * + * * + * INPUT: input_object_id (int) - Input object ID * + * * + * OUTPUT: bool; Was the object found? Does the trigger exist? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +int Script_AircraftIndexFromID(int input_object_id) { + + if (input_object_id < 0) { + return false; + } + + for (int _index = 0; _index < Aircraft.Count(); _index++) { + AircraftClass* _object = Aircraft.Ptr(_index); + + if (_object->ID == input_object_id) { + return _index; + } + } + + return -1; +} + +/*********************************************************************************************** + * Script_InfantryIndexFromID -- Returns InfantryClass* or NULL depending on the input * + * * + * INPUT: input_unit_id (int) - Input Infantry ID * + * * + * OUTPUT: bool; Was the object found? Does the trigger exist? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +int Script_InfantryIndexFromID(int input_object_id) { + + if (input_object_id < 0) { + return false; + } + + for (int _index = 0; _index < Infantry.Count(); _index++) { + InfantryClass* _object = Infantry.Ptr(_index); + + if (_object->ID == input_object_id) { + return _index; + } + } + + return -1; +} + +/*********************************************************************************************** + * Script_VesselIndexFromID -- Returns VesselClass* or NULL depending on the input * + * * + * INPUT: input_unit_id (int) - Input vessel ID * + * * + * OUTPUT: bool; Was the object found? Does the trigger exist? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +int Script_VesselIndexFromID(int input_object_id) { + + if (input_object_id < 0) { + return false; + } + + for (int _index = 0; _index < Vessels.Count(); _index++) { + VesselClass* _object = Vessels.Ptr(_index); + + if (_object->ID == input_object_id) { + return _index; + } + } + + return -1; +} + +/*********************************************************************************************** + * Script_CacheDefaultAttribute - Caches an attribute value upon first usage for restoration * + * * + * SCRIPT INPUT: input_rtti (RTTIType) - The RTTI type for the attrtibute * + * input_id (int) - The ID of the typeclass * + * input_attribute (int) - The attribute to cache * + * input_value (int) - The value if the cache item doesn't exist * + * * + * SCRIPT OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +void Script_CacheDefaultObjectTypeAttribute(RTTIType input_rtti, int input_id, MapScriptObjectAttributeType input_attribute, int input_value) { + + bool cache_item_found = false; + for (std::vector::iterator it = Scen.mapScript->DefaultObjectTypeAttributeCache.begin(); it != Scen.mapScript->DefaultObjectTypeAttributeCache.end(); ++it) {//Error 2-4 + + MapScriptDefaultObjectAttribute* cachedAttribute = (MapScriptDefaultObjectAttribute*)(*it); + + if (input_rtti == cachedAttribute->RTTI && input_id == cachedAttribute->ID && input_attribute == cachedAttribute->attribute) { + cache_item_found = true; + break; + } + + } + + // Cached attribute does not exist; let's cache! + if (!cache_item_found) { + + MapScriptDefaultObjectAttribute* cachedAttribute = new MapScriptDefaultObjectAttribute; + cachedAttribute->RTTI = input_rtti; + cachedAttribute->ID = input_id; + cachedAttribute->attribute = input_attribute; + cachedAttribute->value = input_value; + Scen.mapScript->DefaultObjectTypeAttributeCache.push_back(cachedAttribute); + + } + +} + +/*********************************************************************************************** + * MapScript::CallFunction - Calls a given function within the current script * + * * + * INPUT: functionName - The name of the function to call * + * * + * OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +void MapScript::CallFunction(const char* functionName) { + + lua_getglobal(L, functionName); + lua_pcall(L, 0, 0, 0); + +} + +/*********************************************************************************************** + * MapScript::setLuaPath - Sets Lua's path / extensions to search for scripts * + * * + * This helps Lua know where/how to look for files when using require(), otherwise we could * + * hard code path/extension as we did previously * + * * + * INPUT: pathvalue - See lua documentation RE: LUA_PATH to know how to deal with this * + * * + * OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +void MapScript::SetLuaPath(const char* input_path) +{ + + // Needs space to keep the initial paths + char new_path[1024]; + + // Set new GLOBALS.package.path + lua_getglobal(L, "package"); + lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1) + const char* cur_path = lua_tostring(L, -1); // grab path string from top of stack + + sprintf(new_path, "%s;%s", cur_path, input_path); + + lua_pop(L, 1); + lua_pushstring(L, new_path); + lua_setfield(L, -2, "path"); + lua_pop(L, 1); +} + +/*********************************************************************************************** + * MapScript::CreateCacheObject -- Initializes a cached object for a new cache entry * + * * + * INPUT: mapName - The script path * + * * + * OUTPUT: bool; did the map script load and initialize? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +MapScriptObject* MapScript::CreateCacheObject() { + + MapScriptObject* CacheObject = new MapScriptObject; + + cUID++; + CacheObject->UID = cUID; + + return CacheObject; + +} + +/*********************************************************************************************** + * MapScript::Deinit - Deinitialize/free any data used by MapScript (used within destructor) * + * * + * SCRIPT INPUT: none * + * * + * SCRIPT OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ +void MapScript::Deinit() { + + // Remove any cached objects + for (int i = 0; i < ObjectCache.size(); ++i) { - - // Needs space to keep the initial paths - char new_path[1024]; - - // Set new GLOBALS.package.path - lua_getglobal(L, "package"); - lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1) - const char* cur_path = lua_tostring(L, -1); // grab path string from top of stack - - sprintf(new_path, "%s;%s", cur_path, input_path); - - lua_pop(L, 1); - lua_pushstring(L, new_path); - lua_setfield(L, -2, "path"); - lua_pop(L, 1); + delete ObjectCache[i]; } - /*********************************************************************************************** - * MapScript::CreateCacheObject -- Initializes a cached object for a new cache entry * - * * - * INPUT: mapName - The script path * - * * - * OUTPUT: bool; did the map script load and initialize? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - MapScriptObject* MapScript::CreateCacheObject() { + ObjectCache.clear(); - MapScriptObject* CacheObject = new MapScriptObject; + // We will now restore any default Object attributes that were changed in the script + for (std::vector::iterator it = DefaultObjectTypeAttributeCache.begin(); it != DefaultObjectTypeAttributeCache.end(); ++it) {//Error 2-4 - cUID++; - CacheObject->UID = cUID; + MapScriptDefaultObjectAttribute* cachedAttribute = (MapScriptDefaultObjectAttribute*)(*it); - return CacheObject; + switch (cachedAttribute->RTTI) { - } + case RTTI_BUILDINGTYPE: { + lua_getglobal(L, "SetBuildingTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_UNITTYPE: { + lua_getglobal(L, "SetUnitTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_INFANTRYTYPE: { + lua_getglobal(L, "SetInfantryTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_AIRCRAFTTYPE: { + lua_getglobal(L, "SetAircraftTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_VESSELTYPE: { + lua_getglobal(L, "SetVesselTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; - /*********************************************************************************************** - * MapScript::Deinit - Deinitialize/free any data used by MapScript (used within destructor) * - * * - * SCRIPT INPUT: none * - * * - * SCRIPT OUTPUT: void * - * * - * WARNINGS: ? * - * * - *=============================================================================================*/ - void MapScript::Deinit() { - - // Remove any cached objects - for (int i = 0; i < ObjectCache.size(); ++i) - { - delete ObjectCache[i]; - } - - ObjectCache.clear(); - - // We will now restore any default Object attributes that were changed in the script - for (std::vector::iterator it = DefaultObjectTypeAttributeCache.begin(); it != DefaultObjectTypeAttributeCache.end(); ++it) {//Error 2-4 - - MapScriptDefaultObjectAttribute* cachedAttribute = (MapScriptDefaultObjectAttribute*)(*it); - - switch (cachedAttribute->RTTI) { - - case RTTI_BUILDINGTYPE: { - lua_getglobal(L, "SetBuildingTypeAttribute"); - lua_pushnumber(L, cachedAttribute->ID); - lua_pushnumber(L, cachedAttribute->attribute); - lua_pushnumber(L, cachedAttribute->value); - lua_pcall(L, 3, 1, 0); - }break; - case RTTI_UNITTYPE: { - lua_getglobal(L, "SetUnitTypeAttribute"); - lua_pushnumber(L, cachedAttribute->ID); - lua_pushnumber(L, cachedAttribute->attribute); - lua_pushnumber(L, cachedAttribute->value); - lua_pcall(L, 3, 1, 0); - }break; - case RTTI_INFANTRYTYPE: { - lua_getglobal(L, "SetInfantryTypeAttribute"); - lua_pushnumber(L, cachedAttribute->ID); - lua_pushnumber(L, cachedAttribute->attribute); - lua_pushnumber(L, cachedAttribute->value); - lua_pcall(L, 3, 1, 0); - }break; - case RTTI_AIRCRAFTTYPE: { - lua_getglobal(L, "SetAircraftTypeAttribute"); - lua_pushnumber(L, cachedAttribute->ID); - lua_pushnumber(L, cachedAttribute->attribute); - lua_pushnumber(L, cachedAttribute->value); - lua_pcall(L, 3, 1, 0); - }break; - case RTTI_VESSELTYPE: { - lua_getglobal(L, "SetVesselTypeAttribute"); - lua_pushnumber(L, cachedAttribute->ID); - lua_pushnumber(L, cachedAttribute->attribute); - lua_pushnumber(L, cachedAttribute->value); - lua_pcall(L, 3, 1, 0); - }break; - - } - - } - - // Remove any cached Object Attributes - for (int i = 0; i < DefaultObjectTypeAttributeCache.size(); ++i) - { - delete DefaultObjectTypeAttributeCache[i]; - } - - DefaultObjectTypeAttributeCache.clear(); - - - for (int index = 0; index < Warheads.Count(); index++) { - Warheads.Ptr(index)->Read_INI(RuleINI); - } - - for (int proj = 0; proj < BulletTypes.Count(); proj++) { - BulletTypes.Ptr(proj)->Read_INI(RuleINI); - } - - for (int windex = 0; windex < Weapons.Count(); windex++) { - Weapons.Ptr(windex)->Read_INI(RuleINI); - } - - for (int uindex = 0; uindex < UnitTypes.Count(); uindex++) { - UnitTypes.Ptr(uindex)->Read_INI(RuleINI); - } - - for (int iindex = 0; iindex < InfantryTypes.Count(); iindex++) { - InfantryTypes.Ptr(iindex)->Read_INI(RuleINI); - } - - for (int vindex = 0; vindex < VesselTypes.Count(); vindex++) { - VesselTypes.Ptr(vindex)->Read_INI(RuleINI); - } - - for (int aindex = 0; aindex < AircraftTypes.Count(); aindex++) { - AircraftTypes.Ptr(aindex)->Read_INI(RuleINI); - } - - for (int bindex = 0; bindex < BuildingTypes.Count(); bindex++) { - BuildingTypes.Ptr(bindex)->Read_INI(RuleINI); } } + // Remove any cached Object Attributes + for (int i = 0; i < DefaultObjectTypeAttributeCache.size(); ++i) + { + delete DefaultObjectTypeAttributeCache[i]; + } - /*********************************************************************************************** - * MapScript::Init -- Loads and initializes script for a given map * - * * - * This routine is called at the beginning of a mission * - * * - * INPUT: mapName - The script path * - * * - * OUTPUT: bool; did the map script load and initialize? * - * * - * WARNINGS: none * - * * - *=============================================================================================*/ - bool MapScript::Init(const char* mapName) { - - this->cUID = 0; - - char scriptName[256]; - - // Build map path - sprintf(scriptName, "scripts/%s.script", mapName); - L = luaL_newstate(); - - luaL_openlibs(L); - - // Load file - if (luaL_loadfile(L, scriptName)){ - Console_Printf(lua_tostring(L, -1)); - L = NULL; - return false; - } - - // TODO: I've tried several combinations of paths (including "scripts/?"), - // but I can only get "require 'basefilename'" to work within a - // script, not "require 'basefilename.script'". This may be completely - // normal within lua, but it seems odd. - - // This allows require() to work - SetLuaPath(";scripts/?.script;"); - - if (lua_pcall(L, 0, 0, 0)) { - Console_Printf(lua_tostring(L, -1)); - L = NULL; - return false; - } - - // Reserve object cache memory - ObjectCache.reserve(2000); - - // Reserve type attribute cache memory (to restore rules after script) - DefaultObjectTypeAttributeCache.reserve(1000); - - /********************************************************************************************** - * Red Alert Vanilla Actions * - *=============================================================================================*/ - - lua_register(L, "Win", Script_Win); // player wins! - lua_register(L, "Lose", Script_Lose); // player loses. - lua_register(L, "BeginProduction", Script_BeginProduction); // computer begins factory production. - lua_register(L, "CreateTeam", Script_CreateTeam); // computer creates a certain type of team - lua_register(L, "DestroyTeam", Script_DestroyTeam); // destroy team (comment was redacted. was something offensive originally written?) - lua_register(L, "AllHunt", Script_AllHunt); // all enemy units go into hunt mode (teams destroyed). - lua_register(L, "Reinforcements", Script_Reinforcements); // player gets reinforcements (house that gets them is determined by the Reinforcement instance) - lua_register(L, "DropZoneFlare", Script_DropZoneFlare); // Deploy drop zone smoke. - lua_register(L, "FireSale", Script_FireSale); // Sell all buildings and go on rampage. - lua_register(L, "PlayMovie", Script_PlayMovie); // Play movie (temporarily suspend game). - lua_register(L, "TriggerText", Script_TriggerText); // Triggers a text message display. - lua_register(L, "DestroyTrigger", Script_DestroyTrigger); // Destroy specified trigger. - lua_register(L, "AutoCreate", Script_AutoCreate); // Computer to autocreate teams. - // Win if captured, lose if destroyed // function does not exist - lua_register(L, "AllowWin", Script_AllowWin); // Allows winning if triggered. - lua_register(L, "RevealAll", Script_RevealAll); // Reveal the entire map. - lua_register(L, "RevealCell", Script_RevealCell); // Reveal map around cell #. - lua_register(L, "RevealZone", Script_RevealZone); // Reveal all of specified zone. - lua_register(L, "PlaySound", Script_PlaySound); // Play sound effect. - lua_register(L, "PlayMusic", Script_PlayMusic); // Play musical score. - lua_register(L, "PlaySpeech", Script_PlaySpeech); // Play EVA speech. - // TODO: Force trigger to activate. - lua_register(L, "StartMissionTimer", Script_StartMissionTimer); // Start mission timer. - lua_register(L, "StopMissionTimer", Script_StopMissionTimer); // Stop mission timer. - lua_register(L, "IncreaseMissionTimer", Script_IncreaseMissionTimer); // Increase mission timer time. - lua_register(L, "DecreaseMissionTimer", Script_DecreaseMissionTimer); // Decrease mission timer time. - lua_register(L, "SetMissionTimer", Script_SetMissionTimer); // Set and start the mission timer. - lua_register(L, "SetGlobalValue", Script_SetGlobalValue); // Set global variable. - lua_register(L, "ClearGlobalValue", Script_ClearGlobalValue); // Clear global variable. - lua_register(L, "AutoBaseBuilding", Script_AutoBaseBuilding); // Automated base building. - lua_register(L, "CreepShadow", Script_CreepShadow); // Shadow grows back one 'step'. - lua_register(L, "DestroyTriggerBuilding", Script_DestroyTriggerBuilding); // Destroys the building this trigger is attached to. (in the case of scripging, we can supply the trigger) - lua_register(L, "GiveOneTimeSpecialWeapon", Script_GiveOneTimeSpecialWeapon); // Add a one-time special weapon ability to house. - lua_register(L, "GiveSpecialWeapon", Script_GiveSpecialWeapon); // Add a repeating special weapon ability to house. - lua_register(L, "DesignatePreferredTarget", Script_DesignatePreferredTarget); // Designates preferred target for house. - lua_register(L, "LaunchFakeNukes", Script_LaunchFakeNukes); // Launch fake nuclear missiles from all silos - - /********************************************************************************************** - * Red Alert Vanilla Events * - *=============================================================================================*/ - - lua_register(L, "CellCallback", Script_CellCallback); // player enters this square (or group of squares) - lua_register(L, "SpiedByCallback", Script_SpiedByCallback); // Spied by. - // Thieved by (raided or stolen vehicle). // This doesn't appear to be implemented in the engine (?) - lua_register(L, "ObjectDiscoveryCallback", Script_ObjectDiscoveryCallback); // player discovers this object - lua_register(L, "HouseDiscoveredCallback", Script_HouseDiscoveredCallback); // House has been discovered. - lua_register(L, "ObjectAttackedCallback", Script_ObjectAttackedCallback); // player attacks this object - lua_register(L, "ObjectDestroyedCallback", Script_ObjectDestroyedCallback); // player destroys this object - lua_register(L, "AnyEventCallback", Script_AnyEventCallback); // Any object event will cause the trigger. - lua_register(L, "AllUnitsDestroyedCallback", Script_AllUnitsDestroyedCallback); // all house's units destroyed - lua_register(L, "AllBuildingsDestroyedCallback", Script_AllBuildingsDestroyedCallback); // all house's buildings destroyed - lua_register(L, "AllDestroyedCallback", Script_AllDestroyedCallback); // all house's units & buildings destroyed - lua_register(L, "CreditsReachedCallback", Script_CreditsReachedCallback); // house reaches this many credits - lua_register(L, "TimeReachedCallback", Script_TimeReachedCallback); // Scenario elapsed time from start. - lua_register(L, "MissionTimerCallback", Script_MissionTimerCallback); // Pre expired mission timer. - lua_register(L, "BuildingsDestroyedCallback", Script_BuildingsDestroyedCallback); // Number of buildings destroyed. - lua_register(L, "UnitsDestroyedCallback", Script_UnitsDestroyedCallback); // Number of units destroyed. - lua_register(L, "NoFactoriesCallback", Script_NoFactoriesCallback); // No factories left. - lua_register(L, "CivilianEscapeCallback", Script_CivilianEscapeCallback); // Civilian has been evacuated. - lua_register(L, "BuildingBuiltCallback", Script_BuildingBuiltCallback); // Specified building has been built. - lua_register(L, "UnitBuiltCallback", Script_UnitBuiltCallback); // Specified unit has been built. - lua_register(L, "InfantryBuiltCallback", Script_InfantryBuiltCallback); // Specified infantry has been built. - lua_register(L, "AircraftBuiltCallback", Script_AircraftBuiltCallback); // Specified aircraft has been built. - lua_register(L, "TeamLeavesMapCallback", Script_TeamLeavesMapCallback); // Specified team member leaves map. - lua_register(L, "ZoneEntryCallback", Script_ZoneEntryCallback); // Enters same zone as waypoint 'x'. - lua_register(L, "HorizontalCrossCallback", Script_HorizontalCrossCallback); // Crosses horizontal trigger line. - lua_register(L, "VerticalCrossCallback", Script_VerticalCrossCallback); // Crosses vertical trigger line. - lua_register(L, "GlobalSetCallback", Script_GlobalSetCallback); // If specified global has been set. (somewhat useless with Scripting) - lua_register(L, "GlobalClearedCallback", Script_GlobalClearedCallback); // If specified global has been cleared. (somewhat useless with Scripting) - // If all fake structures are gone. // This doesn't appear to be implemented in the engine (?) - lua_register(L, "LowPowerCallback", Script_LowPowerCallback); // When power drops below 100%. - lua_register(L, "AllBridgesDestroyedCallback", Script_AllBridgesDestroyedCallback); // All bridges destroyed. - lua_register(L, "BuildingExistsCallback", Script_BuildingExistsCallback); // Check for building existing. - - /********************************************************************************************** - * Trigger Utility Functions * - *=============================================================================================*/ - - lua_register(L, "SetTriggerCallback", Script_SetTriggerCallback); // Initiates a given [callback] on an existing [trigger] // TODO: Make this work via name OR ID - lua_register(L, "TriggerAddCell", Script_TriggerAddCell); // Initiates a given [callback] on an existing [trigger] - lua_register(L, "MergeTriggers", Script_MergeTriggers); // Combines the events of two triggers (for multi-event triggers :) - lua_register(L, "GetTriggerByName", Script_GetTriggerByName); // Gets the ID of the trigger with a given name - lua_register(L, "TriggerSetPersistence", Script_TriggerSetPersistence); // Does a trigger go on and on or just run once? - - /********************************************************************************************** - * Object Functions * - *=============================================================================================*/ - lua_register(L, "GetCellObject", Script_GetCellObject); // Gets an object (ID - building/vehicle/aircraft/infantry/vessel), if any, at [Cell/X],[Cell/Y] - - lua_register(L, "SetObjectAttribute", Script_SetObjectAttribute); // Sets an object's attributes (strength, etc.) - lua_register(L, "SetBuildingTypeAttribute", Script_SetBuildingTypeAttribute); // Sets the attribute of a Building type - lua_register(L, "SetVehicleTypeAttribute", Script_SetVehicleTypeAttribute); // Sets the attribute of a Vehicle type - lua_register(L, "SetInfantryTypeAttribute", Script_SetInfantryTypeAttribute); // Sets the attribute of an Infantry type - lua_register(L, "SetVesselTypeAttribute", Script_SetVesselTypeAttribute); // Sets the attribute of a Vessel type - lua_register(L, "SetAircraftTypeAttribute", Script_SetAircraftTypeAttribute); // Sets the attribute of an Aircraft type - - lua_register(L, "GetObjectAttribute", Script_GetObjectAttribute); // Sets an object's attributes (strength, etc.) - lua_register(L, "GetBuildingTypeAttribute", Script_GetBuildingTypeAttribute); // Sets the attribute of a Building type - lua_register(L, "GetVehicleTypeAttribute", Script_GetVehicleTypeAttribute); // Sets the attribute of a Vehicle type - lua_register(L, "GetInfantryTypeAttribute", Script_GetInfantryTypeAttribute); // Sets the attribute of an Infantry type - lua_register(L, "GetVesselTypeAttribute", Script_GetVesselTypeAttribute); // Sets the attribute of a Vessel type - lua_register(L, "GetAircraftTypeAttribute", Script_GetAircraftTypeAttribute); // Sets the attribute of an Aircraft type - - lua_register(L, "SetHouseAttribute", Script_SetHouseAttribute); // Sets a house's attributes - lua_register(L, "GetHouseAttribute", Script_GetHouseAttribute); // Gets a house's attributes - - lua_register(L, "BuildUnit", Script_BuildUnit); // Builds a unit in a given factory / barracks / naval yard / etc - lua_register(L, "CreateVehicle", Script_CreateVehicle); // Creates a unit out of thin air - lua_register(L, "CreateInfantry", Script_CreateInfantry); // Creates a unit out of thin air - lua_register(L, "CreateAircraft", Script_CreateAircraft); // Creates a unit out of thin air - lua_register(L, "CreateVessel", Script_CreateVessel); // Creates a unit out of thin air - - /********************************************************************************************** - * Object Orders Functions * - *=============================================================================================*/ - - lua_register(L, "OrderMove", Script_OrderMove); // Assigns a movement order to the object - lua_register(L, "OrderAttack", Script_OrderAttack); // Assigns an attack order to the object - lua_register(L, "OrderHunt", Script_OrderHunt); // Assigns a hunt order to the object - lua_register(L, "OrderGuard", Script_OrderGuard); // Assigns a guard order to the object - lua_register(L, "OrderEnter", Script_OrderEnter); // Assigns a enter order to the object - lua_register(L, "OrderCapture", Script_OrderCapture); // Assigns a capture order to the object - - /********************************************************************************************** - * Mission Utility Functions * - *=============================================================================================*/ - - lua_register(L, "SetBriefingText", Script_SetBriefingText); // Sets the [text] on the mission briefing screen - - /********************************************************************************************** - * Status / Location Utility Functions * - *=============================================================================================*/ - - lua_register(L, "GiveCredits", Script_GiveCredits); // Give [credits] to [player] - lua_register(L, "GetCredits", Script_GetCredits); // Get [player]'s [credits] - - lua_register(L, "CountBuildings", Script_CountBuildings); // Number of buildings of [type] for given [player] - lua_register(L, "CountAircraft", Script_CountAircraft); // Number of units of [type] for given [player] - lua_register(L, "CountUnits", Script_CountUnits); // Number of units of [type] for given [player] - lua_register(L, "CountInfantry", Script_CountInfantry); // Number of infantry of [type] for given [player] - lua_register(L, "CountVessels", Script_CountVessels); // Number of vessels of [type] for given [player] - - lua_register(L, "GetWaypointX", Script_GetWaypointX); // Get Cell/X of waypoint - lua_register(L, "GetWaypointY", Script_GetWaypointY); // Get Cell/Y of waypoint - - /********************************************************************************************** - * Special / Debug Functions * - *=============================================================================================*/ - - lua_register(L, "PrintConsole", Script_Console_Print); // Print text to console - - /********************************************************************************************** - * Script Globals * - *=============================================================================================*/ - - lua_pushnumber(L, PlayerPtr->ID); // Local player (house) index - lua_setglobal(L, "_localPlayer"); + DefaultObjectTypeAttributeCache.clear(); - return true; - } \ No newline at end of file + for (int index = 0; index < Warheads.Count(); index++) { + Warheads.Ptr(index)->Read_INI(RuleINI); + } + + for (int proj = 0; proj < BulletTypes.Count(); proj++) { + BulletTypes.Ptr(proj)->Read_INI(RuleINI); + } + + for (int windex = 0; windex < Weapons.Count(); windex++) { + Weapons.Ptr(windex)->Read_INI(RuleINI); + } + + for (int uindex = 0; uindex < UnitTypes.Count(); uindex++) { + UnitTypes.Ptr(uindex)->Read_INI(RuleINI); + } + + for (int iindex = 0; iindex < InfantryTypes.Count(); iindex++) { + InfantryTypes.Ptr(iindex)->Read_INI(RuleINI); + } + + for (int vindex = 0; vindex < VesselTypes.Count(); vindex++) { + VesselTypes.Ptr(vindex)->Read_INI(RuleINI); + } + + for (int aindex = 0; aindex < AircraftTypes.Count(); aindex++) { + AircraftTypes.Ptr(aindex)->Read_INI(RuleINI); + } + + for (int bindex = 0; bindex < BuildingTypes.Count(); bindex++) { + BuildingTypes.Ptr(bindex)->Read_INI(RuleINI); + } + +} + + +/*********************************************************************************************** + * MapScript::Init -- Loads and initializes script for a given map * + * * + * This routine is called at the beginning of a mission * + * * + * INPUT: mapName - The script path * + * * + * OUTPUT: bool; did the map script load and initialize? * + * * + * WARNINGS: none * + * * + *=============================================================================================*/ +bool MapScript::Init(const char* mapName) { + + this->cUID = 0; + + char scriptName[256]; + + // Build map path + sprintf(scriptName, "scripts/%s.script", mapName); + L = luaL_newstate(); + + luaL_openlibs(L); + + // Load file + if (luaL_loadfile(L, scriptName)) { + Console_Printf(lua_tostring(L, -1)); + L = NULL; + return false; + } + + // TODO: I've tried several combinations of paths (including "scripts/?"), + // but I can only get "require 'basefilename'" to work within a + // script, not "require 'basefilename.script'". This may be completely + // normal within lua, but it seems odd. + + // This allows require() to work + SetLuaPath(";scripts/?.script;"); + + if (lua_pcall(L, 0, 0, 0)) { + Console_Printf(lua_tostring(L, -1)); + L = NULL; + return false; + } + + // Reserve object cache memory + ObjectCache.reserve(2000); + + // Reserve type attribute cache memory (to restore rules after script) + DefaultObjectTypeAttributeCache.reserve(1000); + + /********************************************************************************************** + * Red Alert Vanilla Actions * + *=============================================================================================*/ + + lua_register(L, "Win", Script_Win); // player wins! + lua_register(L, "Lose", Script_Lose); // player loses. + lua_register(L, "BeginProduction", Script_BeginProduction); // computer begins factory production. + lua_register(L, "CreateTeam", Script_CreateTeam); // computer creates a certain type of team + lua_register(L, "DestroyTeam", Script_DestroyTeam); // destroy team (comment was redacted. was something offensive originally written?) + lua_register(L, "AllHunt", Script_AllHunt); // all enemy units go into hunt mode (teams destroyed). + lua_register(L, "Reinforcements", Script_Reinforcements); // player gets reinforcements (house that gets them is determined by the Reinforcement instance) + lua_register(L, "DropZoneFlare", Script_DropZoneFlare); // Deploy drop zone smoke. + lua_register(L, "FireSale", Script_FireSale); // Sell all buildings and go on rampage. + lua_register(L, "PlayMovie", Script_PlayMovie); // Play movie (temporarily suspend game). + lua_register(L, "TriggerText", Script_TriggerText); // Triggers a text message display. + lua_register(L, "DestroyTrigger", Script_DestroyTrigger); // Destroy specified trigger. + lua_register(L, "AutoCreate", Script_AutoCreate); // Computer to autocreate teams. + // Win if captured, lose if destroyed // function does not exist + lua_register(L, "AllowWin", Script_AllowWin); // Allows winning if triggered. + lua_register(L, "RevealAll", Script_RevealAll); // Reveal the entire map. + lua_register(L, "RevealCell", Script_RevealCell); // Reveal map around cell #. + lua_register(L, "RevealZone", Script_RevealZone); // Reveal all of specified zone. + lua_register(L, "PlaySound", Script_PlaySound); // Play sound effect. + lua_register(L, "PlayMusic", Script_PlayMusic); // Play musical score. + lua_register(L, "PlaySpeech", Script_PlaySpeech); // Play EVA speech. + // TODO: Force trigger to activate. + lua_register(L, "StartMissionTimer", Script_StartMissionTimer); // Start mission timer. + lua_register(L, "StopMissionTimer", Script_StopMissionTimer); // Stop mission timer. + lua_register(L, "IncreaseMissionTimer", Script_IncreaseMissionTimer); // Increase mission timer time. + lua_register(L, "DecreaseMissionTimer", Script_DecreaseMissionTimer); // Decrease mission timer time. + lua_register(L, "SetMissionTimer", Script_SetMissionTimer); // Set and start the mission timer. + lua_register(L, "SetGlobalValue", Script_SetGlobalValue); // Set global variable. + lua_register(L, "ClearGlobalValue", Script_ClearGlobalValue); // Clear global variable. + lua_register(L, "AutoBaseBuilding", Script_AutoBaseBuilding); // Automated base building. + lua_register(L, "CreepShadow", Script_CreepShadow); // Shadow grows back one 'step'. + lua_register(L, "DestroyTriggerBuilding", Script_DestroyTriggerBuilding); // Destroys the building this trigger is attached to. (in the case of scripging, we can supply the trigger) + lua_register(L, "GiveOneTimeSpecialWeapon", Script_GiveOneTimeSpecialWeapon); // Add a one-time special weapon ability to house. + lua_register(L, "GiveSpecialWeapon", Script_GiveSpecialWeapon); // Add a repeating special weapon ability to house. + lua_register(L, "DesignatePreferredTarget", Script_DesignatePreferredTarget); // Designates preferred target for house. + lua_register(L, "LaunchFakeNukes", Script_LaunchFakeNukes); // Launch fake nuclear missiles from all silos + +/********************************************************************************************** +* Red Alert Vanilla Events * +*=============================================================================================*/ + + lua_register(L, "CellCallback", Script_CellCallback); // player enters this square (or group of squares) + lua_register(L, "SpiedByCallback", Script_SpiedByCallback); // Spied by. + // Thieved by (raided or stolen vehicle). // This doesn't appear to be implemented in the engine (?) + lua_register(L, "ObjectDiscoveryCallback", Script_ObjectDiscoveryCallback); // player discovers this object + lua_register(L, "HouseDiscoveredCallback", Script_HouseDiscoveredCallback); // House has been discovered. + lua_register(L, "ObjectAttackedCallback", Script_ObjectAttackedCallback); // player attacks this object + lua_register(L, "ObjectDestroyedCallback", Script_ObjectDestroyedCallback); // player destroys this object + lua_register(L, "AnyEventCallback", Script_AnyEventCallback); // Any object event will cause the trigger. + lua_register(L, "AllUnitsDestroyedCallback", Script_AllUnitsDestroyedCallback); // all house's units destroyed + lua_register(L, "AllBuildingsDestroyedCallback", Script_AllBuildingsDestroyedCallback); // all house's buildings destroyed + lua_register(L, "AllDestroyedCallback", Script_AllDestroyedCallback); // all house's units & buildings destroyed + lua_register(L, "CreditsReachedCallback", Script_CreditsReachedCallback); // house reaches this many credits + lua_register(L, "TimeReachedCallback", Script_TimeReachedCallback); // Scenario elapsed time from start. + lua_register(L, "MissionTimerCallback", Script_MissionTimerCallback); // Pre expired mission timer. + lua_register(L, "BuildingsDestroyedCallback", Script_BuildingsDestroyedCallback); // Number of buildings destroyed. + lua_register(L, "UnitsDestroyedCallback", Script_UnitsDestroyedCallback); // Number of units destroyed. + lua_register(L, "NoFactoriesCallback", Script_NoFactoriesCallback); // No factories left. + lua_register(L, "CivilianEscapeCallback", Script_CivilianEscapeCallback); // Civilian has been evacuated. + lua_register(L, "BuildingBuiltCallback", Script_BuildingBuiltCallback); // Specified building has been built. + lua_register(L, "UnitBuiltCallback", Script_UnitBuiltCallback); // Specified unit has been built. + lua_register(L, "InfantryBuiltCallback", Script_InfantryBuiltCallback); // Specified infantry has been built. + lua_register(L, "AircraftBuiltCallback", Script_AircraftBuiltCallback); // Specified aircraft has been built. + lua_register(L, "TeamLeavesMapCallback", Script_TeamLeavesMapCallback); // Specified team member leaves map. + lua_register(L, "ZoneEntryCallback", Script_ZoneEntryCallback); // Enters same zone as waypoint 'x'. + lua_register(L, "HorizontalCrossCallback", Script_HorizontalCrossCallback); // Crosses horizontal trigger line. + lua_register(L, "VerticalCrossCallback", Script_VerticalCrossCallback); // Crosses vertical trigger line. + lua_register(L, "GlobalSetCallback", Script_GlobalSetCallback); // If specified global has been set. (somewhat useless with Scripting) + lua_register(L, "GlobalClearedCallback", Script_GlobalClearedCallback); // If specified global has been cleared. (somewhat useless with Scripting) + // If all fake structures are gone. // This doesn't appear to be implemented in the engine (?) + lua_register(L, "LowPowerCallback", Script_LowPowerCallback); // When power drops below 100%. + lua_register(L, "AllBridgesDestroyedCallback", Script_AllBridgesDestroyedCallback); // All bridges destroyed. + lua_register(L, "BuildingExistsCallback", Script_BuildingExistsCallback); // Check for building existing. + +/********************************************************************************************** +* Trigger Utility Functions * +*=============================================================================================*/ + + lua_register(L, "SetTriggerCallback", Script_SetTriggerCallback); // Initiates a given [callback] on an existing [trigger] // TODO: Make this work via name OR ID + lua_register(L, "TriggerAddCell", Script_TriggerAddCell); // Initiates a given [callback] on an existing [trigger] + lua_register(L, "MergeTriggers", Script_MergeTriggers); // Combines the events of two triggers (for multi-event triggers :) + lua_register(L, "GetTriggerByName", Script_GetTriggerByName); // Gets the ID of the trigger with a given name + lua_register(L, "TriggerSetPersistence", Script_TriggerSetPersistence); // Does a trigger go on and on or just run once? + +/********************************************************************************************** +* Object Functions * +*=============================================================================================*/ + lua_register(L, "GetCellObject", Script_GetCellObject); // Gets an object (ID - building/vehicle/aircraft/infantry/vessel), if any, at [Cell/X],[Cell/Y] + + lua_register(L, "SetObjectAttribute", Script_SetObjectAttribute); // Sets an object's attributes (strength, etc.) + lua_register(L, "SetBuildingTypeAttribute", Script_SetBuildingTypeAttribute); // Sets the attribute of a Building type + lua_register(L, "SetVehicleTypeAttribute", Script_SetVehicleTypeAttribute); // Sets the attribute of a Vehicle type + lua_register(L, "SetInfantryTypeAttribute", Script_SetInfantryTypeAttribute); // Sets the attribute of an Infantry type + lua_register(L, "SetVesselTypeAttribute", Script_SetVesselTypeAttribute); // Sets the attribute of a Vessel type + lua_register(L, "SetAircraftTypeAttribute", Script_SetAircraftTypeAttribute); // Sets the attribute of an Aircraft type + + lua_register(L, "GetObjectAttribute", Script_GetObjectAttribute); // Sets an object's attributes (strength, etc.) + lua_register(L, "GetBuildingTypeAttribute", Script_GetBuildingTypeAttribute); // Sets the attribute of a Building type + lua_register(L, "GetVehicleTypeAttribute", Script_GetVehicleTypeAttribute); // Sets the attribute of a Vehicle type + lua_register(L, "GetInfantryTypeAttribute", Script_GetInfantryTypeAttribute); // Sets the attribute of an Infantry type + lua_register(L, "GetVesselTypeAttribute", Script_GetVesselTypeAttribute); // Sets the attribute of a Vessel type + lua_register(L, "GetAircraftTypeAttribute", Script_GetAircraftTypeAttribute); // Sets the attribute of an Aircraft type + + lua_register(L, "SetHouseAttribute", Script_SetHouseAttribute); // Sets a house's attributes + lua_register(L, "GetHouseAttribute", Script_GetHouseAttribute); // Gets a house's attributes + + lua_register(L, "BuildUnit", Script_BuildUnit); // Builds a unit in a given factory / barracks / naval yard / etc + lua_register(L, "CreateVehicle", Script_CreateVehicle); // Creates a unit out of thin air + lua_register(L, "CreateInfantry", Script_CreateInfantry); // Creates a unit out of thin air + lua_register(L, "CreateAircraft", Script_CreateAircraft); // Creates a unit out of thin air + lua_register(L, "CreateVessel", Script_CreateVessel); // Creates a unit out of thin air + +/********************************************************************************************** +* Object Orders Functions * +*=============================================================================================*/ + + lua_register(L, "OrderMove", Script_OrderMove); // Assigns a movement order to the object + lua_register(L, "OrderAttack", Script_OrderAttack); // Assigns an attack order to the object + lua_register(L, "OrderHunt", Script_OrderHunt); // Assigns a hunt order to the object + lua_register(L, "OrderGuard", Script_OrderGuard); // Assigns a guard order to the object + lua_register(L, "OrderEnter", Script_OrderEnter); // Assigns a enter order to the object + lua_register(L, "OrderCapture", Script_OrderCapture); // Assigns a capture order to the object + +/********************************************************************************************** +* Mission Utility Functions * +*=============================================================================================*/ + + lua_register(L, "SetBriefingText", Script_SetBriefingText); // Sets the [text] on the mission briefing screen + +/********************************************************************************************** +* Status / Location Utility Functions * +*=============================================================================================*/ + + lua_register(L, "GiveCredits", Script_GiveCredits); // Give [credits] to [player] + lua_register(L, "GetCredits", Script_GetCredits); // Get [player]'s [credits] + + lua_register(L, "CountBuildings", Script_CountBuildings); // Number of buildings of [type] for given [player] + lua_register(L, "CountAircraft", Script_CountAircraft); // Number of units of [type] for given [player] + lua_register(L, "CountUnits", Script_CountUnits); // Number of units of [type] for given [player] + lua_register(L, "CountInfantry", Script_CountInfantry); // Number of infantry of [type] for given [player] + lua_register(L, "CountVessels", Script_CountVessels); // Number of vessels of [type] for given [player] + + lua_register(L, "GetWaypointX", Script_GetWaypointX); // Get Cell/X of waypoint + lua_register(L, "GetWaypointY", Script_GetWaypointY); // Get Cell/Y of waypoint + +/********************************************************************************************** +* Special / Debug Functions * +*=============================================================================================*/ + + lua_register(L, "PrintConsole", Script_Console_Print); // Print text to console + +/********************************************************************************************** +* Script Globals * +*=============================================================================================*/ + + lua_pushnumber(L, PlayerPtr->ID); // Local player (house) index + lua_setglobal(L, "_localPlayer"); + + + return true; +} \ No newline at end of file From 2f4eee66dffa9d636446280f55b7bef2aed0e1cc Mon Sep 17 00:00:00 2001 From: nev6502 Date: Sun, 28 Jun 2020 19:56:53 -0600 Subject: [PATCH 7/7] Several more small fixes; everything should be where it should be now --- code/redalert/mapscript.cpp | 40 +++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/code/redalert/mapscript.cpp b/code/redalert/mapscript.cpp index 8e1a841..6608868 100644 --- a/code/redalert/mapscript.cpp +++ b/code/redalert/mapscript.cpp @@ -5745,7 +5745,11 @@ static int Script_OrderMove(lua_State* L) { if (this_object != NULL) { - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, As_Target(XY_Cell(in_x, in_y))); + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); + } + + Queue_Mission(TargetClass(this_object), MISSION_QMOVE, 0, As_Target(XY_Cell(in_x, in_y))); lua_pushnumber(L, 1); return 1; @@ -5791,6 +5795,10 @@ static int Script_OrderAttackCell(lua_State* L) { this_target = As_Target(XY_Cell(in_x, in_y)); } + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, this_target, this_target); + } + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, this_target, this_target); lua_pushnumber(L, 1); @@ -5841,6 +5849,10 @@ static int Script_OrderAttack(lua_State* L) { this_target = As_Target(XY_Cell(in_x, in_y)); } + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + } + Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); lua_pushnumber(L, 1); @@ -5891,7 +5903,11 @@ static int Script_OrderHunt(lua_State* L) { this_target = As_Target(XY_Cell(in_x, in_y)); } - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_HUNT, 0, this_target); + } + + Queue_Mission(TargetClass(this_object), MISSION_HUNT, 0, this_target); lua_pushnumber(L, 1); return 1; @@ -5941,7 +5957,11 @@ static int Script_OrderGuard(lua_State* L) { this_target = As_Target(XY_Cell(in_x, in_y)); } - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_GUARD, 0, this_target); + } + + Queue_Mission(TargetClass(this_object), MISSION_GUARD, 0, this_target); lua_pushnumber(L, 1); return 1; @@ -5991,7 +6011,11 @@ static int Script_OrderRetreat(lua_State* L) { this_target = As_Target(XY_Cell(in_x, in_y)); } - Queue_Mission(TargetClass(this_object), MISSION_ATTACK, 0, this_target); + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_RETREAT, 0, this_target); + } + + Queue_Mission(TargetClass(this_object), MISSION_RETREAT, 0, this_target); lua_pushnumber(L, 1); return 1; @@ -6041,6 +6065,10 @@ static int Script_OrderEnter(lua_State* L) { this_target = As_Target(XY_Cell(in_x, in_y)); } + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_ENTER, this_target, this_target); + } + Queue_Mission(TargetClass(this_object), MISSION_ENTER, this_target, this_target); lua_pushnumber(L, 1); @@ -6091,6 +6119,10 @@ static int Script_OrderCapture(lua_State* L) { this_target = As_Target(XY_Cell(in_x, in_y)); } + if (this_object->IsRecentlyCreated) { + Queue_Mission(TargetClass(this_object), MISSION_CAPTURE, this_target, this_target); + } + Queue_Mission(TargetClass(this_object), MISSION_CAPTURE, this_target, this_target); lua_pushnumber(L, 1);