From 19569faf2be061562bfa5b9c523d73266adea805 Mon Sep 17 00:00:00 2001 From: nev6502 Date: Sat, 27 Jun 2020 18:16:29 -0600 Subject: [PATCH] Added ability to change attributes for buildings, units, infantry, aircraft and veseels. Values are restored to default values by cacheing values upon first usage and cleaning up with Deinit(). Revised global header to encapsulate the values within sections, drastically reducing variable counts Mouse frequent click/drag fix --- code/redalert/io/userinput.cpp | 6 + code/redalert/mapscript.cpp | 552 +++++++++++++++++++++++++++++++-- code/redalert/mapscript.h | 57 +++- scripts/_Global.script | 519 +++++++++++++++++-------------- 4 files changed, 875 insertions(+), 259 deletions(-) diff --git a/code/redalert/io/userinput.cpp b/code/redalert/io/userinput.cpp index aadd59c..2f0ea73 100644 --- a/code/redalert/io/userinput.cpp +++ b/code/redalert/io/userinput.cpp @@ -58,6 +58,12 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) Keyboard->Put_Element(KN_LMOUSE); leftMouseProcessed = true; + + // Seems to fix "missed mouse click" bug + if (numFramesLMouse == 0) { + numFramesLMouse++; + return; + } numFramesLMouse++; } else if (event.button.button == SDL_BUTTON_RIGHT) { diff --git a/code/redalert/mapscript.cpp b/code/redalert/mapscript.cpp index fa5feb8..807fe15 100644 --- a/code/redalert/mapscript.cpp +++ b/code/redalert/mapscript.cpp @@ -1,5 +1,5 @@ -#include "FUNCTION.H" -#include "MapScript.h" +#include "function.H" +#include "mapscript.h" /********************************************************************************************** * Red Alert Vanilla Actions * @@ -3306,14 +3306,39 @@ - + // Global attributes / Multi object attributes switch ((MapScriptAttributeType)attribute_type) { + case ATTRIBUTE_TYPE: { + + }break; case ATTRIBUTE_STRENGTH: { int attribute_value = lua_tointeger(L, 3); this_object->Strength = attribute_value; }break; + + case ATTRIBUTE_IS_REPAIRING: { + + int attribute_value = lua_tointeger(L, 3); + + switch (this_object->RTTI) { + case RTTI_BUILDING: { + + BuildingClass* this_building = (BuildingClass*)this_object; + this_building->IsRepairing = attribute_value; + + }break; + case RTTI_VESSEL: { + + VesselClass* this_vessel = (VesselClass*)this_object; + this_vessel->IsSelfRepairing = attribute_value; + + }break; + } + }break; + + // Object Class specific default: { TechnoTypeClass* this_type_class; @@ -3344,7 +3369,7 @@ this_type_class = AircraftTypes.Ptr(this_object->Class_Of().ID); break; - } + } if (this_type_class != NULL) { @@ -3531,6 +3556,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxStrength); + + // Set the attribute this_type_class->MaxStrength = attribute_value; }break; @@ -3539,6 +3568,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Cost); + + // Set the attribute this_type_class->Cost = attribute_value; }break; @@ -3546,6 +3579,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SightRange); + + // Set the attribute this_type_class->SightRange = attribute_value; }break; @@ -3553,6 +3590,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Level); + + // Set the attribute this_type_class->Level = attribute_value; }break; @@ -3560,6 +3601,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Armor); + + // Set the attribute this_type_class->Armor = (ArmorType)attribute_value; }break; @@ -3567,9 +3612,24 @@ int attribute_value = lua_tointeger(L, 3); - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->PrimaryWeapon = this_weapon; + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->PrimaryWeapon->ID); + }else { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } + + // Set the attribute + if (attribute_value < 0) { + this_type_class->PrimaryWeapon = NULL; + }else { + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->PrimaryWeapon = this_weapon; + }else { + this_type_class->PrimaryWeapon = NULL; + } } }break; @@ -3577,9 +3637,24 @@ int attribute_value = lua_tointeger(L, 3); - WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); - if (this_weapon != NULL) { - this_type_class->SecondaryWeapon = this_weapon; + if (this_type_class->PrimaryWeapon != NULL) { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->SecondaryWeapon->ID); + }else { + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, -1); + } + + // Set the attribute + if (attribute_value < 0) { + this_type_class->SecondaryWeapon = NULL; + }else{ + WeaponTypeClass* this_weapon = Weapons.Ptr(attribute_value); + if (this_weapon != NULL) { + this_type_class->SecondaryWeapon = this_weapon; + }else { + this_type_class->SecondaryWeapon = NULL; + } } }break; @@ -3587,6 +3662,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->Speed); + + // Set the attribute this_type_class->Speed = (SpeedType)attribute_value; }break; @@ -3594,6 +3673,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxSpeed); + + // Set the attribute this_type_class->MaxSpeed = (MPHType)attribute_value; }break; @@ -3601,6 +3684,10 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxAmmo); + + // Set the attribute this_type_class->MaxAmmo = attribute_value; }break; @@ -3608,55 +3695,87 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->ROT); + + // Set the attribute this_type_class->ROT = attribute_value; }break; - case ATTRIBUTE_IS_CRUSHABLE: { + case ATTRIBUTE_CRUSHABLE: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrushable); + + // Set the attribute this_type_class->IsCrushable = attribute_value; }break; - case ATTRIBUTE_IS_STEALTHY: { + case ATTRIBUTE_STEALTHY: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsStealthy); + + // Set the attribute this_type_class->IsStealthy = attribute_value; }break; - case ATTRIBUTE_IS_SELECTABLE: { + case ATTRIBUTE_SELECTABLE: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelectable); + + // Set the attribute this_type_class->IsSelectable = attribute_value; }break; - case ATTRIBUTE_IS_LEGAL_TARGET: { + case ATTRIBUTE_LEGAL_TARGET: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsLegalTarget); + + // Set the attribute this_type_class->IsLegalTarget = attribute_value; }break; - case ATTRIBUTE_IS_REPAIRABLE: { + case ATTRIBUTE_REPAIRABLE: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsRepairable); + + // Set the attribute this_type_class->IsRepairable = attribute_value; }break; - case ATTRIBUTE_IS_SELF_HEALING: { + case ATTRIBUTE_SELF_HEALING: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsSelfHealing); + + // Set the attribute this_type_class->IsSelfHealing = attribute_value; }break; - case ATTRIBUTE_IS_EXPLODING: { + case ATTRIBUTE_EXPLODES: { unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsExploding); + + // Set the attribute this_type_class->IsExploding = attribute_value; }break; @@ -3664,6 +3783,10 @@ unsigned int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->IsCrew); + + // Set the attribute this_type_class->IsCrew = attribute_value; }break; @@ -3671,14 +3794,312 @@ int attribute_value = lua_tointeger(L, 3); + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_type_class->MaxPassengers); + + // Set the attribute this_type_class->MaxPassengers = attribute_value; }break; + default:{ + + // Object class specific attributes + // Welcome to the web of switches] + + // Type of object + switch (this_type_class->RTTI) { + + // Building Specific + case RTTI_BUILDINGTYPE:{ + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CAPACITY: { + + int attribute_value = lua_tointeger(L, 3); + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Capacity); + + // Set the attribute + this_building_class->Capacity = attribute_value; + + }break; + case ATTRIBUTE_POWER: { + + int attribute_value = lua_tointeger(L, 3); + + // Both power and drain are different variables + // And so we do some trickery here to fill + // the right values based on postivie/negative input + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->Power + this_building_class->Drain); + + // Set the attribute + if (attribute_value > 0) { + this_building_class->Power = attribute_value; + this_building_class->Drain = 0; + }else { + this_building_class->Power = 0; + this_building_class->Drain = attribute_value * -1; // Flip negative power input + } + + }break; + case ATTRIBUTE_SELLABLE: { + + int attribute_value = lua_tointeger(L, 3); + + BuildingTypeClass* this_building_class = (BuildingTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_building_class->IsUnsellable *-1); + + // Set the attribute + // Personal opinion; sellable makes more sense than unsellable + // This replacement could be seen as IsUnNonSellable, or... IsSellable + if (attribute_value == 1) { + this_building_class->IsUnsellable = 0; + } + else { + this_building_class->IsUnsellable = 1; + } + + }break; + } + + }break; + + + // Unit Specific + case RTTI_UNITTYPE:{ + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_CRATE_GOODIE: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrateGoodie); + + // Set the attribute + this_unit_class->IsCrateGoodie = attribute_value; + + }break; + case ATTRIBUTE_CRUSHER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsCrusher); + + // Set the attribute + this_unit_class->IsCrusher = attribute_value; + + }break; + case ATTRIBUTE_HARVEST: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsToHarvest); + + // Set the attribute + this_unit_class->IsToHarvest = attribute_value; + + }break; + case ATTRIBUTE_RADAR_EQUIPPED: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsRadarEquipped); + + // Set the attribute + this_unit_class->IsRadarEquipped = attribute_value; + + }break; + case ATTRIBUTE_JAMMER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsJammer); + + // Set the attribute + this_unit_class->IsJammer = attribute_value; + + }break; + case ATTRIBUTE_GAPPER: { + + int attribute_value = lua_tointeger(L, 3); + + UnitTypeClass* this_unit_class = (UnitTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_unit_class->IsGapper); + + // Set the attribute + this_unit_class->IsGapper = attribute_value; + + }break; + } + + }break; + + + // Infantry Specific + case RTTI_INFANTRYTYPE:{ + + // What type of attribute? + switch (attribute_type) { + case ATTRIBUTE_FEMALE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFemale); + + // Set the attribute + this_infantry_class->IsFemale = attribute_value; + + }break; + case ATTRIBUTE_CAPTURE: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCapture); + + // Set the attribute + this_infantry_class->IsCapture = attribute_value; + + }break; + case ATTRIBUTE_FRAIDY_CAT: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsFraidyCat); + + // Set the attribute + this_infantry_class->IsFraidyCat = attribute_value; + + }break; + case ATTRIBUTE_CIVILIAN: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsCivilian); + + // Set the attribute + this_infantry_class->IsCivilian = attribute_value; + + }break; + case ATTRIBUTE_BOMBER: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsBomber); + + // Set the attribute + this_infantry_class->IsBomber = attribute_value; + + }break; + case ATTRIBUTE_DOG: { + + int attribute_value = lua_tointeger(L, 3); + + InfantryTypeClass* this_infantry_class = (InfantryTypeClass*)this_type_class; + + // Cache default value if first time changing this attribute + Script_CacheDefaultAttribute(this_type_class->RTTI, this_type_class->ID, attribute_type, this_infantry_class->IsDog); + + // Set the attribute + this_infantry_class->IsDog = attribute_value; + + }break; + + } + + }break; + + } // End of object specific switch + + }break; + + } // End of attribute switch + + return -1; + } + + + /*********************************************************************************************** + * Script_CacheDefaultAttribute - Caches an attribute value upon first usage for restoration * + * * + * SCRIPT INPUT: input_rtti (RTTIType) - The RTTI type for the attrtibute * + * input_id (int) - The ID of the typeclass * + * input_attribute (int) - The attribute to cache * + * input_value (int) - The value if the cache item doesn't exist * + * * + * SCRIPT OUTPUT: void * + * * + * WARNINGS: ? * + * * + *=============================================================================================*/ + void Script_CacheDefaultAttribute(RTTIType input_rtti, int input_id, MapScriptAttributeType input_attribute, int input_value) { + + bool cache_item_found = false; + for (std::vector::iterator it = Scen.mapScript->DefaultTypeAttributeCache.begin(); it != Scen.mapScript->DefaultTypeAttributeCache.end(); ++it) {//Error 2-4 + + MapScriptDefaultAttribute* cachedAttribute = (MapScriptDefaultAttribute*)(*it); + + if (input_rtti == cachedAttribute->RTTI && input_id == cachedAttribute->ID && input_attribute == cachedAttribute->attribute) { + cache_item_found = true; + break; + } } + // Cached attribute does not exist; let's cache! + if (!cache_item_found) { + + MapScriptDefaultAttribute* cachedAttribute = new MapScriptDefaultAttribute; + cachedAttribute->RTTI = input_rtti; + cachedAttribute->ID = input_id; + cachedAttribute->attribute = input_attribute; + cachedAttribute->value = input_value; + Scen.mapScript->DefaultTypeAttributeCache.push_back(cachedAttribute); + + } - return -1; } /********************************************************************************************** @@ -4744,6 +5165,7 @@ *=============================================================================================*/ void MapScript::Deinit() { + // Remove any cached objects for (int i = 0; i < ObjectCache.size(); ++i) { delete ObjectCache[i]; @@ -4751,6 +5173,92 @@ ObjectCache.clear(); + // Welcome back to the web of switches where we will restore any default + // attributes that were changed in the script + for (std::vector::iterator it = Scen.mapScript->DefaultTypeAttributeCache.begin(); it != Scen.mapScript->DefaultTypeAttributeCache.end(); ++it) {//Error 2-4 + + MapScriptDefaultAttribute* cachedAttribute = (MapScriptDefaultAttribute*)(*it); + + + + + + switch (cachedAttribute->RTTI) { + + case RTTI_BUILDINGTYPE: { + lua_getglobal(L, "SetBuildingTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_UNITTYPE: { + lua_getglobal(L, "SetUnitTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_INFANTRYTYPE: { + lua_getglobal(L, "SetInfantryTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_AIRCRAFTTYPE: { + lua_getglobal(L, "SetAircraftTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + case RTTI_VESSELTYPE: { + lua_getglobal(L, "SetVesselTypeAttribute"); + lua_pushnumber(L, cachedAttribute->ID); + lua_pushnumber(L, cachedAttribute->attribute); + lua_pushnumber(L, cachedAttribute->value); + lua_pcall(L, 3, 1, 0); + }break; + + } + + + } + + + for (int index = 0; index < Warheads.Count(); index++) { + Warheads.Ptr(index)->Read_INI(RuleINI); + } + + for (int proj = 0; proj < BulletTypes.Count(); proj++) { + BulletTypes.Ptr(proj)->Read_INI(RuleINI); + } + + for (int windex = 0; windex < Weapons.Count(); windex++) { + Weapons.Ptr(windex)->Read_INI(RuleINI); + } + + for (int uindex = 0; uindex < UnitTypes.Count(); uindex++) { + UnitTypes.Ptr(uindex)->Read_INI(RuleINI); + } + + for (int iindex = 0; iindex < InfantryTypes.Count(); iindex++) { + InfantryTypes.Ptr(iindex)->Read_INI(RuleINI); + } + + for (int vindex = 0; vindex < VesselTypes.Count(); vindex++) { + VesselTypes.Ptr(vindex)->Read_INI(RuleINI); + } + + for (int aindex = 0; aindex < AircraftTypes.Count(); aindex++) { + AircraftTypes.Ptr(aindex)->Read_INI(RuleINI); + } + + for (int bindex = 0; bindex < BuildingTypes.Count(); bindex++) { + BuildingTypes.Ptr(bindex)->Read_INI(RuleINI); + } + } /*********************************************************************************************** @@ -4776,6 +5284,7 @@ // Load file if (luaL_loadfile(L, scriptName)){ + Console_Printf(lua_tostring(L, -1)); L = NULL; return false; } @@ -4789,6 +5298,7 @@ SetLuaPath(";scripts/?.script;"); if (lua_pcall(L, 0, 0, 0)) { + Console_Printf(lua_tostring(L, -1)); L = NULL; return false; } @@ -4796,6 +5306,9 @@ // Reserve object cache memory ObjectCache.reserve(2000); + // Reserve type attribute cache memory (to restore rules after script) + DefaultTypeAttributeCache.reserve(1000); + /********************************************************************************************** * Red Alert Vanilla Actions * *=============================================================================================*/ @@ -4894,6 +5407,9 @@ lua_register(L, "SetInfantryTypeAttribute", Script_SetInfantryTypeAttribute); // Sets the attribute of an Infantry type lua_register(L, "SetVesselTypeAttribute", Script_SetVesselTypeAttribute); // Sets the attribute of a Vessel type lua_register(L, "SetAircraftTypeAttribute", Script_SetAircraftTypeAttribute); // Sets the attribute of an Aircraft type + + + //lua_register(L, "GetObjectAttribute", Script_SetAircraftTypeAttribute); // Gets the attribute of an object /********************************************************************************************** * Mission Utility Functions * diff --git a/code/redalert/mapscript.h b/code/redalert/mapscript.h index 532a61b..5548a95 100644 --- a/code/redalert/mapscript.h +++ b/code/redalert/mapscript.h @@ -1,4 +1,4 @@ -// MapScript.h +// mapscript.h // #ifndef MAPSCRIPT_H @@ -20,6 +20,15 @@ struct MapScriptObject { RTTIType RTTI; // The type of object }; +// Stores defaults of rules from before +// variables were changed within +struct MapScriptDefaultAttribute { + RTTIType RTTI; // The type of object + int ID=-1; // The index of the object in its heap + int attribute; + int value; +}; + // // MapScript Class @@ -38,6 +47,7 @@ public: void SetLuaPath(const char* input_path); std::vector ObjectCache; + std::vector DefaultTypeAttributeCache; private: lua_State* L; @@ -47,7 +57,9 @@ private: // Enums typedef enum MapScriptAttributeType : char { - ATTRIBUTE_NONE=0, + + // Techno types + ATTRIBUTE_TYPE=0, ATTRIBUTE_STRENGTH, ATTRIBUTE_MAX_STRENGTH, ATTRIBUTE_COST, @@ -60,15 +72,39 @@ typedef enum MapScriptAttributeType : char { ATTRIBUTE_MAX_SPEED, ATTRIBUTE_MAX_AMMO, ATTRIBUTE_ROTATION_SPEED, - ATTRIBUTE_IS_CRUSHABLE, - ATTRIBUTE_IS_STEALTHY, - ATTRIBUTE_IS_SELECTABLE, - ATTRIBUTE_IS_LEGAL_TARGET, - ATTRIBUTE_IS_REPAIRABLE, - ATTRIBUTE_IS_SELF_HEALING, - ATTRIBUTE_IS_EXPLODING, + ATTRIBUTE_CRUSHABLE, + ATTRIBUTE_STEALTHY, + ATTRIBUTE_SELECTABLE, + ATTRIBUTE_LEGAL_TARGET, + ATTRIBUTE_REPAIRABLE, + ATTRIBUTE_SELF_HEALING, + ATTRIBUTE_EXPLODES, ATTRIBUTE_HAS_CREW, - ATTRIBUTE_MAX_PASSENGERS + ATTRIBUTE_MAX_PASSENGERS, + ATTRIBUTE_IS_REPAIRING, + + // Building Specific + ATTRIBUTE_CAPACITY, + ATTRIBUTE_POWER, + ATTRIBUTE_SELLABLE, + + // Unit Specific + ATTRIBUTE_CRATE_GOODIE, + ATTRIBUTE_CRUSHER, + ATTRIBUTE_HARVEST, + ATTRIBUTE_RADAR_EQUIPPED, + ATTRIBUTE_JAMMER, + ATTRIBUTE_GAPPER, + + // Infantry Specific + ATTRIBUTE_FEMALE, + ATTRIBUTE_CAPTURE, + ATTRIBUTE_FRAIDY_CAT, + ATTRIBUTE_CIVILIAN, + ATTRIBUTE_BOMBER, + ATTRIBUTE_DOG + + } MapScriptAttributeType; // Non-Class-Functions @@ -83,5 +119,6 @@ int Script_VesselIndexFromID(int input_object_id); static int Script_SetObjectTypeAttribute(lua_State* L, TechnoTypeClass* this_type_class, MapScriptAttributeType attribute_type); +void Script_CacheDefaultAttribute(RTTIType input_rtti, int input_id, MapScriptAttributeType input_attribute, int input_value); #endif \ No newline at end of file diff --git a/scripts/_Global.script b/scripts/_Global.script index 230c731..f848203 100644 --- a/scripts/_Global.script +++ b/scripts/_Global.script @@ -4,115 +4,148 @@ -- * * -- *=======================================================* + -- ********************************************************* + -- * * + -- * Houses (players) * + -- * * + -- ********************************************************* + Houses={ + SPAIN=0, -- YELLOW/GOLD + GREECE=1, -- BLUE-GREY + USSR=2, -- RED + ENGLAND=3, -- GREEN + UKRAINE=4, -- ORANGE + GERMANY=5, -- KHAKI/LIGHT BROWN + FRANCE=6, -- AQUA + TURKEY=7, -- RED-OCHRE + GOODGUY=8, -- BLUE-GREY + BADGUY=9, -- RED + NEUTRAL=10, -- YELLOW/GOLD + SPECIAL=11, -- YELLOW/GOLD + MULTI1=12, -- YELLOW/GOLD + MULTI2=13, -- BLUE-GREY + MULTI3=14, -- RED + MULTI4=15, -- GREEN + MULTI5=16, -- ORANGE + MULTI6=17, -- KHAKI/LIGHT BROWN + MULTI7=18, -- AQUA + MULTI8=19 -- RED-OCHRE + } -- ********************************************************* -- * * -- * Buildings * -- * * -- ********************************************************* - - BUILDING_ATEK=0 -- Allied Technology Centre - BUILDING_IRON=1 -- Iron Curtain - BUILDING_WEAP=2 -- Weapons Factory - BUILDING_PDOX=3 -- Chronosphere - BUILDING_PBOX=4 -- Pillbox - BUILDING_HBOX=5 -- Camouflaged Pillbox - BUILDING_DOME=6 -- Radar Dome - BUILDING_GAP =7 -- Gap Generator - BUILDING_GUN =8 -- Gun Turret - BUILDING_AGUN=9 -- Anti-Aircraft Gun - BUILDING_FTUR=10 -- Flame Turret - BUILDING_FACT=11 -- Construction Yard - BUILDING_PROC=12 -- Ore Refinery - BUILDING_SILO=13 -- Ore Silo - BUILDING_HPAD=14 -- Helicopter Pad - BUILDING_SAM =15 -- SAM Site - BUILDING_AFLD=16 -- Airfield - BUILDING_POWR=17 -- Power Plant - BUILDING_APWR=18 -- Advanced Power Plant - BUILDING_STEK=19 -- Soviet Technology Centre - BUILDING_HOSP=20 -- Hospital - BUILDING_BARR=21 -- Barracks (Allied) - BUILDING_TENT=22 -- Barracks (Soviet) - BUILDING_KENN=23 -- Dog Kennel - BUILDING_FIX =24 -- Service Depot - BUILDING_BIO =25 -- Bio-Research Laboratory - BUILDING_MISS=26 -- Technology Centre/Prison - BUILDING_SYRD=27 -- Ship Yard - BUILDING_SPEN=28 -- Sub Pen - BUILDING_MSLO=29 -- Missile Silo - BUILDING_FCOM=30 -- Forward Command Post - BUILDING_TSLA=31 -- Tesla Coil - BUILDING_WEAF=32 -- Fake Weapons Factory - BUILDING_FACF=33 -- Fake Construction Yard - BUILDING_SYRF=34 -- Fake Ship Yard - BUILDING_SPEF=35 -- Fake Sub Pen - BUILDING_DOMF=36 -- Fake Radar Dome - BUILDING_MINV=43 -- Anti-vehicle mine - BUILDING_MINP=44 -- Anti-personnel mine + + BuildingTypes={ + ATEK=0, -- Allied Technology Centre + IRON=1, -- Iron Curtain + WEAP=2, -- Weapons Factory + PDOX=3, -- Chronosphere + PBOX=4, -- Pillbox + HBOX=5, -- Camouflaged Pillbox + DOME=6, -- Radar Dome + GAP =7, -- Gap Generator + GUN =8, -- Gun Turret + AGUN=9, -- Anti-Aircraft Gun + FTUR=10, -- Flame Turret + FACT=11, -- Construction Yard + PROC=12, -- Ore Refinery + SILO=13, -- Ore Silo + HPAD=14, -- Helicopter Pad + SAM =15, -- SAM Site + AFLD=16, -- Airfield + POWR=17, -- Power Plant + APWR=18, -- Advanced Power Plant + STEK=19, -- Soviet Technology Centre + HOSP=20, -- Hospital + BARR=21, -- Barracks (Allied) + TENT=22, -- Barracks (Soviet) + KENN=23, -- Dog Kennel + FIX =24, -- Service Depot + BIO =25, -- Bio-Research Laboratory + MISS=26, -- Technology Centre/Prison + SYRD=27, -- Ship Yard + SPEN=28, -- Sub Pen + MSLO=29, -- Missile Silo + FCOM=30, -- Forward Command Post + TSLA=31, -- Tesla Coil + WEAF=32, -- Fake Weapons Factory + FACF=33, -- Fake Construction Yard + SYRF=34, -- Fake Ship Yard + SPEF=35, -- Fake Sub Pen + DOMF=36, -- Fake Radar Dome + MINV=43, -- Anti-vehicle mine + MINP=44, -- Anti-personnel mine -- Counterstrike - BUILDING_QUEE=84 -- Queen ant structure - BUILDING_LAR1=85 -- Ant - single ant larva - BUILDING_LAR2=86 -- Ant - two ant larvae - + QUEE=84, -- Queen ant structure + LAR1=85, -- Ant - single ant larva + LAR2=86 -- Ant - two ant larvae + } + -- ********************************************************* -- * * -- * Infantry * -- * * -- ********************************************************* - INFANTRY_E1=0 -- Rifle Infantry - INFANTRY_E2=1 -- Grenadier - INFANTRY_E3=2 -- Rocket Soldier - INFANTRY_E4=3 -- Flamethrower - INFANTRY_E6=4 -- Engineer - INFANTRY_E7=5 -- Tanya - INFANTRY_SPY=6 -- Spy - INFANTRY_THF=7 -- Thief - INFANTRY_MEDI=8 -- Field Medic - INFANTRY_GNRL=9 -- General - INFANTRY_DOG=10 -- Attack Dog - INFANTRY_C1=11 -- Joe - INFANTRY_C2=12 -- Barry - INFANTRY_C3=13 -- Shelly - INFANTRY_C4=14 -- Maria - INFANTRY_C5=15 -- Karen - INFANTRY_C6=16 -- Steve - INFANTRY_C7=17 -- Phil - INFANTRY_C8=18 -- Dwight - INFANTRY_C9=19 -- Erik - INFANTRY_C10=20 -- Scientist - INFANTRY_EINSTEIN=21 -- Prof. Einstein - INFANTRY_DELPHI=22 -- Special 1 - INFANTRY_CHAN=23 -- Special 2 - + InfantryTypes={ + E1=0, -- Rifle Infantry + E2=1, -- Grenadier + E3=2, -- Rocket Soldier + E4=3, -- Flamethrower + E6=4, -- Engineer + E7=5, -- Tanya + SPY=6, -- Spy + THF=7, -- Thief + MEDI=8, -- Field Medic + GNRL=9, -- General + DOG=10, -- Attack Dog + C1=11, -- Joe + C2=12, -- Barry + C3=13, -- Shelly + C4=14, -- Maria + C5=15, -- Karen + C6=16, -- Steve + C7=17, -- Phil + C8=18, -- Dwight + C9=19, -- Erik + C10=20, -- Scientist + EINSTEIN=21, -- Prof. Einstein + DELPHI=22, -- Special 1 + CHAN=23 -- Special 2 + } + -- ********************************************************* -- * * -- * Vehicle * -- * * -- ********************************************************* - VEHICLE_4TNK=0 -- Mammoth Tank - VEHICLE_3TNK=1 -- Heavy Tank - VEHICLE_2TNK=2 -- Medium Tank - VEHICLE_1TNK=3 -- Light Tank - VEHICLE_APC=4 -- Armoured Personnel Carrier - VEHICLE_MNLY=5 -- Mine Layer - VEHICLE_JEEP=6 -- Ranger - VEHICLE_HARV=7 -- Ore Truck - VEHICLE_ARTY=8 -- Artillery - VEHICLE_MRJ=9 -- Mobile Radar Jammer - VEHICLE_MGG=10 -- Mobile Gap Generator - VEHICLE_MCV=11 -- Mobile Construction Vehicle - VEHICLE_2VRL=12 -- V2 Rocket Launcher - VEHICLE_TRUK=13 -- Convoy Truck + VehicleTypes={ + _4TNK=0, -- Mammoth Tank + _3TNK=1, -- Heavy Tank + _2TNK=2, -- Medium Tank + _1TNK=3, -- Light Tank + APC=4, -- Armoured Personnel Carrier + MNLY=5, -- Mine Layer + JEEP=6, -- Ranger + HARV=7, -- Ore Truck + ARTY=8, -- Artillery + MRJ=9, -- Mobile Radar Jammer + MGG=10, -- Mobile Gap Generator + MCV=11, -- Mobile Construction Vehicle + _2VRL=12, -- V2 Rocket Launcher + TRUK=13, -- Convoy Truck -- Counterstrike only: - VEHICLE_ANT1=14 -- First ant type - VEHICLE_ANT2=15 -- Second ant type - VEHICLE_ANT3=16 -- Third ant type + ANT1=14, -- First ant type + ANT2=15, -- Second ant type + ANT3=16 -- Third ant type + } -- ********************************************************* -- * * @@ -120,159 +153,183 @@ -- * * -- ********************************************************* - AIRCRAFT_TRAN=0 -- Chinook Helicopter - AIRCRAFT_BADR=1 -- Badger Bomber - AIRCRAFT_U2=2 -- Spy Plane - AIRCRAFT_MIG=3 -- MIG Attack Plane - AIRCRAFT_YAK=4 -- Yak Attack Plane - AIRCRAFT_HELI=5 -- Longbow Helicopter - AIRCRAFT_HIND=6 -- Hind Helicopter - - -- ********************************************************* - -- * * - -- * Houses (players) * - -- * * - -- ********************************************************* - - HOUSE_SPAIN= 0 -- YELLOW/GOLD - HOUSE_GREECE=1 -- BLUE-GREY - HOUSE_USSR=2 -- RED - HOUSE_ENGLAND=3 -- GREEN - HOUSE_UKRAINE=4 -- ORANGE - HOUSE_GERMANY=5 -- KHAKI/LIGHT BROWN - HOUSE_FRANCE=6 -- AQUA - HOUSE_TURKEY=7 -- RED-OCHRE - HOUSE_GOODGUY=8 -- BLUE-GREY - HOUSE_BADGUY=9 -- RED - HOUSE_NEUTRAL=10 -- YELLOW/GOLD - HOUSE_SPECIAL=11 -- YELLOW/GOLD - HOUSE_MULTI1=12 -- YELLOW/GOLD - HOUSE_MULTI2=13 -- BLUE-GREY - HOUSE_MULTI3=14 -- RED - HOUSE_MULTI4=15 -- GREEN - HOUSE_MULTI5=16 -- ORANGE - HOUSE_MULTI6=17 -- KHAKI/LIGHT BROWN - HOUSE_MULTI7=18 -- AQUA - HOUSE_MULTI8=19 -- RED-OCHRE - - -- ********************************************************* - -- * * - -- * Special weapons * - -- * * - -- ********************************************************* - SPECIAL_WEAPON_SONAR=0 - SPECIAL_WEAPON_NUKE=1 - SPECIAL_WEAPON_CHRONO=2 - SPECIAL_WEAPON_PARABOMB=3 - SPECIAL_WEAPON_PARATROOPS=4 - SPECIAL_WEAPON_SPY_PLANE=5 - SPECIAL_WEAPON_IRON_CURTAIN=6 - SPECIAL_WEAPON_GPS=7 - - -- ********************************************************* - -- * * - -- * Target types (for use with DesignatePreferredTarget) * - -- * * - -- ********************************************************* - TARGET_TYPE_ANYTHING=1 - TARGET_TYPE_BUILDINGS=2 - TARGET_TYPE_HARVESTERS=3 - TARGET_TYPE_INFANTRY=4 - TARGET_TYPE_VEHICLES=5 - TARGET_TYPE_SHIPS=6 - TARGET_TYPE_FACTORIES=7 - TARGET_TYPE_BASE_DEFENCES=8 - TARGET_TYPE_BASE_THREATS=9 - TARGET_TYPE_POWER=10 - TARGET_TYPE_FAKE_BUILDINGS=11 - - -- ********************************************************* - -- * * - -- * Trigger persistance * - -- * * - -- ********************************************************* - TRIGGER_VOLATILE=0 - TRIGGER_SEMI_PERSISTENT=1 - TRIGGER_PERSISTENT=2 - - -- ********************************************************* - -- * * - -- * Attribite Types * - -- * * - -- ********************************************************* - ATTRIBUTE_NONE=0 - ATTRIBUTE_STRENGTH=1 -- Object attribute - ATTRIBUTE_MAX_STRENGTH=2 -- Definition attribute - ATTRIBUTE_COST=3 -- Definition attribute - ATTRIBUTE_SIGHT_RANGE=4 -- Definition attribute - ATTRIBUTE_TECH_LEVEL=5 -- Definition attribute - ATTRIBUTE_ARMOR=6 - ATTRIBUTE_PRIMARY_WEAPON=7 - ATTRIBUTE_SECONDARY_WEAPON=8 - ATTRIBUTE_SPEED=9 - ATTRIBUTE_MAX_SPEED=10 - ATTRIBUTE_MAX_AMMO=11 - ATTRIBUTE_ROTATION_SPEED=12 - ATTRIBUTE_IS_CRUSHABLE=13 - ATTRIBUTE_IS_STEALTHY=14 - ATTRIBUTE_IS_SELECTABLE=15 - ATTRIBUTE_IS_LEGAL_TARGET=16 - ATTRIBUTE_IS_REPAIRABLE=17 - ATTRIBUTE_IS_SELF_HEALING=18 - ATTRIBUTE_IS_EXPLODING=19 - ATTRIBUTE_HAS_CREW=20 - ATTRIBUTE_MAX_PASSENGERS=21 - + AircraftTypes={ + TRAN=0, -- Chinook Helicopter + BADR=1, -- Badger Bomber + U2=2, -- Spy Plane + MIG=3, -- MIG Attack Plane + YAK=4, -- Yak Attack Plane + HELI=5, -- Longbow Helicopter + HIND=6, -- Hind Helicopter + } + -- ********************************************************* -- * * -- * Armor Types * -- * * -- ********************************************************* - ARMOR_NONE=0 - ARMOR_WOOD=1 - ARMOR_ALUMINUM=2 - ARMOR_STEEL=3 - ARMOR_CONCRETE=4 - + ArmorTypes={ + NONE=0, + WOOD=1, + ALUMINUM=2, + STEEL=3, + CONCRETE=4 + } + -- ********************************************************* -- * * -- * Weapon Types * -- * * -- ********************************************************* - WEAPON_COLT45=0 - WEAPON_ACK_ACK=1 - WEAPON_VULCAN=2 - WEAPON_MAVERICK=3 - WEAPON_CAMERA=4 - WEAPON_FIREBALL=5 - WEAPON_RIFLE=6 - WEAPON_CHAIN_GUN=7 - WEAPON_PISTOL=8 - WEAPON_M16=9 - WEAPON_DRAGON=10 - WEAPON_HELLFIRE=11 - WEAPON_GRENADE=12 - WEAPON_75MM=13 - WEAPON_90MM=14 - WEAPON_105MM=15 - WEAPON_120MM=16 - WEAPON_TURRET_GUN=17 - WEAPON_MAMMOTH_TUSK=18 - WEAPON_155MM=19 - WEAPON_M60MG=20 - WEAPON_NAPALM=21 - WEAPON_TESLA_ZAP=22 - WEAPON_NIKE=23 - WEAPON_8INCH=24 - WEAPON_STINGER=25 - WEAPON_TORPEDO=26 - WEAPON_2INCH=27 - WEAPON_DEPTH_CHARGE=28 - WEAPON_PARA_BOMB=29 - WEAPON_DOGJAW=30 - WEAPON_HEAL=31 - WEAPON_SCUD=32 - WEAPON_FLAMER=33 - WEAPON_REDEYE=34 + WeaponTypes={ + NONE=-1, + COLT45=0, + ACK_ACK=1, + VULCAN=2, + MAVERICK=3, + CAMERA=4, + FIREBALL=5, + RIFLE=6, + CHAIN_GUN=7, + PISTOL=8, + M16=9, + DRAGON=10, + HELLFIRE=11, + GRENADE=12, + _75MM=13, + _90MM=14, + _105MM=15, + _120MM=16, + TURRET_GUN=17, + MAMMOTH_TUSK=18, + _155MM=19, + M60MG=20, + NAPALM=21, + TESLA_ZAP=22, + NIKE=23, + _8INCH=24, + STINGER=25, + TORPEDO=26, + _2INCH=27, + DEPTH_CHARGE=28, + PARA_BOMB=29, + DOGJAW=30, + HEAL=31, + SCUD=32, + FLAMER=33, + REDEYE=34 + } + + + + -- ********************************************************* + -- * * + -- * Special weapons * + -- * * + -- ********************************************************* + SpecialWeapons={ + Sonar=0, + Nuke=1, + Chrono=2, + Parabomb=3, + Paratroops=4, + SpyPlane=5, + IronCurtain=6, + GPS=7 + } + + -- ********************************************************* + -- * * + -- * Target types (for use with DesignatePreferredTarget) * + -- * * + -- ********************************************************* + TargetTypes={ + Anything=1, + Buildings=2, + Harvesters=3, + Infantry=4, + Vehicles=5, + Ships=6, + Factories=7, + BaseDefences=8, + BaseThreats=9, + Power=10, + FakeBuildings=11 + } + + -- ********************************************************* + -- * * + -- * Trigger persistance * + -- * * + -- ********************************************************* + PersistenceTypes={ + Volatile=0, + SemiPersistent=1, + Persistent=2 + } + + -- ********************************************************* + -- * * + -- * Attribite Types * + -- * * + -- ********************************************************* + Attributes = { + Type=0, + Strength=1, -- Object attribute + MaxStrength=2, -- Definition attribute + Cost=3, -- Definition attribute + SightRange=4, -- Definition attribute + TechLevel=5, -- Definition attribute + Armor=6, + PrimaryWeapon=7, + SecondaryWeapon=8, + Speed=9, + MaxSpeed=10, + MaxAmmo=11, + RotationSpeed=12, + IsCrushable=13, + IsStealthy=14, + IsSelectable=15, + IsLegalTarget=16, + IsRepairable=17, + IsSelfHealing=18, + Explodes=19, + HasCrew=20, + MaxPassengers=21, + IsRepairing=22, + + -- Building Specific + Capacity=23, + Power=24, + Sellable=25, - \ No newline at end of file + -- Unit Specific + IsCrateGoodie=26, + IsCrusher=27, + IsHarvest=28, + IsRadarEquipped=29, + IsJammer=30, + IsGapper=31, + + -- Infantry Specific + IsFemale=32, + Capture=33, + IsFraidyCat=34, + IsCivilian=35, + IsBomber=36, + IsDog=37 + + } + + -- ********************************************************* + -- * * + -- * Fear Type Attribute Values * + -- * * + -- ********************************************************* + FearTypes={ + None=0, -- No fear at all (default state). + Anxious=10, -- Something makes them scared. + Scared=100, -- Scared enough to take cover. + Panic=200, -- Run away! Run away! + Maximum=255 -- Scared to death. + } \ No newline at end of file