warscript 0.0.1-dev.2d7cb44 → 0.0.1-dev.2fd8394

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/core/types/missile.lua +8 -7
  2. package/decl/native.d.ts +1 -0
  3. package/engine/ability-type-extended-tooltip.d.ts +8 -0
  4. package/engine/ability-type-extended-tooltip.lua +44 -0
  5. package/engine/behaviour/ability/emulate-impact.d.ts +14 -0
  6. package/engine/behaviour/ability/emulate-impact.lua +74 -1
  7. package/engine/behaviour/ability/instant-impact.d.ts +12 -1
  8. package/engine/behaviour/ability/instant-impact.lua +17 -2
  9. package/engine/behaviour/ability.d.ts +6 -0
  10. package/engine/behaviour/ability.lua +64 -8
  11. package/engine/buff.d.ts +53 -44
  12. package/engine/buff.lua +254 -227
  13. package/engine/internal/object-data/returned-melee-damage-factor.lua +21 -0
  14. package/engine/internal/unit/ability.lua +19 -15
  15. package/engine/internal/unit/bonus.d.ts +3 -0
  16. package/engine/internal/unit/bonus.lua +11 -0
  17. package/engine/internal/unit+ability.lua +10 -0
  18. package/engine/internal/unit-missile-data.lua +96 -94
  19. package/engine/internal/unit.lua +3 -0
  20. package/engine/lightning.lua +4 -4
  21. package/engine/object-data/entry/ability-type/barrage.d.ts +12 -0
  22. package/engine/object-data/entry/ability-type/barrage.lua +52 -0
  23. package/engine/object-data/entry/ability-type/blank-configurable.d.ts +0 -3
  24. package/engine/object-data/entry/ability-type/blank-configurable.lua +2 -32
  25. package/engine/object-data/entry/ability-type/blank-passive-with-cooldown.d.ts +23 -0
  26. package/engine/object-data/entry/ability-type/blank-passive-with-cooldown.lua +112 -0
  27. package/engine/object-data/entry/ability-type/channel.d.ts +2 -2
  28. package/engine/object-data/entry/ability-type/channel.lua +3 -3
  29. package/engine/object-data/entry/ability-type.d.ts +10 -2
  30. package/engine/object-data/entry/ability-type.lua +55 -3
  31. package/engine/object-data/entry/buff-type/applicable.lua +10 -3
  32. package/engine/object-data/entry/unit-type.d.ts +10 -0
  33. package/engine/object-data/entry/unit-type.lua +34 -20
  34. package/engine/standard/fields/ability.d.ts +2 -2
  35. package/engine/standard/fields/ability.lua +2 -2
  36. package/engine/text-tag.d.ts +13 -1
  37. package/engine/text-tag.lua +79 -42
  38. package/package.json +2 -2
  39. package/engine/internal/unit/pseudo-passive-abilities.lua +0 -11
  40. /package/engine/internal/{unit/pseudo-passive-abilities.d.ts → object-data/returned-melee-damage-factor.d.ts} +0 -0
@@ -0,0 +1,112 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local __TS__Class = ____lualib.__TS__Class
3
+ local __TS__ClassExtends = ____lualib.__TS__ClassExtends
4
+ local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor
5
+ local ____exports = {}
6
+ local ____exhume_2Dcorpses = require("engine.object-data.entry.ability-type.exhume-corpses")
7
+ local ExhumeCorpsesAbilityType = ____exhume_2Dcorpses.ExhumeCorpsesAbilityType
8
+ local ____ability = require("engine.standard.fields.ability")
9
+ local DURATION_HERO_ABILITY_FLOAT_LEVEL_FIELD = ____ability.DURATION_HERO_ABILITY_FLOAT_LEVEL_FIELD
10
+ local DURATION_NORMAL_ABILITY_FLOAT_LEVEL_FIELD = ____ability.DURATION_NORMAL_ABILITY_FLOAT_LEVEL_FIELD
11
+ local TOOLTIP_NORMAL_EXTENDED_ABILITY_STRING_LEVEL_FIELD = ____ability.TOOLTIP_NORMAL_EXTENDED_ABILITY_STRING_LEVEL_FIELD
12
+ local ____ability_2Dtype_2Dextended_2Dtooltip = require("engine.ability-type-extended-tooltip")
13
+ local overrideAbilityTypeExtendedTooltipLocally = ____ability_2Dtype_2Dextended_2Dtooltip.overrideAbilityTypeExtendedTooltipLocally
14
+ local ____local_2Dclient = require("engine.local-client")
15
+ local LocalClient = ____local_2Dclient.LocalClient
16
+ local ____timer = require("core.types.timer")
17
+ local Timer = ____timer.Timer
18
+ local NATIVE_DURATION = 2147483
19
+ local compiletimeAbilityTypeIds = {}
20
+ --- A passive ability whose cooldown can be started (`Ability.startCooldown`): Exhume
21
+ -- Corpses (`Aexh`) is the only passive base ability that shows a cooldown.
22
+ --
23
+ -- The corpse fields of the underlying Exhume Corpses are fixed at zero and its native
24
+ -- durations at a practically infinite value. {@link buffDuration} and
25
+ -- {@link heroBuffDuration} are kept for scripts separately from the native fields.
26
+ --
27
+ -- The game ignores per-ability extended tooltips of this base ability, so the type's own
28
+ -- tooltip is replaced locally with the one of the locally main selected unit's ability.
29
+ -- Read the type's tooltip with `getAbilityTypeExtendedTooltip`, not with the native.
30
+ ____exports.BlankPassiveAbilityWithCooldownAbilityType = __TS__Class()
31
+ local BlankPassiveAbilityWithCooldownAbilityType = ____exports.BlankPassiveAbilityWithCooldownAbilityType
32
+ BlankPassiveAbilityWithCooldownAbilityType.name = "BlankPassiveAbilityWithCooldownAbilityType"
33
+ __TS__ClassExtends(BlankPassiveAbilityWithCooldownAbilityType, ExhumeCorpsesAbilityType)
34
+ function BlankPassiveAbilityWithCooldownAbilityType.prototype.____constructor(self, object)
35
+ ExhumeCorpsesAbilityType.prototype.____constructor(self, object)
36
+ self.levelCount = 1
37
+ self.iconPath = ""
38
+ self.targetEffectPresets = {}
39
+ self.maximumCorpseCount = function() return 0 end
40
+ self.corpseUnitTypeId = function() return 0 end
41
+ self:setNumberLevelField(
42
+ "adur",
43
+ function() return NATIVE_DURATION end
44
+ )
45
+ self:setNumberLevelField(
46
+ "ahdu",
47
+ function() return NATIVE_DURATION end
48
+ )
49
+ self.buffDuration = function() return 0 end
50
+ self.heroBuffDuration = function() return 0 end
51
+ self.buffTypeIds = function() return {} end
52
+ self.techTreeDependencies = {}
53
+ compiletimeAbilityTypeIds[self.id] = true
54
+ end
55
+ BlankPassiveAbilityWithCooldownAbilityType.IS_SYNTHETIC = true
56
+ __TS__SetDescriptor(
57
+ BlankPassiveAbilityWithCooldownAbilityType.prototype,
58
+ "buffDuration",
59
+ {
60
+ get = function(self)
61
+ return DURATION_NORMAL_ABILITY_FLOAT_LEVEL_FIELD:getValue(self)
62
+ end,
63
+ set = function(self, buffDuration)
64
+ DURATION_NORMAL_ABILITY_FLOAT_LEVEL_FIELD:setValue(self, buffDuration)
65
+ end
66
+ },
67
+ true
68
+ )
69
+ __TS__SetDescriptor(
70
+ BlankPassiveAbilityWithCooldownAbilityType.prototype,
71
+ "heroBuffDuration",
72
+ {
73
+ get = function(self)
74
+ return DURATION_HERO_ABILITY_FLOAT_LEVEL_FIELD:getValue(self)
75
+ end,
76
+ set = function(self, heroBuffDuration)
77
+ DURATION_HERO_ABILITY_FLOAT_LEVEL_FIELD:setValue(self, heroBuffDuration)
78
+ end
79
+ },
80
+ true
81
+ )
82
+ local abilityTypeIds = postcompile(function() return compiletimeAbilityTypeIds end)
83
+ if (next(abilityTypeIds)) ~= nil then
84
+ local overriddenLevelCountByAbilityTypeId = {}
85
+ Timer.onPeriod[1 / 32]:addListener(
86
+ 0,
87
+ function()
88
+ local unit = LocalClient.mainSelectedUnit
89
+ for abilityTypeId in pairs(abilityTypeIds) do
90
+ local ability = unit and unit:getAbility(abilityTypeId)
91
+ local levelCount = ability and ability.levelCount or 0
92
+ if ability ~= nil then
93
+ for level = 0, levelCount - 1 do
94
+ overrideAbilityTypeExtendedTooltipLocally(
95
+ abilityTypeId,
96
+ level,
97
+ TOOLTIP_NORMAL_EXTENDED_ABILITY_STRING_LEVEL_FIELD:getValue(ability, level)
98
+ )
99
+ end
100
+ end
101
+ local overriddenLevelCount = overriddenLevelCountByAbilityTypeId[abilityTypeId] or 0
102
+ for level = levelCount, overriddenLevelCount - 1 do
103
+ overrideAbilityTypeExtendedTooltipLocally(abilityTypeId, level, nil)
104
+ end
105
+ if levelCount ~= overriddenLevelCount then
106
+ overriddenLevelCountByAbilityTypeId[abilityTypeId] = levelCount
107
+ end
108
+ end
109
+ end
110
+ )
111
+ end
112
+ return ____exports
@@ -33,8 +33,8 @@ export declare class ChannelAbilityType extends AbilityType {
33
33
  */
34
34
  get isUniqueCast(): boolean[];
35
35
  set isUniqueCast(isUniqueCast: ObjectDataEntryLevelFieldValueSupplier<boolean>);
36
- get casterAttachmentPresetsDuration(): number[];
37
- set casterAttachmentPresetsDuration(casterAttachmentsDuration: ObjectDataEntryLevelFieldValueSupplier<number>);
36
+ get casterEffectPresetsDuration(): number[];
37
+ set casterEffectPresetsDuration(casterEffectPresetsDuration: ObjectDataEntryLevelFieldValueSupplier<number>);
38
38
  /**
39
39
  * Whether the ability should disable and hide other abilities while being channeled.
40
40
  */
@@ -100,13 +100,13 @@ __TS__SetDescriptor(
100
100
  )
101
101
  __TS__SetDescriptor(
102
102
  ChannelAbilityType.prototype,
103
- "casterAttachmentPresetsDuration",
103
+ "casterEffectPresetsDuration",
104
104
  {
105
105
  get = function(self)
106
106
  return self:getNumberLevelField("Ncl4")
107
107
  end,
108
- set = function(self, casterAttachmentsDuration)
109
- self:setNumberLevelField("Ncl4", casterAttachmentsDuration)
108
+ set = function(self, casterEffectPresetsDuration)
109
+ self:setNumberLevelField("Ncl4", casterEffectPresetsDuration)
110
110
  end
111
111
  },
112
112
  true
@@ -32,10 +32,16 @@ export declare abstract class AbilityType extends ObjectDataEntry<AbilityTypeId>
32
32
  set casterCastingEffectPresets(casterCastingEffectPresets: EffectPresetWithParametersInput[]);
33
33
  get casterChannelingEffectPresets(): EffectPresetWithParameters[];
34
34
  set casterChannelingEffectPresets(casterChannelingEffectPresets: EffectPresetWithParametersInput[]);
35
- get casterAttachmentPresets(): TupleOf<EffectPresetWithParameters, 0 | 1 | 2>;
36
- set casterAttachmentPresets(casterAttachmentPresets: TupleOf<AttachmentPresetInput, 0 | 1 | 2>);
35
+ get casterEffectPresets(): TupleOf<EffectPresetWithParameters, 0 | 1 | 2>;
36
+ set casterEffectPresets(casterEffectPresets: TupleOf<AttachmentPresetInput, 0 | 1 | 2>);
37
37
  get effectModelPaths(): string[];
38
38
  set effectModelPaths(effectModelPaths: string[]);
39
+ get effectModelPathsSD(): string[];
40
+ set effectModelPathsSD(effectModelPathsSD: string[]);
41
+ get effectModelPathsHD(): string[];
42
+ set effectModelPathsHD(effectModelPathsHD: string[]);
43
+ get effectModelPathsDE(): string[];
44
+ set effectModelPathsDE(effectModelPathsDE: string[]);
39
45
  get iconPath(): string;
40
46
  set iconPath(iconPath: string);
41
47
  get iconPathSD(): string;
@@ -154,6 +160,8 @@ export declare abstract class AbilityType extends ObjectDataEntry<AbilityTypeId>
154
160
  set effectBuffTypeIds(effectBuffTypeIds: ObjectDataEntryLevelFieldValueSupplier<BuffTypeId[]>);
155
161
  get heroBuffDuration(): number[];
156
162
  set heroBuffDuration(heroBuffDuration: ObjectDataEntryLevelFieldValueSupplier<number>);
163
+ get isHeroAbility(): boolean;
164
+ set isHeroAbility(isHeroAbility: boolean);
157
165
  get learnLevelMinimum(): number;
158
166
  set learnLevelMinimum(learnLevelMinimum: number);
159
167
  get learnLevelStep(): number;
@@ -150,13 +150,13 @@ __TS__SetDescriptor(
150
150
  )
151
151
  __TS__SetDescriptor(
152
152
  AbilityType.prototype,
153
- "casterAttachmentPresets",
153
+ "casterEffectPresets",
154
154
  {
155
155
  get = function(self)
156
156
  return self:getAttachmentPresetListField("acat", {"acap", "aca1"})
157
157
  end,
158
- set = function(self, casterAttachmentPresets)
159
- self:setAttachmentPresetListField("acat", {"acap", "aca1"}, "acac", casterAttachmentPresets)
158
+ set = function(self, casterEffectPresets)
159
+ self:setAttachmentPresetListField("acat", {"acap", "aca1"}, "acac", casterEffectPresets)
160
160
  end
161
161
  },
162
162
  true
@@ -174,6 +174,45 @@ __TS__SetDescriptor(
174
174
  },
175
175
  true
176
176
  )
177
+ __TS__SetDescriptor(
178
+ AbilityType.prototype,
179
+ "effectModelPathsSD",
180
+ {
181
+ get = function(self)
182
+ return self:getStringsField("aeat:sd")
183
+ end,
184
+ set = function(self, effectModelPathsSD)
185
+ self:setStringsField("aeat:sd", effectModelPathsSD)
186
+ end
187
+ },
188
+ true
189
+ )
190
+ __TS__SetDescriptor(
191
+ AbilityType.prototype,
192
+ "effectModelPathsHD",
193
+ {
194
+ get = function(self)
195
+ return self:getStringsField("aeat:hd")
196
+ end,
197
+ set = function(self, effectModelPathsHD)
198
+ self:setStringsField("aeat:hd", effectModelPathsHD)
199
+ end
200
+ },
201
+ true
202
+ )
203
+ __TS__SetDescriptor(
204
+ AbilityType.prototype,
205
+ "effectModelPathsDE",
206
+ {
207
+ get = function(self)
208
+ return self:getStringsField("aeat:de")
209
+ end,
210
+ set = function(self, effectModelPathsDE)
211
+ self:setStringsField("aeat:de", effectModelPathsDE)
212
+ end
213
+ },
214
+ true
215
+ )
177
216
  __TS__SetDescriptor(
178
217
  AbilityType.prototype,
179
218
  "iconPath",
@@ -1022,6 +1061,19 @@ __TS__SetDescriptor(
1022
1061
  },
1023
1062
  true
1024
1063
  )
1064
+ __TS__SetDescriptor(
1065
+ AbilityType.prototype,
1066
+ "isHeroAbility",
1067
+ {
1068
+ get = function(self)
1069
+ return self:getBooleanField("aher")
1070
+ end,
1071
+ set = function(self, isHeroAbility)
1072
+ self:setBooleanField("aher", isHeroAbility)
1073
+ end
1074
+ },
1075
+ true
1076
+ )
1025
1077
  __TS__SetDescriptor(
1026
1078
  AbilityType.prototype,
1027
1079
  "learnLevelMinimum",
@@ -73,7 +73,7 @@ local applicatorAbilityTypeIdByApplicatorTypeByApplicableBuffTypeId, applicatorU
73
73
  abilityType.levelCount = applicableBuffType.levelCount
74
74
  abilityType.buttonPositionX = 0
75
75
  abilityType.buttonPositionY = -11
76
- abilityType.casterAttachmentPresets = {}
76
+ abilityType.casterEffectPresets = {}
77
77
  abilityType.targetEffectPresets = {}
78
78
  abilityType.casterEffectSoundPresetId = nil
79
79
  abilityType.learnLevelMinimum = 6
@@ -305,14 +305,21 @@ preparePhysicalPositiveApplicatorAbility = function(ability, level, duration)
305
305
  setAbilityRealLevelField(ability, ABILITY_RLF_DURATION_NORMAL, level, duration)
306
306
  setAbilityRealLevelField(ability, ABILITY_RLF_DURATION_HERO, level, duration)
307
307
  end
308
- ---
308
+ --- Removes the ability that keeps a hidden buff on the unit. A leftover applicator
309
+ -- makes the next hidden application fail, since the unit already has the ability.
310
+ --
309
311
  -- @internal For use by internal systems only.
310
- ____exports.removeBuff = function(unit, applicableBuffTypeId)
312
+ ____exports.removeBuffApplicator = function(unit, applicableBuffTypeId)
311
313
  local ____opt_3 = applicatorAbilityTypeIdByApplicatorTypeByApplicableBuffTypeId[applicableBuffTypeId]
312
314
  local applicatorAbilityTypeId = ____opt_3 and ____opt_3[0]
313
315
  if applicatorAbilityTypeId ~= nil then
314
316
  unitRemoveAbility(unit, applicatorAbilityTypeId)
315
317
  end
318
+ end
319
+ ---
320
+ -- @internal For use by internal systems only.
321
+ ____exports.removeBuff = function(unit, applicableBuffTypeId)
322
+ ____exports.removeBuffApplicator(unit, applicableBuffTypeId)
316
323
  return unitRemoveAbility(unit, applicableBuffTypeId)
317
324
  end
318
325
  return ____exports
@@ -69,6 +69,16 @@ export declare abstract class UnitType<Id extends UnitTypeId = UnitTypeId> exten
69
69
  protected static generateId(): number;
70
70
  protected static getObjectData(map: WarMap): WarObjects;
71
71
  private isPortraitModelPathSet?;
72
+ /** Portrait fields a model setter emptied because no portrait was set yet. */
73
+ private autoEmptiedPortraitFields?;
74
+ private emptyPortraitForModel;
75
+ /**
76
+ * An explicit portrait wins over the automatic empty portraits of the model setters, so
77
+ * it may also be set after the models: the mode-less portrait (one portrait for every
78
+ * mode) returns the automatically emptied per-mode portraits to their defaults, a
79
+ * per-mode portrait replaces only its own mode's.
80
+ */
81
+ private setPortraitModelPathField;
72
82
  get abilityTypeIds(): AbilityTypeId[];
73
83
  set abilityTypeIds(abilityTypeIds: AbilityTypeId[]);
74
84
  get defaultActiveAbilityTypeId(): AbilityTypeId | undefined;
@@ -484,6 +484,32 @@ end
484
484
  function UnitType.getObjectData(self, map)
485
485
  return map.objects.unit
486
486
  end
487
+ function UnitType.prototype.emptyPortraitForModel(self, portraitField)
488
+ if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
489
+ self:setStringField(portraitField, "")
490
+ if self.autoEmptiedPortraitFields == nil then
491
+ self.autoEmptiedPortraitFields = {}
492
+ end
493
+ self.autoEmptiedPortraitFields[portraitField] = true
494
+ end
495
+ end
496
+ function UnitType.prototype.setPortraitModelPathField(self, portraitField, portraitModelPath)
497
+ local autoEmptiedPortraitFields = self.autoEmptiedPortraitFields
498
+ if autoEmptiedPortraitFields ~= nil then
499
+ if portraitField == "upor" then
500
+ for field in pairs(autoEmptiedPortraitFields) do
501
+ if field ~= portraitField then
502
+ self.object:setField(field, nil)
503
+ end
504
+ end
505
+ self.autoEmptiedPortraitFields = nil
506
+ else
507
+ autoEmptiedPortraitFields[portraitField] = nil
508
+ end
509
+ end
510
+ self:setStringField(portraitField, portraitModelPath)
511
+ self.isPortraitModelPathSet = true
512
+ end
487
513
  function UnitType.prototype.setDeathTypeFlag(self, flag, value)
488
514
  local deathType = self:getNumberField("udea")
489
515
  self:setNumberField("udea", value and deathType | flag or deathType & ~flag)
@@ -1076,9 +1102,7 @@ __TS__SetDescriptor(
1076
1102
  end,
1077
1103
  set = function(self, modelPath)
1078
1104
  self:setStringField("umdl", modelPath)
1079
- if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
1080
- self:setStringField("upor", "")
1081
- end
1105
+ self:emptyPortraitForModel("upor")
1082
1106
  end
1083
1107
  },
1084
1108
  true
@@ -1092,9 +1116,7 @@ __TS__SetDescriptor(
1092
1116
  end,
1093
1117
  set = function(self, modelPathSD)
1094
1118
  self:setStringField("umdl:sd", modelPathSD)
1095
- if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
1096
- self:setStringField("upor:sd", "")
1097
- end
1119
+ self:emptyPortraitForModel("upor:sd")
1098
1120
  end
1099
1121
  },
1100
1122
  true
@@ -1108,9 +1130,7 @@ __TS__SetDescriptor(
1108
1130
  end,
1109
1131
  set = function(self, modelPathHD)
1110
1132
  self:setStringField("umdl:hd", modelPathHD)
1111
- if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
1112
- self:setStringField("upor:hd", "")
1113
- end
1133
+ self:emptyPortraitForModel("upor:hd")
1114
1134
  end
1115
1135
  },
1116
1136
  true
@@ -1124,9 +1144,7 @@ __TS__SetDescriptor(
1124
1144
  end,
1125
1145
  set = function(self, modelPathDE)
1126
1146
  self:setStringField("umdl:de", modelPathDE)
1127
- if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
1128
- self:setStringField("upor:de", "")
1129
- end
1147
+ self:emptyPortraitForModel("upor:de")
1130
1148
  end
1131
1149
  },
1132
1150
  true
@@ -1139,8 +1157,7 @@ __TS__SetDescriptor(
1139
1157
  return self:getStringField("upor")
1140
1158
  end,
1141
1159
  set = function(self, portraitModelPath)
1142
- self:setStringField("upor", portraitModelPath)
1143
- self.isPortraitModelPathSet = true
1160
+ self:setPortraitModelPathField("upor", portraitModelPath)
1144
1161
  end
1145
1162
  },
1146
1163
  true
@@ -1153,8 +1170,7 @@ __TS__SetDescriptor(
1153
1170
  return self:getStringField("upor:sd")
1154
1171
  end,
1155
1172
  set = function(self, portraitModelPathSD)
1156
- self:setStringField("upor:sd", portraitModelPathSD)
1157
- self.isPortraitModelPathSet = true
1173
+ self:setPortraitModelPathField("upor:sd", portraitModelPathSD)
1158
1174
  end
1159
1175
  },
1160
1176
  true
@@ -1167,8 +1183,7 @@ __TS__SetDescriptor(
1167
1183
  return self:getStringField("upor:hd")
1168
1184
  end,
1169
1185
  set = function(self, portraitModelPathHD)
1170
- self:setStringField("upor:hd", portraitModelPathHD)
1171
- self.isPortraitModelPathSet = true
1186
+ self:setPortraitModelPathField("upor:hd", portraitModelPathHD)
1172
1187
  end
1173
1188
  },
1174
1189
  true
@@ -1181,8 +1196,7 @@ __TS__SetDescriptor(
1181
1196
  return self:getStringField("upor:de")
1182
1197
  end,
1183
1198
  set = function(self, portraitModelPathDE)
1184
- self:setStringField("upor:de", portraitModelPathDE)
1185
- self.isPortraitModelPathSet = true
1199
+ self:setPortraitModelPathField("upor:de", portraitModelPathDE)
1186
1200
  end
1187
1201
  },
1188
1202
  true
@@ -7,8 +7,8 @@ export declare const BUTTON_POSITION_ACTIVATED_Y_ABILITY_INTEGER_FIELD: AbilityI
7
7
  export declare const BUTTON_POSITION_RESEARCH_X_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
8
8
  export declare const BUTTON_POSITION_RESEARCH_Y_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
9
9
  export declare const MISSILE_SPEED_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
10
- export declare const TARGET_ATTACHMENTS_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
11
- export declare const CASTER_ATTACHMENTS_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
10
+ export declare const TARGET_EFFECT_COUNT_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
11
+ export declare const CASTER_EFFECT_COUNT_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
12
12
  export declare const PRIORITY_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
13
13
  export declare const LEVELS_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
14
14
  export declare const REQUIRED_LEVEL_ABILITY_INTEGER_FIELD: AbilityIntegerField & symbol;
@@ -18,8 +18,8 @@ ____exports.BUTTON_POSITION_ACTIVATED_Y_ABILITY_INTEGER_FIELD = AbilityIntegerFi
18
18
  ____exports.BUTTON_POSITION_RESEARCH_X_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("arpx"))
19
19
  ____exports.BUTTON_POSITION_RESEARCH_Y_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("arpy"))
20
20
  ____exports.MISSILE_SPEED_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("amsp"))
21
- ____exports.TARGET_ATTACHMENTS_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("atac"))
22
- ____exports.CASTER_ATTACHMENTS_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("acac"))
21
+ ____exports.TARGET_EFFECT_COUNT_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("atac"))
22
+ ____exports.CASTER_EFFECT_COUNT_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("acac"))
23
23
  ____exports.PRIORITY_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("apri"))
24
24
  ____exports.LEVELS_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("alev"))
25
25
  ____exports.REQUIRED_LEVEL_ABILITY_INTEGER_FIELD = AbilityIntegerField:create(fourCC("arlv"))
@@ -20,7 +20,13 @@ declare const enum TextTagPropertyKey {
20
20
  FONT_SIZE = 104,
21
21
  COLOR = 105,
22
22
  X = 106,
23
- Y = 107
23
+ Y = 107,
24
+ UNIT_X = 108,
25
+ UNIT_Y = 109,
26
+ UNIT_Z = 110,
27
+ UNIT_FLY_HEIGHT = 111,
28
+ IS_VISIBILITY_CHECK_PENDING = 112,
29
+ VISIBILITY_CHECK_PHASE = 113
24
30
  }
25
31
  export declare class TextTag extends AbstractDestroyable {
26
32
  private [TextTagPropertyKey.HANDLE]?;
@@ -31,6 +37,12 @@ export declare class TextTag extends AbstractDestroyable {
31
37
  private [TextTagPropertyKey.UNIT]?;
32
38
  private [TextTagPropertyKey.X]?;
33
39
  private [TextTagPropertyKey.Y]?;
40
+ private [TextTagPropertyKey.UNIT_X]?;
41
+ private [TextTagPropertyKey.UNIT_Y]?;
42
+ private [TextTagPropertyKey.UNIT_Z]?;
43
+ private [TextTagPropertyKey.UNIT_FLY_HEIGHT]?;
44
+ private [TextTagPropertyKey.IS_VISIBILITY_CHECK_PENDING]?;
45
+ private [TextTagPropertyKey.VISIBILITY_CHECK_PHASE]?;
34
46
  private constructor();
35
47
  protected onDestroy(): Destructor;
36
48
  get text(): string;
@@ -13,8 +13,6 @@ local ____destroyable = require("destroyable")
13
13
  local AbstractDestroyable = ____destroyable.AbstractDestroyable
14
14
  local ____playerCamera = require("core.types.playerCamera")
15
15
  local worldCoordinatesToFrame = ____playerCamera.worldCoordinatesToFrame
16
- local ____get_2Dterrain_2Dz = require("engine.internal.misc.get-terrain-z")
17
- local getTerrainZ = ____get_2Dterrain_2Dz.getTerrainZ
18
16
  local ____player_2Dlocal_2Dhandle = require("engine.internal.misc.player-local-handle")
19
17
  local PLAYER_LOCAL_HANDLE = ____player_2Dlocal_2Dhandle.PLAYER_LOCAL_HANDLE
20
18
  local createTextTag = CreateTextTag
@@ -36,8 +34,10 @@ local isUnitVisible = IsUnitVisible
36
34
  local getUnitFlyHeight = GetUnitFlyHeight
37
35
  local getUnitX = GetUnitX
38
36
  local getUnitY = GetUnitY
37
+ local getUnitZ = BlzGetUnitZ
39
38
  local unitAlive = UnitAlive
40
39
  local DEFAULT_FONT_SIZE = 0.024
40
+ local VISIBILITY_CHECK_INTERVAL = 4
41
41
  local function applyConfiguration(textTag, configuration)
42
42
  setTextTagFadepoint(textTag, configuration.fadepoint)
43
43
  setTextTagLifespan(textTag, configuration.lifespan)
@@ -54,6 +54,7 @@ local function applyConfiguration(textTag, configuration)
54
54
  setTextTagVisibility(textTag, true)
55
55
  end
56
56
  local unitTextTags = setmetatable({}, {__mode = "k"})
57
+ local nextVisibilityCheckPhase = 0
57
58
  local function ensureHandle(textTag)
58
59
  local handle = textTag[101]
59
60
  if handle == nil then
@@ -109,7 +110,9 @@ function TextTag.create(self, configuration, text, unit)
109
110
  textTag[103] = text
110
111
  textTag[100] = unit
111
112
  textTag[102] = configuration
112
- ensureHandle(textTag)
113
+ textTag[113] = nextVisibilityCheckPhase
114
+ nextVisibilityCheckPhase = (nextVisibilityCheckPhase + 1) % VISIBILITY_CHECK_INTERVAL
115
+ textTag[112] = true
113
116
  unitTextTags[textTag] = true
114
117
  return textTag
115
118
  end
@@ -121,12 +124,14 @@ __TS__SetDescriptor(
121
124
  return self[103] or ""
122
125
  end,
123
126
  set = function(self, text)
124
- setTextTagText(
125
- ensureHandle(self),
126
- text,
127
- self[104] or DEFAULT_FONT_SIZE
128
- )
127
+ if text == self[103] then
128
+ return
129
+ end
129
130
  self[103] = text
131
+ local handle = self[101]
132
+ if handle ~= nil then
133
+ setTextTagText(handle, text, self[104] or DEFAULT_FONT_SIZE)
134
+ end
130
135
  end
131
136
  },
132
137
  true
@@ -139,12 +144,14 @@ __TS__SetDescriptor(
139
144
  return self[104] or DEFAULT_FONT_SIZE
140
145
  end,
141
146
  set = function(self, fontSize)
142
- setTextTagText(
143
- ensureHandle(self),
144
- self[103] or "",
145
- fontSize
146
- )
147
+ if fontSize == self[104] then
148
+ return
149
+ end
147
150
  self[104] = fontSize
151
+ local handle = self[101]
152
+ if handle ~= nil then
153
+ setTextTagText(handle, self[103] or "", fontSize)
154
+ end
148
155
  end
149
156
  },
150
157
  true
@@ -157,14 +164,20 @@ __TS__SetDescriptor(
157
164
  return self[105] or Color.white
158
165
  end,
159
166
  set = function(self, color)
160
- setTextTagColor(
161
- ensureHandle(self),
162
- color.r,
163
- color.g,
164
- color.b,
165
- color.a
166
- )
167
+ if color == self[105] then
168
+ return
169
+ end
167
170
  self[105] = color
171
+ local handle = self[101]
172
+ if handle ~= nil then
173
+ setTextTagColor(
174
+ handle,
175
+ color.r,
176
+ color.g,
177
+ color.b,
178
+ color.a
179
+ )
180
+ end
168
181
  end
169
182
  },
170
183
  true
@@ -178,13 +191,16 @@ __TS__SetDescriptor(
178
191
  end,
179
192
  set = function(self, unit)
180
193
  if unit ~= nil then
181
- setTextTagPosUnit(
182
- ensureHandle(self),
183
- unit.handle,
184
- 0
185
- )
186
194
  self[106] = nil
187
195
  self[107] = nil
196
+ self[108] = nil
197
+ self[109] = nil
198
+ self[111] = nil
199
+ self[112] = true
200
+ local handle = self[101]
201
+ if handle ~= nil then
202
+ setTextTagPosUnit(handle, unit.handle, self[102].offsetZ)
203
+ end
188
204
  unitTextTags[self] = true
189
205
  elseif self[100] ~= nil then
190
206
  local unit = self[100]
@@ -324,25 +340,46 @@ TextTag.SHADOW_STRIKE = __TS__ObjectAssign(
324
340
  lifespan = 5
325
341
  }
326
342
  )
343
+ local visibilityCheckPhase = 0
327
344
  Timer.onPeriod[1 / 64]:addListener(function()
345
+ visibilityCheckPhase = (visibilityCheckPhase + 1) % VISIBILITY_CHECK_INTERVAL
328
346
  for textTag in pairs(unitTextTags) do
329
- local unit = textTag[100].handle
330
- local x = getUnitX(unit)
331
- local y = getUnitY(unit)
332
- local ____, ____, isInView = worldCoordinatesToFrame(
333
- x,
334
- y,
335
- getUnitFlyHeight(unit) + getTerrainZ(x, y)
336
- )
337
- if isInView and not isUnitHidden(unit) and not isUnitLoaded(unit) and isUnitVisible(unit, PLAYER_LOCAL_HANDLE) and unitAlive(unit) then
338
- setTextTagPosUnit(
339
- ensureHandle(textTag),
340
- unit,
341
- textTag[102].offsetZ
342
- )
343
- elseif textTag[101] ~= nil then
344
- destroyTextTag(textTag[101])
345
- textTag[101] = nil
347
+ local handle = textTag[101]
348
+ local isVisibilityCheckDue = textTag[112] or textTag[113] == visibilityCheckPhase
349
+ if handle ~= nil or isVisibilityCheckDue then
350
+ local unit = textTag[100].handle
351
+ local x = getUnitX(unit)
352
+ local y = getUnitY(unit)
353
+ local flyHeight = getUnitFlyHeight(unit)
354
+ local hasPositionChanged = flyHeight ~= textTag[111]
355
+ if x ~= textTag[108] or y ~= textTag[109] then
356
+ textTag[108] = x
357
+ textTag[109] = y
358
+ textTag[110] = nil
359
+ hasPositionChanged = true
360
+ end
361
+ textTag[111] = flyHeight
362
+ local isShown = handle ~= nil
363
+ if isVisibilityCheckDue then
364
+ textTag[112] = nil
365
+ local z = textTag[110]
366
+ if z == nil then
367
+ z = getUnitZ(unit)
368
+ textTag[110] = z
369
+ end
370
+ local ____, ____, isInView = worldCoordinatesToFrame(x, y, flyHeight + z)
371
+ isShown = isInView and not isUnitHidden(unit) and not isUnitLoaded(unit) and isUnitVisible(unit, PLAYER_LOCAL_HANDLE) and unitAlive(unit)
372
+ end
373
+ if not isShown then
374
+ if handle ~= nil then
375
+ destroyTextTag(handle)
376
+ textTag[101] = nil
377
+ end
378
+ elseif handle == nil then
379
+ ensureHandle(textTag)
380
+ elseif hasPositionChanged then
381
+ setTextTagPosUnit(handle, unit, textTag[102].offsetZ)
382
+ end
346
383
  end
347
384
  end
348
385
  end)