diff --git a/src/action/action_attack.cpp b/src/action/action_attack.cpp index 8b02d496e..6de7a80ba 100644 --- a/src/action/action_attack.cpp +++ b/src/action/action_attack.cpp @@ -336,7 +336,7 @@ CUnit *const COrder_Attack::BestTarget(const CUnit &unit, CUnit *const target1, Assert(target1 != NULL); Assert(target2 != NULL); - return (Preference.SimplifiedAutoTargeting + return (GameSettings.SimplifiedAutoTargeting ? ((TargetPriorityCalculate(&unit, target1) > TargetPriorityCalculate(&unit, target2)) ? target1 : target2) : ((ThreatCalculate(unit, *target1) < ThreatCalculate(unit, *target2)) ? target1 : target2)); } @@ -447,7 +447,7 @@ void COrder_Attack::SetAutoTarget(CUnit &unit, CUnit *target) this->SkirmishRange = this->Range; } // Set threshold value only for aggressive units (Prevent to change target) - if (!Preference.SimplifiedAutoTargeting && target->IsAgressive()) + if (!GameSettings.SimplifiedAutoTargeting && target->IsAgressive()) { unit.Threshold = 30; } @@ -503,7 +503,7 @@ bool COrder_Attack::AutoSelectTarget(CUnit &unit) if (unit.UnderAttack && !newTarget->IsAgressive()) { return true; } - if (Preference.SimplifiedAutoTargeting) { + if (GameSettings.SimplifiedAutoTargeting) { const int goal_priority = TargetPriorityCalculate(&unit, goal); const int newTarget_priority = TargetPriorityCalculate(&unit, newTarget); diff --git a/src/ai/ai_resource.cpp b/src/ai/ai_resource.cpp index 6ca25d3f3..51801b6da 100644 --- a/src/ai/ai_resource.cpp +++ b/src/ai/ai_resource.cpp @@ -34,6 +34,7 @@ -- Includes ----------------------------------------------------------------------------*/ +#include "settings.h" #include "stratagus.h" #include "ai_local.h" @@ -806,7 +807,7 @@ static bool AiUpgradeTo(const CUnitType &type, CUnitType &what) { std::vector<CUnit *> table; - if (Preference.AiChecksDependencies || IsNetworkGame()) { + if (GameSettings.AiChecksDependencies || IsNetworkGame()) { if (!CheckDependByType(*AiPlayer->Player, what)) { return false; } @@ -1467,7 +1468,7 @@ void AiAddUnitTypeRequest(CUnitType &type, int count) */ void AiExplore(const Vec2i &pos, int mask) { - if (!Preference.AiExplores) { + if (!GameSettings.AiExplores) { return; } AiExplorationRequest req(pos, mask); diff --git a/src/include/settings.h b/src/include/settings.h index 794df0ad8..99256ad7a 100644 --- a/src/include/settings.h +++ b/src/include/settings.h @@ -246,7 +246,10 @@ struct Settings { struct { unsigned NoFogOfWar:1; /// if dynamic fog of war is disabled unsigned Inside:1; /// if game uses interior tileset or is generally "inside" for the purpose of obstacles - unsigned UserGameSettings:30; /// A bitfield for use by games and their settings + unsigned AiExplores:1; /// If true, AI sends explorers to search for resources (almost useless thing) + unsigned SimplifiedAutoTargeting:1; /// Use alternate target choosing algorithm for auto attack mode (idle, attack-move, patrol, etc.) + unsigned AiChecksDependencies:1; /// If false, the AI can do upgrades even if the dependencies are not met. This can be desirable to simplify AI scripting. + unsigned UserGameSettings:27; /// A bitfield for use by games and their settings }; uint32_t _Bitfield; }; @@ -340,6 +343,9 @@ struct Settings { DefeatReveal = RevealTypes::cAllUnits; NoFogOfWar = 0; Inside = 0; + AiExplores = 1; + AiChecksDependencies = 0; + SimplifiedAutoTargeting = 0; UserGameSettings = 0; } }; diff --git a/src/include/unit.h b/src/include/unit.h index 755a67382..8f5db6602 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -36,6 +36,7 @@ -- Includes ----------------------------------------------------------------------------*/ +#include "settings.h" #include <vector> #ifndef __UNITTYPE_H__ @@ -445,10 +446,10 @@ class CPreference public: CPreference() : ShowSightRange(false), ShowReactionRange(false), ShowAttackRange(false), ShowMessages(true), ShowNoSelectionStats(true), BigScreen(false), - PauseOnLeave(true), AiExplores(true), GrayscaleIcons(false), + PauseOnLeave(true), GrayscaleIcons(false), IconsShift(false), StereoSound(true), MineNotifications(false), - DeselectInMine(false), NoStatusLineTooltips(false), SimplifiedAutoTargeting(false), - AiChecksDependencies(false), SelectionRectangleIndicatesDamage(false), + DeselectInMine(false), NoStatusLineTooltips(false), + SelectionRectangleIndicatesDamage(false), IconFrameG(NULL), PressedIconFrameG(NULL), HardwareCursor(false), ShowOrders(0), ShowNameDelay(0), ShowNameTime(0), AutosaveMinutes(5) {}; @@ -459,15 +460,12 @@ public: bool ShowNoSelectionStats; /// Show stats when no selection is active bool BigScreen; /// If true, shows the big screen(without panels) bool PauseOnLeave; /// If true, game pauses when cursor is gone - bool AiExplores; /// If true, AI sends explorers to search for resources (almost useless thing) bool GrayscaleIcons; /// Use grayscaled icons for unavailable units, upgrades, etc bool IconsShift; /// Shift icons slightly when you press on them bool StereoSound; /// Enables/disables stereo sound effects bool MineNotifications; /// Show mine is running low/depleted messages bool DeselectInMine; /// Deselect peasants in mines bool NoStatusLineTooltips; /// Don't show messages on status line - bool SimplifiedAutoTargeting; /// Use alternate target choosing algorithm for auto attack mode (idle, attack-move, patrol, etc.) - bool AiChecksDependencies; /// If false, the AI can do upgrades even if the dependencies are not met. This can be desirable to simplify AI scripting. bool HardwareCursor; /// If true, uses the hardware to draw the cursor. Shaders do no longer apply to the cursor, but this way it's decoupled from the game refresh rate bool SelectionRectangleIndicatesDamage; /// If true, the selection rectangle interpolates color to indicate damage @@ -475,9 +473,27 @@ public: int ShowNameDelay; /// How many cycles need to wait until unit's name popup will appear. int ShowNameTime; /// How many cycles need to show unit's name popup. int AutosaveMinutes; /// Autosave the game every X minutes; autosave is disabled if the value is 0 - CGraphic *IconFrameG; CGraphic *PressedIconFrameG; + +#if USING_TOLUAPP + // these are "preferences" in the sense that the user wants to set these + // persistently across launches for single player games. However, they are + // relevant for network sync and replays, so the actually relevant storage + // is in GameSettings, and we just have properties for the lua code here +private: + bool AiExplores; + bool SimplifiedAutoTargeting; + bool AiChecksDependencies; + +public: + bool get_AiExplores() { return AiExplores; } + void set_AiExplores(bool v) { AiExplores = GameSettings.AiExplores = v; } + bool get_SimplifiedAutoTargeting() { return SimplifiedAutoTargeting; } + void set_SimplifiedAutoTargeting(bool v) { SimplifiedAutoTargeting = GameSettings.SimplifiedAutoTargeting = v; } + bool get_AiChecksDependencies() { return AiChecksDependencies; } + void set_AiChecksDependencies(bool v) { AiChecksDependencies = GameSettings.AiChecksDependencies = v; } +#endif }; extern CPreference Preference; diff --git a/src/map/fov.cpp b/src/map/fov.cpp index a73a5afaa..efea78a82 100644 --- a/src/map/fov.cpp +++ b/src/map/fov.cpp @@ -137,7 +137,7 @@ void CFieldOfView::Refresh(const CPlayer &player, const CUnit &unit, const Vec2i if (!range) { return; } - if (GameSettings.FoV == FieldOfViewTypes::cShadowCasting && !unit.Type->AirUnit) { + if (GameSettings.FoV == FieldOfViewTypes::cShadowCasting && !unit.Type->AirUnit) { /// FIXME: add high-/lowground OpaqueFields = unit.Type->BoolFlag[ELEVATED_INDEX].value ? 0 : this->Settings.OpaqueFields; if (GameSettings.Inside) { diff --git a/src/network/commands.cpp b/src/network/commands.cpp index bea363402..e1dc5a375 100644 --- a/src/network/commands.cpp +++ b/src/network/commands.cpp @@ -806,7 +806,7 @@ void ExecExtendedCommand(unsigned char type, int status, case ExtendedMessageAutoTargetingDB: /// arg1: 0:true / 1:false if (arg1 == 0 || arg1 == 1) { - Preference.SimplifiedAutoTargeting = arg1 ? true : false; + GameSettings.SimplifiedAutoTargeting = arg1 ? true : false; /// CommandLog(...); } else { /// CommandLog(...); diff --git a/src/tolua/unit.pkg b/src/tolua/unit.pkg index 0e6ba23d1..4b220e26c 100644 --- a/src/tolua/unit.pkg +++ b/src/tolua/unit.pkg @@ -25,15 +25,15 @@ class CPreference bool ShowNoSelectionStats; bool BigScreen; bool PauseOnLeave; - bool AiExplores; + tolua_property bool AiExplores; bool GrayscaleIcons; bool IconsShift; bool StereoSound; bool MineNotifications; bool DeselectInMine; bool NoStatusLineTooltips; - bool SimplifiedAutoTargeting; - bool AiChecksDependencies; + tolua_property bool SimplifiedAutoTargeting; + tolua_property bool AiChecksDependencies; bool HardwareCursor; bool SelectionRectangleIndicatesDamage; diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp index f0dd3f3db..84ceef76a 100644 --- a/src/unit/script_unit.cpp +++ b/src/unit/script_unit.cpp @@ -1516,7 +1516,7 @@ static int CclEnableSimplifiedAutoTargeting(lua_State *l) LuaCheckArgs(l, 1); const bool isSimplified = LuaToBoolean(l, 1); if (!IsNetworkGame()) { - Preference.SimplifiedAutoTargeting = isSimplified; + GameSettings.SimplifiedAutoTargeting = isSimplified; } else { NetworkSendExtendedCommand(ExtendedMessageAutoTargetingDB, int(isSimplified), 0, 0, 0, 0); diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index ab7d853c5..21cedacae 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -2553,7 +2553,7 @@ void DestroyAllInside(CUnit &source) int ThreatCalculate(const CUnit &unit, const CUnit &dest) { - if (Preference.SimplifiedAutoTargeting) { + if (GameSettings.SimplifiedAutoTargeting) { // Original algorithm return smaler values for better targets return -TargetPriorityCalculate(&unit, &dest); } @@ -3157,7 +3157,7 @@ void HitUnit(CUnit *attacker, CUnit &target, int damage, const Missile *missile) return; } - if (Preference.SimplifiedAutoTargeting) { + if (GameSettings.SimplifiedAutoTargeting) { target.Threshold = 0; } else { const int threshold = 30; diff --git a/src/unit/unit_find.cpp b/src/unit/unit_find.cpp index c83fd647c..52d2d6eb0 100644 --- a/src/unit/unit_find.cpp +++ b/src/unit/unit_find.cpp @@ -692,12 +692,12 @@ private: CUnit *Find(Iterator begin, Iterator end) const { CUnit *enemy = NULL; - int best_cost = Preference.SimplifiedAutoTargeting ? INT_MIN : INT_MAX; + int best_cost = GameSettings.SimplifiedAutoTargeting ? INT_MIN : INT_MAX; for (Iterator it = begin; it != end; ++it) { - int cost = Preference.SimplifiedAutoTargeting ? TargetPriorityCalculate(attacker, *it) : ComputeCost(*it); + int cost = GameSettings.SimplifiedAutoTargeting ? TargetPriorityCalculate(attacker, *it) : ComputeCost(*it); - if (Preference.SimplifiedAutoTargeting ? (cost > best_cost) : (cost < best_cost)) { + if (GameSettings.SimplifiedAutoTargeting ? (cost > best_cost) : (cost < best_cost)) { enemy = *it; best_cost = cost; } @@ -975,7 +975,7 @@ public: CUnit *Find(std::vector<CUnit *> &table) { - if (!Preference.SimplifiedAutoTargeting) { + if (!GameSettings.SimplifiedAutoTargeting) { FillBadGood(*attacker, range, good, bad, size).Fill(table.begin(), table.end()); } return Find(table.begin(), table.end()); @@ -1005,7 +1005,7 @@ private: return; } - if (Preference.SimplifiedAutoTargeting) { + if (GameSettings.SimplifiedAutoTargeting) { const int cost = TargetPriorityCalculate(attacker, dest); if (cost > best_cost) { best_unit = dest;