Files
CnC_Remastered_Collection/code/redalert/mapscript.cpp
T
2020-06-28 17:57:57 -06:00

7566 lines
383 KiB
C++

#include "function.H"
#include "mapscript.h"
/**********************************************************************************************
* 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);
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_Win();
}
else {
PlayerPtr->Flag_To_Lose();
}
bool success = this_house->Fire_Sale();
lua_pushboolean(L, int(success));
}
}
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;
}
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_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_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);
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);
}
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) {
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) {
// 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);
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;
}
/***********************************************************************************************
* 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) {
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);
}
// 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);
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) {
int objectID = 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 (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_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);
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) {
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_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;
}
/***********************************************************************************************
* 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);
}
// 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
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);
}
// 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) {
int triggerIndex = lua_tointeger(L, 1);
int in_x = lua_tointeger(L, 2);
int in_y = lua_tointeger(L, 3);
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);
}
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;
}
}
}
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;
}
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;
}
/***********************************************************************************************
* 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) {
int triggerIndex = lua_tointeger(L, 1);
int mergeTriggerIndex = lua_tointeger(L, 2);
TriggerClass* resulting_trigger = Triggers.Ptr(triggerIndex);
TriggerTypeClass* resulting_trigger_type = resulting_trigger->Class;
TriggerClass* merge_trigger = Triggers.Ptr(mergeTriggerIndex);
if (resulting_trigger != NULL && merge_trigger != NULL) {
// 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;
// Make this an "AND" coniditional trigger (event 1 AND event 2)
resulting_trigger->Class->EventControl = MULTI_AND;
resulting_trigger->Class->ActionControl = MULTI_ONLY;
// TODO: only do these individual cleanups for actions that they represent (for efficiency)
// 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) {
MapTriggers.Delete(t_index);
bool find_existing_result;
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) {
MapTriggers.Add(resulting_trigger);
}
break;
}
}
}
// 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;
}
}
}
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);
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: {
}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;
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;
}
}
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;
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: {
// 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, 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;
}
}
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_OrderMove - 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_OrderMove(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) {
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);
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) {
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) {
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);
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;
}
/**********************************************************************************************
* 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) {
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 || 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;
}
/***********************************************************************************************
* 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) {
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;
}
}
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);
int houseType = -1;
// Optional houseType parameter
if (lua_gettop(L) == 2) {
houseType = lua_tointeger(L, 2);
}
// 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);
int houseType = -1;
// Optional houseType parameter
if (lua_gettop(L) == 2) {
houseType = lua_tointeger(L, 2);
}
// 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 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) {
// 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);
int houseType = -1;
// Optional houseType parameter
if (lua_gettop(L) == 2) {
houseType = lua_tointeger(L, 2);
}
// 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 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) {
// 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);
int houseType = -1;
// Optional houseType parameter
if (lua_gettop(L) == 2) {
houseType = lua_tointeger(L, 2);
}
// 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 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) {
// 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);
int houseType = -1;
// Optional houseType parameter
if (lua_gettop(L) == 2) {
houseType = lua_tointeger(L, 2);
}
// 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 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) {
// 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]));
return 1;
}
lua_pushnumber(L, -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) {
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;
}
/**********************************************************************************************
* 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 *
*=============================================================================================*/
/***********************************************************************************************
* 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<MapScriptObject*>::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<BuildingClass*>(this_object)->Class->Type;
dynamic_cast<BuildingClass*>(this_object)->Trigger = input_trigger;
}break;
case RTTI_UNIT:{
input_trigger->Class->Event1.Data.Unit = dynamic_cast<UnitClass*>(this_object)->Class->Type;
dynamic_cast<UnitClass*>(this_object)->Trigger = input_trigger;
}break;
case RTTI_AIRCRAFT:{
input_trigger->Class->Event1.Data.Aircraft = dynamic_cast<AircraftClass*>(this_object)->Class->Type;
dynamic_cast<AircraftClass*>(this_object)->Trigger = input_trigger;
}break;
case RTTI_INFANTRY:{
input_trigger->Class->Event1.Data.Infantry = dynamic_cast<InfantryClass*>(this_object)->Class->Type;
dynamic_cast<InfantryClass*>(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<MapScriptDefaultObjectAttribute*>::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)
{
delete ObjectCache[i];
}
ObjectCache.clear();
// We will now restore any default Object attributes that were changed in the script
for (std::vector<MapScriptDefaultObjectAttribute*>::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);
}
}
/***********************************************************************************************
* 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;
}