warscript 0.0.1-dev.7278154 → 0.0.1-dev.73fbafc

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 (45) hide show
  1. package/attributes.d.ts +1 -0
  2. package/attributes.lua +9 -0
  3. package/core/types/frame.lua +14 -9
  4. package/core/types/playerCamera.lua +44 -0
  5. package/core/types/tileCell.d.ts +9 -0
  6. package/core/types/tileCell.lua +92 -0
  7. package/core/types/timer.d.ts +3 -2
  8. package/core/types/timer.lua +8 -2
  9. package/decl/native.d.ts +2 -2
  10. package/engine/behavior.d.ts +1 -0
  11. package/engine/behavior.lua +9 -0
  12. package/engine/behaviour/ability/remove-buffs.d.ts +9 -0
  13. package/engine/behaviour/ability/remove-buffs.lua +21 -0
  14. package/engine/behaviour/unit/stun-immunity.d.ts +2 -0
  15. package/engine/behaviour/unit/stun-immunity.lua +11 -2
  16. package/engine/behaviour/unit.d.ts +2 -0
  17. package/engine/behaviour/unit.lua +5 -0
  18. package/engine/internal/ability.lua +6 -5
  19. package/engine/internal/item.d.ts +13 -15
  20. package/engine/internal/item.lua +59 -48
  21. package/engine/internal/unit/ability.d.ts +14 -14
  22. package/engine/internal/unit/ability.lua +72 -45
  23. package/engine/internal/unit/main-selected.lua +12 -27
  24. package/engine/internal/unit-missile-launch.lua +42 -21
  25. package/engine/internal/unit.d.ts +4 -2
  26. package/engine/internal/unit.lua +26 -15
  27. package/engine/object-data/entry/ability-type.lua +4 -1
  28. package/engine/random.d.ts +9 -0
  29. package/engine/random.lua +13 -0
  30. package/engine/synchronization.d.ts +11 -0
  31. package/engine/synchronization.lua +77 -0
  32. package/engine/text-tag.lua +1 -1
  33. package/net/socket.lua +1 -1
  34. package/objutil/buff.lua +1 -1
  35. package/package.json +2 -2
  36. package/patch-lualib.lua +1 -1
  37. package/utility/arrays.d.ts +1 -0
  38. package/utility/arrays.lua +8 -0
  39. package/utility/callback-array.d.ts +5 -1
  40. package/utility/callback-array.lua +16 -1
  41. package/utility/linked-set.d.ts +1 -0
  42. package/utility/linked-set.lua +19 -1
  43. package/utility/lua-maps.d.ts +11 -2
  44. package/utility/lua-maps.lua +33 -2
  45. package/utility/types.d.ts +3 -0
@@ -29,6 +29,7 @@ local ____vec2 = require("math.vec2")
29
29
  local distance = ____vec2.distance
30
30
  local itemChargesChangeEvent = __TS__New(Event)
31
31
  local itemAddAbility = BlzItemAddAbility
32
+ local itemRemoveAbility = BlzItemRemoveAbility
32
33
  local getItemAbility = BlzGetItemAbility
33
34
  local isItemPowerup = IsItemPowerup
34
35
  local getItemAbilityByIndex = BlzGetItemAbilityByIndex
@@ -49,6 +50,13 @@ local unitRemoveItem = UnitRemoveItem
49
50
  local unitUseItem = UnitUseItem
50
51
  local unitUseItemPoint = UnitUseItemPoint
51
52
  local unitUseItemTarget = UnitUseItemTarget
53
+ local setItemDropOnDeath = SetItemDropOnDeath
54
+ local setItemDroppable = SetItemDroppable
55
+ local setItemPawnable = SetItemPawnable
56
+ local isItemPawnable = IsItemPawnable
57
+ local getItemIntegerField = BlzGetItemIntegerField
58
+ local setItemBooleanField = BlzSetItemBooleanField
59
+ local getItemBooleanField = BlzGetItemBooleanField
52
60
  local tableRemove = table.remove
53
61
  _G.SetItemCharges = function(whichItem, charges)
54
62
  setItemCharges(whichItem, charges)
@@ -57,9 +65,6 @@ _G.SetItemCharges = function(whichItem, charges)
57
65
  ____exports.Item:of(whichItem)
58
66
  )
59
67
  end
60
- local getItemIntegerField = BlzGetItemIntegerField
61
- local setItemBooleanField = BlzSetItemBooleanField
62
- local getItemBooleanField = BlzGetItemBooleanField
63
68
  invoke = Event.invoke
64
69
  local enumRect = Rect:create(0, 0, 0, 0).handle
65
70
  ---
@@ -138,13 +143,7 @@ Item.name = "Item"
138
143
  __TS__ClassExtends(Item, Handle)
139
144
  function Item.prototype.____constructor(self, handle)
140
145
  Handle.prototype.____constructor(self, handle)
141
- local abilities = doAbilityAction(handle, getItemAbilities, self)
142
- self[100] = abilities
143
- local luaIndexByAbilityTypeId = {}
144
- for i = 1, #abilities do
145
- luaIndexByAbilityTypeId[abilities[i].typeId] = i
146
- end
147
- self[101] = luaIndexByAbilityTypeId
146
+ self[100] = doAbilityAction(handle, getItemAbilities, self)
148
147
  end
149
148
  function Item.prototype.onDestroy(self)
150
149
  local owner = self.owner
@@ -196,31 +195,32 @@ function Item.prototype.addAbility(self, abilityTypeId)
196
195
  if nativeAbility ~= nil then
197
196
  local ability = ItemAbility:of(nativeAbility, abilityTypeId, self)
198
197
  local abilities = self[100]
199
- local luaIndex = #abilities + 1
200
- abilities[luaIndex] = ability
201
- self[101][abilityTypeId] = luaIndex
198
+ abilities[#abilities + 1] = ability
202
199
  return ability
203
200
  end
204
201
  return nil
205
202
  end
206
203
  function Item.prototype.removeAbility(self, abilityTypeId)
207
- local luaIndexByAbilityTypeId = self[101]
208
- local luaIndex = luaIndexByAbilityTypeId[abilityTypeId]
209
- if luaIndex ~= nil then
210
- local abilities = self[100]
211
- abilities[luaIndex]:destroy()
212
- tableRemove(abilities, luaIndex)
213
- luaIndexByAbilityTypeId[abilityTypeId] = nil
214
- return true
204
+ local abilities = self[100]
205
+ for i = 1, #abilities do
206
+ if abilities[i].typeId == abilityTypeId then
207
+ local ability = abilities[i]
208
+ tableRemove(abilities, i)
209
+ ability:destroy()
210
+ return true
211
+ end
215
212
  end
216
- return false
213
+ return doAbilityAction(self.handle, itemRemoveAbility, abilityTypeId)
217
214
  end
218
215
  function Item.prototype.hasAbility(self, abilityTypeId)
219
- return self[101][abilityTypeId] ~= nil
216
+ return doAbilityAction(self.handle, getItemAbility, abilityTypeId) ~= nil
220
217
  end
221
218
  function Item.prototype.getAbility(self, abilityTypeId)
222
- local ability = self[101][abilityTypeId] ~= nil and doAbilityAction(self.handle, getItemAbility, abilityTypeId)
223
- return ability and ItemAbility:of(ability, abilityTypeId, self) or nil
219
+ return ItemAbility:of(
220
+ doAbilityAction(self.handle, getItemAbility, abilityTypeId),
221
+ abilityTypeId,
222
+ self
223
+ )
224
224
  end
225
225
  function Item.getInRange(self, x, y, range)
226
226
  targetCollection = {}
@@ -332,65 +332,68 @@ __TS__SetDescriptor(
332
332
  )
333
333
  __TS__SetDescriptor(
334
334
  Item.prototype,
335
- "dropOnDeath",
335
+ "dropsOnDeath",
336
336
  {
337
337
  get = function(self)
338
- return BlzGetItemBooleanField(self.handle, ITEM_BF_DROPPED_WHEN_CARRIER_DIES)
338
+ return getItemBooleanField(self.handle, ITEM_BF_DROPPED_WHEN_CARRIER_DIES)
339
339
  end,
340
- set = function(self, v)
341
- SetItemDropOnDeath(self.handle, v)
340
+ set = function(self, dropsOnDeath)
341
+ setItemDropOnDeath(self.handle, dropsOnDeath)
342
342
  end
343
343
  },
344
344
  true
345
345
  )
346
346
  __TS__SetDescriptor(
347
347
  Item.prototype,
348
- "droppable",
348
+ "canBeDropped",
349
349
  {
350
350
  get = function(self)
351
- return BlzGetItemBooleanField(self.handle, ITEM_BF_CAN_BE_DROPPED)
351
+ return getItemBooleanField(self.handle, ITEM_BF_CAN_BE_DROPPED)
352
352
  end,
353
- set = function(self, v)
354
- SetItemDroppable(self.handle, v)
353
+ set = function(self, canBeDropped)
354
+ setItemDroppable(self.handle, canBeDropped)
355
355
  end
356
356
  },
357
357
  true
358
358
  )
359
359
  __TS__SetDescriptor(
360
360
  Item.prototype,
361
- "pawnable",
361
+ "canBeSold",
362
362
  {
363
363
  get = function(self)
364
- return IsItemPawnable(self.handle)
364
+ return isItemPawnable(self.handle)
365
365
  end,
366
- set = function(self, v)
367
- SetItemPawnable(self.handle, v)
366
+ set = function(self, canBeSold)
367
+ setItemPawnable(self.handle, canBeSold)
368
368
  end
369
369
  },
370
370
  true
371
371
  )
372
372
  __TS__SetDescriptor(
373
373
  Item.prototype,
374
- "perishable",
374
+ "perishes",
375
375
  {
376
376
  get = function(self)
377
377
  return getItemBooleanField(self.handle, ITEM_BF_PERISHABLE)
378
378
  end,
379
- set = function(self, v)
380
- BlzSetItemBooleanField(self.handle, ITEM_BF_PERISHABLE, v)
379
+ set = function(self, perishes)
380
+ local handle = self.handle
381
+ local powerUp = isItemPowerup(handle)
382
+ setItemBooleanField(handle, ITEM_BF_PERISHABLE, perishes)
383
+ setItemBooleanField(handle, ITEM_BF_USE_AUTOMATICALLY_WHEN_ACQUIRED, powerUp)
381
384
  end
382
385
  },
383
386
  true
384
387
  )
385
388
  __TS__SetDescriptor(
386
389
  Item.prototype,
387
- "powerup",
390
+ "isPowerUp",
388
391
  {
389
392
  get = function(self)
390
393
  return isItemPowerup(self.handle)
391
394
  end,
392
- set = function(self, v)
393
- setItemBooleanField(self.handle, ITEM_BF_USE_AUTOMATICALLY_WHEN_ACQUIRED, v)
395
+ set = function(self, isPowerUp)
396
+ setItemBooleanField(self.handle, ITEM_BF_USE_AUTOMATICALLY_WHEN_ACQUIRED, isPowerUp)
394
397
  end
395
398
  },
396
399
  true
@@ -426,16 +429,24 @@ __TS__SetDescriptor(
426
429
  )
427
430
  __TS__SetDescriptor(
428
431
  Item.prototype,
429
- "usable",
432
+ "isActivelyUsed",
430
433
  {
431
434
  get = function(self)
432
435
  return getItemBooleanField(self.handle, ITEM_BF_ACTIVELY_USED)
433
436
  end,
434
- set = function(self, v)
437
+ set = function(self, isActivelyUsed)
435
438
  local handle = self.handle
436
- local powerup = isItemPowerup(handle)
437
- setItemBooleanField(handle, ITEM_BF_ACTIVELY_USED, v)
438
- setItemBooleanField(handle, ITEM_BF_USE_AUTOMATICALLY_WHEN_ACQUIRED, powerup)
439
+ local powerUp = isItemPowerup(handle)
440
+ local perishes = getItemBooleanField(handle, ITEM_BF_PERISHABLE)
441
+ local dropsOnDeath = getItemBooleanField(handle, ITEM_BF_DROPPED_WHEN_CARRIER_DIES)
442
+ local canBeDropped = getItemBooleanField(handle, ITEM_BF_CAN_BE_DROPPED)
443
+ local canBeSold = isItemPawnable(handle)
444
+ setItemBooleanField(handle, ITEM_BF_ACTIVELY_USED, isActivelyUsed)
445
+ setItemPawnable(handle, canBeSold)
446
+ setItemDroppable(handle, canBeDropped)
447
+ setItemDropOnDeath(handle, dropsOnDeath)
448
+ setItemBooleanField(handle, ITEM_BF_PERISHABLE, perishes)
449
+ setItemBooleanField(handle, ITEM_BF_USE_AUTOMATICALLY_WHEN_ACQUIRED, powerUp)
439
450
  end
440
451
  },
441
452
  true
@@ -133,55 +133,55 @@ declare module "../unit" {
133
133
  }
134
134
  declare module "../unit" {
135
135
  namespace Unit {
136
- const abilityImpactEvent: DispatchingEvent<[Unit, Ability]>;
136
+ const abilityChannelingFinishEvent: DispatchingEvent<[Unit, Ability]>;
137
137
  }
138
138
  }
139
139
  declare module "../unit" {
140
140
  namespace Unit {
141
- const abilityWidgetTargetImpactEvent: DispatchingEvent<[Unit, Ability, Widget]>;
141
+ const abilityStopEvent: DispatchingEvent<[Unit, Ability]>;
142
142
  }
143
143
  }
144
144
  declare module "../unit" {
145
145
  namespace Unit {
146
- const abilityUnitTargetImpactEvent: DispatchingEvent<[Unit, Ability, Unit]>;
146
+ const abilityCommandEvent: {
147
+ readonly [abilityTypeId: number]: {
148
+ readonly [orderTypeStringId: string]: Event<[Unit, Ability, string]>;
149
+ };
150
+ };
147
151
  }
148
152
  }
149
153
  declare module "../unit" {
150
154
  namespace Unit {
151
- const abilityItemTargetImpactEvent: DispatchingEvent<[Unit, Ability, Item]>;
155
+ const abilityImpactEvent: DispatchingEvent<[Unit, Ability]>;
152
156
  }
153
157
  }
154
158
  declare module "../unit" {
155
159
  namespace Unit {
156
- const abilityDestructibleTargetImpactEvent: DispatchingEvent<[Unit, Ability, Destructable]>;
160
+ const abilityWidgetTargetImpactEvent: DispatchingEvent<[Unit, Ability, Widget]>;
157
161
  }
158
162
  }
159
163
  declare module "../unit" {
160
164
  namespace Unit {
161
- const abilityPointTargetImpactEvent: DispatchingEvent<[Unit, Ability, number, number]>;
165
+ const abilityUnitTargetImpactEvent: DispatchingEvent<[Unit, Ability, Unit]>;
162
166
  }
163
167
  }
164
168
  declare module "../unit" {
165
169
  namespace Unit {
166
- const abilityNoTargetImpactEvent: DispatchingEvent<[Unit, Ability]>;
170
+ const abilityItemTargetImpactEvent: DispatchingEvent<[Unit, Ability, Item]>;
167
171
  }
168
172
  }
169
173
  declare module "../unit" {
170
174
  namespace Unit {
171
- const abilityChannelingFinishEvent: DispatchingEvent<[Unit, Ability]>;
175
+ const abilityDestructibleTargetImpactEvent: DispatchingEvent<[Unit, Ability, Destructable]>;
172
176
  }
173
177
  }
174
178
  declare module "../unit" {
175
179
  namespace Unit {
176
- const abilityStopEvent: DispatchingEvent<[Unit, Ability]>;
180
+ const abilityPointTargetImpactEvent: DispatchingEvent<[Unit, Ability, number, number]>;
177
181
  }
178
182
  }
179
183
  declare module "../unit" {
180
184
  namespace Unit {
181
- const abilityCommandEvent: {
182
- readonly [abilityTypeId: number]: {
183
- readonly [orderTypeStringId: string]: Event<[Unit, Ability, string]>;
184
- };
185
- };
185
+ const abilityNoTargetImpactEvent: DispatchingEvent<[Unit, Ability]>;
186
186
  }
187
187
  }
@@ -22,7 +22,12 @@ local checkNotNull = ____preconditions.checkNotNull
22
22
  local ____lazy = require("utility.lazy")
23
23
  local lazyRecord = ____lazy.lazyRecord
24
24
  local ____timer = require("core.types.timer")
25
+ local consumeZeroTimerCallback = ____timer.consumeZeroTimerCallback
25
26
  local Timer = ____timer.Timer
27
+ local ____lua_2Dsets = require("utility.lua-sets")
28
+ local luaSetOf = ____lua_2Dsets.luaSetOf
29
+ local ____attributes = require("attributes")
30
+ local attribute = ____attributes.attribute
26
31
  local eventInvoke = Event.invoke
27
32
  local condition = Condition
28
33
  local createTrigger = CreateTrigger
@@ -347,10 +352,65 @@ rawset(
347
352
  extractAbilityTypeId
348
353
  )
349
354
  )
355
+ local internalAbilityChannelingFinishEvent = __TS__New(UnitTriggerEvent, EVENT_PLAYER_UNIT_SPELL_FINISH, collectUnitAbilityEventParameters)
356
+ rawset(
357
+ Unit,
358
+ "abilityChannelingFinishEvent",
359
+ createDispatchingEvent(internalAbilityChannelingFinishEvent, extractAbilityTypeId)
360
+ )
361
+ local internalAbilityStopEvent = __TS__New(UnitTriggerEvent, EVENT_PLAYER_UNIT_SPELL_ENDCAST, collectUnitAbilityEventParameters)
362
+ rawset(
363
+ Unit,
364
+ "abilityStopEvent",
365
+ createDispatchingEvent(internalAbilityStopEvent, extractAbilityTypeId)
366
+ )
367
+ rawset(
368
+ Unit,
369
+ "abilityCommandEvent",
370
+ lazyRecord(function(abilityTypeId)
371
+ return lazyRecord(function(orderTypeStringId)
372
+ return __TS__New(
373
+ InitializingEvent,
374
+ function(event)
375
+ local trigger = createTrigger()
376
+ triggerRegisterCommandEvent(trigger, abilityTypeId, orderTypeStringId)
377
+ triggerAddCondition(
378
+ trigger,
379
+ condition(function()
380
+ local unit = Unit:of(getTriggerUnit())
381
+ if unit ~= nil then
382
+ local ability = unit:getAbility(abilityTypeId)
383
+ if ability ~= nil then
384
+ eventInvoke(event, unit, ability, orderTypeStringId)
385
+ end
386
+ end
387
+ end)
388
+ )
389
+ end
390
+ )
391
+ end)
392
+ end)
393
+ )
350
394
  local internalAbilityImpactEvent = __TS__New(Event)
351
- internalAbilityChannelingStartEvent:addListener(function(...)
352
- Timer:run(eventInvoke, internalAbilityImpactEvent, ...)
353
- end)
395
+ local impactCallbackIdAttribute = attribute()
396
+ local function invokeImpactEvent(unit, ability, ...)
397
+ ability[impactCallbackIdAttribute] = nil
398
+ eventInvoke(internalAbilityImpactEvent, unit, ability, ...)
399
+ end
400
+ internalAbilityChannelingStartEvent:addListener(
401
+ 999999,
402
+ function(unit, ability, ...)
403
+ ability[impactCallbackIdAttribute] = Timer:run(invokeImpactEvent, unit, ability, ...)
404
+ end
405
+ )
406
+ local function consumeImpactCallback(_, ability)
407
+ local impactCallbackId = ability[impactCallbackIdAttribute]
408
+ if impactCallbackId ~= nil then
409
+ consumeZeroTimerCallback(impactCallbackId)
410
+ end
411
+ end
412
+ internalAbilityChannelingFinishEvent:addListener(999999, consumeImpactCallback)
413
+ internalAbilityStopEvent:addListener(999999, consumeImpactCallback)
354
414
  rawset(
355
415
  Unit,
356
416
  "abilityImpactEvent",
@@ -407,47 +467,14 @@ rawset(
407
467
  extractAbilityTypeId
408
468
  )
409
469
  )
410
- rawset(
411
- Unit,
412
- "abilityChannelingFinishEvent",
413
- createDispatchingEvent(
414
- __TS__New(UnitTriggerEvent, EVENT_PLAYER_UNIT_SPELL_FINISH, collectUnitAbilityEventParameters),
415
- extractAbilityTypeId
416
- )
417
- )
418
- rawset(
419
- Unit,
420
- "abilityStopEvent",
421
- createDispatchingEvent(
422
- __TS__New(UnitTriggerEvent, EVENT_PLAYER_UNIT_SPELL_ENDCAST, collectUnitAbilityEventParameters),
423
- extractAbilityTypeId
424
- )
425
- )
426
- rawset(
427
- Unit,
428
- "abilityCommandEvent",
429
- lazyRecord(function(abilityTypeId)
430
- return lazyRecord(function(orderTypeStringId)
431
- return __TS__New(
432
- InitializingEvent,
433
- function(event)
434
- local trigger = createTrigger()
435
- triggerRegisterCommandEvent(trigger, abilityTypeId, orderTypeStringId)
436
- triggerAddCondition(
437
- trigger,
438
- condition(function()
439
- local unit = Unit:of(getTriggerUnit())
440
- if unit ~= nil then
441
- local ability = unit:getAbilityById(abilityTypeId)
442
- if ability ~= nil then
443
- eventInvoke(event, unit, ability, orderTypeStringId)
444
- end
445
- end
446
- end)
447
- )
448
- end
449
- )
450
- end)
451
- end)
470
+ local spellEffectOnlyAbilityTypeIds = luaSetOf(fourCC("AAns"))
471
+ internalAbilityChannelingStartEvent:addListener(
472
+ -999999,
473
+ function(unit, ability)
474
+ if spellEffectOnlyAbilityTypeIds[ability.parentTypeId] ~= nil then
475
+ eventInvoke(internalAbilityChannelingFinishEvent, unit, ability)
476
+ eventInvoke(internalAbilityStopEvent, unit, ability)
477
+ end
478
+ end
452
479
  )
453
480
  return ____exports
@@ -1,46 +1,31 @@
1
1
  local ____lualib = require("lualib_bundle")
2
2
  local __TS__New = ____lualib.__TS__New
3
3
  local ____exports = {}
4
- local ____player = require("core.types.player")
5
- local Player = ____player.Player
6
- local ____math = require("math")
7
- local MAXIMUM_INTEGER = ____math.MAXIMUM_INTEGER
8
- local MINIMUM_INTEGER = ____math.MINIMUM_INTEGER
9
4
  local ____local_2Dclient = require("engine.local-client")
10
5
  local LocalClient = ____local_2Dclient.LocalClient
11
6
  local ____unit = require("engine.internal.unit")
12
7
  local Unit = ____unit.Unit
13
8
  local ____event = require("event")
14
9
  local Event = ____event.Event
10
+ local ____synchronization = require("engine.synchronization")
11
+ local ObjectBus = ____synchronization.ObjectBus
15
12
  local mainSelectedUnitChangeEvent = __TS__New(Event)
16
13
  rawset(Unit, "mainSelectedUnitChangeEvent", mainSelectedUnitChangeEvent)
17
14
  local mainSelectedUnitByPlayer = {}
18
- local syncSlider = BlzCreateFrameByType(
19
- "SLIDER",
20
- "UnitSyncId",
21
- BlzGetOriginFrame(ORIGIN_FRAME_WORLD_FRAME, 0),
22
- "",
23
- 0
15
+ local unitBus = __TS__New(
16
+ ObjectBus,
17
+ function(unit) return unit.syncId end,
18
+ function(syncId) return Unit:getBySyncId(syncId) end
24
19
  )
25
- BlzFrameSetMinMaxValue(syncSlider, MINIMUM_INTEGER, MAXIMUM_INTEGER)
26
20
  LocalClient.mainSelectedUnitChangeEvent:addListener(function()
27
- local ____opt_0 = LocalClient.mainSelectedUnit
28
- local syncId = ____opt_0 and ____opt_0.syncId
29
- BlzFrameSetValue(syncSlider, syncId or 0)
21
+ unitBus:send(LocalClient.mainSelectedUnit)
30
22
  end)
31
- local trg = CreateTrigger()
32
- BlzTriggerRegisterFrameEvent(trg, syncSlider, FRAMEEVENT_SLIDER_VALUE_CHANGED)
33
- TriggerAddAction(
34
- trg,
35
- function()
36
- local player = Player:of(GetTriggerPlayer())
37
- local mainSelectedUnit = Unit:getBySyncId(BlzGetTriggerFrameValue())
38
- if mainSelectedUnit ~= mainSelectedUnitByPlayer[player] then
39
- mainSelectedUnitByPlayer[player] = mainSelectedUnit
40
- Event.invoke(mainSelectedUnitChangeEvent, player)
41
- end
23
+ unitBus.event:addListener(function(player, unit)
24
+ if unit ~= mainSelectedUnitByPlayer[player] then
25
+ mainSelectedUnitByPlayer[player] = unit
26
+ Event.invoke(mainSelectedUnitChangeEvent, player)
42
27
  end
43
- )
28
+ end)
44
29
  rawset(
45
30
  Unit,
46
31
  "getMainSelectedOf",
@@ -9,11 +9,16 @@ local ____timer = require("core.types.timer")
9
9
  local Timer = ____timer.Timer
10
10
  local ____lua_2Dsets = require("utility.lua-sets")
11
11
  local luaSetOf = ____lua_2Dsets.luaSetOf
12
- local ____math = require("math")
13
- local min = ____math.min
12
+ local ____attributes = require("attributes")
13
+ local attribute = ____attributes.attribute
14
+ local ____linked_2Dset = require("utility.linked-set")
15
+ local LinkedSet = ____linked_2Dset.LinkedSet
14
16
  local autoAttackFinishEvent = __TS__New(Event)
15
17
  rawset(Unit, "autoAttackFinishEvent", autoAttackFinishEvent)
16
- local eventTimerByUnit = {}
18
+ local units = __TS__New(LinkedSet)
19
+ local targetAttribute = attribute()
20
+ local impactDelayAttribute = attribute()
21
+ local passedTimeAttribute = attribute()
17
22
  local instantOrderIds = luaSetOf(
18
23
  orderId("avatar"),
19
24
  orderId("berserk"),
@@ -30,29 +35,45 @@ local instantOrderIds = luaSetOf(
30
35
  orderId("unimmolation")
31
36
  )
32
37
  local function reset(source, orderId)
33
- if not (instantOrderIds[orderId] ~= nil) then
34
- local eventTimer = eventTimerByUnit[source]
35
- if eventTimer then
36
- eventTimer:destroy()
37
- eventTimerByUnit[source] = nil
38
- end
38
+ if not (instantOrderIds[orderId] ~= nil) and units:remove(source) then
39
+ source[targetAttribute] = nil
40
+ source[impactDelayAttribute] = nil
41
+ source[passedTimeAttribute] = nil
39
42
  end
40
43
  end
41
44
  Unit.onImmediateOrder:addListener(reset)
42
45
  Unit.onPointOrder:addListener(reset)
43
46
  Unit.onTargetOrder:addListener(reset)
44
- local function timerCallback(source, target)
45
- eventTimerByUnit[source] = nil
46
- Event.invoke(autoAttackFinishEvent, source, target)
47
+ local timerPeriod = 1 / 64
48
+ local function invokeEvent(unit)
49
+ units:remove(unit)
50
+ local target = unit[targetAttribute]
51
+ unit[targetAttribute] = nil
52
+ unit[impactDelayAttribute] = nil
53
+ unit[passedTimeAttribute] = nil
54
+ Event.invoke(autoAttackFinishEvent, unit, target)
55
+ end
56
+ local function checkUnit(unit)
57
+ local passedTime = unit[passedTimeAttribute] + timerPeriod
58
+ if passedTime >= unit[impactDelayAttribute] then
59
+ invokeEvent(unit)
60
+ else
61
+ unit[passedTimeAttribute] = passedTime
62
+ end
47
63
  end
48
- Unit.autoAttackStartEvent:addListener(function(source, target)
49
- local attackPoint = (source:chooseWeapon(target) or source.firstWeapon).impactDelay
50
- local timer = Timer:simple(
51
- attackPoint + min(0.001, attackPoint / 2),
52
- timerCallback,
53
- source,
54
- target
55
- )
56
- eventTimerByUnit[source] = timer
64
+ Timer.onPeriod[timerPeriod]:addListener(function()
65
+ units:forEach(checkUnit)
57
66
  end)
67
+ Unit.autoAttackStartEvent:addListener(
68
+ 999999,
69
+ function(source, target)
70
+ if source[targetAttribute] ~= nil then
71
+ invokeEvent(source)
72
+ end
73
+ source[targetAttribute] = target
74
+ source[impactDelayAttribute] = (source:chooseWeapon(target) or source.firstWeapon).impactDelay
75
+ source[passedTimeAttribute] = -timerPeriod
76
+ units:add(source)
77
+ end
78
+ )
58
79
  return ____exports
@@ -80,6 +80,8 @@ export declare class UnitWeapon {
80
80
  readonly unit: Unit;
81
81
  readonly index: 0 | 1;
82
82
  constructor(unit: Unit, index: 0 | 1);
83
+ get isEnabled(): boolean;
84
+ set isEnabled(isEnabled: boolean);
83
85
  get cooldown(): number;
84
86
  set cooldown(cooldown: number);
85
87
  get damage(): [minimumDamage: number, maximumDamage: number];
@@ -271,8 +273,8 @@ export declare class Unit extends Handle<junit> {
271
273
  setAbilityLevel(abilityId: number, level: number): number;
272
274
  getAbilityLevel(abilityId: number): number;
273
275
  hasAbility(abilityId: number): boolean;
274
- getAbilityById(abilityId: number): UnitAbility | undefined;
275
- removeAbility(abilityId: number): boolean;
276
+ getAbility(abilityId: number): UnitAbility | undefined;
277
+ removeAbility(abilityTypeId: number): boolean;
276
278
  hideAbility(abilityId: number, flag: boolean): void;
277
279
  getAbilityRemainingCooldown(abilityId: number): number;
278
280
  startAbilityCooldown(abilityId: number, cooldown: number): void;
@@ -410,6 +410,19 @@ function UnitWeapon.prototype.____constructor(self, unit, index)
410
410
  self.unit = unit
411
411
  self.index = index
412
412
  end
413
+ __TS__SetDescriptor(
414
+ UnitWeapon.prototype,
415
+ "isEnabled",
416
+ {
417
+ get = function(self)
418
+ return BlzGetUnitWeaponBooleanField(self.unit.handle, UNIT_WEAPON_BF_ATTACKS_ENABLED, self.index)
419
+ end,
420
+ set = function(self, isEnabled)
421
+ BlzSetUnitWeaponBooleanField(self.unit.handle, UNIT_WEAPON_BF_ATTACKS_ENABLED, self.index, isEnabled)
422
+ end
423
+ },
424
+ true
425
+ )
413
426
  __TS__SetDescriptor(
414
427
  UnitWeapon.prototype,
415
428
  "cooldown",
@@ -836,11 +849,13 @@ function Unit.prototype.queueAnimation(self, animation)
836
849
  QueueUnitAnimation(self.handle, animation)
837
850
  end
838
851
  function Unit.prototype.chooseWeapon(self, target)
839
- if target:isAllowedTarget(self, self.firstWeapon.allowedTargetCombatClassifications) then
840
- return self.firstWeapon
852
+ local firstWeapon = self.firstWeapon
853
+ if firstWeapon.isEnabled and target:isAllowedTarget(self, firstWeapon.allowedTargetCombatClassifications) then
854
+ return firstWeapon
841
855
  end
842
- if target:isAllowedTarget(target, self.secondWeapon.allowedTargetCombatClassifications) then
843
- return self.secondWeapon
856
+ local secondWeapon = self.secondWeapon
857
+ if secondWeapon.isEnabled and target:isAllowedTarget(target, secondWeapon.allowedTargetCombatClassifications) then
858
+ return secondWeapon
844
859
  end
845
860
  return nil
846
861
  end
@@ -935,20 +950,21 @@ end
935
950
  function Unit.prototype.hasAbility(self, abilityId)
936
951
  return getUnitAbilityLevel(self.handle, abilityId) > 0
937
952
  end
938
- function Unit.prototype.getAbilityById(self, abilityId)
953
+ function Unit.prototype.getAbility(self, abilityId)
939
954
  local ability = doUnitAbilityAction(self.handle, abilityId, getUnitAbility, abilityId)
940
955
  return UnitAbility:of(ability, abilityId, self)
941
956
  end
942
- function Unit.prototype.removeAbility(self, abilityId)
957
+ function Unit.prototype.removeAbility(self, abilityTypeId)
943
958
  local abilities = self.abilities
944
959
  for i = 1, #abilities do
945
- if abilities[i].typeId == abilityId then
946
- abilities[i]:destroy()
960
+ if abilities[i].typeId == abilityTypeId then
961
+ local ability = abilities[i]
947
962
  tremove(abilities, i)
963
+ ability:destroy()
948
964
  return true
949
965
  end
950
966
  end
951
- return false
967
+ return doUnitAbilityAction(self.handle, abilityTypeId, unitRemoveAbility, abilityTypeId)
952
968
  end
953
969
  function Unit.prototype.hideAbility(self, abilityId, flag)
954
970
  BlzUnitHideAbility(self.handle, abilityId, flag)
@@ -2467,12 +2483,7 @@ Unit.onDamaging = (function()
2467
2483
  preventRetaliation = damagingEventPreventRetaliation
2468
2484
  }
2469
2485
  if data.isAttack and source then
2470
- local weapon = BlzGetUnitWeaponBooleanField(source.handle, UNIT_WEAPON_BF_ATTACKS_ENABLED, 1) and (BlzGetUnitWeaponBooleanField(source.handle, UNIT_WEAPON_BF_ATTACKS_ENABLED, 0) and -1 or 1) or 0
2471
- if weapon == -1 then
2472
- local targetsAllowed = BlzGetUnitWeaponIntegerField(source.handle, UNIT_WEAPON_IF_ATTACK_TARGETS_ALLOWED, 0)
2473
- weapon = 0
2474
- end
2475
- data.weapon = assert(source.weapons[weapon + 1])
2486
+ data.weapon = source:chooseWeapon(target)
2476
2487
  end
2477
2488
  if not data.isAttack or not source or not source._attackHandlers then
2478
2489
  invoke(