warscript 0.0.1-dev.87b6c38 → 0.0.1-dev.8895725

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 (102) hide show
  1. package/core/types/frame.lua +47 -1
  2. package/core/types/handle.lua +6 -9
  3. package/core/types/item.d.ts +1 -0
  4. package/core/types/item.lua +1 -0
  5. package/core/types/player.d.ts +1 -1
  6. package/core/types/player.lua +12 -11
  7. package/core/types/sound.lua +1 -1
  8. package/destroyable.d.ts +1 -0
  9. package/destroyable.lua +9 -0
  10. package/engine/behavior.d.ts +4 -2
  11. package/engine/behavior.lua +69 -11
  12. package/engine/behaviour/ability/damage.d.ts +3 -0
  13. package/engine/behaviour/ability/damage.lua +8 -2
  14. package/engine/behaviour/ability/emulate-impact.lua +5 -4
  15. package/engine/behaviour/ability.d.ts +9 -5
  16. package/engine/behaviour/ability.lua +29 -0
  17. package/engine/behaviour/unit/stun-immunity.d.ts +1 -1
  18. package/engine/behaviour/unit/stun-immunity.lua +5 -4
  19. package/engine/behaviour/unit.lua +13 -3
  20. package/engine/buff.d.ts +56 -19
  21. package/engine/buff.lua +283 -142
  22. package/engine/internal/ability.lua +15 -15
  23. package/engine/internal/item/fields.d.ts +12 -0
  24. package/engine/internal/item/fields.lua +33 -0
  25. package/engine/internal/item.d.ts +4 -5
  26. package/engine/internal/item.lua +37 -40
  27. package/engine/internal/mechanics/cast-ability.lua +6 -3
  28. package/engine/internal/object-data/attribute-bonus.lua +2 -2
  29. package/engine/internal/object-data/health-bonus.d.ts +2 -0
  30. package/engine/internal/object-data/health-bonus.lua +16 -0
  31. package/engine/internal/object-data/mana-bonus.d.ts +2 -0
  32. package/engine/internal/object-data/mana-bonus.lua +16 -0
  33. package/engine/internal/object-data/mana-regeneration-rate-increase-factor.d.ts +2 -0
  34. package/engine/internal/object-data/mana-regeneration-rate-increase-factor.lua +16 -0
  35. package/engine/internal/unit/attributes.d.ts +17 -0
  36. package/engine/internal/unit/attributes.lua +46 -0
  37. package/engine/internal/unit/bonus.d.ts +6 -0
  38. package/engine/internal/unit/bonus.lua +33 -3
  39. package/engine/internal/unit/fly-height.lua +3 -3
  40. package/engine/internal/unit/interrupts.d.ts +12 -0
  41. package/engine/internal/unit/interrupts.lua +28 -0
  42. package/engine/internal/unit/range-event.d.ts +12 -0
  43. package/engine/internal/unit/range-event.lua +90 -0
  44. package/engine/internal/unit/scale.lua +3 -3
  45. package/engine/internal/unit+bonus.lua +3 -3
  46. package/engine/internal/unit-missile-launch.lua +12 -5
  47. package/engine/internal/unit.d.ts +2 -9
  48. package/engine/internal/unit.lua +79 -121
  49. package/engine/local-client.d.ts +6 -1
  50. package/engine/local-client.lua +60 -5
  51. package/engine/object-data/auxiliary/health-regeneration-type.d.ts +8 -0
  52. package/engine/object-data/auxiliary/health-regeneration-type.lua +2 -0
  53. package/engine/object-data/auxiliary/unit-attribute.lua +1 -1
  54. package/engine/object-data/entry/ability-type/{armor-increase.d.ts → armor-bonus.d.ts} +3 -3
  55. package/engine/object-data/entry/ability-type/{armor-increase.lua → armor-bonus.lua} +9 -9
  56. package/engine/object-data/entry/ability-type/health-bonus.d.ts +8 -0
  57. package/engine/object-data/entry/ability-type/health-bonus.lua +26 -0
  58. package/engine/object-data/entry/ability-type/mana-bonus.d.ts +8 -0
  59. package/engine/object-data/entry/ability-type/mana-bonus.lua +26 -0
  60. package/engine/object-data/entry/ability-type/mana-regeneration.d.ts +8 -0
  61. package/engine/object-data/entry/ability-type/mana-regeneration.lua +26 -0
  62. package/engine/object-data/entry/ability-type/reincarnation.d.ts +8 -0
  63. package/engine/object-data/entry/ability-type/reincarnation.lua +26 -0
  64. package/engine/object-data/entry/ability-type.d.ts +2 -0
  65. package/engine/object-data/entry/ability-type.lua +84 -4
  66. package/engine/object-data/entry/buff-type/applicable.lua +113 -109
  67. package/engine/object-data/entry/destructible-type.d.ts +12 -0
  68. package/engine/object-data/entry/destructible-type.lua +78 -0
  69. package/engine/object-field/ability.lua +2 -2
  70. package/engine/object-field/item.d.ts +22 -0
  71. package/engine/object-field/item.lua +118 -0
  72. package/engine/object-field/unit.d.ts +7 -4
  73. package/engine/object-field/unit.lua +4 -0
  74. package/engine/object-field.d.ts +3 -1
  75. package/engine/object-field.lua +177 -119
  76. package/engine/random.d.ts +1 -0
  77. package/engine/random.lua +8 -0
  78. package/engine/standard/fields/item.d.ts +4 -0
  79. package/engine/standard/fields/item.lua +6 -0
  80. package/engine/standard/fields/unit.d.ts +11 -5
  81. package/engine/standard/fields/unit.lua +13 -4
  82. package/engine/unit.d.ts +3 -0
  83. package/engine/unit.lua +3 -0
  84. package/lualib_bundle.lua +1 -1
  85. package/math.d.ts +2 -0
  86. package/math.lua +14 -0
  87. package/objutil/buff.lua +9 -7
  88. package/objutil/object.lua +1 -1
  89. package/operation.lua +1 -4
  90. package/package.json +5 -5
  91. package/patch-lua.lua +15 -0
  92. package/utility/linked-map.d.ts +35 -0
  93. package/utility/linked-map.lua +107 -0
  94. package/utility/linked-set.d.ts +3 -1
  95. package/utility/linked-set.lua +27 -0
  96. package/utility/records.lua +20 -1
  97. package/utility/unordered-map.d.ts +27 -0
  98. package/utility/unordered-map.lua +99 -0
  99. /package/engine/internal/object-data/{armor-increase.d.ts → armor-bonus.d.ts} +0 -0
  100. /package/engine/internal/object-data/{armor-increase.lua → armor-bonus.lua} +0 -0
  101. /package/engine/object-data/entry/ability-type/{attribute-increase.d.ts → attribute-bonus.d.ts} +0 -0
  102. /package/engine/object-data/entry/ability-type/{attribute-increase.lua → attribute-bonus.lua} +0 -0
@@ -24,11 +24,23 @@ local frameCoordinatesToWorld = ____playerCamera.frameCoordinatesToWorld
24
24
  local worldCoordinatesToFrame = ____playerCamera.worldCoordinatesToFrame
25
25
  local ____get_2Dterrain_2Dz = require("engine.internal.misc.get-terrain-z")
26
26
  local getTerrainZ = ____get_2Dterrain_2Dz.getTerrainZ
27
+ local ____lua_2Dsets = require("utility.lua-sets")
28
+ local mutableLuaSet = ____lua_2Dsets.mutableLuaSet
29
+ local ____socket = require("net.socket")
30
+ local Socket = ____socket.Socket
31
+ local ____lua_2Dmaps = require("utility.lua-maps")
32
+ local getOrPut = ____lua_2Dmaps.getOrPut
33
+ local luaMapInvert = ____lua_2Dmaps.luaMapInvert
34
+ local luaMapOf = ____lua_2Dmaps.luaMapOf
35
+ local mutableLuaMap = ____lua_2Dmaps.mutableLuaMap
27
36
  local frameClick = BlzFrameClick
28
37
  local frameGetEnable = BlzFrameGetEnable
29
38
  local frameIsVisible = BlzFrameIsVisible
30
39
  local frameSetEnable = BlzFrameSetEnable
31
40
  local frameSetScale = BlzFrameSetScale
41
+ local getHandleId = GetHandleId
42
+ local getOriginFrame = BlzGetOriginFrame
43
+ local location = Location
32
44
  local ____rawget = _G.rawget
33
45
  local rawset = _G.rawset
34
46
  local invoke = Event.invoke
@@ -130,6 +142,30 @@ do
130
142
  FramePoint.BOTTOM_RIGHT = FRAMEPOINT_BOTTOMRIGHT
131
143
  end
132
144
  local tooltipByFrame = setmetatable({}, {__mode = "k"})
145
+ local keyByAsyncInitOriginFrameType = luaMapOf(ORIGIN_FRAME_PORTRAIT_HP_TEXT, "hp", ORIGIN_FRAME_PORTRAIT_MANA_TEXT, "mana")
146
+ local asyncInitOriginFrameTypeByKey = luaMapInvert(keyByAsyncInitOriginFrameType)
147
+ local seenAsyncInitOriginFrameTypes = mutableLuaSet()
148
+ local seenAsyncInitOriginFrameTypesSocket = __TS__New(Socket)
149
+ local seenPlayersByAsyncInitOriginFrameType = mutableLuaMap()
150
+ seenAsyncInitOriginFrameTypesSocket.onMessage:addListener(function(player, key)
151
+ local asyncInitOriginFrameType = asyncInitOriginFrameTypeByKey[key]
152
+ if asyncInitOriginFrameType ~= nil then
153
+ getOrPut(seenPlayersByAsyncInitOriginFrameType, asyncInitOriginFrameType, mutableLuaSet)[player] = true
154
+ end
155
+ end)
156
+ local function haveAllPlayersSeenAsyncInitOriginFrameType(frame)
157
+ local players = seenPlayersByAsyncInitOriginFrameType[frame]
158
+ if players == nil then
159
+ return false
160
+ end
161
+ for ____, player in ipairs(Player.all) do
162
+ if player.isUser and player.isPlaying and not (players[player] ~= nil) then
163
+ return false
164
+ end
165
+ end
166
+ keyByAsyncInitOriginFrameType[frame] = nil
167
+ return true
168
+ end
133
169
  ____exports.Frame = __TS__Class()
134
170
  local Frame = ____exports.Frame
135
171
  Frame.name = "Frame"
@@ -308,7 +344,17 @@ function Frame.byOrigin(self, frameType, index)
308
344
  if index == nil then
309
345
  index = 0
310
346
  end
311
- return self:of(BlzGetOriginFrame(frameType, index))
347
+ local frame = getOriginFrame(frameType, index)
348
+ local asyncInitOriginFrameTypeKey = keyByAsyncInitOriginFrameType[frameType]
349
+ if index == 0 and asyncInitOriginFrameTypeKey ~= nil and not haveAllPlayersSeenAsyncInitOriginFrameType(frameType) then
350
+ if getHandleId(frame) == 0 or seenAsyncInitOriginFrameTypes[frameType] ~= nil then
351
+ location(0, 0)
352
+ else
353
+ seenAsyncInitOriginFrameTypes[frameType] = true
354
+ seenAsyncInitOriginFrameTypesSocket:send(asyncInitOriginFrameTypeKey)
355
+ end
356
+ end
357
+ return self:of(frame)
312
358
  end
313
359
  Frame.GAME_UI = ____exports.Frame:byOrigin(ORIGIN_FRAME_GAME_UI)
314
360
  Frame.CONSOLE_UI = ____exports.Frame:byOrigin(ORIGIN_FRAME_SIMPLE_UI_PARENT)
@@ -15,6 +15,8 @@ local ____exception = require("exception")
15
15
  local IllegalStateException = ____exception.IllegalStateException
16
16
  local ____attributes = require("attributes")
17
17
  local AttributesHolder = ____attributes.AttributesHolder
18
+ local ____preconditions = require("utility.preconditions")
19
+ local checkNotNull = ____preconditions.checkNotNull
18
20
  local getHandleId = GetHandleId
19
21
  local onCreateEventByHandleConstructor = {}
20
22
  local onDestroyEventByHandleConstructor = {}
@@ -66,17 +68,12 @@ function Handle.prototype.onDestroy(self, ...)
66
68
  return nil
67
69
  end
68
70
  function Handle.prototype.destroy(self, ...)
71
+ if self[0] == 2 or self[0] == 3 then
72
+ return nil
73
+ end
69
74
  local clazz = self.constructor
70
75
  local id = getHandleId(self.handle)
71
- if not clazz.memoized[id] then
72
- error(
73
- __TS__New(
74
- IllegalStateException,
75
- "Double-destroy run for handle " .. tostring(id)
76
- ),
77
- 0
78
- )
79
- end
76
+ checkNotNull(clazz.memoized[id])
80
77
  self[0] = 2
81
78
  if self.onDestroyEvent then
82
79
  Event.invoke(self.onDestroyEvent)
@@ -1,4 +1,5 @@
1
1
  /** @noSelfInFile */
2
2
  import { Item } from "../../engine/internal/item";
3
3
  import "../../engine/internal/item+owner";
4
+ import "../../engine/internal/item/fields";
4
5
  export { Item };
@@ -2,5 +2,6 @@ local ____exports = {}
2
2
  local ____item = require("engine.internal.item")
3
3
  local Item = ____item.Item
4
4
  require("engine.internal.item+owner")
5
+ require("engine.internal.item.fields")
5
6
  ____exports.Item = Item
6
7
  return ____exports
@@ -28,6 +28,7 @@ export declare class Player extends Handle<jplayer> {
28
28
  static readonly neutralExtra: Player;
29
29
  private static events;
30
30
  readonly id: number;
31
+ readonly slotState: jplayerslotstate;
31
32
  constructor(handle: jplayer);
32
33
  onDestroy(): HandleDestructor;
33
34
  toString(): string;
@@ -45,7 +46,6 @@ export declare class Player extends Handle<jplayer> {
45
46
  get isUser(): boolean;
46
47
  get isPlaying(): boolean;
47
48
  get controller(): jmapcontrol;
48
- get slotState(): jplayerslotstate;
49
49
  clearSelection(): void;
50
50
  selectSingle(unit: Unit): void;
51
51
  select(unit: Unit): void;
@@ -56,6 +56,7 @@ Player.name = "Player"
56
56
  __TS__ClassExtends(Player, Handle)
57
57
  function Player.prototype.____constructor(self, handle)
58
58
  Handle.prototype.____constructor(self, handle)
59
+ self.slotState = GetPlayerSlotState(self.handle)
59
60
  self.id = GetPlayerId(handle)
60
61
  end
61
62
  function Player.prototype.onDestroy(self)
@@ -364,7 +365,7 @@ __TS__SetDescriptor(
364
365
  Player.prototype,
365
366
  "isUser",
366
367
  {get = function(self)
367
- return GetPlayerController(self.handle) == MAP_CONTROL_USER
368
+ return self.controller == MAP_CONTROL_USER
368
369
  end},
369
370
  true
370
371
  )
@@ -372,7 +373,7 @@ __TS__SetDescriptor(
372
373
  Player.prototype,
373
374
  "isPlaying",
374
375
  {get = function(self)
375
- return GetPlayerSlotState(self.handle) == PLAYER_SLOT_STATE_PLAYING
376
+ return self.slotState == PLAYER_SLOT_STATE_PLAYING
376
377
  end},
377
378
  true
378
379
  )
@@ -380,15 +381,9 @@ __TS__SetDescriptor(
380
381
  Player.prototype,
381
382
  "controller",
382
383
  {get = function(self)
383
- return GetPlayerController(self.handle)
384
- end},
385
- true
386
- )
387
- __TS__SetDescriptor(
388
- Player.prototype,
389
- "slotState",
390
- {get = function(self)
391
- return GetPlayerSlotState(self.handle)
384
+ local controller = GetPlayerController(self.handle)
385
+ rawset(self, "controller", controller)
386
+ return controller
392
387
  end},
393
388
  true
394
389
  )
@@ -490,4 +485,10 @@ __TS__ObjectDefineProperty(
490
485
  end}
491
486
  )
492
487
  Player.colorChangedEvent = playerColorChangedEvent
488
+ ____exports.Player.onLeave:addListener(
489
+ 999999,
490
+ function(player)
491
+ rawset(player, "slotState", PLAYER_SLOT_STATE_LEFT)
492
+ end
493
+ )
493
494
  return ____exports
@@ -22,7 +22,7 @@ local setSoundPlayPosition = SetSoundPlayPosition
22
22
  local stopSound = StopSound
23
23
  local attachSoundToUnit = AttachSoundToUnit
24
24
  local killSoundWhenDone = KillSoundWhenDone
25
- ____exports.SoundChannel = SoundChannel or ({})
25
+ ____exports.SoundChannel = ____exports.SoundChannel or ({})
26
26
  ____exports.SoundChannel.General = 0
27
27
  ____exports.SoundChannel[____exports.SoundChannel.General] = "General"
28
28
  ____exports.SoundChannel.UnitSelection = 1
package/destroyable.d.ts CHANGED
@@ -10,6 +10,7 @@ export interface Destroyable {
10
10
  destroy(): void;
11
11
  }
12
12
  export declare abstract class AbstractDestroyable implements Destroyable {
13
+ get isDestroyed(): boolean;
13
14
  /**
14
15
  * An overriding function should always call the super one at the end of it,
15
16
  * in the following manner: `return super.onDestroy()`.
package/destroyable.lua CHANGED
@@ -1,6 +1,7 @@
1
1
  local ____lualib = require("lualib_bundle")
2
2
  local __TS__Class = ____lualib.__TS__Class
3
3
  local __TS__New = ____lualib.__TS__New
4
+ local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor
4
5
  local ____exports = {}
5
6
  local ____exception = require("exception")
6
7
  local IllegalStateException = ____exception.IllegalStateException
@@ -28,4 +29,12 @@ function AbstractDestroyable.prototype.destroy(self)
28
29
  end
29
30
  return true
30
31
  end
32
+ __TS__SetDescriptor(
33
+ AbstractDestroyable.prototype,
34
+ "isDestroyed",
35
+ {get = function(self)
36
+ return stateByDestroyable[self] ~= nil
37
+ end},
38
+ true
39
+ )
31
40
  return ____exports
@@ -18,9 +18,11 @@ export declare abstract class Behavior<T extends AnyNotNil, PeriodicActionParame
18
18
  private [BehaviorPropertyKey.PREVIOUS_BEHAVIOR]?;
19
19
  private [BehaviorPropertyKey.NEXT_BEHAVIOR]?;
20
20
  private [BehaviorPropertyKey.TIMER]?;
21
- protected constructor(object: T, priority?: BehaviorPriority);
21
+ constructor(object: T, priority?: BehaviorPriority);
22
22
  protected onDestroy(): Destructor;
23
- protected registerEvent<K extends string, Args extends any[]>(this: Behavior<any, PeriodicActionParameters> & Record<K, (this: this, ...args: Args) => unknown>, event: Event<[...Args]>, listener: K): void;
23
+ protected registerGlobalEvent<K extends string, Args extends any[]>(this: Behavior<any, PeriodicActionParameters> & Record<K, (this: this, ...args: Args) => unknown>, event: Event<[...Args]>, listener: K): void;
24
+ protected deregisterGlobalEvent(event: Event<any>): boolean;
25
+ protected registerEvent<K extends string, Args extends any[]>(this: Behavior<any, PeriodicActionParameters> & Record<K, (this: this, ...args: Args) => unknown>, event: Event<[...Args]>, extractObject: (...args: Args) => T | undefined, listener: K): void;
24
26
  protected deregisterEvent(event: Event<any>): boolean;
25
27
  protected onPeriod(...parameters: PeriodicActionParameters): void;
26
28
  protected startPeriodicAction(interval: number, ...parameters: PeriodicActionParameters): void;
@@ -57,9 +57,17 @@ local function reduceBehaviors(behaviorConstructor, object, operation, initial,
57
57
  end
58
58
  return accumulator
59
59
  end
60
+ local behaviorsByGlobalEvent = {}
61
+ local listenerByBehaviorByGlobalEvent = {}
62
+ local globalEventsByBehavior = {}
60
63
  local behaviorsByEvent = {}
61
64
  local listenerByBehaviorByEvent = {}
62
65
  local eventsByBehavior = {}
66
+ local function safeCallBehaviorListener(behavior, behaviors, listenerByBehavior, ...)
67
+ if behaviors[behavior] ~= nil then
68
+ safeCall(behavior[listenerByBehavior[behavior]], behavior, ...)
69
+ end
70
+ end
63
71
  ____exports.Behavior = __TS__Class()
64
72
  local Behavior = ____exports.Behavior
65
73
  Behavior.name = "Behavior"
@@ -87,18 +95,32 @@ function Behavior.prototype.onDestroy(self)
87
95
  if ____opt_0 ~= nil then
88
96
  ____opt_0:destroy()
89
97
  end
90
- local events = eventsByBehavior[self]
91
- if events ~= nil then
92
- for event in pairs(events) do
93
- local ____opt_2 = behaviorsByEvent[event]
98
+ local globalEvents = globalEventsByBehavior[self]
99
+ if globalEvents ~= nil then
100
+ for event in pairs(globalEvents) do
101
+ local ____opt_2 = behaviorsByGlobalEvent[event]
94
102
  if ____opt_2 ~= nil then
95
103
  ____opt_2:remove(self)
96
104
  end
97
- local ____opt_4 = listenerByBehaviorByEvent[event]
105
+ local ____opt_4 = listenerByBehaviorByGlobalEvent[event]
98
106
  if ____opt_4 ~= nil then
99
107
  ____opt_4[self] = nil
100
108
  end
101
109
  end
110
+ globalEventsByBehavior[self] = nil
111
+ end
112
+ local events = eventsByBehavior[self]
113
+ if events ~= nil then
114
+ for event in pairs(events) do
115
+ local ____opt_6 = behaviorsByEvent[event]
116
+ if ____opt_6 ~= nil then
117
+ ____opt_6[self] = nil
118
+ end
119
+ local ____opt_8 = listenerByBehaviorByEvent[event]
120
+ if ____opt_8 ~= nil then
121
+ ____opt_8[self] = nil
122
+ end
123
+ end
102
124
  eventsByBehavior[self] = nil
103
125
  end
104
126
  local previousBehavior = self[0]
@@ -115,7 +137,35 @@ function Behavior.prototype.onDestroy(self)
115
137
  end
116
138
  return AbstractDestroyable.prototype.onDestroy(self)
117
139
  end
118
- function Behavior.prototype.registerEvent(self, event, listener)
140
+ function Behavior.prototype.registerGlobalEvent(self, event, listener)
141
+ local listenerByBehavior = getOrPut(listenerByBehaviorByGlobalEvent, event, mutableLuaMap)
142
+ listenerByBehavior[self] = listener
143
+ getOrPut(globalEventsByBehavior, self, mutableLuaSet)[event] = true
144
+ local behaviors = behaviorsByGlobalEvent[event]
145
+ if behaviors == nil then
146
+ event:addListener(function(...)
147
+ local behaviors = behaviorsByGlobalEvent[event]
148
+ if behaviors ~= nil then
149
+ for behavior in pairs(behaviors) do
150
+ safeCall(behavior[listenerByBehavior[behavior]], behavior, ...)
151
+ end
152
+ end
153
+ end)
154
+ behaviors = __TS__New(LinkedSet)
155
+ behaviorsByGlobalEvent[event] = behaviors
156
+ end
157
+ behaviors:add(self)
158
+ end
159
+ function Behavior.prototype.deregisterGlobalEvent(self, event)
160
+ local behaviors = behaviorsByGlobalEvent[event]
161
+ if behaviors ~= nil and behaviors:remove(self) then
162
+ globalEventsByBehavior[self][event] = nil
163
+ listenerByBehaviorByGlobalEvent[event][self] = nil
164
+ return true
165
+ end
166
+ return false
167
+ end
168
+ function Behavior.prototype.registerEvent(self, event, extractObject, listener)
119
169
  local listenerByBehavior = getOrPut(listenerByBehaviorByEvent, event, mutableLuaMap)
120
170
  listenerByBehavior[self] = listener
121
171
  getOrPut(eventsByBehavior, self, mutableLuaSet)[event] = true
@@ -124,19 +174,27 @@ function Behavior.prototype.registerEvent(self, event, listener)
124
174
  event:addListener(function(...)
125
175
  local behaviors = behaviorsByEvent[event]
126
176
  if behaviors ~= nil then
127
- for behavior in pairs(behaviors) do
128
- safeCall(behavior[listenerByBehavior[behavior]], behavior, ...)
177
+ local object = extractObject(...)
178
+ if object ~= nil then
179
+ ____exports.Behavior:forAll(
180
+ object,
181
+ safeCallBehaviorListener,
182
+ behaviors,
183
+ listenerByBehavior,
184
+ ...
185
+ )
129
186
  end
130
187
  end
131
188
  end)
132
- behaviors = __TS__New(LinkedSet)
189
+ behaviors = {}
133
190
  behaviorsByEvent[event] = behaviors
134
191
  end
135
- behaviors:add(self)
192
+ behaviors[self] = true
136
193
  end
137
194
  function Behavior.prototype.deregisterEvent(self, event)
138
195
  local behaviors = behaviorsByEvent[event]
139
- if behaviors ~= nil and behaviors:remove(self) then
196
+ if behaviors ~= nil and behaviors[self] ~= nil then
197
+ behaviors[self] = nil
140
198
  eventsByBehavior[self][event] = nil
141
199
  listenerByBehaviorByEvent[event][self] = nil
142
200
  return true
@@ -25,8 +25,11 @@ export declare abstract class DamageAbilityBehavior<T extends DamageAbilityBehav
25
25
  protected readonly damage: AbilityDependentValue<number>;
26
26
  protected readonly parameters?: T | undefined;
27
27
  protected constructor(ability: Ability, damage: AbilityDependentValue<number>, parameters?: T | undefined);
28
+ protected precalculatedDamage?: number;
28
29
  protected calculateDamage(caster: Unit): number;
29
30
  protected damageTarget(caster: Unit, target: Widget, damage?: number): void;
31
+ onChannelingStart(caster: Unit): void;
32
+ onStop(): void;
30
33
  }
31
34
  export declare class DamageSelfAbilityBehavior extends DamageAbilityBehavior {
32
35
  constructor(ability: Ability, damage: AbilityDependentValue<number>, parameters?: DamageAbilityBehaviorParameters);
@@ -39,7 +39,7 @@ function DamageAbilityBehavior.prototype.damageTarget(self, caster, target, dama
39
39
  local parameters = self.parameters
40
40
  caster:damageTarget(
41
41
  target,
42
- damage or self:calculateDamage(caster),
42
+ damage or self.precalculatedDamage or self:calculateDamage(caster),
43
43
  nil,
44
44
  nil,
45
45
  self:resolveCurrentAbilityDependentValue(parameters and parameters.attackType),
@@ -48,6 +48,12 @@ function DamageAbilityBehavior.prototype.damageTarget(self, caster, target, dama
48
48
  self:resolveCurrentAbilityDependentValue(parameters and parameters.metadata)
49
49
  )
50
50
  end
51
+ function DamageAbilityBehavior.prototype.onChannelingStart(self, caster)
52
+ self.precalculatedDamage = self:calculateDamage(caster)
53
+ end
54
+ function DamageAbilityBehavior.prototype.onStop(self)
55
+ self.precalculatedDamage = nil
56
+ end
51
57
  ____exports.DamageSelfAbilityBehavior = __TS__Class()
52
58
  local DamageSelfAbilityBehavior = ____exports.DamageSelfAbilityBehavior
53
59
  DamageSelfAbilityBehavior.name = "DamageSelfAbilityBehavior"
@@ -83,7 +89,7 @@ function DamageAreaAbilityBehavior.prototype.damageArea(self, caster, x, y)
83
89
  y,
84
90
  self:resolveCurrentAbilityDependentValue(parameters and parameters.areaOfEffect or AREA_OF_EFFECT_ABILITY_FLOAT_LEVEL_FIELD)
85
91
  )
86
- local damage = self:calculateDamage(caster)
92
+ local damage = self.precalculatedDamage or self:calculateDamage(caster)
87
93
  local maximumDamage = self:resolveCurrentAbilityDependentValue(parameters and parameters.maximumDamage or 0)
88
94
  if maximumDamage ~= 0 and damage > maximumDamage then
89
95
  damage = maximumDamage / #targets
@@ -10,9 +10,6 @@ local Unit = ____unit.Unit
10
10
  local ____ability = require("engine.standard.fields.ability")
11
11
  local COOLDOWN_ABILITY_FLOAT_LEVEL_FIELD = ____ability.COOLDOWN_ABILITY_FLOAT_LEVEL_FIELD
12
12
  local MANA_COST_ABILITY_INTEGER_LEVEL_FIELD = ____ability.MANA_COST_ABILITY_INTEGER_LEVEL_FIELD
13
- local ____math = require("math")
14
- local max = ____math.max
15
- local MINIMUM_POSITIVE_NORMALIZED_FLOAT = ____math.MINIMUM_POSITIVE_NORMALIZED_FLOAT
16
13
  local ____sound = require("core.types.sound")
17
14
  local Sound3D = ____sound.Sound3D
18
15
  local SoundSettings = ____sound.SoundSettings
@@ -31,7 +28,11 @@ function EmulateImpactAbilityBehavior.prototype.emulateImpact(self, caster)
31
28
  return false
32
29
  end
33
30
  caster.mana = caster.mana - manaCost
34
- self.ability.cooldownRemaining = max(cooldown, MINIMUM_POSITIVE_NORMALIZED_FLOAT)
31
+ if cooldown == 0 then
32
+ self.ability:interruptCast()
33
+ else
34
+ self.ability.cooldownRemaining = cooldown
35
+ end
35
36
  self:flashCasterEffect(caster)
36
37
  local soundPresetId = self.ability:getField(ABILITY_SF_EFFECT_SOUND)
37
38
  if soundPresetId ~= "" then
@@ -26,16 +26,20 @@ export declare abstract class AbilityBehavior<Parameters extends {
26
26
  get unit(): Unit | undefined;
27
27
  protected resolveCurrentAbilityDependentValue<T extends boolean | number | string>(value: AbilityDependentValue<T>): T;
28
28
  protected resolveCurrentAbilityDependentValue<T extends boolean | number | string>(value?: AbilityDependentValue<T>): T | undefined;
29
- protected flashCasterEffect(widget: Widget, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
30
- protected flashTargetEffect(widget: Widget, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
31
- protected flashAreaEffect(x: number, y: number, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
32
- protected flashEffect(x: number, y: number, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
33
- protected flashSpecialEffect(...args: [
29
+ flashCasterEffect(widget: Widget, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
30
+ flashTargetEffect(widget: Widget, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
31
+ flashAreaEffect(x: number, y: number, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
32
+ flashEffect(x: number, y: number, ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]): void;
33
+ flashSpecialEffect(...args: [
34
34
  ...pointOrWidget: [x: number, y: number] | [widget: Widget],
35
35
  ...parametersOrDuration: [parameters?: EffectParameters] | [duration?: number, parameters?: EffectParameters]
36
36
  ]): void;
37
37
  private static MissileLaunchConfig;
38
38
  private get missileLaunchConfig();
39
+ protected launchMissile(source: Unit, ...args: [
40
+ ...pointOrWidget: [x: number, y: number] | [widget: Unit /** TODO: support Widget */],
41
+ ...parameters: NonNullable<Parameters["missileParameters"]>
42
+ ]): void;
39
43
  protected onCreate(): void;
40
44
  onValueChange(_value: ReadonlySubscribableAbilityDependentValue<string | number | boolean>): void;
41
45
  onMissileArrival(...parameters: NonNullable<Parameters["missileParameters"]>): void;
@@ -30,7 +30,14 @@ local ____ability = require("engine.object-field.ability")
30
30
  local AbilityField = ____ability.AbilityField
31
31
  local AbilityLevelField = ____ability.AbilityLevelField
32
32
  local resolveCurrentAbilityDependentValue = ____ability.resolveCurrentAbilityDependentValue
33
+ local ____missile = require("core.types.missile")
34
+ local Missile = ____missile.Missile
33
35
  local createBehaviorFunctionsByAbilityTypeId = {}
36
+ local function invokeOnMissileArrival(_missile, success, abilityBehavior, ...)
37
+ if success then
38
+ abilityBehavior:onMissileArrival(...)
39
+ end
40
+ end
34
41
  local exclusiveOnImpactHandlerAbilityBehaviorByAbility = setmetatable({}, {__mode = "k"})
35
42
  local function createUnitEventListener(key)
36
43
  return function(unit, ability, ...)
@@ -160,6 +167,28 @@ function AbilityBehavior.prototype.flashSpecialEffect(self, xOrWidget, yOrParame
160
167
  )
161
168
  end
162
169
  end
170
+ function AbilityBehavior.prototype.launchMissile(self, source, xOrWidget, yOrParameter, ...)
171
+ if type(xOrWidget) ~= "number" then
172
+ Missile:launch(
173
+ self.missileLaunchConfig,
174
+ source,
175
+ xOrWidget,
176
+ invokeOnMissileArrival,
177
+ self,
178
+ yOrParameter,
179
+ ...
180
+ )
181
+ else
182
+ Missile:launch(
183
+ self.missileLaunchConfig,
184
+ source,
185
+ vec2(xOrWidget, yOrParameter),
186
+ invokeOnMissileArrival,
187
+ self,
188
+ ...
189
+ )
190
+ end
191
+ end
163
192
  function AbilityBehavior.prototype.onCreate(self)
164
193
  end
165
194
  function AbilityBehavior.prototype.onValueChange(self, _value)
@@ -7,7 +7,7 @@ import { Destructor } from "../../../destroyable";
7
7
  import { BehaviorPriority } from "../../behavior";
8
8
  export type StunImmunityUnitBehaviorParameters = {
9
9
  readonly priority?: BehaviorPriority;
10
- buffTypeIds?: LuaSet<BuffTypeId>;
10
+ buffTypeIds?: readonly BuffTypeId[];
11
11
  textTagPreset?: TextTagPreset;
12
12
  textTagText?: string;
13
13
  additionalAction?: (this: void, unit: Unit) => void;
@@ -8,14 +8,15 @@ local UnitBehavior = ____unit.UnitBehavior
8
8
  local ____ability_2Dtype = require("engine.object-data.entry.ability-type")
9
9
  local AbilityType = ____ability_2Dtype.AbilityType
10
10
  local ____arrays = require("utility.arrays")
11
- local flatMapToLuaSet = ____arrays.flatMapToLuaSet
11
+ local distinct = ____arrays.distinct
12
+ local flatMap = ____arrays.flatMap
12
13
  local map = ____arrays.map
13
14
  local ____text_2Dtag = require("engine.text-tag")
14
15
  local TextTag = ____text_2Dtag.TextTag
15
16
  local ____timer = require("core.types.timer")
16
17
  local Timer = ____timer.Timer
17
18
  local DEFAULT_BUFF_TYPE_IDS = postcompile(function()
18
- return flatMapToLuaSet(
19
+ return distinct(flatMap(
19
20
  AbilityType:getAllByBaseIds(map({
20
21
  "AHtb",
21
22
  "AHbh",
@@ -41,11 +42,11 @@ local DEFAULT_BUFF_TYPE_IDS = postcompile(function()
41
42
  "ACcb"
42
43
  }, fourCC)),
43
44
  function(abilityType) return __TS__ArrayFlat(abilityType.buffTypeIds) end
44
- )
45
+ ))
45
46
  end)
46
47
  local function process(behavior)
47
48
  local hasRemovedBuffs = false
48
- for buffTypeId in pairs(behavior.parameters.buffTypeIds or DEFAULT_BUFF_TYPE_IDS) do
49
+ for ____, buffTypeId in ipairs(behavior.parameters.buffTypeIds or DEFAULT_BUFF_TYPE_IDS) do
49
50
  hasRemovedBuffs = hasRemovedBuffs or behavior.unit:removeBuff(buffTypeId)
50
51
  end
51
52
  if hasRemovedBuffs then
@@ -21,6 +21,8 @@ local ____bonus = require("engine.internal.unit.bonus")
21
21
  local addOrUpdateOrRemoveUnitBonus = ____bonus.addOrUpdateOrRemoveUnitBonus
22
22
  local getUnitBonus = ____bonus.getUnitBonus
23
23
  local removeUnitBonus = ____bonus.removeUnitBonus
24
+ local ____linked_2Dmap = require("utility.linked-map")
25
+ local LinkedMap = ____linked_2Dmap.LinkedMap
24
26
  local safeCall = warpack.safeCall
25
27
  local createBehaviorFunctionsByUnitTypeId = {}
26
28
  local behaviorsByOwningPlayerEvent = {}
@@ -79,16 +81,24 @@ function UnitBehavior.prototype.onDestroy(self)
79
81
  end
80
82
  function UnitBehavior.prototype.getUnitBonus(self, bonusType)
81
83
  local ____opt_10 = self._bonusIdByBonusType
82
- local bonusId = ____opt_10 and ____opt_10[bonusType]
84
+ local bonusId = ____opt_10 and ____opt_10:get(bonusType)
83
85
  return bonusId == nil and 0 or getUnitBonus(self.object, bonusType, bonusId)
84
86
  end
85
87
  function UnitBehavior.prototype.addOrUpdateOrRemoveUnitBonus(self, bonusType, value)
86
88
  local bonusIdByBonusType = self._bonusIdByBonusType
87
89
  if bonusIdByBonusType == nil then
88
- bonusIdByBonusType = {}
90
+ bonusIdByBonusType = __TS__New(LinkedMap)
89
91
  self._bonusIdByBonusType = bonusIdByBonusType
90
92
  end
91
- bonusIdByBonusType[bonusType] = addOrUpdateOrRemoveUnitBonus(self.object, bonusType, bonusIdByBonusType[bonusType], value)
93
+ bonusIdByBonusType:put(
94
+ bonusType,
95
+ addOrUpdateOrRemoveUnitBonus(
96
+ self.object,
97
+ bonusType,
98
+ bonusIdByBonusType:get(bonusType),
99
+ value
100
+ )
101
+ )
92
102
  end
93
103
  function UnitBehavior.prototype.registerOwningPlayerEvent(self, event, extractPlayer, listener)
94
104
  local listenerByBehavior = getOrPut(listenerByBehaviorByOwningPlayerEvent, event, mutableLuaMap)