Download Data/ClassDef-Effects.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 285 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/Data/ClassDef-Effects.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/Data/ClassDef-Effects.lua
-
curl -L -o ClassDef-Effects.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/Data/ClassDef-Effects.lua
285 kB
| -- ========== GENERATED BY ClassDef Editor (Ctrl-Alt-F3) DO NOT EDIT MANUALLY! ========== | |
| PlaceObj('EffectDef', { | |
| id = "ApplyGuiltyOrRighteous", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Apply guilty or righteous effect on unit", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Apply guilty or righteous effect on unit", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| ApplyGuiltyOrRighteousEffect(self.effectType) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ApplyGuiltyOrRighteous', {}), | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "effectType", | |
| 'name', "effectType", | |
| 'help', "Whether the effect is possive or negative (proud or guilty)", | |
| 'default', "positive", | |
| 'items', function (self) return { "positive", "negative" } end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetUIText", | |
| 'params', "effect", | |
| 'code', function (self, effect) | |
| if self.effectType == "positive" then | |
| return T(235589045798, "Some mercs may <em>approve</em> of this.") | |
| else | |
| return T(596690068964, "Some mercs may <em>regret</em> this.") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local helperText = self.effectType == "positive" and "positive(righteous)" or "negative(guilty)" | |
| return Untranslated("Apply " .. helperText .. " effect on unit" ) | |
| end, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| "BanterFunctionObjectBase", | |
| }, | |
| id = "BanterSetUnitInteraction", | |
| PlaceObj('PropertyDefPresetIdList', { | |
| 'id', "Banters", | |
| 'name', "Banters", | |
| 'help', "List of banters to play.", | |
| 'preset_class', "BanterDef", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Enabled", | |
| 'name', "Enabled", | |
| 'help', "Whether the banter is enabled.", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Banters then | |
| return "No banters" | |
| end | |
| for i,banter_id in ipairs(self.Banters) do | |
| if not Banters[banter_id] then | |
| return "Invalid banter ID " .. banter_id | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set banters to play when interacting with unit.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set banters to play when interacting with unit.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| local triggered = self:MatchMapUnits(obj, context) | |
| if not triggered or not context.target_units then return end | |
| for i,unit in ipairs(context.target_units) do | |
| unit.banters = self.Enabled and table.copy(self.Banters) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'TestObject', PlaceObj('BanterSetUnitInteraction', { | |
| Banters = { | |
| "AbuserPoacher", | |
| }, | |
| TargetUnit = "North", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "BobbyRayConsumeStock", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Bobby Ray", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(161499412562, --[[EffectDef Effects BobbyRayConsumeStock value]] "Consumes some of Bobby Ray's stock"), | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Consumes some of Bobby Ray's stock to simulate other buyers.\n\nEach item is evaluated independently.\nA roll with ItemConsumeProbability change determines whether an item will be purchased or not.\nIf chosen, a percentage of its stock is consumed (at least one unit is always consumed), between Min and Max StockConsumption values.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| BobbyRayStoreConsumeRandomStock(self.ItemConsumeProbability, self.MinimumStockConsumption, self.MaximumStockConsumption) | |
| end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "ItemConsumeProbability", | |
| 'help', "Probability of each item to get picked for consumption", | |
| 'extra_code', "default = const.BobbyRay.FakePurchase_PickProbability", | |
| 'default', 13, | |
| 'scale', "%", | |
| 'slider', true, | |
| 'min', 0, | |
| 'max', 100, | |
| 'modifiable', true, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "MinimumStockConsumption", | |
| 'help', "Minimum percentage of available stock consumed", | |
| 'extra_code', "default = const.BobbyRay.FakePurchase_StockConsumedMin", | |
| 'default', 25, | |
| 'scale', "%", | |
| 'slider', true, | |
| 'min', 0, | |
| 'max', 100, | |
| 'modifiable', true, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "MaximumStockConsumption", | |
| 'help', "Maximum percentage of available stock consumed (if only one unit is available, it is always consumed)", | |
| 'extra_code', "default = const.BobbyRay.FakePurchase_StockConsumedMax", | |
| 'default', 50, | |
| 'scale', "%", | |
| 'slider', true, | |
| 'min', 0, | |
| 'max', 100, | |
| 'modifiable', true, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('BobbyRaySetState', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "BobbyRayRestockShop", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Bobby Ray", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(879032376225, --[[EffectDef Effects BobbyRayRestockShop value]] "Restocks Bobby Ray's Shop"), | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Restocks Bobby Ray's Shop\n\nFrom the whole pool of items that can appear in the shop (with respect to tier), a percentage between Restock_PercentageMin and Restock_PercentageMax (see the const editor, with separate variables controlling standard and used items) is restocked.\n\nThe above values are further multiplied by this effect's RestockModifier. Values below 100 decrease the number of items picked for restocking, values above 100 increase it.\n\nItems already present in the shop get their stock recalculated (never decreased, but restocking may have no effect), otherwise a new entry is created.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| BobbyRayStoreRestock(self.RestockModifier_Standard, self.RestockModifier_Used) | |
| end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "RestockModifier_Standard", | |
| 'help', "Modifier to the number of standard items chosen for restock per event (applied to the Restock_StandardPercentage variables defined in the const editor).\n\n100 causes no change.", | |
| 'default', 100, | |
| 'scale', "%", | |
| 'slider', true, | |
| 'min', 10, | |
| 'max', 500, | |
| 'modifiable', true, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "RestockModifier_Used", | |
| 'help', "Modifier to the number of used items chosen for restock per event (applied to the Restock_UsedPercentage variables defined in the const editor).\n\n100 causes no change.", | |
| 'default', 100, | |
| 'scale', "%", | |
| 'slider', true, | |
| 'min', 10, | |
| 'max', 500, | |
| 'modifiable', true, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('BobbyRaySetState', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "BobbyRaySetState", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Bobby Ray", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(746538815418, --[[EffectDef Effects BobbyRaySetState value]] "Sets shop tier availability"), | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Possible values are:\nClosed (default, 0)\nTier-i unlocked (i>=1)", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetQuestVar(QuestGetState("BobbyRayQuest"), "UnlockedTier", self.State == "Closed" and 0 or self.State) | |
| end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "State", | |
| 'default', "Closed", | |
| 'items', function (self) return {"Closed", 1, 2, 3, 4, 5, 6, 7, 8} end, | |
| 'translate', true, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('BobbyRaySetState', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "ChangeTiredness", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| "UnitData", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Changes a unit's Energy", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Changes a unit's Energy", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOfClasses(obj, "Unit", "UnitData") and not obj:IsDead() then | |
| obj:ChangeTired(self.delta) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ChangeTiredness', {}), | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "delta", | |
| 'name', "Delta", | |
| 'default', 0, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "CityGrantLoyalty", | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "City", | |
| 'help', "Change loyalty of the specified city", | |
| 'items', function (self) return table.map(GetCurrentCampaignPreset().Cities, "Id") end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Amount", | |
| 'help', "Amount of loyalty to change with.", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "SpecialConversationMessage", | |
| 'name', "Special Conversation Message", | |
| 'help', "The message to display in the log when the effect is executed from a conversation phrase.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Add <Amount> to city <u(City)> loyalty.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Grants a given value of loyalty to a given city. The loyalty can be negative.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.City then | |
| return "Missing City" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local msgPrefix = false | |
| if IsKindOf(obj, "QuestsDef") and QuestIsBoolVar(obj,"Completed",true) then | |
| msgPrefix = T{858740141061, "Mission <DisplayName> completed", DisplayName = obj.DisplayName} | |
| else | |
| msgPrefix = self.SpecialConversationMessage or "" | |
| end | |
| CityModifyLoyalty(self.City, self.Amount, msgPrefix) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local city = gv_Cities and gv_Cities[self.City] | |
| local city_name =city and city.DisplayName or Untranslated(self.City) | |
| if self.Amount>0 then | |
| return T{571842717111, "Gained <em><Amount> Loyalty</em> with <em><City></em>",Amount = self.Amount, City = city_name} | |
| elseif self.Amount<0 then | |
| return T{749649970601, "Lost <em><Amount> Loyalty</em> with <em><City></em>",Amount = -self.Amount, City = city_name} | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('CityGrantLoyalty', { | |
| City = "ErnieVillage", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "CompleteGuardpostObjective", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "GuardpostObjective", | |
| 'name', "GuardpostObjective", | |
| 'preset_class', "GuardpostObjective", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Complete guardpost objective <u(GuardpostObjective)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Complete a guardpost objective, weakening the guardpost.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetGuardpostObjectiveCompleted(self.GuardpostObjective) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('CompleteGuardpostObjective', { | |
| GuardpostObjective = "AbandonedMansion", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sectors", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "ConversateWithUnit", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Group", | |
| 'name', "Group", | |
| 'help', "The group to affect. If left as default (empty) the interactable the effect is attached to will be affected.", | |
| 'default', "", | |
| 'items', function (self) return GridMarkerGroupsCombo() end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Group then | |
| return "No group" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Start a conversation with the unit of group", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Start a conversation with the unit of group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local interactable = false | |
| local allInGroup = Groups[self.Group] | |
| for i, obj in ipairs(allInGroup) do | |
| if IsKindOf(obj, "Interactable") then | |
| interactable = obj | |
| break | |
| end | |
| end | |
| if not interactable then return end | |
| local unitsOnMap = GetAllPlayerUnitsOnMap() | |
| local closestUnit = false | |
| local closestDistance = false | |
| for i, u in ipairs(unitsOnMap) do | |
| if not CanInteractWith_SyncHelper(u, interactable) then goto continue end | |
| local dist = IsValid(u) and u:GetDist(interactable) | |
| if not closestDistance or dist < closestDistance then | |
| closestDistance = dist | |
| closestUnit = u | |
| end | |
| ::continue:: | |
| end | |
| if closestUnit then | |
| local conversation = FindEnabledConversation(interactable) | |
| if conversation then | |
| OpenConversationDialog(closestUnit, conversation, false, "interaction", interactable) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'TestObject', PlaceObj('ConversateWithUnit', { | |
| Group = "12Chairs_ChairMarker", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "CustomCodeEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Execute custom code", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Executes custom code", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not self.custom_code then return end | |
| local custom_code_func, err = load(self.custom_code) | |
| if custom_code_func then | |
| -- Procall to ensure there isnt a yield (it cant be saved) | |
| procall(custom_code_func) | |
| else | |
| assert(custom_code_func) | |
| print(err) | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'category', "", | |
| 'id', "custom_code", | |
| 'name', "Custom Code", | |
| 'help', "Runs this code.", | |
| 'translate', false, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('CustomCodeEffect', {}), | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if self.custom_code then | |
| local func, err = load(self.custom_code) | |
| if not func then | |
| return err | |
| end | |
| end | |
| end, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "DisableInteractionMarkerEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Disable interaction markers of a specific group.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local groupName = self.Group | |
| if groupName == "" then | |
| if context and context.interactable and IsKindOf(context.interactable, "Interactable") then | |
| context.interactable.enabled = self.Negate | |
| elseif IsKindOf(obj, "Interactable") then | |
| obj.enabled = self.Negate | |
| else | |
| assert(not "Non interactable object with DisableInteractionMarker effect and no group.") | |
| end | |
| return | |
| end | |
| MapForEach("map", "Interactable", function(m) | |
| if table.find(m.Groups, groupName) then | |
| m.enabled = self.Negate | |
| end | |
| end) | |
| end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Group", | |
| 'name', "Group", | |
| 'help', "The group to affect. If left as default (empty) the interactable the effect is attached to will be affected.", | |
| 'default', "", | |
| 'items', function (self) return GridMarkerGroupsCombo() end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('DisableInteractionMarkerEffect', { | |
| Group = "GameIntro", | |
| Negate = true, | |
| }), | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Negate", | |
| 'name', "Negate", | |
| 'help', "Enable interaction markers instead.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactable", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.Group == "" then | |
| if self.Negate then | |
| return T(299761711576, "Enable attached interaction marker.") | |
| else | |
| return T(311484226676, "Disable attached interaction marker.") | |
| end | |
| end | |
| if self.Negate then | |
| return T{697268621451, "Enable interaction markers of group <u(Group)>", self} | |
| else | |
| return T{571476004863, "Disable interaction markers of group <u(Group)>", self} | |
| end | |
| end, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "EndSectorWarningState", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "End the current sector's Warning State", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "End the Warning State for the current sector.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if gv_SatelliteView then return end | |
| EndWarningState() | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('EndSectorWarningState', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ExecForEachUnitInSector", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Sector", | |
| 'help', "Sector id", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefNestedList', { | |
| 'id', "Effects", | |
| 'name', "Effects", | |
| 'help', "Effects to execute.", | |
| 'base_class', "Effect", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local effects = self.Effects | |
| if not effects or #effects == 0 then return true end | |
| if not context then context = {} end | |
| context.is_sector_unit = true | |
| context.target_units = {} | |
| local squads = GetSquadsInSector(self.Sector) | |
| for i, squad in ipairs(squads) do | |
| for j, unit_id in ipairs(squad.units) do | |
| local unit = gv_UnitData[unit_id] | |
| context.target_units[1] = unit | |
| for _, effect in ipairs(effects) do | |
| effect:__exec(unit, context) | |
| end | |
| end | |
| end | |
| context.is_sector_unit = false | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', 'Executes effects for all units in all squads in the given sector. Target unit effects must be with TargetUnit = "current unit"', | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "For each unit from sector '<u(Sector)>' execute all nested effects.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ExecForEachUnitInSector', { | |
| Sector = "A1", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "Explosion", | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.LocationGroup then | |
| return "Set the Location Group" | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "LocationGroup", | |
| 'name', "Location Group", | |
| 'help', "Object group defining the location of the effect.", | |
| 'items', function (self) return table.keys2(Groups) end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "ExplosionType", | |
| 'help', "What kind of grenade/mine is the explosion caused by.", | |
| 'default', "Landmine", | |
| 'items', function (self) return GrenadesComboItems({"Landmine"}) end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Damage", | |
| 'help', "Damage to be done.", | |
| 'default', 30, | |
| 'min', 0, | |
| 'max', 200, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "AreaOfEffect", | |
| 'name', "Area of Effect", | |
| 'help', "the blast range (radius) in number of tiles.", | |
| 'default', 3, | |
| 'min', 0, | |
| 'max', 20, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Noise", | |
| 'name', "Noise", | |
| 'help', "Range (in tiles) in which the explosion alerts unaware enemies.", | |
| 'template', true, | |
| 'default', 20, | |
| 'min', 0, | |
| 'max', 100, | |
| 'modifiable', true, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "AppliedEffect", | |
| 'name', "Applied Effect", | |
| 'help', "What effect to be applied on the victim when the damage is dealt.", | |
| 'preset_class', "CharacterEffectCompositeDef", | |
| 'preset_group', "Default", | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "aoeType", | |
| 'name', "AOE Type", | |
| 'help', "additional effect that happens after the explosion (optional)", | |
| 'template', true, | |
| 'default', "none", | |
| 'items', function (self) return {"none", "fire", "smoke", "teargas", "toxicgas"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(892386429862, --[[EffectDef Effects Explosion value]] "Create an explosion"), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Create an explosion", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local objs = Groups and self.LocationGroup and Groups[self.LocationGroup] or empty_table | |
| if #objs <= 0 then | |
| return | |
| end | |
| local pos = AveragePoint(objs) | |
| local weapon = PlaceObject((self.ExplosionType == "Landmine") and "Landmine" or "Grenade") | |
| weapon.AreaOfEffect = self.AreaOfEffect | |
| weapon.BaseDamage = self.Damage | |
| weapon.Noise = self.Noise | |
| weapon.AppliedEffect = self.AppliedEffect | |
| weapon.aoeType = self.aoeType | |
| local proj = PlaceObject("FXGrenade") | |
| proj:SetPos(pos) | |
| proj.fx_actor_class = self.ExplosionType | |
| CreateGameTimeThread(function() | |
| ExplosionDamage(nil, weapon, pos, proj) | |
| DoneObject(proj) | |
| DoneObject(weapon) | |
| end) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('Explosion', { | |
| LocationGroup = "Closest AmbientZoneMarker", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "FailGuardpostObjective", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "GuardpostObjective", | |
| 'name', "GuardpostObjective", | |
| 'preset_class', "GuardpostObjective", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Fail guardpost objective <u(GuardpostObjective)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Fail a guardpost objective", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetGuardpostObjectiveFailed(self.GuardpostObjective) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('CompleteGuardpostObjective', { | |
| GuardpostObjective = "AbandonedMansion", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sectors", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ForceResetAmbientLife", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Forces Reset of Ambient Life Behavior(Alt-Shift-A cheat)", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Does the same thing as the Alt + Shift + A which resets the Ambient life", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| Msg("AmbientLifeDespawn") | |
| Msg("WallVisibilityChanged") | |
| g_AmbientLifeSpawn = true | |
| Msg("AmbientLifeSpawn") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| self:__exec(obj, context) | |
| WaitMsg("AmbientLifeSpawned") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__skip", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| self:__exec(obj, context) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ForceResetAmbientLife', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "GoBerserk", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Go Berserk", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Go Berserk", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOf(obj, "Unit") and not obj:IsDead() then | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GoBerserk', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "UnitTarget", | |
| "Effect", | |
| }, | |
| group = "Effects", | |
| id = "GrantExperienceEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(785742586188, --[[EffectDef Effects GrantExperienceEffect value]] "Grant <u(Amount)> to unit <u(TargetUnit)>"), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Grant experience to units. This is to be used when a map is loaded, for satellite view use GrantExperienceSector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not context then context = {} end | |
| local units = self:MatchMapUnits(obj, context) | |
| if units and context.target_units then | |
| local amount = self.Amount | |
| if type(amount) == "string" then | |
| if const[amount] then | |
| amount = const[amount] | |
| else | |
| amount = tonumber(amount) | |
| end | |
| end | |
| RewardTeamExperience({ RewardExperience = amount }, { units = context.target_units }, self.logImportant) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "UnitCheck", | |
| 'params', "unit, obj, context", | |
| 'code', function (self, unit, obj, context) | |
| return true | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GrantExperienceEffect', { | |
| Amount = 5551, | |
| TargetUnit = "player mercs on map", | |
| }), | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "Choose one of the predefined amounts", | |
| 'default', "XPQuestReward_Small", | |
| 'items', function (self) return GetQuestRewardConstItems() end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "logImportant", | |
| 'name', "Log as Important", | |
| 'help', "Whther to show the XP gain as important message in the combat log.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "GrantExperienceSector", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(990833526031, --[[EffectDef Effects GrantExperienceSector value]] "Grant <u(Amount)> to all player units on sector <u(Sector)>"), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Grant experience to all player mercs on the specified sector.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector_id | |
| local getUnits = false | |
| if self.Sector == "current" then | |
| sector_id = gv_CurrentSectorId | |
| getUnits = not gv_SatelliteView | |
| else | |
| sector_id = self.Sector | |
| end | |
| local units = GetPlayerSectorUnits(sector_id, getUnits) | |
| if units then | |
| local amount = self.Amount | |
| if type(amount) == "string" then | |
| if const[amount] then | |
| amount = const[amount] | |
| else | |
| amount = tonumber(amount) | |
| end | |
| end | |
| RewardTeamExperience({ RewardExperience = amount }, { units = units, sector = sector_id }, self.logImportant) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| local amount = self.Amount | |
| if type(amount) == "string" and not const[amount] and not tonumber(amount) then | |
| return "Invalid amount " .. tostring(amount) .. " - should be a number or a const" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "UnitCheck", | |
| 'params', "unit, obj, context", | |
| 'code', function (self, unit, obj, context) | |
| return true | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local sector_id | |
| local getUnits = false | |
| if self.Sector == "current" then | |
| sector_id = gv_CurrentSectorId | |
| getUnits = not gv_SatelliteView | |
| else | |
| sector_id = self.Sector | |
| end | |
| local units = game and GetPlayerSectorUnits(sector_id, getUnits) or T(111137020067, "[Mercs]") | |
| local names = game and ConcatListWithAnd(table.map(units, function(o) return o.Nick; end)) or units | |
| local amount = self.Amount | |
| if type(amount) == "string" then | |
| if const[amount] then | |
| amount = const[amount] | |
| else | |
| amount = tonumber(amount) | |
| end | |
| end | |
| if amount>0 then | |
| return T{894599074999, "Gained XP: <unit> (<Amount>)",Amount = amount, unit = names} | |
| elseif amount<0 then | |
| return T{955913519115, "Lost XP: <unit> (<Amount>)",Amount = amount, unit = names} | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Sector", | |
| 'name', "Sector", | |
| 'help', "Sector", | |
| 'default', "current", | |
| 'items', function (self) return table.iappend({{text="current",value="current"}}, GetCampaignSectorsCombo()) end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "Choose one of the predefined amounts", | |
| 'default', "XPQuestReward_Small", | |
| 'items', function (self) return GetQuestRewardConstItems() end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "logImportant", | |
| 'name', "Log as Important", | |
| 'help', "Whther to show the XP gain as important message in the combat log.", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GrantExperienceSector', { | |
| Amount = 3333, | |
| Sector = "I1", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupAddStatusEffect", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Status", | |
| 'name', "Status", | |
| 'preset_class', "CharacterEffectCompositeDef", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Add <u(Status)> effect to units in group <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Add status effect to units in group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "StatusEffectObject") then | |
| unit:AddStatusEffect(self.Status) | |
| end | |
| end | |
| if not next(context.target_units) then | |
| print("GroupAddStatusEffect couldn't find group", self.TargetUnit) | |
| return | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupAddStatusEffect', { | |
| Status = "Wounded", | |
| TargetUnit = "any", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| id = "GroupAlert", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Alert units from <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Alert units from given group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local units = {} | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "Unit") then | |
| units[#units + 1] = unit | |
| end | |
| end | |
| if not next(units) then | |
| print("GroupAlert couldn't find group", self.TargetUnit) | |
| return | |
| end | |
| CreateGameTimeThread(function() | |
| gv_CombatStartFromConversation = true | |
| TriggerUnitAlert("script", units, "aware") | |
| end, units) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupAlert', { | |
| TargetUnit = "any", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| Comment = "tactical", | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupAssignToArea", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Assign units from <u(TargetUnit)> to tactical area(s)", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Assigns units from given group to tactical area(s)", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not g_TacticalMap then return end | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local reset = self.Mode == "overwrite" | |
| local area | |
| if self.Mode ~= "clear" and (#(self.IndividualAreas or empty_table) > 0) then | |
| area = self.IndividualAreas | |
| end | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "Unit") then | |
| g_TacticalMap:AssignUnit(unit, area, reset) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.Mode == "clear" or #(self.IndividualAreas or empty_table) == 0 then | |
| return Untranslated("Clear assignment for units from <u(TargetUnit)>") | |
| else | |
| local areas = "" | |
| for _, area in ipairs(self.IndividualAreas) do | |
| if #areas == 0 then | |
| areas = area | |
| else | |
| areas = areas .. ", " .. area | |
| end | |
| end | |
| if self.Mode == "add" then | |
| return Untranslated(string.format("Add areas to assignement for units from <u(TargetUnit)>: [%s]", areas)) | |
| end | |
| return Untranslated(string.format("Assign units from <u(TargetUnit)> to areas [%s]", areas)) | |
| end | |
| return self.EditorView | |
| end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Mode", | |
| 'name', "Assign Mode", | |
| 'default', "overwrite", | |
| 'items', function (self) return { "overwrite", "add", "clear" } end, | |
| }), | |
| PlaceObj('PropertyDefStringList', { | |
| 'id', "IndividualAreas", | |
| 'extra_code', 'no_edit = function(self) return self.Mode == "clear" end, no_validate = true', | |
| 'items', function (self) return GridMarkerFightAreaCombo("") end, | |
| 'max_items', 64, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupAssignToArea', {}), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupChangeName", | |
| PlaceObj('PropertyDefText', { | |
| 'id', "ChangeName", | |
| 'name', "Change Name", | |
| 'help', "Name to be changed to", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Change the name for units from <u(TargetUnit)> to <u(ChangeName)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change the name of units from given group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "Unit") then | |
| unit.Name = self.ChangeName | |
| ObjModified(unit) | |
| end | |
| end | |
| if not next(context.target_units) then | |
| print(self.id, " couldn't find any units of: ", self.TargetUnit) | |
| return | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.ChangeName then | |
| return "Set Change Name" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupChangeName', { | |
| ChangeName = T(894200980407, --[[EffectDef Effects GroupChangeName ChangeName]] "Worker"), | |
| TargetUnit = "Miners", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupChangeTiredness", | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "Mode", | |
| 'default', "Absolute", | |
| 'items', function (self) return { "Absolute", "Delta" } end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "Level", | |
| 'extra_code', 'no_edit = function(self) return self.Mode ~= "Absolute" end', | |
| 'default', 0, | |
| 'items', function (self) return UnitTirednessComboItems end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Delta", | |
| 'extra_code', 'no_edit = function(self) return self.Mode == "Absolute" end', | |
| 'default', 1, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Change Energy for units from <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change Energy for units from given group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "Unit") then | |
| if self.Mode == "Absolute" then | |
| unit:SetTired(self.Level) | |
| else | |
| unit:ChangeTired(self.Delta) | |
| end | |
| end | |
| end | |
| if not next(context.target_units) then | |
| print("GroupChangeTiredness couldn't find any units of: ", self.TargetUnit) | |
| return | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if self.Mode == "Delta" and self.Delta == 0 then | |
| return "No effect" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupChangeTiredness', { | |
| Level = 2, | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupRemoveStatusEffect", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Status", | |
| 'name', "Status", | |
| 'preset_class', "CharacterEffectCompositeDef", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Remove <u(Status)> effect from units in group <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Remove status effect from units in group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "StatusEffectObject") then | |
| o:RemoveStatusEffect(self.Status) | |
| end | |
| end | |
| if not next(context.target_units) then | |
| print("GroupRemoveStatusEffect couldn't find any units of: ", self.TargetUnit) | |
| return | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupRemoveStatusEffect', { | |
| Status = "Wounded", | |
| TargetUnit = "any", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "GroupSetAITargetModifier", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Group", | |
| 'name', "Group", | |
| 'help', "Unit group that will receive the modifier", | |
| 'default', "false", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Target", | |
| 'help', "Target unit group subject to the modifier", | |
| 'default', "false", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Modifier", | |
| 'help', "Modifier value, 100% means no modification (reset to default)", | |
| 'default', 100, | |
| 'scale', "%", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "AI target modifier for <u(Group)> against <u(Target)> <Modifier>%", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set AI Targeting modifier of a group of units against another group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if self.Modifier == 100 then | |
| if gv_AITargetModifiers[self.Group] then | |
| gv_AITargetModifiers[self.Group][self.Target] = nil | |
| if next(gv_AITargetModifiers[self.Group]) == nil then | |
| gv_AITargetModifiers[self.Group] = nil | |
| end | |
| end | |
| else | |
| gv_AITargetModifiers[self.Group] = gv_AITargetModifiers[self.Group] or {} | |
| gv_AITargetModifiers[self.Group][self.Target] = self.Modifier | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetAITargetModifier', { | |
| Group = "LegionRaider", | |
| Modifier = 1000, | |
| Target = "Igor", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupSetArchetype", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Change archetype for units from <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change archetype for units from given group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local units = {} | |
| local archetype = self.Archetype | |
| if archetype == "<default>" then | |
| archetype = nil | |
| end | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "Unit") then | |
| unit.script_archetype = archetype | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "Archetype", | |
| 'default', "<default>", | |
| 'items', function (self) return table.keys2(Archetypes, true, "<default>") end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetArchetype', { | |
| TargetUnit = "current unit", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "AnimParams", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupSetBehaviorAdvanceTo", | |
| PlaceObj('PropertyDefText', { | |
| 'id', "MarkerId", | |
| 'help', "Marker description: can specify an id.", | |
| 'translate', false, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerGroup", | |
| 'help', "Marker description: marker group.", | |
| 'default', "", | |
| 'items', function (self) return GetBehaviorGroups end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerType", | |
| 'help', "Marker description: markers type.", | |
| 'default', "Position", | |
| 'items', function (self) return GetGridMarkerTypesCombo end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "PropagateAnimParams", | |
| 'help', "AdvanceTo behavior passes the control to Roam behavior on finish and if this checked all the AnimParams here will be propagated to Roam", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(TargetUnit)> Advance(s) to the marker", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set units behavior to Advance towar a map marker.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local markers = MapGetMarkers(self.MarkerType, self.MarkerGroup, function(o) | |
| return o:IsMarkerEnabled() and ((self.MarkerId or "" == "") or o.ID == self.MarkerID) | |
| end) | |
| if #(markers or empty_table) == 0 then | |
| printf("SetBehaviorAdvanceTo didn't find any markers (type %s, group %s, id %s)", tostring(self.MarkerType), tostring(self.MarkerGroup), tostring(self.MarkerId)) | |
| return | |
| end | |
| if g_Combat then return end | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local params = self:GetAnimParams() | |
| params.PropagateAnimParams = self.PropagateAnimParams | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") and not o:IsDead() then | |
| local marker = table.interaction_rand(markers, "GridMarker", o) | |
| o:SetCommandParams("AdvanceTo", params) | |
| o:SetCommand("AdvanceTo", marker:GetHandle()) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetBehaviorAdvanceTo', { | |
| MarkerGroup = "GameIntro", | |
| MarkerId = "Start", | |
| MarkerType = "Defender", | |
| PropagateAnimParams = true, | |
| TargetUnit = "any", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "AnimParams", | |
| "UnitTarget", | |
| }, | |
| id = "GroupSetBehaviorExit", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerGroup", | |
| 'help', "Exit marker group.", | |
| 'extra_code', "no_edit = function(self) return self.closest end", | |
| 'default', "", | |
| 'items', function (self) return GetBehaviorGroups end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "closest", | |
| 'name', "Closest Available", | |
| 'help', "", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "delay", | |
| 'name', "Delay", | |
| 'default', 0, | |
| 'scale', "sec", | |
| 'min', 0, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(TargetUnit)> exit the map via <u(MarkerGroup)> marker", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Units exit the map using a specified marker", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local units = context.target_units or empty_table | |
| for i = #units, 1, -1 do | |
| if not IsKindOf(units[i], "Unit") then | |
| table.remove(units, i) | |
| end | |
| end | |
| if #units == 0 then | |
| return | |
| end | |
| local marker_group = not self.closest and self.MarkerGroup or "" | |
| local markers = MapGetMarkers("Entrance", marker_group) | |
| if not markers or #markers == 0 then | |
| return | |
| end | |
| local marker | |
| if marker_group == "" then | |
| -- pick nearest | |
| local ucenter = AveragePoint2D(units) | |
| marker = ChooseClosestObject(markers, ucenter) | |
| else | |
| -- pick random | |
| marker = table.interaction_rand(markers, "GridMarker") | |
| end | |
| local start_time = self.delay + GameTime() | |
| if g_Combat then | |
| for _, unit in ipairs(units) do | |
| if not unit:IsDead() then | |
| unit:SetBehavior("ExitMap", { marker, start_time }) | |
| end | |
| end | |
| else | |
| local params = self:GetAnimParams() | |
| for _, unit in ipairs(units) do | |
| if unit.command == "ExplosionFly" then | |
| unit:SetCommandParams("ExitMap", params) | |
| unit:SetBehavior("ExitMap", { marker, start_time }) | |
| elseif not unit:IsDead() then | |
| unit:SetCommandParams("ExitMap", params) | |
| unit:SetCommand("ExitMap", marker, start_time) | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Set behavior of <u(TargetUnit)> to ExitMap at <u(MarkerGroup)>") | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetBehaviorExit', { | |
| MarkerGroup = "East", | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "AnimParams", | |
| "UnitTarget", | |
| }, | |
| id = "GroupSetBehaviorIdle", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set behavior of <u(TargetUnit)> to Idle", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set units behavior to Idle", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local params = self:GetAnimParams() | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") and not o:IsDead() then | |
| o:SetBehavior() | |
| o:SetCommandParams("Idle", params) | |
| o:SetCommand("Idle") | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetBehaviorIdle', { | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "AnimParams", | |
| "UnitTarget", | |
| }, | |
| id = "GroupSetBehaviorPatrol", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerGroup", | |
| 'help', "Patrol markers group", | |
| 'default', "", | |
| 'items', function (self) return GetBehaviorGroups end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Repeat", | |
| 'name', "Repeat Route", | |
| 'help', "Repeat route?", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Orient", | |
| 'name', "End Orient", | |
| 'help', "Use marker orientation on the end", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(TargetUnit)> patrol(s) between <u(MarkerGroup)> markers", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set unit behavior to Patrol between markers", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local params = self:GetAnimParams() | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") and not o:IsDead() then | |
| o:SetCommandParams("Patrol", params) | |
| local behaviorParams = {self.MarkerGroup, 1, self.Repeat, self.Orient} | |
| if g_Combat then | |
| o:SetBehavior("Patrol", behaviorParams) | |
| elseif o.being_interacted_with then | |
| o:QueueCommand("Patrol", unpack_params(behaviorParams)) | |
| else | |
| o:SetCommand("Patrol", unpack_params(behaviorParams)) | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetBehaviorPatrol', { | |
| MarkerGroup = "GameIntro", | |
| Repeat = true, | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "AnimParams", | |
| "UnitTarget", | |
| }, | |
| id = "GroupSetBehaviorRoam", | |
| PlaceObj('PropertyDefText', { | |
| 'id', "MarkerId", | |
| 'help', "Marker description: can specify an id.", | |
| 'translate', false, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerGroup", | |
| 'help', "Marker description: marker group.", | |
| 'default', "", | |
| 'items', function (self) return GetBehaviorGroups end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerType", | |
| 'help', "Marker description: markers type.", | |
| 'default', "Position", | |
| 'items', function (self) return GetGridMarkerTypesCombo end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(TargetUnit)> roam(s) around marker", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set units behavior to Roam around a map's marker.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local markers = MapGetMarkers(self.MarkerType, self.MarkerGroup, function(o) | |
| return o:IsMarkerEnabled() and ((self.MarkerId or "" == "") or o.ID == self.MarkerID) | |
| end) | |
| if #(markers or empty_table) == 0 then | |
| printf("SetBehaviorRoam didn't find any markers (type %s, group %s, id %s)", tostring(self.MarkerType), tostring(self.MarkerGroup), tostring(self.MarkerId)) | |
| return | |
| end | |
| local params = self:GetAnimParams() | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") and not o:IsDead() then | |
| local marker = table.interaction_rand(markers, "GridMarker", o) | |
| o:SetCommandParams("Roam", params) | |
| if g_Combat then | |
| o:SetBehavior("Roam", { marker, self.Orient }) | |
| elseif o.being_interacted_with then | |
| o:QueueCommand("Roam", marker, self.Orient) | |
| else | |
| o:SetCommand("Roam", marker, self.Orient) | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetBehaviorRoam', { | |
| MarkerGroup = "GameIntro", | |
| MarkerId = "Start", | |
| MarkerType = "Defender", | |
| TargetUnit = "Red", | |
| UseWeapons = true, | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Orient", | |
| 'name', "End Orient", | |
| 'help', "Use marker orientation on the end", | |
| 'default', true, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupSetImmortal", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "setImmortal", | |
| 'name', "Set immortal to", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set the immortal property of units from <u(TargetUnit)> to <select(setImmortal, 'false', 'true')>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set the immortal property of units from a given group.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "Unit") then | |
| unit.immortal = self.setImmortal | |
| ObjModified(unit) | |
| end | |
| end | |
| if not next(context.target_units) then | |
| print(self.id, " couldn't find any units of: ", self.TargetUnit) | |
| return | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetImmortal', { | |
| TargetUnit = "GreasyBasil", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupSetInfected", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "setInfected", | |
| 'name', "Set infected to", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set the infected property of units from <u(TargetUnit)> to <select(setInfected, 'false', 'true')>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set the infected property of units from a given group. (Some animations change based on this property)", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| for _, unit in ipairs(context.target_units) do | |
| if IsKindOf(unit, "Unit") then | |
| unit.infected = self.setInfected | |
| ObjModified(unit) | |
| end | |
| end | |
| if not next(context.target_units) then | |
| print(self.id, " couldn't find any units of: ", self.TargetUnit) | |
| return | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetInfected', { | |
| TargetUnit = "Raiders", | |
| setInfected = true, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "AnimParams", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "GroupSetRoutine", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set routine of <u(TargetUnit)> to <u(Routine)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set routine of units", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local params = self:GetAnimParams() | |
| params.PropagateAnimParams = self.PropagateAnimParams | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") then | |
| o.routine = self.Routine == "spawner" and o.routine_spawner.Routine or self.Routine | |
| o.routine_area = self.RoutineArea == "spawner" and "self" or self.RoutineArea | |
| o.behavior = false | |
| o:SetCommandParams("Idle", params) | |
| o:SetCommand("Idle") | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'category', "", | |
| 'id', "Routine", | |
| 'help', "Set units of group to particular routine, or the one from their spawner.", | |
| 'default', "spawner", | |
| 'items', function (self) local r = table.copy(UnitRoutines) r[#r+1] = "spawner" return r end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'category', "", | |
| 'id', "RoutineArea", | |
| 'help', "Area to play the routine in, or use the one from the spawner.", | |
| 'default', "spawner", | |
| 'items', function (self) local g = table.copy(GridMarkerGroupsCombo()) g[1+#g] = "spawner" return g end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "PropagateAnimParams", | |
| 'help', "AdvanceTo behavior passes the control to Roam behavior on finish and if this checked all the AnimParams here will be propagated to Roam", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetRoutine', { | |
| PropagateAnimParams = true, | |
| Routine = "StandStill", | |
| RoutineArea = "East", | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| id = "GroupSetSide", | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "Side", | |
| 'help', "The new side of group.", | |
| 'items', function (self) return Sides end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "CreateSquad", | |
| 'help', "If set to false the units will not create a new squad. Keep in mind they will be ejected from their old squad so they will despawn on the next presence check.", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Change the side of <u(TargetUnit)> to <u(Side)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change groups side", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| if not next(context.target_units) then | |
| print("GroupSetSide couldn't find group", self.TargetUnit) | |
| return | |
| end | |
| if self.CreateSquad then | |
| local squads = {} | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") and o.Squad then | |
| table.insert_unique(squads, o.Squad) | |
| local memberArrayName = "members" .. o.Squad | |
| local memberArray = squads[memberArrayName] | |
| if not memberArray then | |
| memberArray = {} | |
| squads[memberArrayName] = memberArray | |
| end | |
| memberArray[#memberArray + 1] = o.session_id | |
| end | |
| end | |
| for i, s in ipairs(squads) do | |
| local squadObj = gv_Squads[s] | |
| local createNew = false | |
| if squadObj.Side ~= self.Side then -- If squad is not of this side already | |
| -- Check all units in the squad. | |
| local units = squadObj.units | |
| for _, u in ipairs(units) do | |
| -- If any of the units in the squad are not part of the group, | |
| -- they must remain on their old side in the old squad. | |
| local unit = g_Units[u] | |
| if not table.find(context.target_units, unit) then | |
| createNew = true | |
| break | |
| end | |
| end | |
| end | |
| if createNew then | |
| local unitsToChangeSide = squads["members" .. s] | |
| CreateNewSatelliteSquad({ | |
| Side = self.Side, | |
| CurrentSector = squadObj.CurrentSector, | |
| Name = SquadName:GetNewSquadName(self.Side, unitsToChangeSide) | |
| }, unitsToChangeSide) | |
| else | |
| SetSatelliteSquadSide(s, self.Side) | |
| end | |
| end | |
| else | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") then | |
| local ud = gv_UnitData[o.session_id] | |
| RemoveUnitFromSquad(ud, "script") | |
| -- Dirty hack to prevent instant despawn when setting side to neutral. | |
| if self.Side == "neutral" then | |
| o.IsMerc = function() return false end | |
| end | |
| end | |
| end | |
| end | |
| for _, o in ipairs(context.target_units) do | |
| if IsKindOf(o, "Unit") then | |
| o:SetSide(self.Side) | |
| end | |
| end | |
| Msg("GroupChangeSide", self.TargetUnit, self.Side, context.target_units) | |
| CheckGameOver() | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| self:__exec(obj, context) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Side then | |
| return "Set the new side!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('GroupSetSide', { | |
| Side = "enemy1", | |
| TargetUnit = "Buns", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "AnimParams", | |
| "UnitTarget", | |
| }, | |
| id = "GroupTeleport", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerGroup", | |
| 'help', "Marker group where the units should be teleported to.", | |
| 'default', "", | |
| 'items', function (self) return GetBehaviorGroups end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(TargetUnit)> will be teleported to <u(MarkerGroup)> marker", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Units group teleports to a specified marker", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| context = type(context) == "table" and context or {} | |
| self:MatchMapUnits(obj, context) | |
| local units = context.target_units or empty_table | |
| for i = #units, 1, -1 do | |
| if not IsKindOf(units[i], "Unit") then | |
| table.remove(units, i) | |
| end | |
| end | |
| if #(units or empty_table) == 0 then | |
| return string.format("No units from group '%s' to teleport", self.TargetUnit) | |
| end | |
| local markers = MapGetMarkers(nil, self.MarkerGroup) | |
| if not markers or #markers == 0 then | |
| return string.format("No markets in '%s' to teleport group '%s' to", self.MarkerGroup, self.TargetUnit) | |
| end | |
| local unit_pos, units_left = {} | |
| for _, marker in ipairs(markers) do | |
| units_left = {} | |
| local dest = GetUnitsDestinations(units, marker) | |
| for idx, unit in ipairs(units) do | |
| if dest[idx] then | |
| table.insert(unit_pos, unit) | |
| unit_pos[unit] = point(point_unpack(dest[idx])) | |
| else | |
| table.insert(units_left, unit) | |
| end | |
| end | |
| if #units_left == 0 then break end | |
| units = units_left | |
| end | |
| if #units_left > 0 then | |
| for _, unit in ipairs(units_left) do | |
| StoreErrorSource(unit, string.format("No position found for group '%s' teleport to markers '%s'!", self.TargetUnit, self.MarkerGroup)) | |
| end | |
| end | |
| for _, unit in ipairs(unit_pos) do | |
| NetSyncEvent("StartCombatAction", netUniqueId, "Teleport", unit, g_Combat and 0 or false, unit_pos[unit]) | |
| end | |
| return string.format("%d unit(s) from '%s' teleported to '%s'", #units, self.TargetUnit, self.MarkerGroup) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Teleport <u(TargetUnit)> to <u(MarkerGroup)>") | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('GroupTeleport', { | |
| MarkerGroup = "West", | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "Heal", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| "UnitData", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Restore unit's health", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Restores unit's health", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOf(obj, "UnitData") then | |
| HealUnitData(obj) | |
| else | |
| obj:ReviveOnHealth() | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('Heal', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "HealWounds", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Heal unit's wounds", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Heals unit's wounds", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| obj:RemoveStatusEffect("Wounded", "all") | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('HealWounds', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "HerbalMedicineEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| "UnitData", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Grant AP or Go Berserk", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Grant AP or Go Berserk", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOf(obj, "Unit") and not obj:IsDead() then | |
| local berserkRoll = InteractionRand(100, "HerbalMedicine") | |
| local apRoll = InteractionRand(100, "HerbalMedicine") | |
| if berserkRoll < self.berserkChance then | |
| end | |
| if apRoll < self.apChance then | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ChangeTiredness', {}), | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "berserkChance", | |
| 'name', "Berserk Chance", | |
| 'default', 15, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "apChance", | |
| 'name', "AP Chance", | |
| 'default', 15, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "HideQuestBadge", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Hide a quest badge", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local questState = (self.Quest and gv_Quests[self.Quest]) or (IsKindOf(obj, "QuestsDef") and obj) or false | |
| assert(questState) | |
| if not questState then return end | |
| local magicParam = badgeHideIdentifierNote | |
| local preset, index = self:GetLinePreset() | |
| assert(preset) -- Missing quest probably | |
| if not preset then return end | |
| magicParam = magicParam .. tostring(index) .. "@" .. tostring(self.BadgeIdx) | |
| if self.Show then | |
| questState[magicParam] = nil | |
| else | |
| questState[magicParam] = true | |
| end | |
| UpdateQuestBadges(questState) | |
| if g_SatelliteUI then | |
| local badge = preset.Badges[self.BadgeIdx] | |
| if badge and badge.Sector then | |
| g_SatelliteUI:UpdateSectorVisuals(badge.Sector) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Show", | |
| 'help', "Show the badge instead. (if it was hidden with this effect)", | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Quest", | |
| 'name', "Quest", | |
| 'help', "Which quest to associate this badge with. If the effect is placed on a quest it will attempt to find it itself.", | |
| 'preset_class', "QuestsDef", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "BadgeIdx", | |
| 'name', "Badge Id", | |
| 'extra_code', "sort_order = 9", | |
| 'default', 1, | |
| 'min', 1, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "Preview", | |
| 'dont_save', true, | |
| 'read_only', true, | |
| 'extra_code', "sort_order = 10", | |
| 'translate', false, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('HideQuestBadge', { | |
| LogLine = 4, | |
| Quest = "01_Landing", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "LogLine", | |
| 'name', "Log Line", | |
| 'help', "Change the state of that line.", | |
| 'items', function (self) return GetQuestNoteLinesCombo(self.Quest) end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Quest or self.Quest=="" then | |
| return "Specify the quest!" | |
| end | |
| if not Quests[self.Quest] then | |
| return "Missing quest!" | |
| end | |
| if not self.LogLine then | |
| return "Specify the line!" | |
| end | |
| local preset = self:GetLinePreset() | |
| if not preset then | |
| return "Invalid line!" | |
| end | |
| if not preset.Badges or #preset.Badges == 0 then | |
| return "This line doesn't place badges." | |
| end | |
| if self.BadgeIdx > #preset.Badges then | |
| return "Badge id out of range" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetLinePreset", | |
| 'code', function (self) | |
| local line = self.LogLine | |
| local quest = Quests[self.Quest] | |
| if not quest or not line then return end | |
| local notePreset = table.find_value(quest.NoteDefs, "Idx", line) | |
| if not notePreset then return end | |
| return notePreset, line | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local actionWord = self.Show and "Show " or "Hide " | |
| actionWord = actionWord .. self.BadgeIdx .. " " | |
| --Hide quest badge placed by <LogLine> | |
| if self.LogLine then | |
| local linePreset = self:GetLinePreset() | |
| if not linePreset then | |
| return Untranslated("Hide Badge: Missing quest!") | |
| end | |
| local text = linePreset and linePreset.Text or "log line not found" | |
| if linePreset.Badges then | |
| local badge = linePreset.Badges[self.BadgeIdx] | |
| self.Preview = "Badge on " .. (badge.BadgeUnit or "") .. " in " .. (badge.Sector or "") | |
| return Untranslated(actionWord .. "badge placed by <u(Quest)>: ").. Untranslated(text) | |
| else | |
| self.Preview = "Invalid badge" | |
| return Untranslated("Invalid badge") | |
| end | |
| else | |
| self.Preview = "" | |
| return Untranslated(actionWord .. "badge placed by <u(Quest)>: invalid log line specified") | |
| end | |
| end, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "InteractingMercReduceItemCondition", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "ItemId", | |
| 'items', function (self) return ClassDescendantsCombo("InventoryItem") end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Equipped", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "ReduceAmount", | |
| 'default', 1, | |
| 'min', 1, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Reduce the condition of an interaction merc's item", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Reduce the condition of interaction merc's <u(ItemId)> by <ReduceAmount>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local unit = context and context.target_units | |
| unit = unit and unit[1] | |
| if not unit then return end | |
| local item = false | |
| if self.Equipped then | |
| item = unit:GetItemInSlot("Handheld A", self.ItemId) or | |
| unit:GetItemInSlot("Handheld B", self.ItemId) | |
| else | |
| item = unit:GetItemInSlot("Inventory", self.ItemId) | |
| end | |
| if not item then return end | |
| unit:ItemModifyCondition(item, -self.ReduceAmount) | |
| CombatLog("short", T{597332256786, "<DisplayName> condition decreased by <dmg>.", DisplayName = item.DisplayName, dmg = self.ReduceAmount}) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.ItemId then | |
| return "Set Item!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) | |
| return SelectedObj | |
| end, | |
| 'TestObject', PlaceObj('InteractingMercReduceItemCondition', { | |
| ItemId = "Machete", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "KillTimer", | |
| PlaceObj('PropertyDefText', { | |
| 'id', "Name", | |
| 'name', "Name", | |
| 'help', "Name of the timer.", | |
| 'translate', false, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "StopTCE", | |
| 'name', "Stop TCE", | |
| 'help', "Wether to execute the effects after the timer or not.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Kill timer <Name>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Kills the visual UI timer displayed in the upper center of the screen", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "quest, context, TCE", | |
| 'code', function (self, quest, context, TCE) | |
| local data = TimerGetData(self.Name) | |
| if data then | |
| data.time = 0 | |
| data.StopTCE = self.StopTCE | |
| Msg("TimerFinished", data.id) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Name then | |
| return "KillTimer needs a name!" | |
| end | |
| if GetParentTableOfKindNoCheck(self, "TestHarness") then | |
| return | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "UI & Log", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('KillTimer', { | |
| Name = "xxxx", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "LightsSetState", | |
| PlaceObj('PropertyDefText', { | |
| 'id', "MarkerId", | |
| 'help', "Marker description: can specify an id.", | |
| 'translate', false, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerGroup", | |
| 'help', "Marker description: marker group.", | |
| 'default', "", | |
| 'items', function (self) return LightsMarkerGroups end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerType", | |
| 'help', "Marker description: markers type.", | |
| 'default', "Position", | |
| 'items', function (self) return GetGridMarkerTypesCombo end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "TurnOn", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "EssentialLights", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "OptionalLights", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "AttachedLights", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return string.format("Turns Lights %s in %s marker(s) area(s)", self.TurnOn and "ON" or "OFF", self.MarkerGroup) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Turns ON/OFF Lights inside marker's area", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local markers = MapGetLightsMarkers(self.MarkerType, self.MarkerGroup, function(o) | |
| return o:IsMarkerEnabled() and ((self.MarkerId or "" == "") or o.ID == self.MarkerID) | |
| end) | |
| if #(markers or empty_table) == 0 then | |
| printf("%s didn't find any markers (type %s, group %s, id %s)", self.class, tostring(self.MarkerType), tostring(self.MarkerGroup), tostring(self.MarkerId)) | |
| return | |
| end | |
| local lights = GetLights(function(light) | |
| local detail = light:GetDetailClass() | |
| if not self.EssentialLights and detail == "Essential" then | |
| return false | |
| end | |
| if not self.OptionalLights and detail == "Optional" then | |
| return false | |
| end | |
| if not self.AttachedLights and light:GetParent() then | |
| return false | |
| end | |
| return true | |
| end) | |
| for _, marker in ipairs(markers) do | |
| marker.lights_off = not self.TurnOn | |
| for _, light in ipairs(lights) do | |
| if marker:IsInsideArea2D(light) then | |
| if marker.lights_off then | |
| marker:TurnLightOff(light) | |
| else | |
| marker:TurnLightOn(light) | |
| end | |
| end | |
| end | |
| end | |
| Msg("LightsStateUpdated") | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('LightsSetState', { | |
| MarkerGroup = "Room1", | |
| TurnOn = false, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "LockpickableSetState", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Group", | |
| 'name', "Group", | |
| 'help', "The group in which the lockpick resides.", | |
| 'items', function (self) return GridMarkerGroupsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "State", | |
| 'help', "The state to set the locking in.", | |
| 'items', function (self) return { "unlocked", "locked", "change-difficulty" } end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "NewDifficulty", | |
| 'name', "New Difficulty", | |
| 'help', 'The difficulty to change to if the state is "change-difficulty".', | |
| 'default', "None", | |
| 'items', function (self) return const.DifficultyPresetsNew end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Change the state of lockpickables in <u(Group)> to <u(State)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change lockpickable (containers, doors) state.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| for _, o in ipairs(Groups[self.Group]) do | |
| if o:IsKindOf("Lockpickable") then | |
| if self.State == "change-difficulty" then | |
| o.lockpickDifficulty = self.NewDifficulty | |
| else | |
| o:SetLockpickState(self.State == "unlocked" and "closed" or self.State) | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.State then | |
| return "Set the new state!" | |
| end | |
| if not self.Group then | |
| return "Set the group" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('LockpickableSetState', { | |
| Group = "JosePatrol", | |
| NewDifficulty = "VeryHard", | |
| State = "change-difficulty", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "LogMessageAdd", | |
| PlaceObj('PropertyDefText', { | |
| 'id', "message", | |
| 'name', "Message", | |
| 'help', "The message to display.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| CombatLog("important", self.message) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Log:<message>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Add a short message in game log", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.message or self.message == "" then | |
| return "Add a message" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('LogMessageAdd', { | |
| message = T(406026787074, --[[EffectDef Effects LogMessageAdd message]] "MSG"), | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "UI & Log", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ModifySatelliteAggro", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Halt", | |
| 'help', "Stop passive aggro increase", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "AggroAmount", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "HaltDays", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "AmountIsPercent", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Modify Satellite aggro", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.Halt then | |
| if self.HaltDays then | |
| return Untranslated("Halt satellite aggro for " .. self.HaltDays .. " days.") | |
| end | |
| return Untranslated("Halt satellite aggro") | |
| elseif self.AggroAmount == 0 and not self.Halt then | |
| return Untranslated("Unhalt satellite aggro") | |
| elseif self.AmountIsPercent then | |
| return Untranslated("Add " .. self.AggroAmount / 100 .. "% satellite aggro") | |
| else | |
| return Untranslated("Add " .. self.AggroAmount .. " satellite aggro") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| gv_SatelliteAttacksHalted = self.Halt | |
| -- When halting reset. | |
| if gv_SatelliteAttacksHalted then | |
| gv_SatelliteAggro = 0 | |
| gv_SatelliteAttacksHaltedFor = self.HaltDays | |
| return | |
| end | |
| ModifySatelliteAggression(self.AggroAmount, self.AmountIsPercent) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.AggroAmount then | |
| return "No amount specified" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ModifySatelliteAggro', { | |
| AmountIsPercent = false, | |
| Halt = true, | |
| HaltDays = 3, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "TrapSpawnProperties", | |
| }, | |
| group = "Effects", | |
| id = "ModifyTrapSpawnersEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(678225332862, --[[EffectDef Effects ModifyTrapSpawnersEffect value]] "Change trap spawners of group <u(Group)>"), | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change the properties of trap spawners in a specific group.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local props = self:GetPropertyList() | |
| for i, s in ipairs(Groups[self.Group]) do | |
| if s:IsKindOf("TrapSpawnMarker") then | |
| s:ApplyPropertyList(props) | |
| end | |
| end | |
| if self.SpawnActive ~= "dont change" then | |
| for i, s in ipairs(Groups[self.Group]) do | |
| if s:IsKindOf("TrapSpawnMarker") then | |
| s:SetActive(self.SpawnActive == "enable") | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Group", | |
| 'name', "Spawner Group", | |
| 'help', "The spawner group to affect.", | |
| 'default', "", | |
| 'items', function (self) return GridMarkerGroupsCombo() end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ModifyTrapSpawnersEffect', { | |
| Group = "Raiders", | |
| SpawnActive = "enable", | |
| done = true, | |
| visibility = set( "player1" ), | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Traps", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'category', "Spawner", | |
| 'id', "SpawnActive", | |
| 'name', "Override Spawner Status", | |
| 'help', "Override whether the spawner is active. If disabled any spawned traps will be despawned.", | |
| 'default', "don't change", | |
| 'items', function (self) return {"don't change", "enable", "disable"} end, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "MusicSetPlaylist", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Playlist", | |
| 'name', "Playlist", | |
| 'items', function (self) return PresetsCombo("RadioStationPreset", "Default") end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Changes the current playlist", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Changes the current playlist", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| StartRadioStation(self.Playlist) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('MusicSetPlaylist', { | |
| Playlist = "Exploration_Farmlands", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "MusicSetSectorPlaylist", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "SectorID", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MusicExploration", | |
| 'name', "Exploration Music", | |
| 'items', function (self) return PresetsCombo("RadioStationPreset", "Default") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MusicConflict", | |
| 'name', "Conflict Music", | |
| 'items', function (self) return PresetsCombo("RadioStationPreset", "Default") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MusicCombat", | |
| 'name', "Combat Music", | |
| 'items', function (self) return PresetsCombo("RadioStationPreset", "Default") end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Changes the playlists of a sector", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Changes the playlists of a sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if GetSectorMusicOverride("MusicExploration") ~= self.MusicExploration then | |
| SetSectorMusicOverride(self.SectorID, "MusicExploration", self.MusicExploration) | |
| end | |
| if GetSectorMusicOverride("MusicConflict") ~= self.MusicConflict then | |
| SetSectorMusicOverride(self.SectorID, "MusicConflict", self.MusicConflict) | |
| end | |
| if GetSectorMusicOverride("MusicCombat") ~= self.MusicCombat then | |
| SetSectorMusicOverride(self.SectorID, "MusicCombat", self.MusicCombat) | |
| end | |
| ResetSectorStation() | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('MusicSetSectorPlaylist', { | |
| MusicCombat = "Combat_Dramatic", | |
| MusicConflict = "Enemy_Territory", | |
| MusicExploration = "Exploration_Cliffs", | |
| SectorID = "I1", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "MusicSetTrack", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Playlist", | |
| 'name', "Playlist", | |
| 'items', function (self) return PresetsCombo("RadioStationPreset", "Default") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Track", | |
| 'name', "Track", | |
| 'items', function (self) return RadioPlaylistCombo(self.Playlist) end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Plays a track and then continues with the current playlist(radio station)", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Plays a track and then continues with the current playlist(radio station)", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local _, playlist = RadioPlaylistCombo(self.Playlist) | |
| local track = table.find_value(playlist, "path", self.Track) | |
| MusicPlayTrack(track) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('MusicSetTrack', { | |
| Playlist = "Combat_Farmlands", | |
| Track = "Music/Combat_Farmlands/GS_PZ_Cerebral_Battle_Track_03", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "NeutralNPCDontMove", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Prevent neutral unit from moving in combat.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Prevents neutral unit from moving in combat.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local units = Groups[self.TargetUnit] or empty_table | |
| for _, unit in ipairs(units) do | |
| unit.neutral_ai_dont_move = true | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "NPC Name", | |
| 'help', "The name of the NPC to associate.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "Specify Target Unit" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('NeutralNPCDontMove', { | |
| TargetUnit = "Barry", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "LootTableFunctionObjectBase", | |
| }, | |
| group = "Effects", | |
| id = "NpcUnitGiveItem", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "ItemId", | |
| 'name', "Item", | |
| 'preset_class', "InventoryItemCompositeDef", | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "LootTableId", | |
| 'name', "LootTable", | |
| 'preset_class', "LootDef", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "DontDrop", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "NPC Name", | |
| 'help', "The name of the NPC to associate.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Give <u(ItemId)>/<u(LootTableId)> to <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Give an item to an npc, and have them equip items", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local units = empty_table | |
| local group = Groups[self.TargetUnit] | |
| if group then | |
| local unitClass = {} | |
| for i, obj in ipairs(group) do | |
| if IsKindOf(obj, "Unit") then | |
| unitClass[#unitClass + 1] = obj | |
| end | |
| end | |
| units = unitClass | |
| else | |
| units = context.target_units or units | |
| end | |
| if not units or not units[1] then return end | |
| local items = {} | |
| if self.ItemId and self.ItemId~="" then | |
| table.insert(items, PlaceInventoryItem(self.ItemId)) | |
| end | |
| if self.LootTableId then | |
| local loot_tbl = LootDefs[self.LootTableId] | |
| if loot_tbl then | |
| loot_tbl:GenerateLoot(self, {}, InteractionRand(nil, "NpcGive"), items) | |
| end | |
| end | |
| local unit = units[1] | |
| for i, item in ipairs(items) do | |
| item.drop_chance = self.DontDrop and 0 or 100 | |
| if unit:CanAddItem("Handheld A", item) then | |
| unit:AddItem("Handheld A", item) | |
| elseif unit:CanAddItem("Head", item) then | |
| unit:AddItem("Head", item) | |
| elseif unit:CanAddItem("Torso", item) then | |
| unit:AddItem("Torso", item) | |
| elseif unit:CanAddItem("Legs", item) then | |
| unit:AddItem("Legs", item) | |
| else | |
| unit:AddItem("Inventory", item) | |
| end | |
| end | |
| unit:UpdateOutfit() | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.ItemId and not self.LootTableId then | |
| return "No items set" | |
| end | |
| if not self.TargetUnit then | |
| return "No target unit" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('NpcUnitGiveItem', { | |
| ItemId = "Coin", | |
| TargetUnit = "Bella", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "NpcUnitTakeItem", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "ItemId", | |
| 'name', "Item", | |
| 'preset_class', "InventoryItemCompositeDef", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "NPC Name", | |
| 'help', "The name of the NPC to associate.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Take <u(ItemId)> from <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Take an item from an NPC", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local units = empty_table | |
| local group = Groups[self.TargetUnit] | |
| if group then | |
| local unitClass = {} | |
| for i, obj in ipairs(group) do | |
| if IsKindOf(obj, "Unit") then | |
| unitClass[#unitClass + 1] = obj | |
| end | |
| end | |
| units = unitClass | |
| else | |
| units = context.target_units or units | |
| end | |
| if not units or not units[1] then return end | |
| local unit = units[1] | |
| local itemsToRemove = {} | |
| local itemsToRemoveSlots = {} | |
| unit:ForEachItem(false, function(item, slot) | |
| if item.class == self.ItemId then | |
| itemsToRemove[#itemsToRemove + 1] = item | |
| itemsToRemoveSlots[#itemsToRemoveSlots + 1] = slot | |
| end | |
| end) | |
| for i, item in ipairs(itemsToRemove) do | |
| unit:RemoveItem(itemsToRemoveSlots[i], item) | |
| end | |
| unit:UpdateOutfit() | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.ItemId then | |
| return "No items set" | |
| end | |
| if not self.TargetUnit then | |
| return "No target unit" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('NpcUnitTakeItem', { | |
| ItemId = "Lockpick", | |
| TargetUnit = "Livewire", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "PhraseSetEnabled", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Conversation", | |
| 'help', "The conversation the phrase is in.", | |
| 'preset_class', "Conversation", | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "PhraseId", | |
| 'help', "The Id of the phrase to enable/disable.", | |
| 'items', function (self) return GetPhraseIdsCombo(self.Conversation) end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Enabled", | |
| 'help', "Enable or disable the phrase.", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enables or disables a particular conversation phrase.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local enable = self.Enabled and Untranslated("Enable phrase ") or Untranslated("Disable phrase ") | |
| return Untranslated("<u(Conversation)>: ") .. enable .. Untranslated("<u(PhraseId)>") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetPhraseEnabledState(self.Conversation .. "." .. self.PhraseId, self.Enabled) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "OnAfterEditorNew", | |
| 'params', "parent, ged, is_paste", | |
| 'code', function (self, parent, ged, is_paste) | |
| local preset = GetParentTableOfKind(self, "Conversation") | |
| if preset:IsKindOf("Conversation") then | |
| self.Conversation = preset.id | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('PhraseSetEnabled', { | |
| Conversation = "FlagHill_Corazon_1", | |
| PhraseId = "Greeting", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "PhraseSetSeen", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Conversation", | |
| 'help', "The conversation the phrase is in.", | |
| 'preset_class', "Conversation", | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "PhraseId", | |
| 'help', "The Id of the phrase to enable/disable.", | |
| 'items', function (self) return GetPhraseIdsCombo(self.Conversation) end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Seen", | |
| 'help', "Sets the phrase as not seen (highlighted) by default; check the box to set the phrase as seen (dimmed) instead.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Changes a conversation's phrase \"seen\" (dimmed) status.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local seen = self.Seen and Untranslated("seen") or Untranslated("not seen") | |
| return Untranslated("<u(Conversation)>: Set phrase<u(PhraseId)> as ") .. seen | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetPhraseSeen(self.Conversation .. "." .. self.PhraseId, self.Seen) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "OnAfterEditorNew", | |
| 'params', "parent, ged, is_paste", | |
| 'code', function (self, parent, ged, is_paste) | |
| local preset = GetParentTableOfKind(self, "Conversation") | |
| if preset:IsKindOf("Conversation") then | |
| self.Conversation = preset.id | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('PhraseSetSeen', { | |
| Conversation = "FlagHill_Corazon_1", | |
| PhraseId = "Greeting", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "BanterFunctionObjectBase", | |
| }, | |
| id = "PlayBanterEffect", | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Banters then | |
| return "No banters" | |
| end | |
| for i,banter_id in ipairs(self.Banters) do | |
| if not Banters[banter_id] then | |
| return "Invalid banter ID " .. banter_id | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Play banter(s): ").. Untranslated(table.concat(self.Banters, ", ")) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "An effect to play a banter.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local is_marker = IsKindOf(obj, "GridMarker") | |
| local context_is_table = context and type(context)=="table" | |
| local targetUnitsTable = context_is_table and rawget(context, "target_units") | |
| targetUnitsTable = targetUnitsTable and table.icopy(targetUnitsTable) | |
| local units = targetUnitsTable or (is_marker and { obj } or {}) | |
| if self.searchInMarker and is_marker then | |
| MapForEach("map", "Unit", function(u) | |
| if obj:IsInsideArea(u:GetPos()) then | |
| units[#units + 1] = u | |
| end | |
| end) | |
| elseif self.searchInMap then | |
| MapForEach("map", "Unit", function(u) | |
| units[#units + 1] = u | |
| end) | |
| MapForEach("map", "CheeringDummy", function(u) | |
| units[#units + 1] = u | |
| end) | |
| end | |
| if context_is_table and rawget(context, "interactable") then | |
| units = table.copy(units) | |
| table.insert(units, 1, context.interactable) | |
| end | |
| local fallback = false | |
| if self.FallbackToMerc then | |
| for _, unit in ipairs(g_Units) do | |
| if unit:IsPlayerAlly() and not unit:IsDead() then | |
| fallback = unit | |
| break | |
| end | |
| end | |
| -- search for any actor also | |
| if not fallback and self.anyFallback then | |
| for _, unit in ipairs(g_Units) do | |
| if not unit:IsDead() then | |
| fallback = unit | |
| break | |
| end | |
| end | |
| end | |
| end | |
| local banters, banterActors = FilterAvailableBanters(self.Banters, context, units, fallback) | |
| if not banters then | |
| CombatLog("debug","No banters can be played with the selected actors") | |
| return | |
| end | |
| local idx = InteractionRand(#banters, "PlayBanterEffect") + 1 | |
| local banterToPlay = banters[idx] | |
| local actorsToPlayWith = banterActors[idx] | |
| local anyActorOverride = self.AnyActorOverrideGroup | |
| -- Support for banter from conversation | |
| if context_is_table and context and context.found_merc then | |
| anyActorOverride = context.found_merc | |
| end | |
| local banterObj = PlayBanter(banterToPlay, actorsToPlayWith, fallback, anyActorOverride, self.WaitSetpieceEnd) | |
| if banterObj then | |
| local playerPos = IsValid(obj) and obj:GetPos() | |
| if playerPos then | |
| banterObj:SetPos(playerPos) | |
| end | |
| local resumeData = {} | |
| resumeData.preset = banterObj.preset.id | |
| local banterUnits = {} | |
| for i, u in ipairs(banterObj.associated_units) do | |
| banterUnits[#banterUnits + 1] = u.handle | |
| end | |
| resumeData.units = banterUnits | |
| resumeData.fallbackUnit = banterObj.fallback_actor and banterObj.fallback_actor.handle | |
| resumeData.any_actor_override = banterObj.any_actor_override and banterObj.any_actor_override.handle | |
| resumeData.playerHandle = banterObj.handle | |
| if playerPos then resumeData.player_pos = playerPos end | |
| g_PlayingBanterEffects[self] = resumeData | |
| end | |
| return banterObj | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__skip", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| for i, banterId in ipairs(self.Banters) do | |
| SkipBanterFromUI(banterId) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local banterObj = self:__exec(obj, context) | |
| local event = self.banterSequentialWaitFor | |
| if banterObj and event ~= "" then | |
| local notTimedOut, preset_id | |
| while preset_id ~= banterObj.preset.id do | |
| notTimedOut, preset_id = WaitMsg(event) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if #self.Banters == 0 then | |
| return "Add at least one banter" | |
| end | |
| if self.searchInMarker and self.searchInMap then | |
| return "Don't select both search in marker and search in map." | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefPresetIdList', { | |
| 'id', "Banters", | |
| 'name', "Banters", | |
| 'help', "List of banters to play.", | |
| 'preset_class', "BanterDef", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "searchInMarker", | |
| 'name', "Include Marker Units", | |
| 'help', "The only valid actors for a banter are the units passed by the previous conditions. By setting this on units inside a GridMarker will also be included as valid actors.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "banterSequentialWaitFor", | |
| 'name', "Wait For", | |
| 'help', "The banter event to wait for (if executing sequentially).", | |
| 'default', "BanterDone", | |
| 'items', function (self) return {"", "BanterStart", "BanterDone", "BanterLineStart", "BanterLineDone"} end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "searchInMap", | |
| 'name', "Include Whole Map", | |
| 'help', "The only valid actors for a banter are the units passed by the previous conditions. By setting this on units from the whole map will be considered. Your banter might spawn on a unit off screen.", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "FallbackToMerc", | |
| 'name', "Radio", | |
| 'help', "If enabled the banter will appear over the first merc on map if the banter actor is not present on the map.", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "WaitSetpieceEnd", | |
| 'help', "if enabled the banter will wait for the setpiece to end", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "anyFallback", | |
| 'name', "Use any unit as fallback for Radio.", | |
| 'help', "Use this if the Radio banter is not played.", | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "AnyActorOverrideGroup", | |
| 'name', "Any Actor Override Group", | |
| 'help', 'Banter lines with actor "any" will be played by the first /object/ from the group.', | |
| 'translate', false, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'code', function (self) | |
| local resumeData = g_PlayingBanterEffects[self] | |
| if resumeData and resumeData.playerHandle then | |
| local player = HandleToObject[resumeData.playerHandle] | |
| if IsValid(player) then | |
| resumeData.current_line = (player.current_line and player.current_line + 1) or 1 | |
| return "PlayBanterEffect", resumeData | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('PlayBanterEffect', { | |
| Banters = { | |
| "DiamondRed_Boss_ExecutePsycho", | |
| }, | |
| searchInMap = true, | |
| searchInMarker = false, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "PlayNotNowVR", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', 'Unit plays "NotNow" VR', | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', 'Unit plays "NotNow" VR.', | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| PlayVoiceResponse(obj, "NotNow") | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('PlayNotNowVR', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "PlaySetpiece", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Play <setpiece> setpiece", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Play a Set-piece.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local triggerUnits = false | |
| if type(context) == "table" and rawget(context, "target_units") then | |
| triggerUnits = rawget(context, "target_units") | |
| elseif Groups[obj] then | |
| triggerUnits = Groups[obj] | |
| elseif gv_CurrentSectorId then | |
| triggerUnits = table.map(GetPlayerMercsInSector(gv_CurrentSectorId), function(o) return g_Units[o] end) | |
| end | |
| local foundMerc = false | |
| if type(context) == "table" and rawget(context, "found_merc") then | |
| foundMerc = rawget(context, "found_merc") | |
| foundMerc = g_Units[foundMerc] | |
| end | |
| local setpiece = Setpieces[self.setpiece] | |
| if setpiece.TakePlayerControl then | |
| local dlg = OpenDialog("XSetpieceDlg", false, { | |
| setpiece = self.setpiece, | |
| setpiece_seed = InteractionRand(nil, "Setpiece"), | |
| triggerUnits = triggerUnits, | |
| extra_params = foundMerc and { {foundMerc} } | |
| }) | |
| if GameState.entering_sector then | |
| dlg:FadeOut(0) -- immediate black screen to hide any stray frames if we are started upon entering a sector (with a loading screen) | |
| end | |
| else | |
| CreateGameTimeThread(function() | |
| StartSetpiece(self.setpiece, false, InteractionRand(nil, "Setpiece"), triggerUnits, foundMerc) | |
| end) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| self:__exec(obj, context) | |
| local setpiece = Setpieces[self.setpiece] | |
| if setpiece.TakePlayerControl then | |
| WaitMsg("SetpieceEnded") | |
| else | |
| WaitMsg("SetpieceEndExecution") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.setpiece then return "No setpiece set." end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "setpiece", | |
| 'name', "Setpiece", | |
| 'help', "The id of the set piece preset to play.", | |
| 'preset_class', "SetpiecePrg", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('PlaySetpiece', { | |
| setpiece = "MoveTest", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "UnitTarget", | |
| "Effect", | |
| }, | |
| group = "Effects", | |
| id = "PlayUnitVoiceResponse", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "VoiceResponse", | |
| 'name', "Voice Response", | |
| 'help', "Voice response type to choose a phrase from; the phrases of the current unit will be used.", | |
| 'items', function (self) return GetVoiceResponseCombo(self, self.TargetUnit) end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(TargetUnit)> plays '<u(VoiceResponse)>'", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Target unit plays voice response", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not self.VoiceResponse then return end | |
| if not context then context = {} end | |
| local units = self:MatchMapUnits(obj, context) | |
| if units and context.target_units then | |
| local unit = context.target_units[ AsyncRand(# context.target_units) +1] | |
| if not unit or not self.VoiceResponse then return end | |
| PlayVoiceResponse(unit, self.VoiceResponse, true) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "Choose target unit" | |
| end | |
| if not self.VoiceResponse then | |
| return "Choose voice response id" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "UnitCheck", | |
| 'params', "unit, obj, context", | |
| 'code', function (self, unit, obj, context) | |
| return true | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) | |
| return {target_units = { SelectedObj}} | |
| end, | |
| 'TestObject', PlaceObj('PlayUnitVoiceResponse', { | |
| TargetUnit = "Fidel", | |
| VoiceResponse = "Order", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "PlayerGrantMoney", | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "Amount of money to grant.", | |
| 'default', 0, | |
| 'min', 0, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Grant <money(Amount)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Give money to player.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| AddMoney(self.Amount, "deposit") | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('PlayerGrantMoney', { | |
| Amount = 2, | |
| }), | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local amount = self.Amount | |
| if amount>0 then | |
| return T{666348317447, "<money(Amount)> acquired",Amount = amount} | |
| elseif amount<0 then | |
| return T{194741866993, "Paid <money(Amount)>",Amount = amount} | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseFX", | |
| 'code', function (self) | |
| return "ConversationMoneyGained" | |
| end, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "PlayerPayMoney", | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "Amount of money to pay.", | |
| 'default', 0, | |
| 'min', 0, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Pay <money(Amount)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Take money from player.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| AddMoney(-self.Amount, "expense") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local amount = self.Amount | |
| return T{194741866993, "Paid <money(Amount)>",Amount = amount} | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetUIText", | |
| 'params', "context", | |
| 'code', function (self, context) | |
| return T{982094780061, "Give <money(Amount)>", Amount = self.Amount} | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('PlayerPayMoney', { | |
| Amount = 3, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('ClassDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "QuestFunctionObjectBase", | |
| }, | |
| group = "Effects", | |
| id = "QuestEffectBase", | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "OnAfterEditorNew", | |
| 'params', "obj, socket, paste, old_id", | |
| 'code', function (self, obj, socket, paste, old_id) | |
| if not paste then | |
| local quest_def = GetParentTableOfKindNoCheck(obj, "QuestsDef") | |
| if quest_def then | |
| self.QuestId = quest_def.id | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Quests", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "QuestEffectBase", | |
| }, | |
| group = "Effects", | |
| id = "QuestKillTCE", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "QuestId", | |
| 'name', "Quest id", | |
| 'help', "Quest to change.", | |
| 'preset_class', "QuestsDef", | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "TCE", | |
| 'name', "TCE", | |
| 'help', "Quest TCE to kill", | |
| 'items', function (self) return GetQuestsVarsCombo(self.QuestId, "TCEState") end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Kills '<u(TCE)>' TCE from '<u(QuestId)>' quest", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Kills specific TCE from a given quest", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not RunningSequentialEffects then return false end | |
| if not self.QuestId or self.QuestId == "" or not self.TCE or self.TCE == "" then return false end | |
| for i = #RunningSequentialEffects, 1, -1 do | |
| local run_state = RunningSequentialEffects[i] | |
| if run_state[5] == self.QuestId and run_state[6] == self.TCE then | |
| DeleteThread(run_state[1]) | |
| table.remove(RunningSequentialEffects, i) | |
| return | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.QuestId or self.QuestId=="" then | |
| return "Specify the quest!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('QuestKillTCE', { | |
| QuestId = "_TestQuest", | |
| TCE = "TCE_State", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "QuestEffectBase", | |
| }, | |
| group = "Effects", | |
| id = "QuestSetVariableBool", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'category', "General", | |
| 'id', "QuestId", | |
| 'name', "Quest id", | |
| 'help', "Quest to change.", | |
| 'preset_class', "QuestsDef", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| return QuestHasVariable(preset, "QuestVarBool") | |
| end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'category', "General", | |
| 'id', "Prop", | |
| 'name', "Quest Variable", | |
| 'help', "Quest variable to change.", | |
| 'items', function (self) return GetQuestsVarsCombo(self.QuestId,"Bool") end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'category', "General", | |
| 'id', "Toggle", | |
| 'name', "Toggle Current Value", | |
| 'help', "Toggles the current flag value (changes it from 'true' to 'false' and vice versa).", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'category', "General", | |
| 'id', "Set", | |
| 'name', "Change to", | |
| 'help', "Value to set.", | |
| 'extra_code', "no_edit = function(self) return self.Toggle end", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "A way to change the quest's flag. If not 'Toggle' then changes the flag to 'Set' value, else toggle the flag's value.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local quest = QuestGetState(self.QuestId or "") | |
| if not quest then return end | |
| if self.Toggle then | |
| SetQuestVar(quest, self.Prop, not rawget(quest, self.Prop)) | |
| else | |
| SetQuestVar(quest, self.Prop, self.Set) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.QuestId or self.QuestId=="" then | |
| return "Specify the quest!" | |
| end | |
| if not self.Prop then | |
| return "Specify the param to change!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.Toggle then | |
| return Untranslated("Quest <u(QuestId)>: toggle <u(Prop)>") | |
| else | |
| return Untranslated("Quest <u(QuestId)>: <u(Prop)> = " .. tostring(self.Set)) | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('QuestSetVariableBool', { | |
| Prop = "TalkedToLuc", | |
| QuestId = "01_Landing", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "QuestEffectBase", | |
| }, | |
| group = "Effects", | |
| id = "QuestSetVariableNum", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'category', "General", | |
| 'id', "QuestId", | |
| 'name', "Quest id", | |
| 'help', "Quest to change.", | |
| 'preset_class', "QuestsDef", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| return QuestHasVariable(preset, "QuestVarNum") | |
| end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'category', "General", | |
| 'id', "Prop", | |
| 'name', "Quest Variable", | |
| 'help', "Quest variable to change.", | |
| 'items', function (self) return GetQuestsVarsCombo(self.QuestId,"Num") end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'category', "General", | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "Value to set.", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'category', "General", | |
| 'id', "RandomRangeMax", | |
| 'name', "Random Amount Max", | |
| 'help', 'If set, the amount will be a random number between "Amount" and this number. Both values are inclusive.', | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'category', "General", | |
| 'id', "Percent", | |
| 'name', "Percent", | |
| 'help', "Percent change to current value, if operation is modify.", | |
| 'default', 100, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'category', "General", | |
| 'id', "Operation", | |
| 'name', "Operation", | |
| 'help', "Modify the current value with amount/percent or set a new one.", | |
| 'default', "modify", | |
| 'items', function (self) return {"set", "modify"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change a quest variable's value. Modifies the current value wiyh amount/percent or sets a new amount.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local quest = QuestGetState(self.QuestId or "") | |
| if not quest then return end | |
| local prev_val = rawget(quest,self.Prop) | |
| local new_val | |
| local mod_amount = self.Amount | |
| if self.RandomRangeMax then | |
| mod_amount = mod_amount + InteractionRand(self.RandomRangeMax - mod_amount + 1, "QuestVariableNum") | |
| end | |
| if self.Operation=="set" then | |
| new_val = mod_amount | |
| elseif self.Operation=="modify" then | |
| new_val = (prev_val or 0) + mod_amount | |
| if self.Percent~=0 then | |
| new_val = MulDivRound(new_val, self.Percent, 100) | |
| end | |
| end | |
| SetQuestVar(quest, self.Prop, new_val) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.QuestId or self.QuestId=="" then | |
| return "Specify the quest!" | |
| end | |
| if not self.Prop then | |
| return "Specify the param to change!" | |
| end | |
| if self.RandomRangeMax and self.RandomRangeMax < self.Amount then | |
| return "Max cannot be smaller than min (Amount)." | |
| end | |
| if self.Operation~="set" then | |
| local quest = QuestGetState(self.QuestId or "") | |
| local prev_val = rawget(quest,self.Prop) | |
| if not prev_val then | |
| return "This prop has not set any value and can not be changed" | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local printValue = "<Amount>" | |
| if self.RandomRangeMax then | |
| printValue = printValue .. "-<RandomRangeMax>" | |
| end | |
| if self.Operation=="set" then | |
| return Untranslated("Quest <u(QuestId)>:<u(Prop)> = " .. printValue) | |
| elseif self.Operation=="modify" then | |
| return Untranslated("Quest <u(QuestId)>:<u(Prop)> = <Percent>% from (<u(Prop)> + " .. printValue .. ")") | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('QuestSetVariableNum', { | |
| Amount = 5, | |
| Operation = "set", | |
| Prop = "TestVarNum", | |
| QuestId = "_TestQuest", | |
| RandomRangeMax = 10, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "QuestEffectBase", | |
| }, | |
| group = "Effects", | |
| id = "QuestSetVariableSpecialValue", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'category', "General", | |
| 'id', "QuestId", | |
| 'name', "Quest id", | |
| 'help', "Quest to change.", | |
| 'preset_class', "QuestsDef", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| return QuestHasVariable(preset, "QuestVarNum") | |
| end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'category', "General", | |
| 'id', "Prop", | |
| 'name', "Quest Variable", | |
| 'help', "Quest variable to change.", | |
| 'no_validate', true, | |
| 'items', function (self) return GetQuestsVarsCombo(self.QuestId,"Num") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'category', "General", | |
| 'id', "Special", | |
| 'name', "Special value type", | |
| 'help', "Value to set.", | |
| 'default', "current campaign time", | |
| 'items', function (self) return {"current campaign time"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set a quest number variable to a special value, chosen from the Special property.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local quest = QuestGetState(self.QuestId or "") | |
| if not quest then return end | |
| local new_val | |
| if self.Special == "current campaign time" then | |
| new_val = Game.CampaignTime | |
| end | |
| SetQuestVar(quest, self.Prop, new_val) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.QuestId or self.QuestId=="" then | |
| return "Specify the quest!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.Special == "current campaign time" then | |
| return Untranslated("Quest <u(QuestId)>:<u(Prop)> = current campaign time") | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('QuestSetVariableSpecialValue', { | |
| Prop = "TestVarNum", | |
| QuestId = "_TestQuest", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "QuestEffectBase", | |
| }, | |
| group = "Effects", | |
| id = "QuestSetVariableText", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'category', "General", | |
| 'id', "QuestId", | |
| 'name', "Quest id", | |
| 'help', "Quest to change.", | |
| 'preset_class', "QuestsDef", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| return QuestHasVariable(preset, "QuestVarText") | |
| end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'category', "General", | |
| 'id', "Prop", | |
| 'name', "Quest Variable", | |
| 'help', "Quest variable to change", | |
| 'items', function (self) return GetQuestsVarsCombo(self.QuestId, "Text") end, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'category', "General", | |
| 'id', "Text", | |
| 'name', "Text", | |
| 'help', "Value to set.", | |
| 'default', '""', | |
| 'translate', false, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Quest <u(QuestId)>:<u(Prop)> = '<u(Text)>'", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change a quest's text variable.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local quest = QuestGetState(self.QuestId or "") | |
| if not quest then return end | |
| SetQuestVar(quest, self.Prop, self.Text) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.QuestId or self.QuestId=="" then | |
| return "Specify the quest!" | |
| end | |
| if not self.Prop then | |
| return "Specify the param to change!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('QuestSetVariableText', { | |
| Prop = "TestVarText", | |
| QuestId = "_TestQuest", | |
| Text = "test", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "QuestEffectBase", | |
| }, | |
| group = "Effects", | |
| id = "QuestSetVariableTimer", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'category', "General", | |
| 'id', "QuestId", | |
| 'name', "Quest id", | |
| 'help', "Quest to change.", | |
| 'preset_class', "QuestsDef", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| return QuestHasVariable(preset, "QuestVarNum") | |
| end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'category', "General", | |
| 'id', "Prop", | |
| 'name', "Quest Variable", | |
| 'help', "Quest variable to change.", | |
| 'items', function (self) return GetQuestsVarsCombo(self.QuestId,"Num") end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'category', "General", | |
| 'id', "TimeAmount", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'category', "General", | |
| 'id', "TimeAmountRangeMax", | |
| 'help', "If set the time amount will be randomed between TimeAmount and this value.", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'category', "General", | |
| 'id', "Timescale", | |
| 'default', "h", | |
| 'items', function (self) return GetTimeScalesCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set a timer to a quest variable.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local quest = QuestGetState(self.QuestId or "") | |
| if not quest then return end | |
| local prev_val = rawget(quest, self.Prop) | |
| local timeAmount = self.TimeAmount | |
| if self.TimeAmountRangeMax ~= 0 then | |
| timeAmount = timeAmount + InteractionRand(self.TimeAmountRangeMax - timeAmount + 1, "QuestVariableTimer") | |
| end | |
| timeAmount = timeAmount * (const.Scale[self.Timescale] or const.Scale.h) | |
| local triggerTime = Game.CampaignTime + timeAmount | |
| SetQuestVar(quest, self.Prop, triggerTime) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.QuestId or self.QuestId=="" then | |
| return "Specify the quest!" | |
| end | |
| if not self.Prop then | |
| return "Specify the param to change!" | |
| end | |
| if (self.TimeAmountRangeMax or 0) ~= 0 and self.TimeAmountRangeMax < self.TimeAmount then | |
| return "Max cannot be smaller than min (TimeAmount)." | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local printValue = "<TimeAmount>" | |
| if (self.TimeAmountRangeMax or 0) ~= 0 then | |
| printValue = printValue .. "-<TimeAmountRangeMax>" | |
| end | |
| return Untranslated("Set quest timer in <u(QuestId)>:<u(Prop)> for after " .. printValue .. " " .. self.Timescale) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('QuestSetVariableTimer', { | |
| Prop = "TimeToBetrayal", | |
| QuestId = "03_DefeatTheLegion", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "ConversationFunctionObjectBase", | |
| }, | |
| group = "Effects", | |
| id = "RadioStartConversation", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Conversation", | |
| 'name', "Conversation", | |
| 'help', "Conversation to start.", | |
| 'preset_class', "Conversation", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Icon", | |
| 'default', "UI/Hud/radio", | |
| 'items', function (self) return GetRadioConversationIconsCombo end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Start radio conversation <u(Conversation)>.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Starts a specific radio conversation - no groups or conditions are checked.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| StartConversationEffect(self.Conversation, {radio = true, icon = self.Icon}) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| StartConversationEffect(self.Conversation, {radio = true, icon = self.Icon}, "wait") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Conversation then | |
| return "Please specify conversation" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'params', "thread, stack, stack_index", | |
| 'code', function (self, thread, stack, stack_index) | |
| return "RadioStartConversation", self.Conversation, self.Icon | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('RadioStartConversation', { | |
| Conversation = "Bastien_3", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "RandomEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "ReturnClass", | |
| 'type', "text", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Play a random effect from a list.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Play a random effect from a list.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local num = #self.Effects | |
| if num > 0 then | |
| local roll = InteractionRand(num, "RandomEffect") + 1 | |
| self.Effects[roll]:__exec() | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefNestedList', { | |
| 'id', "Effects", | |
| 'name', "Effects", | |
| 'base_class', "Effect", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Effects or #self.Effects < 1 then | |
| return "Please specify some effects" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('RandomEffect', { | |
| Effects = { | |
| PlaceObj('PlayerGrantMoney', { | |
| Amount = 10, | |
| }), | |
| PlaceObj('PlayerGrantMoney', { | |
| Amount = 20, | |
| }), | |
| }, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "RandomEffectWithCondition", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "ReturnClass", | |
| 'type', "text", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Play a random effect from a list whose conditions evaluate to true.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Play a random effect from a list whose conditions evaluate to true.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local valid = {} | |
| for i, eff in ipairs(self.Effects) do | |
| if EvalConditionList(eff.Conditions, obj, context) then | |
| valid[#valid + 1] = eff | |
| end | |
| end | |
| local num = #valid | |
| if num > 0 then | |
| local roll = InteractionRand(num, "RandomEffect") + 1 | |
| local effRolled = valid[roll] | |
| local effects = effRolled.Effects | |
| for _, effect in ipairs(effects) do | |
| effect:__exec(obj, context) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefNestedList', { | |
| 'id', "Effects", | |
| 'name', "Effects", | |
| 'base_class', "ConditionalEffect", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Effects or #self.Effects < 1 then | |
| return "Please specify some effects" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('RandomEffectWithCondition', { | |
| Effects = { | |
| PlaceObj('ConditionalEffect', { | |
| 'Conditions', { | |
| PlaceObj('CheckExpression', {}), | |
| }, | |
| 'Effects', { | |
| PlaceObj('PlayerGrantMoney', { | |
| Amount = 10, | |
| }), | |
| }, | |
| }), | |
| PlaceObj('ConditionalEffect', { | |
| 'Conditions', { | |
| PlaceObj('CheckExpression', { | |
| Expression = function (self, obj) return false end, | |
| }), | |
| }, | |
| 'Effects', { | |
| PlaceObj('PlayerGrantMoney', { | |
| Amount = 10000, | |
| }), | |
| }, | |
| }), | |
| PlaceObj('ConditionalEffect', { | |
| 'Conditions', { | |
| PlaceObj('CheckExpression', {}), | |
| }, | |
| 'Effects', { | |
| PlaceObj('PlayerPayMoney', { | |
| Amount = 10, | |
| }), | |
| }, | |
| }), | |
| }, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "RechargeCDs", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| "UnitData", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Recharge a unit's CDs", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Recharge a unit's CDs", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOfClasses(obj, "Unit", "UnitData") and not obj:IsDead() then | |
| obj:RechargeSignatures() | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('RechargeCDs', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "RegenerateGuardpostObjective", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "GuardpostObjective", | |
| 'name', "GuardpostObjective", | |
| 'preset_class', "GuardpostObjective", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Regenerate guardpost objective <u(GuardpostObjective)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Regenerate a completed guardpost objective.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetGuardpostObjectiveRegenerated(self.GuardpostObjective) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('RegenerateGuardpostObjective', { | |
| GuardpostObjective = "AbandonedMansion", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sectors", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ReplaceMercEffect", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "ExistingMerc", | |
| 'name', "Existing Merc", | |
| 'help', "Existing merc to replace.", | |
| 'items', function (self) return MercPresetCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "NewMercDef", | |
| 'name', "New Merc Definition", | |
| 'help', "New merc definition to use for replacement.", | |
| 'items', function (self) return MercPresetCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Replace <u(ExistingMerc)> with <u(NewMercDef)> keeping his progress.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Replace a merc with another definition while keeping his progress. Example use: switch Larry to Larry_Clean.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| ReplaceMerc(self.ExistingMerc, self.NewMercDef, "keepInventory") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.ExistingMerc then | |
| return "Choose an existing merc to replace" | |
| end | |
| if not self.NewMercDef then | |
| return "Choose a new merc definition to replace the existing one with" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetUIText", | |
| 'params', "context,template, game", | |
| 'code', function (self, context,template, game) | |
| local merc = gv_UnitData and gv_UnitData[self.Merc] | |
| local name | |
| if not merc then | |
| name = game and "" or Untranslated("[MercName]") | |
| else | |
| name = merc.Nick or merc.Name | |
| end | |
| return T{246469241790, "Recruit merc (<em><name></em>)", name= name} | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ReplaceMercEffect', { | |
| ExistingMerc = "Larry", | |
| NewMercDef = "Larry_Clean", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ResetAmbientLife", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Ephemeral", | |
| 'name', "Ephemeral Only", | |
| 'help', "All ambient life units or just ephemeral ones.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "KickPerpetualUnits", | |
| 'name', "Kick Perpetual Units", | |
| 'help', "If checked perpetual units will be reset too, otherwise they will stay in their markers.", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "ForceImmediateKick", | |
| 'name', "Force Immediate Kick", | |
| 'help', "Forces immedite kick so the marker and the unit can be used right away - usually clearing the marker happens after playing exit animation. Anyway if UnitsStealForPerpetualMarkers effect is scheduled right after this one it can not work as expected since it will be called before the destructors and the units/marker will be still busy", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Reset Ambient Life Behavior", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Forces all units in ambient life behavior to check the condition of the spot they are using and makes them leave if that condition is not met", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| for _, unit in ipairs(g_Units) do | |
| if (not self.Ephemeral or unit.ephemeral) and unit:IsVisiting() then | |
| unit:ResetAmbientLife(self.KickPerpetualUnits, self.ForceImmediateKick) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ResetAmbientLife', { | |
| Ephemeral = false, | |
| KickPerpetualUnits = true, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "RestoreHealth", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| "UnitData", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Restore unit's health", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Restores unit's health", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOfClasses(obj, "Unit", "UnitData") and not obj:IsDead() then | |
| obj.HitPoints = Min(obj.MaxHitPoints, obj.HitPoints + self.amount) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('RestoreHealth', {}), | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "amount", | |
| 'name', "Amount", | |
| 'default', 9999, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SatelliteShortcutSetSpeed", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "shortcut_id", | |
| 'items', function (self) return PresetsCombo("SatelliteShortcutPreset") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "speed_const", | |
| 'help', "The constant denoting the shortcut's speed", | |
| 'default', "RiverTravelTime", | |
| 'items', function (self) return ConstCategoryToCombo(const.SatelliteShortcut) end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set the speed of a satellite shortcut", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SatelliteShortcutChangeSpeed(self.shortcut_id, self.speed_const) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.shortcut_id then | |
| return "Specify shortcut!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable then | |
| return Untranslated("Enable satellite shortcut <u(shortcut_id)>", self) | |
| else | |
| return Untranslated("Disable satellite shortcut <u(shortcut_id)>", self) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SatelliteShortcutSetSpeed', { | |
| shortcut_id = "SubwayB11toF12", | |
| speed_const = "UBahnFast", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SatelliteShortcutUnlockEffect", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "shortcut_id", | |
| 'items', function (self) return PresetsCombo("SatelliteShortcutPreset") end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "enable", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable a satellite shortcut", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SatelliteShortcutSetEnabled(self.shortcut_id, self.enable) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.shortcut_id then | |
| return "Specify shortcut!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable then | |
| return Untranslated("Enable satellite shortcut <u(shortcut_id)>", self) | |
| else | |
| return Untranslated("Disable satellite shortcut <u(shortcut_id)>", self) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SatelliteShortcutUnlockEffect', { | |
| shortcut_id = "RiverStartK9toH9_Mid_3", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ScatterAmbientLife", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Scatter Ambient Life", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "orders all of the ambient life units on the map (ones spawned from AmbientZones) to stop what they are doing on the spot and trigger the conflict logic.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| ChangeGameState({ConflictScripted=true}) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ScatterAmbientLife', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorAddOperationProgress", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "operation", | |
| 'name', "Operation", | |
| 'help', "Operation to add progress to.", | |
| 'items', function (self) return table.keys(SectorOperations) end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "perc", | |
| 'name', "Add Perc", | |
| 'help', "Percent of the target progress that will be added.", | |
| 'default', 0, | |
| 'min', 0, | |
| 'max', 100, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Adds progress to a given operation in a given sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SectorOperations[self.operation]:BoostProgress(self.perc, gv_Sectors[self.sector_id]) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Adds <percent(perc)> progress to <u(operation)> in sector <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorAddOperationProgress', { | |
| operation = "HospitalTreatment", | |
| perc = 34, | |
| sector_id = "A10", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorDisableAutoResolve", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "value", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/Disable auto-resolve on the sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if sector then | |
| sector.autoresolve_disabled = not self.value | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.value then | |
| return Untranslated("Enable auto-resolve for sector <u(sector_id)>") | |
| else | |
| return Untranslated("Disable auto-resolve for sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorDisableAutoResolve', { | |
| sector_id = "H4", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorEnableAutoDeploy", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "deploy", | |
| 'help', "Enable/disable auto-deploy on enter.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/Disable auto-deploy mode on sector enter", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if sector then | |
| sector.enabled_auto_deploy = self.deploy | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.deploy then | |
| return Untranslated("Enable auto-deploy for sector <u(sector_id)>") | |
| else | |
| return Untranslated("Disable auto-deploy for sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorEnableAutoDeploy', { | |
| deploy = false, | |
| sector_id = "A1", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "LootTableFunctionObjectBase", | |
| }, | |
| group = "Effects", | |
| id = "SectorEnableCustomOperation", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "operation", | |
| 'name', "Operation", | |
| 'help', "Custom operation.", | |
| 'items', function (self) return GetCustomOperations() end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "DisplayLog", | |
| 'name', "Display in Log", | |
| 'help', "Whether to display enabling the Operation in the combat log", | |
| }), | |
| PlaceObj('PropertyDefNestedList', { | |
| 'category', "Execution", | |
| 'id', "EffectsOnSuccess", | |
| 'name', "On Success", | |
| 'help', "Effects that are executed after the operation is completed.", | |
| 'base_class', "Effect", | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'category', "Execution", | |
| 'id', "LootTableId", | |
| 'name', "Loot Table Id", | |
| 'help', "Loot table to generate items that will be granted after the operation is completed.", | |
| 'preset_class', "LootDef", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'category', "Execution", | |
| 'id', "GrantItemApply", | |
| 'name', "GrantItemApply", | |
| 'help', 'Loot table roll - "first"(merc) - only once, "all"(mercs) for each merc', | |
| 'default', "first", | |
| 'items', function (self) return {"first", "all"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enables custom operation in the sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if not sector then return end | |
| sector.custom_operations = sector.custom_operations or {} | |
| sector.custom_operations[self.operation] = { | |
| status = "enabled", | |
| progress = 0, | |
| EffectsOnSuccess = self.EffectsOnSuccess, | |
| LootTableId = self.LootTableId, | |
| GrantItemApply = self.GrantItemApply | |
| } | |
| ObjModified(sector) | |
| ObjModified(gv_Squads) | |
| if self.DisplayLog then | |
| CombatLog("important",T{537039992460, "New <em>Sector Operation</em> available (<em><SectorId(sector)></em>): <em><ActivityName></em>", ActivityName = SectorOperations[self.operation] and SectorOperations[self.operation].display_name or "", sector = self.sector_id}) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Enables custom Operation <u(operation)> in sector <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| elseif not self.operation then | |
| return "Specify custom operation!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| return T{588881082990, "Operation is available: <em><ActivityName></em>", ActivityName = SectorOperations[self.operation] and SectorOperations[self.operation].display_name or ""} | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorEnableCustomOperation', { | |
| GrantItemApply = "all", | |
| LootTableId = "AdonisArmor_Pants_Body_Medium", | |
| operation = "ArcheologicalRuins_ImproveMine", | |
| sector_id = "A17", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "SectorEnableWarningState", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Enable", | |
| 'name', "Enable", | |
| 'help', "Enable", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'default', "current", | |
| 'items', function (self) return table.iappend({{text="current",value="current"}}, GetCampaignSectorsCombo()) end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/Disable the Warning State mechanic for sector. (does NOT trigger it)", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Change <u(sector_id)> sector's WarningStateEnabled to <Bool(Enable)>. (does NOT trigger it)", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector_id = self.sector_id == "current" and gv_CurrentSectorId or self.sector_id | |
| local sector = gv_Sectors[sector_id] | |
| sector.warningStateEnabled = self.Enable | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorEnableWarningState', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorEnterConflict", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "conflict_mode", | |
| 'help', "Force or resolve conflict in that sector.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return table.iappend({{text="current",value="current"}}, GetCampaignSectorsCombo()) end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "disable_travel", | |
| 'help', "Disables all travel zones on the map.", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "lock_conflict", | |
| 'help', "Killing all enemies on the map cannot resolve a locked conflict, only scripts can.", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "no_exploration_resolve", | |
| 'help', "dont resolve conflict in exploration", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "descr_id", | |
| 'help', 'This text is displayed when the "Conflict" text is rolled over and in the description of the conflict window. Define texts in the conflict descriptions editor.', | |
| 'items', function (self) return PresetGroupCombo("ConflictDescription", "Default") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "spawn_mode", | |
| 'items', function (self) return {"attack", "defend", "explore"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Forces/Resolve conflict mode for the speciafied sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = self.sector_id == "current" and gv_Sectors[gv_CurrentSectorId] or gv_Sectors[self.sector_id] | |
| if not sector then return end | |
| if self.conflict_mode then | |
| ForceEnterConflictEffect( | |
| sector, | |
| self.spawn_mode, | |
| self.disable_travel, | |
| self.lock_conflict, | |
| self.descr_id, | |
| self.no_exploration_resolve and "force-exploration-only" or "force" | |
| ) | |
| else | |
| sector.ForceConflict = false | |
| if gv_Sectors[gv_CurrentSectorId] == sector then | |
| if sector.conflict then | |
| sector.conflict.locked = false | |
| end | |
| CheckMapConflictResolved("no voice") | |
| else | |
| ResolveConflict(sector, "no voice") | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.conflict_mode then | |
| return Untranslated("Force conflict mode for sector <u(sector_id)>") | |
| else | |
| return Untranslated("Remove forced conflict mode for sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorEnterConflict', { | |
| sector_id = "I3", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorGrantIntel", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Grants intel for the sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| DiscoverIntelForSector(self.sector_id) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Grant intel for sector <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local campaign = CampaignPresets[Game and Game.Campaign or DefaultCampaign] | |
| local sector = gv_Sectors and gv_Sectors[self.sector_id] or table.find_value(campaign.Sectors, "Id", self.sector_id) | |
| if sector and sector.intel_discovered then | |
| return T{903574434021, "<em>Intel</em> is already available for <em><SectorName(sector)></em>", sector = sector} | |
| end | |
| return T{223883822777, "Gained <em>Intel</em> for <em><SectorName(sector)></em>", sector = sector} | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorGrantIntel', { | |
| sector_id = "A1", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorModifyEnemySquads", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "percent", | |
| 'name', "Percent", | |
| 'help', "Percent for enemy count modification.", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "count", | |
| 'name', "Count", | |
| 'help', "Specific count for enemy count modification.", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "UnitTemplate", | |
| 'name', "UnitTemplate", | |
| 'help', "Unit template that will be affected or all if false.", | |
| 'items', function (self) return GetEnemySquadsUnitTemplates("all") end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "The spawned enemy squads in that sector get their units or specified type of units decreased or increased by that specified percent. To remove all units from unittype, set pecent to -100", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local value, valueType = self.percent, "percent" | |
| local count = self.count | |
| if count and count ~= 0 then | |
| value = count | |
| valueType = "count" | |
| end | |
| ModifySectorEnemySquads(self.sector_id, value, valueType, self.UnitTemplate) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local value, valueType = self.percent, "percent" | |
| local count = self.count | |
| if count and count ~= 0 then | |
| value = count | |
| valueType = "count" | |
| end | |
| local valString = valueType == "percent" and (tostring(value) .. "%") or tostring(value) | |
| if value > 0 then | |
| if self.UnitTemplate then | |
| return Untranslated("Increases <u(UnitTemplate)> units in enemy squads force in <u(sector_id)> by " .. valString) | |
| else | |
| return Untranslated("Increases all enemies in <u(sector_id)> by ".. valString) | |
| end | |
| else | |
| if self.UnitTemplate then | |
| return Untranslated("Decreases <u(UnitTemplate)> units in enemy squads force in <u(sector_id)> by " .. valString) | |
| else | |
| return Untranslated("Decreases all enemies in <u(sector_id)> by " .. valString) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorModifyEnemySquads', { | |
| UnitTemplate = "LegionRaider", | |
| percent = 100, | |
| sector_id = "F7", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorModifyMineProperties", | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "DepletionTime", | |
| 'name', "Depletion Income Modifier Percent", | |
| 'help', "% modifier for depletion time", | |
| 'min', 1, | |
| 'max', 500, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "DailyIncome", | |
| 'name', "Daily Income Modifier Percent", | |
| 'help', "% modifier for profit per day at 100% loyalty. For instance 200 would double, and 50 would halve", | |
| 'min', 0, | |
| 'max', 1000, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Modify diamond mine properties for a given sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if self.DepletionTime then | |
| if not sector.depletion_mods then sector.depletion_mods = {} end | |
| sector.depletion_mods[#sector.depletion_mods + 1] = self.DepletionTime | |
| end | |
| if self.DailyIncome then | |
| if not sector.income_mods then sector.income_mods = {} end | |
| sector.income_mods[#sector.income_mods + 1] = self.DailyIncome | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Modify diamond mine related properties on <sector_id>") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| if self.DailyIncome and next(gv_Sectors) then | |
| local name = gv_Sectors[self.sector_id].display_name | |
| if self.DailyIncome > 100 then | |
| return T{830978589245, "<Name> diamond production increased by <(value -100)>%", value = self.DailyIncome, Name = name} | |
| end | |
| if self.DailyIncome<100 then | |
| return T{340934605682, "<Name> diamond production decreased by <(100-value)>%", value = self.DailyIncome, Name = name} | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorModifyMineProperties', { | |
| DailyIncome = 200, | |
| sector_id = "H4", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorRemoveCustomOperation", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "operation", | |
| 'name', "Operation", | |
| 'help', "Remove custom operation.", | |
| 'items', function (self) return GetCustomOperations() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Removes custom operation in the sector, sets operation mercs to Idle", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if not sector then return end | |
| local operation = self.operation | |
| if sector.custom_operations and sector.custom_operations[operation] then | |
| sector.custom_operations[operation] = nil | |
| end | |
| local mercs = GetPlayerSectorUnits(self.sector_id) | |
| SectorOperation_CancelByGame(mercs, operation, true) | |
| ObjModified(sector) | |
| ObjModified(gv_Squads) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Removes custom Operation <u(operation)> in sector <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| elseif not self.operation then | |
| return "Specify custom operation!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| return T{565334741205, "<ActivityName> Operation is unavailable", ActivityName = SectorOperations[self.operation] and SectorOperations[self.operation].display_name or ""} | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorRemoveCustomOperation', { | |
| operation = "HospitalTreatmentCustom", | |
| sector_id = "A19", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "SectorReplaceEnemySquadList", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Overrides EnemySquadList in sector <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Overrides EnemySquadList in a given sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if not sector then return end | |
| if sector.EnemySquadsList and #sector.EnemySquadsList > 0 then | |
| sector.EnemySquadsList = table.copy(self.EnemySquadsList) | |
| end | |
| if sector.StrongEnemySquadsList and #sector.StrongEnemySquadsList > 0 then | |
| sector.StrongEnemySquadsList = table.copy(self.StrongEnemySquadsList) | |
| end | |
| if sector.ExtraDefenderSquads and #sector.ExtraDefenderSquads > 0 then | |
| sector.ExtraDefenderSquads = table.copy(self.ExtraDefenderSquads) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefPresetIdList', { | |
| 'id', "EnemySquadsList", | |
| 'name', "Enemy Squads List", | |
| 'help', "A random squad from the list will be chosen on guardpost spawn time.", | |
| 'extra_code', "", | |
| 'preset_class', "EnemySquads", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| if preset.group ~= "Test Encounters" then return obj end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefPresetIdList', { | |
| 'id', "StrongEnemySquadsList", | |
| 'name', "Strong Enemy Squads List", | |
| 'extra_code', "", | |
| 'preset_class', "EnemySquads", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| if preset.group ~= "Test Encounters" then return obj end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefPresetIdList', { | |
| 'id', "ExtraDefenderSquads", | |
| 'name', "Extra Defender Squads", | |
| 'extra_code', "", | |
| 'preset_class', "EnemySquads", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| if preset.group ~= "Test Encounters" then return obj end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorReplaceEnemySquadList', { | |
| EnemySquadsList = { | |
| "ColonialSquad", | |
| }, | |
| ExtraDefenderSquads = { | |
| "ColonialSquad", | |
| }, | |
| sector_id = "H4", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "SectorReplaceTargetSectors", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Overrides TargetSectors in a given sector", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Overrides TargetSectors in a given sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if sector then | |
| sector.TargetSectors = table.copy(self.TargetSectors, "deep") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefStringList', { | |
| 'id', "TargetSectors", | |
| 'name', "Target Sectors", | |
| 'help', "Target sectors for spawned enemy squads.", | |
| 'extra_code', "", | |
| 'items', function (self) return GetCampaignSectorsCombo("") end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorReplaceTargetSectors', { | |
| TargetSectors = { | |
| "C1", | |
| "D2", | |
| }, | |
| sector_id = "F7", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetAwarenessSequence", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "awareness_sequence", | |
| 'name', "Awareness Sequence", | |
| 'default', "Standard", | |
| 'items', function (self) return { "Standard", "Skip Setpiece", "Skip All" } end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/Disable auto-deploy mode on sector enter", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if sector then | |
| sector.awareness_sequence = self.awareness_sequence | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated(string.format("Set Awareness Sequence for for sector <u(sector_id)> to %s", self.awareness_sequence)) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetAwarenessSequence', { | |
| sector_id = "A1", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetCustomConflictDesc", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "descr_id", | |
| 'help', 'This text is displayed when the "Conflict" text is rolled over and in the description of the conflict window. Define texts in the conflict descriptions editor.', | |
| 'items', function (self) return PresetGroupCombo("ConflictDescription", "Default") end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set a custom conflict description for the given sector. Cleared when the conflict is resolved.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| sector.CustomConflictDescr = self.descr_id | |
| if sector.conflict and not sector.conflict.descr_id then | |
| sector.conflict.descr_id = self.descr_id | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Set conflict description <u(descr_id)> for <u(sector_id)>") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| if not self.descr_id then | |
| return "Specify description preset!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetCustomConflictDesc', { | |
| descr_id = "DiamondRed_Quest", | |
| sector_id = "A2", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetForceConflict", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "force", | |
| 'name', "Force Conflict", | |
| 'help', "Force conflict value.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/Disable 'force conflict' for the sector - entering sectors with force conflict set to true results in conflict mode with or without enemy presence in the sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not gv_Sectors[self.sector_id] then return end | |
| gv_Sectors[self.sector_id].ForceConflict = self.force | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.force then | |
| return Untranslated("Enable sector <u(sector_id)> force conflict") | |
| else | |
| return Untranslated("Disable sector <u(sector_id)> force conflict") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorSetForceConflict', { | |
| force = true, | |
| sector_id = "I3", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetHospital", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "enable", | |
| 'help', "Add/remove hospital in sector.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/disable hospital in specified sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| sector.HospitalLocked = not self.enable | |
| sector.Hospital = true -- Legacy | |
| Msg("BuildingLockChanged", self.sector_id) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| return T{588881082990, "Operation is available: <em><ActivityName></em>", ActivityName = SectorOperations["HospitalTreatment"] and SectorOperations["HospitalTreatment"].display_name or ""} | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable then | |
| return Untranslated("Enable hospital in sector <u(sector_id)>") | |
| else | |
| return Untranslated("Disable hospital in sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetHospital', { | |
| sector_id = "A1", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetMap", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MapFile", | |
| 'default', "", | |
| 'items', function (self) return ListMaps() end, | |
| }), | |
| PlaceObj('PropertyDefUIImage', { | |
| 'id', "image", | |
| }), | |
| PlaceObj('PropertyDefUIImage', { | |
| 'id', "loading_screen", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change the map of a sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sectorPreset = gv_Sectors[self.sector_id] | |
| if sectorPreset then | |
| sectorPreset.Map = self.MapFile | |
| if self.image and self.image ~= "" then | |
| sectorPreset.image = self.image | |
| end | |
| if self.loading_screen and self.loading_screen ~= "" then | |
| sectorPreset.override_loading_screen = self.loading_screen | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Change the sector map of <u(sector_id)> to <u(MapFile)>", self) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| elseif self.enable_sticky and self.disable_sticky then | |
| return "You cannot both enable and disable sticky side, choose one" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorSetMap', { | |
| MapFile = "K-11U - Cryolabor", | |
| sector_id = "G12_Underground", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetMilitia", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "enable", | |
| 'help', "Set militia in sector.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/disable militia in specified sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| gv_Sectors[self.sector_id].Militia = self.enable | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable then | |
| return Untranslated("Enable militia in sector <u(sector_id)>") | |
| else | |
| return Untranslated("Disable militia in sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetMilitia', { | |
| sector_id = "A1", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetMineProperties", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Depletion", | |
| 'default', "no-change", | |
| 'items', function (self) return { "no-change", "enabled", "disabled" } end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "HasMine", | |
| 'default', "no-change", | |
| 'items', function (self) return { "no-change", "enabled", "disabled" } end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "DepletionTime", | |
| 'help', "In how many days the mine will deplete", | |
| 'min', 1, | |
| 'max', 500, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "DailyIncome", | |
| 'help', "Profit per day at 100% loyalty", | |
| 'min', 0, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set diamond mine properties for a given sector.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if self.Depletion ~= "no-change" then | |
| sector.Depletion = self.Depletion == "enabled" | |
| end | |
| if self.HasMine ~= "no-change" then | |
| sector.Mine = self.HasMine == "enabled" | |
| end | |
| if self.DepletionTime then | |
| sector.DepletionTime = self.DepletionTime | |
| end | |
| if self.DailyIncome then | |
| sector.DailyIncome = self.DailyIncome | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Set diamond mine related properties on <sector_id>") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetMineProperties', { | |
| DailyIncome = 4214, | |
| DepletionTime = 500, | |
| HasMine = "enabled", | |
| sector_id = "I1", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetPort", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "enable", | |
| 'help', "Add/remove port in sector.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/disable port in specified sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| sector.PortLocked = not self.enable | |
| sector.Port = true -- Legacy | |
| if sector.Side == "player1" or sector.Side == "player2" then | |
| gv_PlayerSectorCounts["Port"] = gv_PlayerSectorCounts["Port"] + 1 | |
| end | |
| Msg("BuildingLockChanged", self.sector_id) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable then | |
| return Untranslated("Enable port in sector <u(sector_id)>") | |
| else | |
| return Untranslated("Disable port in sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetPort', { | |
| sector_id = "F5", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetRAndROperation", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "enable", | |
| 'help', "Set RAndR operation in sector.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/disable RAndR operation in specified sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| gv_Sectors[self.sector_id].RAndRAllowed = self.enable | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable then | |
| return Untranslated("Enable RAndR in sector <u(sector_id)>") | |
| else | |
| return Untranslated("Disable RAndR in sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetRAndROperation', { | |
| sector_id = "A9", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetRepairShopOperation", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "enable", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enable/Disable Repair Shop operations in the specified sector.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| gv_Sectors[self.sector_id].RepairShop = self.enable | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable then | |
| return Untranslated("Enable Repair Shop operations in sector <u(sector_id)>") | |
| else | |
| return Untranslated("Disable Repair Shop operations in sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorSetRepairShopOperation', { | |
| sector_id = "I3", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSetSide", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "side", | |
| 'name', "Side", | |
| 'help', "Choose side for sector.", | |
| 'default', "player1", | |
| 'items', function (self) return table.iappend(table.map(SideDefs, "Id"), {"dont-change"}) end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "enable_sticky", | |
| 'name', "Enable Sticky Side", | |
| 'help', "This will forcefully set sticky side to true.", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "disable_sticky", | |
| 'name', "Disable Sticky Side", | |
| 'help', "This will forcefully set sticky side to false.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Change sector side and sticky side option (optional)", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| if not sector then return end | |
| if self.enable_sticky then | |
| sector.StickySide = true | |
| elseif self.disable_sticky then | |
| sector.StickySide = false | |
| end | |
| if self.side == "dont-change" then | |
| if g_StartingCombat then return end | |
| UpdateSectorControl(self.sector_id) | |
| else | |
| SatelliteSectorSetSide(self.sector_id, self.side, "force") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.enable_sticky then | |
| return Untranslated("Set side <u(side)> and enable sticky side in sector <u(sector_id)>") | |
| elseif self.disable_sticky then | |
| return Untranslated("Set side <u(side)> and disable sticky side in sector <u(sector_id)>") | |
| else | |
| return Untranslated("Set side <u(side)> in sector <u(sector_id)>") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| elseif self.enable_sticky and self.disable_sticky then | |
| return "You cannot both enable and disable sticky side, choose one" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorSetSide', { | |
| enable_sticky = true, | |
| sector_id = "H4", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSpawnSquad", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "squad_def_id", | |
| 'name', "Squad", | |
| 'help', "Pre-defined enemy squad.", | |
| 'items', function (self) return EnemySquadsComboItems("exclude test squads") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "side", | |
| 'name', "Side", | |
| 'default', "enemy1", | |
| 'items', function (self) return {"enemy1", "enemy2", "ally"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Spawns a predefined squad on the sector", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Spawn a <u(squad_def_id)> squad in sector <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not gv_Sectors[self.sector_id] then return end | |
| GenerateEnemySquad(self.squad_def_id, self.sector_id, "Effect", nil, self.side) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| elseif not self.squad_def_id then | |
| return "Specify squad!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorSpawnSquad', { | |
| sector_id = "I1", | |
| squad_def_id = "ArmyPatrol", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorSquadDespawn", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Removes all enemy and militia squads in that sector.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Removes enemy squads and militia in <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local squads = GetSectorSquads(self.sector_id) | |
| for i = #squads, 1, -1 do | |
| local squad = squads[i] | |
| if self.Enemies and IsEnemySquad(squad.UniqueId) or | |
| self.Militia and squad.militia | |
| then | |
| RemoveSquad(squad) | |
| end | |
| end | |
| if not gv_SatelliteView and self.sector_id == gv_CurrentSectorId then | |
| LocalCheckUnitsMapPresence() | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SectorSquadDespawn', { | |
| sector_id = "I2", | |
| }), | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Militia", | |
| 'name', "Remove militia", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Enemies", | |
| 'name', "Remove enemies", | |
| 'default', true, | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorTrainMilitia", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Amount", | |
| 'extra_code', "default = const.Satellite.MilitiaUnitsPerTraining", | |
| 'min', 1, | |
| 'max', 8, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Grants intel for the sector", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector = gv_Sectors[self.sector_id] | |
| local _, trained =SpawnMilitia(self.Amount, sector) | |
| if trained == 0 then return end | |
| local logText = T{769055535456, "<amount> militia dispatched to <SectorName(sector)>", | |
| amount = trained, | |
| sector = sector | |
| } | |
| CombatLog("important", logText) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Train <u(Amount)> militia on <u(sector_id)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local campaign = CampaignPresets[Game and Game.Campaign or DefaultCampaign] | |
| local sector = gv_Sectors and gv_Sectors[self.sector_id] or table.find_value(campaign.Sectors, "Id", self.sector_id) | |
| return T{445122419956, "Sent <em>Militia</em> to <em><SectorName(sector)></em>", sector = sector} | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorTrainMilitia', { | |
| Amount = 5, | |
| sector_id = "I1", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SectorsGrantIntel", | |
| PlaceObj('PropertyDefStringList', { | |
| 'id', "sector_id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Grants intel for an array of sectors", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| DiscoverIntelForSectors(self.sector_id) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Grant intel for sectors <list(sector_id, ', ')>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local campaign = CampaignPresets[Game and Game.Campaign or DefaultCampaign] | |
| local knew = {} | |
| local new = {} | |
| for i, s in ipairs(self.sector_id) do | |
| local sector = gv_Sectors and gv_Sectors[s] or table.find_value(campaign.Sectors, "Id", s) | |
| if sector then | |
| if sector.intel_discovered then | |
| knew[#knew + 1] = T{427357563595, "<em><SectorName></em>", SectorName = sector and sector.display_name or "",} | |
| else | |
| new[#new + 1] = T{165345603261, "<em><SectorName></em> (sector <SectorId(sId)>)", SectorName = sector and sector.display_name or "", sId = s} | |
| end | |
| end | |
| end | |
| local textCombined = false | |
| if #new > 0 then | |
| textCombined = T{309239191160, "Gained <em>Intel</em> for <sectors>.", sectors = table.concat(new, ", ")} | |
| end | |
| if #knew > 0 then | |
| local knewText = T{124400089767, "Intel for <sectors> is already available.", sectors = table.concat(knew, ", ")} | |
| if textCombined then | |
| textCombined = textCombined .. T(226690869750, "<newline>") .. knewText | |
| else | |
| textCombined = knewText | |
| end | |
| end | |
| return textCombined | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('SectorsGrantIntel', { | |
| sector_id = { | |
| "A12", | |
| "A5", | |
| }, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "SetBadgeEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(946118376279, --[[EffectDef Effects SetBadgeEffect value]] "Place a badge of preset <u(BadgePreset)> on unit <u(BadgeUnit)>"), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Place a badge on a unit.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local quest = (self.Quest and gv_Quests[self.Quest]) or (IsKindOf(obj, "QuestsDef") and obj) or false | |
| assert(quest) | |
| if not quest then return end | |
| if not self.BadgeUnit then return end | |
| local prefix = "" | |
| if self.Remove then | |
| prefix = badgeRemoveIdentifier | |
| end | |
| quest[badgeParamIdentifier .. self.BadgeUnit] = prefix .. (self.BadgePreset or "") | |
| UpdateQuestBadges(quest) | |
| end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Remove", | |
| 'help', "Remove the badge instead.", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "BadgeUnit", | |
| 'name', "Badge on Unit", | |
| 'help', "The unit/group to place the badge on, if it exists on the current map.", | |
| 'items', function (self) return GridMarkerGroupsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "BadgePreset", | |
| 'name', "Badge Preset", | |
| 'help', "The badge preset to spawn.", | |
| 'preset_class', "BadgePresetDef", | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Quest", | |
| 'name', "Quest", | |
| 'help', "Which quest to associate this badge with. If the effect is placed on a quest it will attempt to find it itself.", | |
| 'preset_class', "QuestsDef", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SetBadgeEffect', { | |
| BadgePreset = "DefaultQuestBadge", | |
| BadgeUnit = "sector:D7", | |
| Quest = "01_Landing", | |
| Remove = true, | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "SetBehaviorVisitAL", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "ActorGroup", | |
| 'name', "Actor Group", | |
| 'help', "Unit group that will exit the map.", | |
| 'default', "", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "MarkerGroup", | |
| 'name', "Marker Group", | |
| 'help', "Exit marker group.", | |
| 'extra_code', "no_edit = function(self) return self.closest end", | |
| 'default', "", | |
| 'items', function (self) return GetALMarkersGroups end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Kick", | |
| 'name', "Kick", | |
| 'help', "", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(ActorGroup)> visits <u(MarkerGroup)> marker", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Units vists specified Ambient Life marker", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local group_actors = ValidateUnitGroupForEffectExec(self.ActorGroup, self, obj) | |
| local actors = table.ifilter(group_actors, function(_, actor) | |
| return IsKindOf(actor, "Unit") and not actor.perpetual_marker | |
| end) | |
| if #actors == 0 then return end | |
| local actor = actors[1] | |
| if not IsValid(actor) then return end | |
| local visitables = table.ifilter(g_Visitables, function(_, visitable) | |
| local marker_groups = visitable[1].Groups | |
| local from_group = not not table.find(marker_groups, self.MarkerGroup) | |
| return from_group | |
| end) | |
| if #visitables == 0 then return end | |
| local marker_visitable = visitables[1] | |
| if marker_visitable.reserved == actor.handle then | |
| return -- same unit already visiting | |
| end | |
| local marker = marker_visitable[1] | |
| if marker_visitable.reserved then | |
| if not self.Kick then | |
| return -- can't kick currently visiting unit | |
| end | |
| local unit = HandleToObject[marker_visitable.reserved] | |
| if IsValid(unit) then | |
| unit:FreeVisitable(marker_visitable) | |
| unit:SetCommand("Idle") | |
| end | |
| end | |
| actor:ReserveVisitable(marker_visitable) | |
| if marker:Random(100) < marker.ChanceSpawn then | |
| marker.perpetual_unit = actor | |
| actor.perpetual_marker = marker | |
| end | |
| if GameState and (GameState.entering_sector or GameState.setpiece_playing) and marker.Teleport then | |
| actor.teleport_allowed_once = true | |
| end | |
| actor:SetCommand("Visit", marker_visitable) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Sets <u(ActorGroup)> to visit <u(MarkerGroup)> marker") | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SetBehaviorVisitAL', { | |
| ActorGroup = "Hanging_Luc", | |
| MarkerGroup = "SP_HaningCrying_01", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SetDeploymentModeEffect", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "DeploymentMode", | |
| 'name', "Deployment Mode", | |
| 'help', "Sector id.", | |
| 'default', "defend", | |
| 'items', function (self) return {"defend", "attack"} end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "DeploymentDir", | |
| 'name', "Deployment Direction", | |
| 'help', "Deployment Direction during attack", | |
| 'extra_code', 'no_edit = function(self) return self.DeploymentMode == "defend" end', | |
| 'default', "North", | |
| 'items', function (self) return {"North", "East", "South", "West"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set Deployment Mode(and direction if attacking)r", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetDeploymentMode(self.DeploymentMode) | |
| if self.DeploymentMode == "attack" then | |
| gv_DeploymentDir = self.DeploymentDir | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set Deployment Mode", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SetDeploymentModeEffect', { | |
| DeploymentMode = "attack", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "SetSectorAutoResolveDefenderBonus", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Set a sector's Auto Resolve Defender Bonus.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set <u(sector_id)> sector's Auto Resolve Defender Bonus to <u(autoResolveDefenderBonus)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "autoResolveDefenderBonus", | |
| 'name', "Auto Resolve Defender Bonus", | |
| 'default', 0, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'default', "current", | |
| 'items', function (self) return table.iappend({{text="current",value="current"}}, GetCampaignSectorsCombo()) end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sector_id = self.sector_id == "current" and gv_CurrentSectorId or self.sector_id | |
| local sector = gv_Sectors[sector_id] | |
| sector.AutoResolveDefenderBonus = self.autoResolveDefenderBonus | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SetSectorAutoResolveDefenderBonus', { | |
| autoResolveDefenderBonus = 300, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SetSectorDiscovered", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "sector_id", | |
| 'name', "Sector Id", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Sets a sector to discovered", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local sectorPreset = gv_Sectors[self.sector_id] | |
| if sectorPreset then | |
| sectorPreset.discovered = true | |
| if g_SatelliteUI then | |
| g_SatelliteUI:UpdateSectorVisuals(self.sector_id) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return Untranslated("Set <u(sector_id)> to discovered", self) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.sector_id then | |
| return "Specify sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SetSectorDiscovered', { | |
| sector_id = "F12_Underground", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "SetTimer", | |
| PlaceObj('PropertyDefText', { | |
| 'id', "Name", | |
| 'name', "Name", | |
| 'help', "Name of the timer.", | |
| 'translate', false, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "Label", | |
| 'name', "Label", | |
| 'help', "The label to display on the timer.", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Time", | |
| 'name', "Time", | |
| 'help', "Time (in secs) to wait.", | |
| 'default', 60000, | |
| 'scale', "sec", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set timer <Name>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "The effect set a visual UI timer displayed in the upper center of the screen", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "quest, context, TCE", | |
| 'code', function (self, quest, context, TCE) | |
| if not (GameState.Conflict or GameState.ConflictScripted or GameState.Combat) then | |
| -- NOTE: Combat can be started without going through Conflict first, e.g. Stealth Kill | |
| StoreErrorSource("once", "SetTimer running in a sector without Conflict/Combat!") | |
| end | |
| TimerCreate(self.Name, self.Label, self.Time) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "quest, context, TCE", | |
| 'code', function (self, quest, context, TCE) | |
| self:__exec(quest, context, TCE) | |
| return TimerWait(self.Name) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__skip", | |
| 'params', "quest, context, TCE", | |
| 'code', function (self, quest, context, TCE) | |
| return self:__exec(quest, context, TCE) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Name then | |
| return "SetTimer needs a name!" | |
| end | |
| if not self.Time then | |
| return "SetTimer needs time specified!" | |
| end | |
| if GetParentTableOfKindNoCheck(self, "TestHarness") then | |
| return | |
| end | |
| local container = GetParentTableOfKind(self, "TriggeredConditionalEvent") | |
| if not container then | |
| return "SetTimer can only be used in TCEs" | |
| end | |
| if not container.SequentialEffects then | |
| return "SetTimer can be used only in TCEs with Sequential Effects execution!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'params', "thread, stack, stack_index", | |
| 'code', function (self, thread, stack, stack_index) | |
| return "TimerWait", self.Name | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "UI & Log", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SetTimer', { | |
| Name = "test harness timer", | |
| Time = 35000, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ShowGuardpostObjective", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "GuardpostObjective", | |
| 'name', "GuardpostObjective", | |
| 'preset_class', "GuardpostObjective", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Make guardpost objective <u(GuardpostObjective)> visible.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Make a guardpost objective visible.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| SetGuardpostObjectiveSeen(self.GuardpostObjective) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ShowGuardpostObjective', { | |
| GuardpostObjective = "AbandonedMansion", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sectors", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "ShowPopup", | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.PopupId then | |
| return "No PopupId" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'value', T(113381273919, --[[EffectDef Effects ShowPopup value]] "Show popup notification <u(PopupId)>"), | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Displays popup notification", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local id = self.PopupId | |
| local preset = PopupNotifications[id] | |
| if not preset then | |
| StoreErrorSource(Presets.PopupNotification[1][1], "Trying to show missing pop-up: " .. id) | |
| return | |
| end | |
| if preset.OnceOnly and gv_DisabledPopups[id] then | |
| return | |
| end | |
| ShowPopupNotification(id) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| self:__exec(obj, context) | |
| Msg("ClosePopup" .. self.PopupId) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__skip", | |
| 'params', "quest, context, TCE", | |
| 'code', function (self, quest, context, TCE) | |
| return self:__exec(quest, context, TCE) | |
| end, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "PopupId", | |
| 'help', "Popup notification preset id.", | |
| 'preset_class', "PopupNotification", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'params', "thread, stack, stack_index", | |
| 'code', function (self, thread, stack, stack_index) | |
| return "ShowPopup", self.PopupId | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('ShowPopup', { | |
| PopupId = "BoatTravel", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "UI & Log", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "SleepEffect", | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return T(206265192932, "Delay: <u(Sleep)> ms") | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "An effect to delay other effects' execution.", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Sleep", | |
| 'name', "Sleep", | |
| 'help', "Sleep time in ms.", | |
| 'default', 1000, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| return | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| Sleep(self.Sleep) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__skip", | |
| 'params', "quest, context, TCE", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'params', "thread, stack, stack_index", | |
| 'code', function (self, thread, stack, stack_index) | |
| local remainig = GetThreadStatus(thread) - GameTime() | |
| assert(type(remainig) == "number") | |
| assert(remainig >= 0) | |
| return "Sleep", remainig | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('SleepEffect', { | |
| Sleep = 1100, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "StartDeploymentInCurrentSector", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Enter deployment mode if it is valid for the currently loaded sector", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "WaitClicked", | |
| 'name', "Wait Clicked", | |
| 'help', "Waits for the button to be clicked before continuing to trigger next effects.", | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "EntranceZone", | |
| 'name', "EntranceZone", | |
| 'help', "Specific entrance zone", | |
| 'default', "custom", | |
| 'items', function (self) return {"attacker", "defender", "custom"} end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if self.EntranceZone and self.EntranceZone ~= "custom" then | |
| SetDeploymentMode(self.EntranceZone) | |
| else | |
| gv_Deployment = "custom" | |
| end | |
| StartDeployment() | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| self:__exec(obj, context) | |
| if self.WaitClicked then | |
| WaitMsg("DeploymentModeDone") | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__skip", | |
| 'params', "quest, context, TCE", | |
| 'code', function (self, quest, context, TCE) | |
| return self:__exec(quest, context, TCE) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'params', "thread, stack, stack_index", | |
| 'code', function (self, thread, stack, stack_index) | |
| return "StartDeploymentInCurrentSector", self.EntranceZone | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Enter deployment mode", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('StartDeploymentInCurrentSector', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "TriggerGuardPostAttack", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "guardpost_sector_id", | |
| 'name', "Guardpost Sector", | |
| 'help', "Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefStringList', { | |
| 'id', "effect_target_sector_ids", | |
| 'name', "Target Sectors", | |
| 'help', "Attack one of these sectors.", | |
| 'item_default', "last captured", | |
| 'items', function (self) return GetCampaignSectorsCombo("last captured") end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "time", | |
| 'name', "Time", | |
| 'help', "Time to pass before spawning the squad.", | |
| 'default', 43200, | |
| 'scale', "h", | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "custom_quest_id", | |
| 'name', "Custom Quest Id", | |
| 'help', "This could would be used in quests (ex. to check if the attack squad was defeated - with SquadDefeated condition).", | |
| 'translate', false, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "reach_quest_id", | |
| 'name', "Reach Quest Id", | |
| 'help', "Quest to set variables to true when squad reaches it destination sector.", | |
| 'preset_class', "QuestsDef", | |
| }), | |
| PlaceObj('PropertyDefSet', { | |
| 'id', "reach_quest_var", | |
| 'name', "Var to check", | |
| 'help', "Variable in reach quest to set to true when squad reaches it destination sector", | |
| 'items', function (self) return table.keys2(QuestGetVariables(self.reach_quest_id), "sorted") end, | |
| 'max_items_in_set', 1, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Spawns enemy squad from guardpost after time.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local targets = Untranslated(table.concat(self.effect_target_sector_ids, ", ")) | |
| return T{926384305749, "Spawns enemy squad from guardpost on <u(guardpost_sector_id)> to (<targets>) after <CampaignTime(time)>", self, targets = targets} | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local gp = g_Guardposts[self.guardpost_sector_id] | |
| if not gp then | |
| StoreErrorSource(self, "TriggerGuardPostAttack - guardpost_sector_id should be sector with guardpost.") | |
| end | |
| if table.find(self.effect_target_sector_ids, "last captured") and not gv_LastSectorTakenByPlayer then | |
| return | |
| end | |
| if gp then | |
| gp:ForceSetNextSpawnTimeAndSector(self.time, self.effect_target_sector_ids, self.custom_quest_id, self.reach_quest_id, self.reach_quest_var) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.guardpost_sector_id then | |
| return "Specify Guardpost Sector" | |
| elseif not self.effect_target_sector_ids[1] or self.effect_target_sector_ids[1] == "" then | |
| return "Specify Target Sector!" | |
| end | |
| local sector = gv_Sectors and gv_Sectors[self.guardpost_sector_id] | |
| if sector and not sector.Guardpost then | |
| return "Sector should be a guardpost sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('TriggerGuardPostAttack', { | |
| effect_target_sector_ids = { | |
| "H11", | |
| }, | |
| guardpost_sector_id = "H4", | |
| reach_quest_id = "_TestQuest", | |
| reach_quest_var = set( "TestVarBool" ), | |
| time = 3600, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "TriggerSectorWarningState", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Trigger the current sector's Warning State", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Triggers the Warning State for the current sector.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if gv_SatelliteView then return end | |
| local sector = gv_Sectors[gv_CurrentSectorId] | |
| local alliedUnits = GetPlayerSectorUnits(gv_CurrentSectorId, "getUnits") | |
| local enemyUnits = GetAllEnemyUnits(alliedUnits[1]) | |
| local triggeringUnit | |
| if IsKindOf(obj, "Unit") and table.find(alliedUnits, obj) then | |
| triggeringUnit = obj | |
| else | |
| triggeringUnit = alliedUnits[1] | |
| end | |
| EnterWarningState(enemyUnits, alliedUnits, triggeringUnit) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('TriggerSectorWarningState', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "TriggerSquadAttack", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "source_sector_id", | |
| 'name', "Source Sector", | |
| 'help', "Source Sector id.", | |
| 'items', function (self) return GetCampaignSectorsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefStringList', { | |
| 'id', "effect_target_sector_ids", | |
| 'name', "Target Sectors", | |
| 'help', "Attack one of these sectors.", | |
| 'item_default', "last captured", | |
| 'items', function (self) return GetCampaignSectorsCombo("last captured") end, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "reach_quest_id", | |
| 'name', "Reach Quest Id", | |
| 'help', "Quest to set variables to true when squad reaches it destination sector.", | |
| 'preset_class', "QuestsDef", | |
| }), | |
| PlaceObj('PropertyDefSet', { | |
| 'id', "reach_quest_var", | |
| 'name', "Var to check", | |
| 'help', "Variable in reach quest to set to true when squad reaches it destination sector", | |
| 'items', function (self) return table.keys2(QuestGetVariables(self.reach_quest_id), "sorted") end, | |
| 'max_items_in_set', 1, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "custom_quest_id", | |
| 'name', "Custom Quest Id", | |
| 'help', "This could would be used in quests (ex. to check if the attack squad was defeated - with SquadDefeated condition).", | |
| 'translate', false, | |
| }), | |
| PlaceObj('PropertyDefPresetIdList', { | |
| 'category', "", | |
| 'id', "EnemySquadsList", | |
| 'name', "Enemy Squads List", | |
| 'help', "A random squad from the list will be chosen on guardpost spawn time", | |
| 'extra_code', "no_edit = function(self) return not self.Guardpost end", | |
| 'preset_class', "EnemySquads", | |
| 'preset_filter', function (preset, obj, prop_meta) | |
| if preset.group ~= "Test Encounters" then return obj end | |
| end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'category', "", | |
| 'id', "Squad", | |
| 'name', "Squad", | |
| 'help', "Squad that will be spawned in the sector on campaign start", | |
| 'items', function (self) return EnemySquadsComboItems("exclude test squads") end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Spawns specific enemy squad after time.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| local targets = Untranslated(table.concat(self.effect_target_sector_ids, ", ")) | |
| return T{768343821287, "Spawns specific enemy squad to (<targets>)", self, targets = targets} | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Sector effects", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if table.find(self.effect_target_sector_ids, "last captured") and not gv_LastSectorTakenByPlayer then | |
| return | |
| end | |
| local sector = gv_Sectors[self.source_sector_id] | |
| if not sector then return end | |
| local sector_ids = self.effect_target_sector_ids | |
| if gv_LastSectorTakenByPlayer then | |
| table.replace(sector_ids, "last captured", gv_LastSectorTakenByPlayer) | |
| end | |
| local target_sector_id = table.interaction_rand(sector_ids, "TriggerSquadAttack") | |
| --local next_squad = table.interaction_rand(sector.EnemySquadsList or empty_table, "TriggerSquadAttack") | |
| --local next_squad_units = GenerateRandEnemySquadUnits(next_squad) | |
| local squad_id = GenerateEnemySquad(self.Squad, self.source_sector_id, "TriggerSquadAttack") | |
| if squad_id then | |
| gv_CustomQuestIdToSquadId[self.custom_quest_id or self.Squad] = squad_id | |
| local squad = gv_Squads[squad_id] | |
| squad.on_reach_quest = self.reach_quest_id | |
| squad.on_reach_var = self.reach_quest_var | |
| if target_sector_id ~= self.source_sector_id then | |
| SendSatelliteSquadOnRoute(squad, target_sector_id) | |
| local timeToReach = GetTotalRouteTravelTime(squad.CurrentSector, squad.route, squad) | |
| AddTimelineEvent("squad-attack-" .. squad.UniqueId, Game.CampaignTime + timeToReach, "squad-attack", squad.UniqueId) | |
| end | |
| return squad_id | |
| end | |
| StoreErrorSource(sector, string.format("Sector '%s' does not have enemy squad '%s'", self.source_sector_id, self.Squad)) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Squad then | |
| return "Specify Squad" | |
| elseif not self.effect_target_sector_ids[1] or self.effect_target_sector_ids[1] == "" then | |
| return "Specify Target Sector!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('TriggerSquadAttack', { | |
| Squad = "LegionAttackSquad_01", | |
| effect_target_sector_ids = { | |
| "I2", | |
| }, | |
| source_sector_id = "I3", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "UnitAddGrit", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| "UnitData", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Add grit to the unit.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Add grit to the unit.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local unit = obj | |
| if IsKindOf(unit, "UnitData") then | |
| unit = g_Units[unit.session_id] | |
| end | |
| if IsKindOf(unit, "Unit") and not unit:IsDead() then | |
| unit:ApplyTempHitPoints(self.amount) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "amount", | |
| 'name', "Amount", | |
| 'default', 30, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitAddGrit', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "UnitAddStatusEffect", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Status", | |
| 'name', "Status", | |
| 'preset_class', "CharacterEffectCompositeDef", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Add <u(Status)> effect to the unit", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Add status effect to a unit", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOf(obj, "Unit") and not obj:IsDead() then | |
| obj:AddStatusEffect(self.Status) | |
| end | |
| if not context then context = {} end | |
| local units = self:MatchMapUnits(obj, context) | |
| if units and context.target_units then | |
| for _, unit in ipairs(context.target_units) do | |
| if self.Status == "Wounded" then | |
| obj:AddWounds(1) | |
| else | |
| obj:AddStatusEffect(self.Status) | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "UnitCheck", | |
| 'params', "unit, obj, context", | |
| 'code', function (self, unit, obj, context) | |
| return IsKindOf(unit, "Unit") and not unit:IsDead() | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return T(237536962390, "Add <u(Status)> to the unit") | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitAddStatusEffect', { | |
| Status = "Bleeding", | |
| TargetUnit = "current unit", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitApplyAppearance", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "Target Unit", | |
| 'help', "Target unit for match.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Appearance", | |
| 'name', "Appearance", | |
| 'help', "Appearance to set.", | |
| 'preset_class', "AppearancePreset", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "<u(TargetUnit)> changes appearance to <Appearance>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Changes the appearance of an unit", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local units = Groups[self.TargetUnit] or empty_table | |
| if units[1] then | |
| units[1]:ApplyAppearance(self.Appearance) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "Choose target unit to die" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitApplyAppearance', { | |
| Appearance = "Bastien", | |
| TargetUnit = "Fidel", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitDie", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetGroup", | |
| 'name', "Target Group", | |
| 'help', "Target group for match.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "skipAnim", | |
| 'name', "Skip Animation", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "killImmortal", | |
| 'name', "Kill Immortal", | |
| 'help', "Makes units mortal and then kills them.", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Units from group <u(TargetGroup)> die", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Kill units from specified group", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local group = Groups[self.TargetGroup] or empty_table | |
| for i, v in ipairs(group) do | |
| if IsKindOf(v, "Unit") and not v:IsDead() then | |
| v.villain = false | |
| if self.killImmortal then | |
| v.immortal = false | |
| end | |
| v:SetCommand("Die", self.skipAnim) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetGroup then | |
| return "Choose target unit to die" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitDie', { | |
| TargetGroup = "Martha", | |
| killImmortal = true, | |
| skipAnim = true, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "UnitTarget", | |
| "Effect", | |
| }, | |
| group = "Effects", | |
| id = "UnitEnvEffectTick", | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "EffectType", | |
| 'default', "Burning", | |
| 'items', function (self) return {"Burning", "ToxicGas", "TearGas", "Smoke", "Darkness"} end, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "CombatMoment", | |
| 'default', "n/a", | |
| 'items', function (self) return {"start turn", "end turn", "n/a"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Trigger <u(EffectType)> tick for <u(TargetUnit)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Trigger environmental effect tick for target unit", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not context then context = {} end | |
| local units = self:MatchMapUnits(obj, context) | |
| if units and context.target_units then | |
| local moment = (self.CombatMoment ~= "n/a") and self.CombatMoment or nil | |
| local func = EnvEffectBurningTick | |
| if self.EffectType == "ToxicGas" then | |
| func = EnvEffectToxicGasTick | |
| elseif self.EffectType == "TearGas" then | |
| func = EnvEffectTearGasTick | |
| elseif self.EffectType == "Smoke" then | |
| func = EnvEffectSmokeTick | |
| elseif self.EffectType == "Darkness" then | |
| func = EnvEffectDarknessTick | |
| end | |
| for _, unit in ipairs(context.target_units) do | |
| if IsValid(unit) and IsKindOf(unit, "Unit") and not unit:IsDead() then | |
| func(unit, nil, moment) | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "Choose target unit" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "UnitCheck", | |
| 'params', "unit, obj, context", | |
| 'code', function (self, unit, obj, context) | |
| return true | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitEnvEffectTick', { | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "UnitGrantAP", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Grant <u(ap)> AP to the unit", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Modify unit's AP", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if IsKindOf(obj, "Unit") and not obj:IsDead() then | |
| if self.ap > 0 then | |
| obj:GainAP(self.ap*const.Scale.AP) | |
| else | |
| obj:ConsumeAP(self.ap*const.Scale.AP) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "ap", | |
| 'name', "AP", | |
| 'help', "Action Points to Give", | |
| 'default', 8, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitGrantAP', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "LootTableFunctionObjectBase", | |
| }, | |
| id = "UnitGrantItem", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "ItemId", | |
| 'name', "Item", | |
| 'help', "The id of the item that will be granted.", | |
| 'preset_class', "InventoryItemCompositeDef", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "How many items are granted.", | |
| 'default', 1, | |
| 'min', 1, | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "LootTableId", | |
| 'name', "Loot Table Id", | |
| 'help', "Loot table to generate items that will be granted.", | |
| 'preset_class', "LootDef", | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "GrantedItemsTextUI", | |
| 'dont_save', true, | |
| 'no_edit', true, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "GrantedItemsEditorTextUI", | |
| 'dont_save', true, | |
| 'no_edit', true, | |
| }), | |
| PlaceObj('PropertyDefTable', { | |
| 'id', "GeneratedItems", | |
| 'dont_save', true, | |
| 'no_edit', true, | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "actor", | |
| 'name', "Log Actor", | |
| 'help', "How to log the received items.", | |
| 'default', "important", | |
| 'items', function (self) return {"short", "important"} end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.ItemId and self.LootTableId then | |
| return Untranslated("<u(ItemId)>(<Amount>) and \'<u(LootTableId)>\' loot table items are given to the merc") | |
| end | |
| if self.ItemId then | |
| return Untranslated("<u(ItemId)>(<Amount>) given to the merc") | |
| end | |
| if self.LootTableId then | |
| return Untranslated("Loot table items \'<u(LootTableId)>\' given to the merc") | |
| end | |
| return "" | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Give item to a merc or to any from its squad.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| -- can work with both unit and a unit session_id | |
| local unit_id = type(obj) == "string" and obj or obj.session_id --please no SelectedObj here, this is sync | |
| local squad = gv_UnitData[unit_id] and gv_UnitData[unit_id].Squad | |
| if not squad then | |
| -- try to give to the first of player squads | |
| local squads = GetSectorSquadsFromSide(gv_CurrentSectorId, "player1") | |
| squad = #squads>0 and squads[1].UniqueId | |
| end | |
| --to any player squad | |
| assert(squad, "There is not unit or player squad on the sector") | |
| if not squad then | |
| if g_PlayerSquads and #g_PlayerSquads>0 then | |
| squad = g_PlayerSquads[1].UniqueId | |
| end | |
| end | |
| assert(squad, "There is not any player squad.The item is not given.") | |
| if not squad then return end | |
| local sector = gv_Squads[squad].CurrentSector | |
| local all_mercs = gv_Squads[squad].units | |
| if unit_id then | |
| all_mercs = table.copy(all_mercs) | |
| table.remove_entry(all_mercs, unit_id) | |
| table.insert(all_mercs, 1, unit_id) | |
| end | |
| unit_id = unit_id or all_mercs[1] | |
| -- loot table | |
| local items = UnitGrantItem.GenerateItems(self, "game") or {} | |
| CombatLogActorOverride = self.actor | |
| AddItemsToSquadBag(squad, items) | |
| for idx, merc in ipairs(all_mercs) do | |
| if #items<=0 then break end | |
| local unit = g_Units[merc] or gv_UnitData[merc] | |
| unit:AddItemsToInventory(items) | |
| end | |
| if #items > 0 then | |
| local unit = g_Units[unit_id] | |
| if unit then | |
| unit:DropItemsInContainer(items, | |
| function(unit, item, amount) | |
| CombatLog("important", T{740183432105, " Inventory full. <amount><em><item></em> dropped by <name>", amount = amount>1 and Untranslated(amount.." x ") or "", item = amount>1 and item.DisplayNamePlural or item.DisplayName, name = unit:GetDisplayName()}) | |
| end) | |
| else | |
| local stash = GetSectorInventory(sector) | |
| if stash then | |
| AddItemsToInventory(stash, items, true) | |
| end | |
| end | |
| end | |
| -- items | |
| if self.ItemId then | |
| local amount = self.Amount | |
| local item | |
| if amount > 0 then | |
| amount = AddItemToSquadBag(squad, self.ItemId, amount) | |
| end | |
| for idx, merc in ipairs(all_mercs) do | |
| if amount <= 0 then break end | |
| local unit = g_Units[merc] or gv_UnitData[merc] | |
| amount = unit:AddToInventory(self.ItemId, amount) | |
| end | |
| if amount > 0 then | |
| local unit = g_Units[unit_id] | |
| if unit then | |
| unit:DropItemContainer(self.ItemId, amount, | |
| function(unit, item, amount) | |
| CombatLog("important", T{740183432105, " Inventory full. <amount><em><item></em> dropped by <name>", amount = amount>1 and Untranslated(amount.." x ") or "", item = amount>1 and item.DisplayNamePlural or item.DisplayName, name = unit:GetDisplayName()}) | |
| end) | |
| else | |
| local stash = GetSectorInventory(sector) | |
| if stash then | |
| local itm = PlaceInventoryItem(self.ItemId) | |
| AddItemsToInventory(stash, {itm},true) | |
| end | |
| end | |
| end | |
| end | |
| self.GeneratedItems = false | |
| CombatLogActorOverride = false | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if (not self.ItemId or self.ItemId == "") and not self.LootTableId then | |
| return "Set Item or loot table!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local item = self.ItemId and InventoryItemDefs[self.ItemId] | |
| if item then | |
| local item_name = item.DisplayName | |
| local item_name_pl = item.DisplayNamePlural | |
| if self.ItemId == "Money" then | |
| return T{283114521154, "<em><money(Amount)></em> obtained", Amount = self.Amount} | |
| else | |
| return T{215465168779, "<Amount> x <em><item></em> obtained", Amount = self.Amount, item = self.Amount<=1 and item_name or item_name_pl} | |
| end | |
| end | |
| self:GenerateItems(game) | |
| if game then | |
| if self.GrantedItemsTextUI and self.GrantedItemsTextUI ~= "" then | |
| return T{871249882862, "<items_list> obtained", items_list = self.GrantedItemsTextUI} | |
| end | |
| else | |
| if self.GrantedItemsEditorTextUI and self.GrantedItemsEditorTextUI ~= "" then | |
| return T{871249882862, "<items_list> obtained", items_list = self.GrantedItemsEditorTextUI} | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GenerateItems", | |
| 'params', "game", | |
| 'code', function (self, game) | |
| if game and self.GeneratedItems then return self.GeneratedItems end -- items are already generated don't try again. | |
| if not game and self.GrantedItemsEditorTextUI then return end | |
| local items = {} | |
| local loot_tbl = LootDefs[self.LootTableId] | |
| if loot_tbl then | |
| loot_tbl:GenerateLoot(self, {}, InteractionRand(nil, "Loot"), items) | |
| end | |
| if #items > 0 then | |
| if game then | |
| self.GeneratedItems = items | |
| self.GrantedItemsTextUI = GetItemsNamesText(items) | |
| else | |
| self.GrantedItemsEditorTextUI = GetItemsNamesText(items) | |
| end | |
| end | |
| return items | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseFX", | |
| 'code', function (self) | |
| return "ConversationItemGained" | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) | |
| return SelectedObj | |
| end, | |
| 'TestObject', PlaceObj('UnitGrantItem', { | |
| ItemId = "AK47", | |
| LootTableId = "LootBox05_ammo", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitJoinAsMerc", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "Target Unit", | |
| 'help', "Target unit for match.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Merc", | |
| 'help', "The Merc to join the team.", | |
| 'items', function (self) return MercPresetCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Make <u(TargetUnit)> join team as <u(Merc)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Unit joins as a specified merc.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local units = Groups[self.TargetUnit] or empty_table | |
| units = table.ifilter(units, function(_, u) | |
| return IsKindOf(u, "Unit") | |
| end) | |
| -- can work with both unit and a unit session_id | |
| local unit_id = type(obj) == "string" and obj or obj.session_id --please no SelectedObj here, this is sync | |
| local squad = gv_UnitData[unit_id] and gv_UnitData[unit_id].Squad | |
| squad = squad and gv_Squads[squad] | |
| if units[1] and squad and self.Merc then | |
| units[1]:JoinSquadAs(self.Merc, squad) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "Choose target unit to join" | |
| end | |
| if not self.Merc then | |
| return "Choose merc as which the unit joins" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetUIText", | |
| 'params', "context,template, game", | |
| 'code', function (self, context,template, game) | |
| local merc = gv_UnitData and gv_UnitData[self.Merc] | |
| local name | |
| if not merc then | |
| name = game and "" or Untranslated("[MercName]") | |
| else | |
| name = merc.Nick or merc.Name | |
| end | |
| return T{246469241790, "Recruit merc (<em><name></em>)", name= name} | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitJoinAsMerc', { | |
| Merc = "PierreMerc", | |
| TargetUnit = "Pierre", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "UnitMakeNonVillain", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Make <UnitId> non villain.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Make all instances of the specified persistant villain unit non-villain (killable)", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local units = g_PersistentUnitData[self.UnitId] | |
| for i, u in ipairs(units) do | |
| MakeUnitNonVillain(u) | |
| -- Heal unit if enabled and exists, dont use | |
| -- standard heal logic to make it invisible. | |
| local mapUnit = g_Units[u.session_id] | |
| if mapUnit and self.HealHP then | |
| mapUnit.HitPoints = mapUnit.Health | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "UnitId", | |
| 'items', function (self) return GetPersistentSessionIds() end, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "HealHP", | |
| 'help', "whether to also heal the unit to full", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitMakeNonVillain', { | |
| UnitId = "NPC_Pierre", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitSetConflictIgnore", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "ConflictIgnore", | |
| 'name', "Conflict Ignore", | |
| 'help', "Whether to be afraid in conflicts or not.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "Target Unit", | |
| 'help', "Target unit for match.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set <u(TargetUnit)> ConflictIgnore to <if(ConflictIgnore)>true</if><if(not(ConflictIgnore))>false</if>.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Sets units to be affraid(or not) during confict.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local objects = Groups[self.TargetUnit] or empty_table | |
| for _, obj in ipairs(objects) do | |
| if IsKindOf(obj, "Unit") then | |
| obj.conflict_ignore = self.ConflictIgnore | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "Choose TargetUnit!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitSetConflictIgnore', { | |
| TargetUnit = "Luc", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitSetHireStatus", | |
| PlaceObj('PropertyDefChoice', { | |
| 'id', "Status", | |
| 'name', "Hire Status", | |
| 'help', "The hiring status to set.", | |
| 'default', "Available", | |
| 'items', function (self) return PresetGroupCombo("MercHireStatus", "Default") end, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "Target Unit", | |
| 'help', "Target unit for match.", | |
| 'items', function (self) return GetTargetUnitCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set <u(TargetUnit)> to status <u(Status)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Sets the hiring status of the merc to a specified value.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not self.Status then return false end | |
| local unit = UnitDataDefs[self.TargetUnit] | |
| local unitData = gv_UnitData[unit.id] | |
| if not unitData then return end | |
| unitData.HireStatus = self.Status | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Status then | |
| return "Choose unit hiring status to set!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitSetHireStatus', { | |
| TargetUnit = "Tex", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitSetOnline", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Online", | |
| 'name', "Online", | |
| 'help', "Whether to set it online or offline.", | |
| 'default', true, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "Target Unit", | |
| 'help', "Target unit for match.", | |
| 'items', function (self) return GetTargetUnitCombo() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Set <u(TargetUnit)> messenger availability to <u(Status)>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Sets a merc's online/offline status in the PDA messenger. When offline mercs cannot be hired.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local unit = UnitDataDefs[self.TargetUnit] | |
| local unitData = gv_UnitData[unit.id] | |
| if not unitData then return end | |
| unitData:SetMessengerOnline(self.Online) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "Choose targetunit!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitSetOnline', { | |
| TargetUnit = "Igor", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| id = "UnitSetStatusEffectImmunity", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "ReturnClass", | |
| 'type', "text", | |
| }), | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Status", | |
| 'name', "Status", | |
| 'preset_class', "CharacterEffectCompositeDef", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Immune", | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "Reason", | |
| 'help', "Text label used for keeping track of the different reasons a unit can have for being immune to the specific status effect. All reasons must be cleared in order for the unit to be able to receive the effect again.", | |
| 'default', "script", | |
| 'translate', false, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "translate", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| if self.Immune then | |
| return Untranslated("Make unit immune to <u(Status)>") | |
| end | |
| return Untranslated("Clear immunity to <u(Status)> from unit") | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Add or remove immunity to specified status effect to a target unit", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if self.Immune then | |
| obj:AddStatusEffectImmunity(self.Status, self.Reason) | |
| else | |
| obj:RemoveStatusEffectImmunity(self.Status, self.Reason) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitSetStatusEffectImmunity', { | |
| Immune = true, | |
| Status = "Bleeding", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "ConversationFunctionObjectBase", | |
| }, | |
| id = "UnitStartConversation", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "Conversation", | |
| 'name', "Conversation", | |
| 'help', "Conversation to start.", | |
| 'preset_class', "Conversation", | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Start conversation <u(Conversation)>.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Starts a specific conversation - no groups or conditions are checked.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| StartConversationEffect(self.Conversation, context) | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| StartConversationEffect(self.Conversation, context, "wait") | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Conversation then | |
| return "Please specify conversation" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "new", | |
| 'params', "...", | |
| 'code', function (self, ...) | |
| -- backward compatibility | |
| local ret = Effect.new(self, ...) | |
| if rawget(ret, "Group") then | |
| ret.Conversation = ret.Group | |
| ret.Group = nil | |
| end | |
| return ret | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'params', "thread, stack, stack_index", | |
| 'code', function (self, thread, stack, stack_index) | |
| return "UnitStartConversation", self.Conversation | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitStartConversation', { | |
| Conversation = "Ernie_Luc", | |
| }), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactions", | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitStatBoost", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Stat", | |
| 'name', "Stat", | |
| 'help', "", | |
| 'items', function (self) return GetUnitStatsCombo() end, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "How much to boost the specified Stat.", | |
| }), | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "source", | |
| 'name', "Source", | |
| 'help', "What kind of source is the thing that provides the stat boost.", | |
| 'default', "Book", | |
| 'items', function (self) return {"Book", "Other"} end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Boost unit's stat <Stat>", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Boosts unit's stat", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not obj.is_clone then | |
| local modId | |
| if self.source == "Book" then | |
| modId = string.format("StatBoostBook-%s-%s-%d", self.Stat, obj.session_id, GetPreciseTicks()) | |
| GainStat(obj, self.Stat, self.Amount, modId, "Studying") | |
| else | |
| modId = string.format("StatBoost-%s-%s-%d", self.Stat, obj.session_id, GetPreciseTicks()) | |
| GainStat(obj, self.Stat, self.Amount, modId) | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Stat then | |
| return "Choose stat" | |
| elseif not self.Amount then | |
| return "Choose amount" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitStatBoost', { | |
| Amount = 1, | |
| Stat = "Health", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "UnitTakeDamage", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "RequiredObjClasses", | |
| 'type', "string_list", | |
| 'value', { | |
| "Unit", | |
| }, | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Damage", | |
| 'default', 5, | |
| 'min', 0, | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "FloatingText", | |
| 'help', "Will only be displayed if the target unit is visible for the player; <Damage> parameter will be provided for the text.", | |
| 'default', T(477545213542, --[[EffectDef Effects UnitTakeDamage default]] "<Damage>"), | |
| }), | |
| PlaceObj('PropertyDefText', { | |
| 'id', "LogMessage", | |
| 'help', "<Damage> and <Name> parameters will be provided for the text.", | |
| 'default', T(879191059352, --[[EffectDef Effects UnitTakeDamage default]] "<em><Name></em> takes <em><Damage></em> damage."), | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Deal <Damage> damage to the unit", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Deal damage to the unit", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if not context then context = {} end | |
| local units = self:MatchMapUnits(obj, context) | |
| if units and context.target_units then | |
| local floating_text = T{self.FloatingText, Damage = self.Damage} | |
| local pov_team = GetPoVTeam() | |
| for _, unit in ipairs(context.target_units) do | |
| if not unit:IsDead() then | |
| local has_visibility = HasVisibilityTo(pov_team, obj) | |
| local log_msg = T{self.LogMessage, { Name = unit:GetLogName(), Damage = self.Damage}} | |
| unit:TakeDirectDamage(self.Damage, has_visibility and floating_text or false, "short", log_msg) | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "UnitCheck", | |
| 'params', "unit, obj, context", | |
| 'code', function (self, unit, obj, context) | |
| return true | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitTakeDamage', { | |
| TargetUnit = "any merc", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitTakeItem", | |
| PlaceObj('PropertyDefPresetId', { | |
| 'id', "ItemId", | |
| 'name', "Item", | |
| 'help', "The id of the item that will be taken.", | |
| 'preset_class', "InventoryItemCompositeDef", | |
| }), | |
| PlaceObj('PropertyDefNumber', { | |
| 'id', "Amount", | |
| 'name', "Amount", | |
| 'help', "How many items to take.", | |
| 'default', 1, | |
| 'min', 1, | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "AnySquad", | |
| 'name', "Any player squad", | |
| 'help', "if true: takes item from any player's squad. if false: takes item from current squad", | |
| }), | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "AddToLogVar", | |
| 'name', "Add to log", | |
| 'help', "Add message to log.", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Take <u(ItemId)>(<Amount>) from merc(s) in squad.", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Removes the first given item from the inventory of a merc in the squad.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "AddToLog", | |
| 'params', "unit, item, amount", | |
| 'code', function (self, unit, item, amount) | |
| if self.AddToLogVar then | |
| local unit_name | |
| if type(unit)=="number" then | |
| unit_name = g_Classes.SquadBag.DisplayName | |
| else | |
| unit_name = unit:GetDisplayName() | |
| end | |
| CombatLog("short", T{795253111432, "<amount> x <em><item></em> taken from <name>", amount = amount>=1 and amount or "", item = amount>1 and item.DisplayNamePlural or item.DisplayName, name = unit_name}) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| -- can work with both unit and a unit session_id | |
| local unit_id = false | |
| if type(obj) == "string" then | |
| unit_id = obj | |
| elseif IsKindOf(obj, "Unit") then | |
| unit_id = obj.session_id | |
| end | |
| local all_mercs = false | |
| local squad = unit_id and gv_UnitData[unit_id] and gv_UnitData[unit_id].Squad | |
| if squad then | |
| all_mercs = table.copy(gv_Squads[squad].units) | |
| if self.AnySquad then | |
| local side = gv_Squads[squad].Side | |
| if side=="player1" then | |
| table.iappend(all_mercs,GetAllPlayerUnitsOnMapSessionId()) | |
| end | |
| for sq_id, sqd in pairs(gv_Squads) do | |
| if sq_id~=squad and (sqd.Side ==side) then | |
| table.iappend(all_mercs, sqd.units ) | |
| end | |
| end | |
| all_mercs = table.get_unique(all_mercs) | |
| end | |
| table.remove_entry(all_mercs, unit_id) | |
| table.insert(all_mercs, 1, unit_id) -- prioritize unit_id | |
| else | |
| all_mercs = GetAllPlayerUnitsOnMapSessionId() | |
| end | |
| TakeItemFromMercs(all_mercs, self.ItemId, self.Amount, | |
| function(unit, item, unit_amount, effect) | |
| effect:AddToLog(unit, item, unit_amount) | |
| end, | |
| self) | |
| InventoryUIRespawn() | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.ItemId then | |
| return "Set Item!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetUIText", | |
| 'params', "context, template, game", | |
| 'code', function (self, context, template, game) | |
| local item_name = InventoryItemDefs[self.ItemId].DisplayName | |
| local item_name_pl = InventoryItemDefs[self.ItemId].DisplayNamePlural | |
| local unit_id = ConversationGetPlayerMerc() | |
| local has_item = HasItemInSquad(unit_id, self.ItemId, self.Amount) | |
| if self.ItemId=="Money" then | |
| return has_item and T{304179156341, "Give <em><money(Amount)></em>", Amount = self.Amount} | |
| or T{231000532062, "<em><money(Amount)></em> required", Amount = self.Amount} | |
| end | |
| if template then | |
| return T{template, Amount = self.Amount, item = self.Amount<=1 and item_name or item_name_pl} | |
| else | |
| return has_item and T{590581690149, "Give <em><Amount> <item></em>",Amount =self.Amount, item = self.Amount<=1 and item_name or item_name_pl} | |
| or T{635806839384, "<em><Amount> <item></em> required",Amount =self.Amount, item = self.Amount<=1 and item_name or item_name_pl} | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetPhraseTopRolloverText", | |
| 'params', "negative, template, game", | |
| 'code', function (self, negative, template, game) | |
| local item_name = InventoryItemDefs[self.ItemId].DisplayName | |
| local item_name_pl = InventoryItemDefs[self.ItemId].DisplayNamePlural | |
| if self.ItemId=="Money" then | |
| return T{792302629761, "Delivered <em><money(Amount)></em>",Amount = self.Amount} | |
| else | |
| return T{652398655206, "Delivered <Amount> x <em><item></em>",Amount = self.Amount, item = self.Amount<=1 and item_name or item_name_pl} | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitTakeItem', { | |
| Amount = 10, | |
| AnySquad = true, | |
| ItemId = "_12gauge_Buckshot", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitsAddToAmbientLife", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "Group", | |
| 'name', "Group", | |
| 'help', "Units Group to add to Ambient Life.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Add objects of group to Ambient Zone", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Add objects of group to Ambient Zone marker's responsibilities.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.Group then | |
| return "Choose Units Group!" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local group_units = Groups[self.Group] or empty_table | |
| if #group_units == 0 then return end | |
| local zone | |
| MapForEach("map", "AmbientZoneMarker", function(marker) | |
| zone = marker | |
| return false | |
| end) | |
| if zone then | |
| zone:RegisterUnits(table.ifilter(group_units, function(i, u) | |
| return IsKindOf(u, "Unit") | |
| end)) | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitsAddToAmbientLife', { | |
| Group = "ZoneGroup", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitsDespawnAmbientLife", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Ephemeral", | |
| 'name', "Ephemeral Only", | |
| 'help', "All ambient life units or just ephemeral ones.", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Despawn all Ambient Life Units", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Despawn all ambient units - abrupt, don't wait for exit animations.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| MapForEach("map", "AmbientZoneMarker", function(zone) | |
| for _, units in ipairs(zone.units) do | |
| for idx = #units, 1, -1 do | |
| local unit = units[idx] | |
| if not self.Ephemeral or unit.ephemeral then | |
| table.remove(units, idx) | |
| DoneObject(unit) | |
| end | |
| end | |
| end | |
| end) | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UnitsDespawnAmbientLife', { | |
| Ephemeral = false, | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitsKickAmbientLife", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "AL_Group", | |
| 'name', "AL Group", | |
| 'help', "Target unit for match.", | |
| 'items', function (self) return GetALMarkerGroups() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Kicks Ambient Life <AL_Group> group from Their Markers", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Forces all units in ambient life behavior visiting specific group cancel their visit behavior", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| for _, unit in ipairs(g_Units) do | |
| if IsVisitingUnit(unit) then | |
| if unit.last_visit:IsInGroup(self.AL_Group) then | |
| unit:SetBehavior() | |
| unit:SetCommand("Idle") | |
| unit.perpetual_marker = false | |
| end | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.AL_Group then | |
| return "Choose group of AL markers to kick units from" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetUIText", | |
| 'params', "context,template, game", | |
| 'code', function (self, context,template, game) | |
| local merc = gv_UnitData and gv_UnitData[self.Merc] | |
| local name | |
| if not merc then | |
| name = game and "" or Untranslated("[MercName]") | |
| else | |
| name = merc.Nick or merc.Name | |
| end | |
| return T{246469241790, "Recruit merc (<em><name></em>)", name= name} | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('UnitsKickAmbientLife', { | |
| AL_Group = "ChairGroup", | |
| }), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitsKickFromPerpetualMarkers", | |
| PlaceObj('PropertyDefBool', { | |
| 'id', "Ephemeral", | |
| 'name', "Ephemeral Only", | |
| 'help', "All ambient life units or just ephemeral ones.", | |
| 'default', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Kick Units from Perpetual Markers", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Kicks all Ambient Life units which are in perpetual markers", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| for _, unit in ipairs(g_Units) do | |
| if (not self.Ephemeral or unit.ephemeral) and unit.perpetual_marker then | |
| unit:SetBehavior() | |
| unit:SetCommand("Idle") | |
| unit.perpetual_marker = false | |
| end | |
| end | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('UnitsKickFromPerpetualMarkers', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UnitsStealForPerpetualMarkers", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Steal Units for Perpetual Markers", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Steal units for perpetual markers as if the Ambient Life is respawn", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| AmbientLifePerpetualMarkersSteal() | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) end, | |
| 'TestObject', PlaceObj('UnitsStealForPerpetualMarkers', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| group = "Effects", | |
| id = "UpdateInteractablesHighlight", | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Disable interaction markers of a specific group.", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| if CurrentMap == "" or IsChangingMap() then return end | |
| if not g_Units then return end | |
| local ui_units = {} | |
| for _, unit in ipairs(g_Units) do | |
| if IsValid(unit) and not unit:IsDead() and unit.team and unit.team.control == "UI" then | |
| table.insert(ui_units, unit) | |
| end | |
| end | |
| if #ui_units == 0 then return end | |
| MapForEach("map", "Interactable", function(interactable) | |
| if not IsValid(interactable) then return end | |
| for _, unit in ipairs(ui_units) do | |
| if not UICanInteractWith(unit, interactable) then | |
| interactable:HighlightIntensely(false, "unit-nearby") | |
| end | |
| end | |
| if not (IsKindOf(interactable, "ContainerMarker") and interactable:IsMarkerEnabled()) then | |
| interactable:HighlightIntensely(false, "cursor") | |
| interactable:HighlightIntensely(false, "unit-nearby") | |
| end | |
| end) | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Interactable", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetEditorView", | |
| 'code', function (self) | |
| return T(680362306074, "Forces update of all highlighted interactables") | |
| end, | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('UpdateInteractablesHighlight', {}), | |
| }), | |
| }) | |
| PlaceObj('EffectDef', { | |
| DefParentClassList = { | |
| "Effect", | |
| "UnitTarget", | |
| }, | |
| group = "Effects", | |
| id = "WaitNpcIdle", | |
| PlaceObj('PropertyDefCombo', { | |
| 'id', "TargetUnit", | |
| 'name', "NPC Name", | |
| 'help', "The name of the NPC to associate.", | |
| 'items', function (self) return GetUnitGroups() end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorView", | |
| 'type', "text", | |
| 'value', "Wait for the NPC to become idle", | |
| 'untranslated', true, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "Documentation", | |
| 'type', "text", | |
| 'value', "Wait for the NPC to become idle (requires sequential execution)", | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__exec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| assert(false) -- This effect requires sequential execution | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "__waitexec", | |
| 'params', "obj, context", | |
| 'code', function (self, obj, context) | |
| local ctx = {} | |
| local units = self:MatchMapUnits(obj, ctx) | |
| local firstUnit = units and ctx.target_units | |
| firstUnit = firstUnit and firstUnit[1] | |
| if firstUnit then | |
| WaitIdle(firstUnit) | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetResumeData", | |
| 'code', function (self) | |
| return "WaitNpcIdle", self.TargetUnit | |
| end, | |
| }), | |
| PlaceObj('ClassMethodDef', { | |
| 'name', "GetError", | |
| 'code', function (self) | |
| if not self.TargetUnit then | |
| return "No target unit" | |
| end | |
| end, | |
| }), | |
| PlaceObj('ClassConstDef', { | |
| 'name', "EditorNestedObjCategory", | |
| 'type', "text", | |
| 'value', "Units", | |
| }), | |
| PlaceObj('TestHarness', { | |
| 'name', "TestHarness", | |
| 'TestedOnce', true, | |
| 'Tested', true, | |
| 'GetTestSubject', function (self) return SelectedObj end, | |
| 'TestObject', PlaceObj('WaitNpcIdle', { | |
| TargetUnit = "StealthTutorialNPC", | |
| }), | |
| }), | |
| }) | |