diff --git a/code/REDALERT/MapScript.cpp b/code/REDALERT/MapScript.cpp index da94f84..dc42a44 100644 --- a/code/REDALERT/MapScript.cpp +++ b/code/REDALERT/MapScript.cpp @@ -5,10 +5,12 @@ #include "MapScript.h" /*********************************************************************************************** - * Script_GiveCreditsToPlayer - Gives a given player a given amount of credits * + * Script_GiveCredits - Gives a given player a given amount of credits * * * - * SCRIPT INPUT: houseType (int) - The player (house) index to give credits to * - * cashToGive (int) - The amount of cold hard credits to give the player * + * SCRIPT INPUT: cashToGive (int) - The amount of cold hard credits to give the player * + * * + * houseType (int) - The player (house) index to give credits to * + * or -1 to give to all players * * * * SCRIPT OUTPUT: void * * * @@ -22,16 +24,28 @@ * 6/11/2020 - JM Created * * 6/12/2020 - JJ Added player (house) index input * *=============================================================================================*/ -static int Script_GiveCreditsToPlayer(lua_State* L) { - int houseType = lua_tointeger(L, 1); - int cashToGive = lua_tointeger(L, 2); +static int Script_GiveCredits(lua_State* L) { + + int cashToGive = lua_tointeger(L, 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) { + if (house->ID == houseType || houseType == -1) { house->Refund_Money(cashToGive); + + // Discontinue giving out free cash if a specific house was specified + if (houseType >= 0) { + break; + } } } @@ -42,8 +56,11 @@ static int Script_GiveCreditsToPlayer(lua_State* L) { /*********************************************************************************************** * Script_NumBuildingTypeForPlayer - Returns the amount of specific buildings for a player * * * - * SCRIPT INPUT: houseType (int) - The player (house) index to count buildings for * - * structType (int) - The structure index to count buildings for * + * 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 * * * * SCRIPT OUTPUT: result (number) - The amount of matching buildings for that player * * * @@ -54,15 +71,66 @@ static int Script_GiveCreditsToPlayer(lua_State* L) { * WARNINGS: ? * * * *=============================================================================================*/ -static int Script_NumBuildingTypeForPlayer(lua_State* L) { - int houseType = lua_tointeger(L, 1); - int structType = lua_tointeger(L, 2); +static int Script_CountBuildings(lua_State* L) { + int structType = lua_tointeger(L, 1); + + int houseType = -1; + + // Optional houseType parameter + if (lua_gettop(L) == 2) { + houseType = lua_tointeger(L, 2); + } + int result = 0; for (int b_index = 0; b_index < Buildings.Count(); b_index++) { BuildingClass* building = Buildings.Ptr(b_index); - if (building->Owner() == houseType) { - if (building->Class->Type == structType) { + if (building->Owner() == houseType || houseType == -1) { + if (building->Class->Type == structType || structType == -1) { + result++; + } + } + } + + lua_pushnumber(L, result); + return 1; +} + + +/*********************************************************************************************** + * Script_CountAircraft - Returns the amount of specific aircraft for a player * + * * + * 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 * + * * + * 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); + + int houseType = -1; + + // 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); + + if (aircraft->Owner() == houseType || houseType == -1) { + if (aircraft->Class->Type == aircraftType || aircraftType == -1) { result++; } } @@ -72,16 +140,156 @@ static int Script_NumBuildingTypeForPlayer(lua_State* L) { return 1; } +/*********************************************************************************************** + * Script_CountUnits - Returns the amount of specific units for a player * + * * + * 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 * + * * + * 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); + + int houseType = -1; + + // 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); + + if (unit->Owner() == houseType || houseType == -1) { + if (unit->Class->Type == unitType || unitType == -1) { + result++; + } + } + } + + lua_pushnumber(L, result); + return 1; +} + + +/*********************************************************************************************** + * Script_CountInfantry - Returns the amount of specific infantry for a player * + * * + * 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 * + * * + * 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); + + int houseType = -1; + + // 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); + + if (infantry->Owner() == houseType || houseType == -1) { + if (infantry->Class->Type == infantryType || infantryType == -1) { + result++; + } + } + } + + lua_pushnumber(L, result); + return 1; +} + + +/*********************************************************************************************** + * Script_CountVessels - Returns the amount of specific vessels for a player * + * * + * 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 * + * * + * 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); + + int houseType = -1; + + // 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); + + if (vessel->Owner() == houseType || houseType == -1) { + if (vessel->Class->Type == vesselType || vesselType == -1) { + result++; + } + } + } + + lua_pushnumber(L, result); + return 1; +} + + /*********************************************************************************************** * Script_SetTriggerCallback - Adds a lua callback to an existing trigger * * * - * SCRIPT INPUT: triggerName (string) - The ININame of the trigger via its class * - * callbackName (string) - The function name to be called when the actions * - * have been met * - * actionIndex (int) (optional) - 0 (default): always callback on any of the * - * given paths of the trigger * - * 1: only callback on first action * - * 2: only callback on second action * + * SCRIPT INPUT: triggerName (string) - The ININame of the trigger via its class * + * * + * 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 * * * @@ -141,7 +349,7 @@ static int Script_SetTriggerCallback(lua_State* L) { * * *=============================================================================================*/ static int Script_Win(lua_State* L) { - + int houseType = lua_tointeger(L, -1); if (houseType != HOUSE_NONE) { @@ -888,13 +1096,13 @@ void MapScript::SetLuaPath( const char* input_path) bool MapScript::Init(const char* mapName) { 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)){ L = NULL; return false; @@ -908,14 +1116,11 @@ bool MapScript::Init(const char* mapName) { // This allows require() to work SetLuaPath(";scripts/?.script;"); - if (lua_pcall(L, 0, 0, 0)) { L = NULL; return false; } - - /********************************************************************************************** * Red Alert Vanilla Actions * *=============================================================================================*/ @@ -990,17 +1195,22 @@ bool MapScript::Init(const char* mapName) { *=============================================================================================*/ lua_register(L, "SetBriefingText", Script_SetBriefingText); // Sets the [text] on the mission briefing screen - lua_register(L, "GiveCreditsToPlayer", Script_GiveCreditsToPlayer); // Give [player] [credits] - lua_register(L, "NumBuildingTypeForPlayer", Script_NumBuildingTypeForPlayer); // Number of buildings of [type] for given [player] - - lua_register(L, "SetTriggerCallback", Script_SetTriggerCallback); // Initiates a given [callback] on an existing [trigger] + lua_register(L, "GiveCredits", Script_GiveCredits); // Give [credits] to [player] + + 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, "SetTriggerCallback", Script_SetTriggerCallback); // Initiates a given [callback] on an existing [trigger] + /********************************************************************************************** * Script Globals * *=============================================================================================*/ - lua_pushnumber(L, PlayerPtr->ID); // Local (human) player + lua_pushnumber(L, PlayerPtr->ID); // Local player (house) index lua_setglobal(L, "_localPlayer");