warscript 0.0.1-dev.63f1d69 → 0.0.1-dev.69da8a0

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 (59) hide show
  1. package/binaryreader.d.ts +1 -0
  2. package/binaryreader.lua +3 -0
  3. package/core/types/frame.d.ts +5 -0
  4. package/core/types/frame.lua +34 -1
  5. package/core/util.d.ts +1 -1
  6. package/core/util.lua +6 -0
  7. package/engine/behavior.d.ts +2 -2
  8. package/engine/behavior.lua +6 -6
  9. package/engine/behaviour/ability/apply-buff.d.ts +3 -5
  10. package/engine/behaviour/ability/damage.d.ts +33 -11
  11. package/engine/behaviour/ability/damage.lua +89 -31
  12. package/engine/behaviour/ability/heal.d.ts +33 -6
  13. package/engine/behaviour/ability/heal.lua +89 -10
  14. package/engine/behaviour/ability/restore-mana.d.ts +15 -0
  15. package/engine/behaviour/ability/restore-mana.lua +29 -0
  16. package/engine/behaviour/unit.d.ts +5 -0
  17. package/engine/behaviour/unit.lua +20 -0
  18. package/engine/buff.d.ts +60 -18
  19. package/engine/buff.lua +239 -62
  20. package/engine/game-map.d.ts +7 -0
  21. package/engine/game-map.lua +32 -0
  22. package/engine/internal/ability.d.ts +1 -11
  23. package/engine/internal/ability.lua +2 -78
  24. package/engine/internal/item+owner.lua +2 -2
  25. package/engine/internal/unit/bonus.d.ts +4 -2
  26. package/engine/internal/unit/bonus.lua +6 -1
  27. package/engine/internal/unit/item.d.ts +23 -0
  28. package/engine/internal/unit/item.lua +74 -0
  29. package/engine/internal/unit+ability.lua +2 -2
  30. package/engine/internal/unit+transport.lua +4 -10
  31. package/engine/internal/unit-missile-launch.lua +24 -5
  32. package/engine/internal/unit.d.ts +6 -4
  33. package/engine/internal/unit.lua +32 -23
  34. package/engine/local-client.d.ts +7 -2
  35. package/engine/local-client.lua +77 -0
  36. package/engine/object-data/entry/item-type.d.ts +12 -0
  37. package/engine/object-data/entry/item-type.lua +78 -0
  38. package/engine/object-field/ability.d.ts +17 -0
  39. package/engine/object-field/ability.lua +51 -1
  40. package/engine/unit.d.ts +1 -0
  41. package/engine/unit.lua +1 -0
  42. package/index.d.ts +1 -0
  43. package/index.lua +1 -0
  44. package/lualib_bundle.lua +7 -2
  45. package/net/socket.d.ts +7 -1
  46. package/net/socket.lua +45 -4
  47. package/network.d.ts +1 -0
  48. package/network.lua +3 -2
  49. package/objutil/buff.lua +1 -1
  50. package/package.json +2 -2
  51. package/patch-lua.d.ts +0 -0
  52. package/patch-lua.lua +10 -0
  53. package/property.d.ts +55 -0
  54. package/property.lua +374 -0
  55. package/utility/linked-set.d.ts +11 -2
  56. package/utility/linked-set.lua +5 -2
  57. package/utility/types.d.ts +1 -0
  58. package/core/mapbounds.d.ts +0 -8
  59. package/core/mapbounds.lua +0 -12
@@ -21,6 +21,7 @@ local AUTO_ATTACK_DAMAGE_INCREASE_DUMMY_ABILITY_TYPE_ID = ____auto_2Dattack_2Dda
21
21
  local ____movement_2Dspeed_2Dincrease_2Dfactor = require("engine.internal.object-data.movement-speed-increase-factor")
22
22
  local MOVEMENT_SPEED_INCREASE_FACTOR_ABILITY_FIELD = ____movement_2Dspeed_2Dincrease_2Dfactor.MOVEMENT_SPEED_INCREASE_FACTOR_ABILITY_FIELD
23
23
  local MOVEMENT_SPEED_INCREASE_FACTOR_DUMMY_ABILITY_TYPE_ID = ____movement_2Dspeed_2Dincrease_2Dfactor.MOVEMENT_SPEED_INCREASE_FACTOR_DUMMY_ABILITY_TYPE_ID
24
+ local damageFactorByUnit = {}
24
25
  local receivedDamageFactorByUnit = {}
25
26
  ____exports.UnitBonusType = {}
26
27
  local UnitBonusType = ____exports.UnitBonusType
@@ -46,13 +47,14 @@ do
46
47
  reduce = sum,
47
48
  initialValue = 0
48
49
  }
49
- UnitBonusType.DAMAGE = {
50
+ UnitBonusType.AUTO_ATTACK_DAMAGE = {
50
51
  abilityTypeId = AUTO_ATTACK_DAMAGE_INCREASE_DUMMY_ABILITY_TYPE_ID,
51
52
  field = AUTO_ATTACK_DAMAGE_INCREASE_ABILITY_FIELD,
52
53
  integer = false,
53
54
  reduce = sum,
54
55
  initialValue = 0
55
56
  }
57
+ UnitBonusType.DAMAGE_FACTOR = {reduce = product, valueByUnit = damageFactorByUnit, initialValue = 1}
56
58
  UnitBonusType.RECEIVED_DAMAGE_FACTOR = {reduce = product, valueByUnit = receivedDamageFactorByUnit, initialValue = 1}
57
59
  end
58
60
  local bonusesByUnitByBonusType = {}
@@ -180,6 +182,9 @@ end
180
182
  Unit.onDamage:addListener(
181
183
  4,
182
184
  function(source, target, event)
185
+ if source ~= nil and damageFactorByUnit[source] ~= nil then
186
+ event.amount = event.amount * damageFactorByUnit[source]
187
+ end
183
188
  if receivedDamageFactorByUnit[target] ~= nil then
184
189
  event.amount = event.amount * receivedDamageFactorByUnit[target]
185
190
  end
@@ -0,0 +1,23 @@
1
+ /** @noSelfInFile */
2
+ import { Item } from "../item";
3
+ export interface UnitItems extends ReadonlyArray<Item | undefined> {
4
+ readonly length: 0 | 1 | 2 | 3 | 4 | 5 | 6;
5
+ [0]: Item | undefined;
6
+ [1]: Item | undefined;
7
+ [2]: Item | undefined;
8
+ [3]: Item | undefined;
9
+ [4]: Item | undefined;
10
+ [5]: Item | undefined;
11
+ }
12
+ export declare class UnitItems {
13
+ constructor(handle: junit);
14
+ protected __newindex(slot: number, item: Item | undefined): void;
15
+ protected __index(key: string | number): unknown;
16
+ protected __len(): number;
17
+ protected __ipairs(): LuaIterator<LuaMultiReturn<[number, Item | undefined]>, junit>;
18
+ }
19
+ declare module "../unit" {
20
+ interface Unit {
21
+ readonly items: UnitItems;
22
+ }
23
+ }
@@ -0,0 +1,74 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local __TS__Class = ____lualib.__TS__Class
3
+ local __TS__New = ____lualib.__TS__New
4
+ local __TS__ObjectDefineProperty = ____lualib.__TS__ObjectDefineProperty
5
+ local ____exports = {}
6
+ local ____item = require("engine.internal.item")
7
+ local Item = ____item.Item
8
+ local ____unit = require("engine.internal.unit")
9
+ local Unit = ____unit.Unit
10
+ local rawset = _G.rawset
11
+ local ____type = _G.type
12
+ local isItemPowerup = IsItemPowerup
13
+ local setItemBooleanField = BlzSetItemBooleanField
14
+ local unitAddItem = UnitAddItem
15
+ local unitDropItemSlot = UnitDropItemSlot
16
+ local unitInventorySize = UnitInventorySize
17
+ local unitItemInSlot = UnitItemInSlot
18
+ local unitRemoveItemFromSlot = UnitRemoveItemFromSlot
19
+ local handleByUnitItems = setmetatable({}, {__mode = "k"})
20
+ local function unitItemsNext(handle, index)
21
+ local slot = index & 7
22
+ if index >> 3 == slot then
23
+ return nil, nil
24
+ end
25
+ return index + 1, Item:of(unitItemInSlot(handle, slot))
26
+ end
27
+ ____exports.UnitItems = __TS__Class()
28
+ local UnitItems = ____exports.UnitItems
29
+ UnitItems.name = "UnitItems"
30
+ function UnitItems.prototype.____constructor(self, handle)
31
+ handleByUnitItems[self] = handle
32
+ end
33
+ function UnitItems.prototype.__newindex(self, slot, item)
34
+ local handle = handleByUnitItems[self]
35
+ if slot < 1 or slot > unitInventorySize(handle) then
36
+ return
37
+ end
38
+ unitRemoveItemFromSlot(handle, slot - 1)
39
+ if item ~= nil then
40
+ local itemHandle = item.handle
41
+ local isPowerup = isItemPowerup(itemHandle)
42
+ if isPowerup then
43
+ setItemBooleanField(itemHandle, ITEM_BF_USE_AUTOMATICALLY_WHEN_ACQUIRED, false)
44
+ end
45
+ unitAddItem(handle, itemHandle)
46
+ unitDropItemSlot(handle, itemHandle, slot - 1)
47
+ if isPowerup then
48
+ setItemBooleanField(itemHandle, ITEM_BF_USE_AUTOMATICALLY_WHEN_ACQUIRED, true)
49
+ end
50
+ end
51
+ end
52
+ function UnitItems.prototype.__index(self, key)
53
+ if ____type(key) == "number" then
54
+ return Item:of(unitItemInSlot(handleByUnitItems[self], key - 1))
55
+ end
56
+ return rawget(____exports.UnitItems.prototype, key)
57
+ end
58
+ function UnitItems.prototype.__len(self)
59
+ return unitInventorySize(handleByUnitItems[self])
60
+ end
61
+ function UnitItems.prototype.__ipairs(self)
62
+ local handle = handleByUnitItems[self]
63
+ return unitItemsNext, handle, unitInventorySize(handle) << 3
64
+ end
65
+ __TS__ObjectDefineProperty(
66
+ Unit.prototype,
67
+ "items",
68
+ {get = function(self)
69
+ local items = __TS__New(____exports.UnitItems, self.handle)
70
+ rawset(self, "items", items)
71
+ return items
72
+ end}
73
+ )
74
+ return ____exports
@@ -40,7 +40,7 @@ ItemAbility.onCreate:addListener(
40
40
  end
41
41
  end
42
42
  )
43
- Unit.onItemPickup:addListener(
43
+ Unit.itemPickedUpEvent:addListener(
44
44
  0,
45
45
  function(unit, item)
46
46
  for ____, ability in ipairs(item.abilities) do
@@ -48,7 +48,7 @@ Unit.onItemPickup:addListener(
48
48
  end
49
49
  end
50
50
  )
51
- Unit.onItemDrop:addListener(
51
+ Unit.itemDroppedEvent:addListener(
52
52
  4,
53
53
  function(unit, item)
54
54
  for ____, ability in ipairs(item.abilities) do
@@ -6,9 +6,8 @@ local ____unit = require("engine.internal.unit")
6
6
  local Unit = ____unit.Unit
7
7
  local ____event = require("event")
8
8
  local Event = ____event.Event
9
- local ____mapbounds = require("core.mapbounds")
10
- local boundMax = ____mapbounds.boundMax
11
- local boundRegion = ____mapbounds.boundRegion
9
+ local ____game_2Dmap = require("engine.game-map")
10
+ local GameMap = ____game_2Dmap.GameMap
12
11
  local eventInvoke = Event.invoke
13
12
  local tableRemove = table.remove
14
13
  local ____assert = _G.assert
@@ -58,8 +57,8 @@ triggerAddCondition(
58
57
  deboard(unit)
59
58
  end
60
59
  if not unitAlive(handle) then
61
- unit.x = boundMax.x
62
- unit.y = boundMax.y
60
+ unit.x = GameMap.worldBoundsRect.maxX
61
+ unit.y = GameMap.worldBoundsRect.maxY
63
62
  end
64
63
  local transport = Unit:of(getTransportUnit())
65
64
  transportByUnit[unit] = transport
@@ -68,11 +67,6 @@ triggerAddCondition(
68
67
  eventInvoke(onBoardEvent, unit, transport)
69
68
  end)
70
69
  )
71
- boundRegion.onUnitEnter:addListener(function(unit)
72
- if transportByUnit[unit] ~= nil and not isUnitLoaded(unit.handle) then
73
- deboard(unit)
74
- end
75
- end)
76
70
  Unit.deathEvent:addListener(function(unit)
77
71
  if transportByUnit[unit] ~= nil then
78
72
  deboard(unit)
@@ -7,14 +7,33 @@ local ____event = require("event")
7
7
  local Event = ____event.Event
8
8
  local ____timer = require("core.types.timer")
9
9
  local Timer = ____timer.Timer
10
+ local ____lua_2Dsets = require("utility.lua-sets")
11
+ local luaSetOf = ____lua_2Dsets.luaSetOf
10
12
  local autoAttackFinishEvent = __TS__New(Event)
11
13
  rawset(Unit, "autoAttackFinishEvent", autoAttackFinishEvent)
12
14
  local eventTimerByUnit = {}
13
- local function reset(source)
14
- local eventTimer = eventTimerByUnit[source]
15
- if eventTimer then
16
- eventTimer:destroy()
17
- eventTimerByUnit[source] = nil
15
+ local instantOrderIds = luaSetOf(
16
+ orderId("avatar"),
17
+ orderId("berserk"),
18
+ orderId("divineshield"),
19
+ orderId("immolation"),
20
+ orderId("moveslot0"),
21
+ orderId("moveslot1"),
22
+ orderId("moveslot2"),
23
+ orderId("moveslot3"),
24
+ orderId("moveslot4"),
25
+ orderId("moveslot5"),
26
+ orderId("unavatar"),
27
+ orderId("undivineshield"),
28
+ orderId("unimmolation")
29
+ )
30
+ local function reset(source, orderId)
31
+ if not (instantOrderIds[orderId] ~= nil) then
32
+ local eventTimer = eventTimerByUnit[source]
33
+ if eventTimer then
34
+ eventTimer:destroy()
35
+ eventTimerByUnit[source] = nil
36
+ end
18
37
  end
19
38
  end
20
39
  Unit.onImmediateOrder:addListener(reset)
@@ -42,6 +42,7 @@ export interface DamagingEvent {
42
42
  damageType: jdamagetype;
43
43
  weaponType: jweapontype;
44
44
  readonly isAttack: boolean;
45
+ readonly originalAmount: number;
45
46
  }
46
47
  export type DamageEvent = DamagingEvent & {
47
48
  preventDeath<P extends any[]>(this: DamageEvent, callback: (this: void, ...parameters: P) => any, ...parameters: P): void;
@@ -287,7 +288,7 @@ export declare class Unit extends Handle<junit> {
287
288
  static getInRange(x: number, y: number, range: number, predicate?: (unit: Unit) => boolean): Unit[];
288
289
  static getInCollisionRange(x: number, y: number, range: number, predicate?: (unit: Unit) => boolean): Unit[];
289
290
  static getInSector(pos: Vec2, range: number, offsetAngle: number, centralAngle: number): Unit[];
290
- static getSelectionOf(player: Player): Unit[];
291
+ static getSelectionOf(player: Player, target?: Unit[]): Unit[];
291
292
  static readonly deathEvent: UnitTriggerEvent<[Unit]>;
292
293
  static readonly onDecay: UnitTriggerEvent<[]>;
293
294
  static readonly onResurrect: InitializingEvent<[Unit], void>;
@@ -322,9 +323,10 @@ export declare class Unit extends Handle<junit> {
322
323
  static readonly autoAttackStartEvent: UnitTriggerEvent<[Unit]>;
323
324
  static readonly onDamaging: Event<[source: Unit | undefined, target: Unit, event: DamagingEvent]>;
324
325
  static readonly onDamage: InitializingEvent<[source: Unit | undefined, target: Unit, event: DamageEvent], jtrigger>;
325
- static onItemDrop: UnitTriggerEvent<[Item]>;
326
- static onItemPickup: UnitTriggerEvent<[Item]>;
327
- static onItemUse: UnitTriggerEvent<[Item]>;
326
+ static itemDroppedEvent: UnitTriggerEvent<[Item]>;
327
+ static itemPickedUpEvent: UnitTriggerEvent<[Item]>;
328
+ static itemUsedEvent: UnitTriggerEvent<[Item]>;
329
+ static itemStackedEvent: UnitTriggerEvent<[Item]>;
328
330
  static get onCreate(): EventDispatcher<[Unit], [Unit]>;
329
331
  static get destroyEvent(): EventDispatcher<[Unit], [Unit]>;
330
332
  getField(field: junitintegerfield | junitrealfield): number;
@@ -290,7 +290,6 @@ local function dispatch(event, idGetter, argsGetter)
290
290
  return event[id]
291
291
  end
292
292
  if not initialized then
293
- local invoke = Event.invoke
294
293
  event:addListener(function(...)
295
294
  local id = idGetter(...)
296
295
  local dispatched = rawget(self, id)
@@ -328,7 +327,6 @@ local function dispatchAbility(event)
328
327
  return event[id]
329
328
  end
330
329
  if not initialized then
331
- local invoke = Event.invoke
332
330
  event:addListener(function(unit, ability, ...)
333
331
  local dispatched = rawget(self, ability.typeId)
334
332
  if dispatched ~= nil then
@@ -706,7 +704,10 @@ function Unit.prototype.onDestroy(self)
706
704
  if eventsToDestroy ~= nil then
707
705
  forEach(eventsToDestroy, "destroy")
708
706
  end
709
- removeUnit(handle)
707
+ if getUnitAbilityLevel(handle, leaveDetectAbilityId) > 0 then
708
+ unitRemoveAbility(handle, leaveDetectAbilityId)
709
+ removeUnit(handle)
710
+ end
710
711
  return Handle.prototype.onDestroy(self)
711
712
  end
712
713
  function Unit.prototype.addAttackHandler(self, condition, action)
@@ -864,7 +865,7 @@ function Unit.prototype.dropItemSlot(self, item, slot)
864
865
  return UnitDropItemSlot(self.handle, item.handle, slot)
865
866
  end
866
867
  function Unit.prototype.itemInSlot(self, slot)
867
- return Item:of(UnitItemInSlot(self.handle, slot))
868
+ return Item:of(unitItemInSlot(self.handle, slot))
868
869
  end
869
870
  function Unit.prototype.addAbility(self, abilityId)
870
871
  if unitAddAbility(self.handle, abilityId) then
@@ -1107,8 +1108,11 @@ function Unit.getInSector(self, pos, range, offsetAngle, centralAngle)
1107
1108
  )
1108
1109
  return targetCollection
1109
1110
  end
1110
- function Unit.getSelectionOf(self, player)
1111
- targetCollection = {}
1111
+ function Unit.getSelectionOf(self, player, target)
1112
+ if target == nil then
1113
+ target = {}
1114
+ end
1115
+ targetCollection = target
1112
1116
  targetCollectionNextIndex = 1
1113
1117
  GroupEnumUnitsSelected(dummyGroup, player.handle, collectIntoTarget)
1114
1118
  return targetCollection
@@ -2061,7 +2065,6 @@ Unit.onDecay = __TS__New(
2061
2065
  Unit.onResurrect = __TS__New(
2062
2066
  InitializingEvent,
2063
2067
  function(event)
2064
- local invoke = Event.invoke
2065
2068
  local dead = setmetatable({}, {__mode = "k"})
2066
2069
  ____exports.Unit.deathEvent:addListener(function(unit)
2067
2070
  dead[unit] = true
@@ -2077,10 +2080,15 @@ Unit.onResurrect = __TS__New(
2077
2080
  Unit.morphEvent = __TS__New(
2078
2081
  InitializingEvent,
2079
2082
  function(event)
2083
+ local function ifNotLeft(unit)
2084
+ local handle = unit.handle
2085
+ if getUnitAbilityLevel(handle, leaveDetectAbilityId) ~= 0 and unitAddAbility(handle, morphDetectAbilityId) then
2086
+ invoke(event, unit)
2087
+ end
2088
+ end
2080
2089
  ____exports.Unit.onImmediateOrder[orderId("undefend")]:addListener(function(unit)
2081
2090
  if getUnitAbilityLevel(unit.handle, morphDetectAbilityId) == 0 then
2082
- assert(unitAddAbility(unit.handle, morphDetectAbilityId))
2083
- Timer:run(Event.invoke, event, unit)
2091
+ Timer:run(ifNotLeft, unit)
2084
2092
  end
2085
2093
  end)
2086
2094
  end
@@ -2118,7 +2126,6 @@ Unit.onSpellEffect = dispatchId(__TS__New(
2118
2126
  Unit.onTargetCast = dispatchId(__TS__New(
2119
2127
  InitializingEvent,
2120
2128
  function(event)
2121
- local invoke = Event.invoke
2122
2129
  local function listener(unit, id)
2123
2130
  local ____GetSpellTargetUnit_result_8
2124
2131
  if GetSpellTargetUnit() then
@@ -2335,7 +2342,6 @@ Unit.autoAttackStartEvent = __TS__New(
2335
2342
  )
2336
2343
  Unit.onDamaging = (function()
2337
2344
  local event = __TS__New(Event)
2338
- local invoke = Event.invoke
2339
2345
  local trigger = CreateTrigger()
2340
2346
  TriggerRegisterAnyUnitEventBJ(trigger, EVENT_PLAYER_UNIT_DAMAGING)
2341
2347
  TriggerAddCondition(
@@ -2434,7 +2440,6 @@ end)()
2434
2440
  Unit.onDamage = __TS__New(
2435
2441
  InitializingEvent,
2436
2442
  function(event)
2437
- local invoke = Event.invoke
2438
2443
  local trigger = CreateTrigger()
2439
2444
  TriggerRegisterAnyUnitEventBJ(trigger, EVENT_PLAYER_UNIT_DAMAGED)
2440
2445
  TriggerAddCondition(
@@ -2450,6 +2455,7 @@ Unit.onDamage = __TS__New(
2450
2455
  damageType = BlzGetEventDamageType(),
2451
2456
  weaponType = BlzGetEventWeaponType(),
2452
2457
  isAttack = BlzGetEventIsAttack(),
2458
+ originalAmount = GetEventDamage(),
2453
2459
  preventDeath = damageEventPreventDeath
2454
2460
  }
2455
2461
  local evData = setmetatable(
@@ -2500,7 +2506,7 @@ Unit.onDamage = __TS__New(
2500
2506
  DestroyTrigger(trigger)
2501
2507
  end
2502
2508
  )
2503
- Unit.onItemDrop = __TS__New(
2509
+ Unit.itemDroppedEvent = __TS__New(
2504
2510
  ____exports.UnitTriggerEvent,
2505
2511
  EVENT_PLAYER_UNIT_DROP_ITEM,
2506
2512
  function()
@@ -2511,7 +2517,7 @@ Unit.onItemDrop = __TS__New(
2511
2517
  return IgnoreEvent
2512
2518
  end
2513
2519
  )
2514
- Unit.onItemPickup = __TS__New(
2520
+ Unit.itemPickedUpEvent = __TS__New(
2515
2521
  ____exports.UnitTriggerEvent,
2516
2522
  EVENT_PLAYER_UNIT_PICKUP_ITEM,
2517
2523
  function()
@@ -2522,10 +2528,15 @@ Unit.onItemPickup = __TS__New(
2522
2528
  return IgnoreEvent
2523
2529
  end
2524
2530
  )
2525
- Unit.onItemUse = __TS__New(
2531
+ Unit.itemUsedEvent = __TS__New(
2526
2532
  ____exports.UnitTriggerEvent,
2527
2533
  EVENT_PLAYER_UNIT_USE_ITEM,
2528
- function() return ____exports.Unit:of(GetTriggerUnit()), Item:of(GetManipulatedItem()) end
2534
+ function() return ____exports.Unit:of(getTriggerUnit()), Item:of(getManipulatedItem()) end
2535
+ )
2536
+ Unit.itemStackedEvent = __TS__New(
2537
+ ____exports.UnitTriggerEvent,
2538
+ EVENT_PLAYER_UNIT_STACK_ITEM,
2539
+ function() return ____exports.Unit:of(getTriggerUnit()), Item:of(getManipulatedItem()) end
2529
2540
  )
2530
2541
  __TS__ObjectDefineProperty(
2531
2542
  Unit,
@@ -2575,15 +2586,13 @@ __TS__ObjectDefineProperty(
2575
2586
  orderId("unimmolation")
2576
2587
  }) do
2577
2588
  ____exports.Unit.onImmediateOrder[leaveOrderId]:addListener(function(unit)
2578
- if unit.state == 1 then
2579
- local handle = unit.handle
2580
- for i = 1, #leaveAbilityIds do
2581
- if getUnitAbilityLevel(handle, leaveAbilityIds[i]) ~= 0 then
2582
- return
2583
- end
2589
+ local handle = unit.handle
2590
+ for i = 1, #leaveAbilityIds do
2591
+ if getUnitAbilityLevel(handle, leaveAbilityIds[i]) ~= 0 then
2592
+ return
2584
2593
  end
2585
- unit:destroy()
2586
2594
  end
2595
+ unit:destroy()
2587
2596
  end)
2588
2597
  end
2589
2598
  end)(Unit)
@@ -1,7 +1,7 @@
1
1
  /** @noSelfInFile */
2
2
  import { Unit } from "../core/types/unit";
3
3
  import { Async } from "../core/types/async";
4
- import { TriggerEvent } from "../event";
4
+ import { Event, TriggerEvent } from "../event";
5
5
  import { GraphicsMode } from "./index";
6
6
  export declare class LocalClient {
7
7
  private constructor();
@@ -11,6 +11,11 @@ export declare class LocalClient {
11
11
  static get isHD(): boolean;
12
12
  static get graphicsMode(): GraphicsMode;
13
13
  static get isActive(): boolean;
14
- static get mouseFocusUnit(): Async<Unit>;
14
+ static get mouseFocusUnit(): Async<Unit> | undefined;
15
+ static get mainSelectedUnit(): Async<Unit> | undefined;
16
+ static get mainSelectedUnitChangeEvent(): Event<[
17
+ previousMainSelectedUnit: Unit | undefined,
18
+ newMainSelectedUnit: Unit | undefined
19
+ ]>;
15
20
  static readonly onDisconnect: TriggerEvent<[]>;
16
21
  }
@@ -6,13 +6,25 @@ local ____exports = {}
6
6
  local ____unit = require("core.types.unit")
7
7
  local Unit = ____unit.Unit
8
8
  local ____event = require("event")
9
+ local Event = ____event.Event
9
10
  local TriggerEvent = ____event.TriggerEvent
11
+ local ____frame = require("core.types.frame")
12
+ local Frame = ____frame.Frame
13
+ local ____player = require("core.types.player")
14
+ local Player = ____player.Player
15
+ local ____timer = require("core.types.timer")
16
+ local Timer = ____timer.Timer
10
17
  local loadTOCFile = BlzLoadTOCFile
11
18
  local getLocalClientWidth = BlzGetLocalClientWidth
12
19
  local getLocalClientHeight = BlzGetLocalClientHeight
13
20
  local isLocalClientActive = BlzIsLocalClientActive
21
+ local isHeroUnitId = IsHeroUnitId
22
+ local getHandleId = GetHandleId
14
23
  local getMouseFocusUnit = BlzGetMouseFocusUnit
24
+ local getUnitRealField = BlzGetUnitRealField
25
+ local getUnitTypeId = GetUnitTypeId
15
26
  local getLocale = BlzGetLocale
27
+ local tableSort = table.sort
16
28
  local tocPath = "_warscript\\IsHD.toc"
17
29
  compiletime(function()
18
30
  if currentMap then
@@ -21,6 +33,28 @@ compiletime(function()
21
33
  currentMap:addFileString("_HD.w3mod\\" .. tocPath, fdfPath .. "\r\n")
22
34
  end
23
35
  end)
36
+ local selectionContainerFrame
37
+ local selectionContainerFrameChildren
38
+ Timer:run(function()
39
+ selectionContainerFrame = Frame:byName("SimpleInfoPanelUnitDetail").parent:getChild(5):getChild(0)
40
+ selectionContainerFrameChildren = selectionContainerFrame.children
41
+ end)
42
+ local localSelectedUnits = {}
43
+ local indexByLocalSelectedUnit = {}
44
+ local function compareUnitsSelectionPriority(a, b)
45
+ local aHandle = a.handle
46
+ local bHandle = b.handle
47
+ local priorityDelta = getUnitRealField(bHandle, UNIT_RF_PRIORITY) - getUnitRealField(aHandle, UNIT_RF_PRIORITY)
48
+ if priorityDelta ~= 0 then
49
+ return priorityDelta < 0
50
+ end
51
+ local aTypeId = getUnitTypeId(aHandle)
52
+ local bTypeId = getUnitTypeId(bHandle)
53
+ local orderDelta = (isHeroUnitId(aTypeId) and getHandleId(aHandle) or aTypeId) - (isHeroUnitId(bTypeId) and getHandleId(bHandle) or bTypeId)
54
+ return (orderDelta ~= 0 and orderDelta or indexByLocalSelectedUnit[a] - indexByLocalSelectedUnit[b]) < 0
55
+ end
56
+ local mainSelectedUnitChangeEvent
57
+ local previousMainSelectedUnit
24
58
  ____exports.LocalClient = __TS__Class()
25
59
  local LocalClient = ____exports.LocalClient
26
60
  LocalClient.name = "LocalClient"
@@ -69,6 +103,49 @@ __TS__ObjectDefineProperty(
69
103
  return Unit:of(getMouseFocusUnit())
70
104
  end}
71
105
  )
106
+ __TS__ObjectDefineProperty(
107
+ LocalClient,
108
+ "mainSelectedUnit",
109
+ {get = function(self)
110
+ Unit:getSelectionOf(Player["local"], localSelectedUnits)
111
+ for i = 1, #localSelectedUnits do
112
+ indexByLocalSelectedUnit[localSelectedUnits[i]] = i
113
+ end
114
+ tableSort(localSelectedUnits, compareUnitsSelectionPriority)
115
+ local mainSelectedUnitIndex
116
+ if selectionContainerFrame and selectionContainerFrameChildren and selectionContainerFrame.visible then
117
+ for i = 0, #selectionContainerFrameChildren - 1 do
118
+ if selectionContainerFrameChildren[i + 1].visible then
119
+ mainSelectedUnitIndex = i
120
+ break
121
+ end
122
+ end
123
+ end
124
+ local mainSelectedUnit = localSelectedUnits[(mainSelectedUnitIndex or 0) + 1]
125
+ for i = 1, #localSelectedUnits do
126
+ indexByLocalSelectedUnit[localSelectedUnits[i]] = nil
127
+ localSelectedUnits[i] = nil
128
+ end
129
+ if mainSelectedUnitChangeEvent ~= nil and mainSelectedUnit ~= previousMainSelectedUnit then
130
+ Event.invoke(mainSelectedUnitChangeEvent, previousMainSelectedUnit, mainSelectedUnit)
131
+ previousMainSelectedUnit = mainSelectedUnit
132
+ end
133
+ return mainSelectedUnit
134
+ end}
135
+ )
136
+ __TS__ObjectDefineProperty(
137
+ LocalClient,
138
+ "mainSelectedUnitChangeEvent",
139
+ {get = function(self)
140
+ if mainSelectedUnitChangeEvent == nil then
141
+ mainSelectedUnitChangeEvent = __TS__New(Event)
142
+ Timer.onPeriod[1 / 64]:addListener(function()
143
+ local _ = ____exports.LocalClient.mainSelectedUnit
144
+ end)
145
+ end
146
+ return mainSelectedUnitChangeEvent
147
+ end}
148
+ )
72
149
  LocalClient.onDisconnect = __TS__New(
73
150
  TriggerEvent,
74
151
  function(trigger)
@@ -45,4 +45,16 @@ export declare class ItemType extends ObjectDataEntry<ItemTypeId> {
45
45
  set tooltipText(tooltipText: string);
46
46
  get tooltipExtendedText(): string;
47
47
  set tooltipExtendedText(tooltipText: string);
48
+ get goldCost(): number;
49
+ set goldCost(goldCost: number);
50
+ get lumberCost(): number;
51
+ set lumberCost(lumberCost: number);
52
+ get activelyUsed(): boolean;
53
+ set activelyUsed(activelyUsed: boolean);
54
+ get perishable(): boolean;
55
+ set perishable(perishable: boolean);
56
+ get initialStackSize(): number;
57
+ set initialStackSize(initialStackSize: number);
58
+ get maximumStackSize(): number;
59
+ set maximumStackSize(maximumStackSize: number);
48
60
  }
@@ -256,4 +256,82 @@ __TS__SetDescriptor(
256
256
  },
257
257
  true
258
258
  )
259
+ __TS__SetDescriptor(
260
+ ItemType.prototype,
261
+ "goldCost",
262
+ {
263
+ get = function(self)
264
+ return self:getNumberField("igol")
265
+ end,
266
+ set = function(self, goldCost)
267
+ self:setNumberField("igol", goldCost)
268
+ end
269
+ },
270
+ true
271
+ )
272
+ __TS__SetDescriptor(
273
+ ItemType.prototype,
274
+ "lumberCost",
275
+ {
276
+ get = function(self)
277
+ return self:getNumberField("ilum")
278
+ end,
279
+ set = function(self, lumberCost)
280
+ self:setNumberField("ilum", lumberCost)
281
+ end
282
+ },
283
+ true
284
+ )
285
+ __TS__SetDescriptor(
286
+ ItemType.prototype,
287
+ "activelyUsed",
288
+ {
289
+ get = function(self)
290
+ return self:getBooleanField("iusa")
291
+ end,
292
+ set = function(self, activelyUsed)
293
+ self:setBooleanField("iusa", activelyUsed)
294
+ end
295
+ },
296
+ true
297
+ )
298
+ __TS__SetDescriptor(
299
+ ItemType.prototype,
300
+ "perishable",
301
+ {
302
+ get = function(self)
303
+ return self:getBooleanField("iper")
304
+ end,
305
+ set = function(self, perishable)
306
+ self:setBooleanField("iper", perishable)
307
+ end
308
+ },
309
+ true
310
+ )
311
+ __TS__SetDescriptor(
312
+ ItemType.prototype,
313
+ "initialStackSize",
314
+ {
315
+ get = function(self)
316
+ return self:getNumberField("iuse")
317
+ end,
318
+ set = function(self, initialStackSize)
319
+ self:setNumberField("iuse", initialStackSize)
320
+ end
321
+ },
322
+ true
323
+ )
324
+ __TS__SetDescriptor(
325
+ ItemType.prototype,
326
+ "maximumStackSize",
327
+ {
328
+ get = function(self)
329
+ return self:getNumberField("ista")
330
+ end,
331
+ set = function(self, maximumStackSize)
332
+ self:setNumberField("ista", maximumStackSize)
333
+ end
334
+ },
335
+ true
336
+ )
259
337
  return ____exports
@@ -6,6 +6,9 @@ import { ObjectDataEntryId } from "../object-data/entry";
6
6
  import { LightningTypeId } from "../object-data/entry/lightning-type";
7
7
  import { CombatClassifications } from "../object-data/auxiliary/combat-classification";
8
8
  import { UnitTypeId } from "../object-data/entry/unit-type";
9
+ import { BuffResistanceType } from "../object-data/auxiliary/buff-resistance-type";
10
+ import { BuffPolarity } from "../object-data/auxiliary/buff-polarity";
11
+ import { ReadonlyNonEmptyLinkedSet } from "../../utility/linked-set";
9
12
  export declare abstract class AbilityField<ValueType extends number | string | boolean = number | string | boolean, NativeFieldType extends jabilityfield = jabilityfield> extends ObjectField<AbilityType, Ability, ValueType, NativeFieldType> {
10
13
  protected get instanceClass(): typeof Ability;
11
14
  protected getObjectDataEntryId(instance: Ability): AbilityTypeId;
@@ -107,6 +110,20 @@ export declare class AbilityAbilityTypeIdLevelField extends AbilityObjectDataEnt
107
110
  }
108
111
  export declare class AbilityUnitTypeIdLevelField extends AbilityObjectDataEntryIdLevelField<UnitTypeId> {
109
112
  }
113
+ export declare abstract class AbilityEnumLevelField<T extends number> extends AbilityLevelField<T, T, jabilityintegerlevelfield> {
114
+ protected abstract values: ReadonlyNonEmptyLinkedSet<T>;
115
+ protected get defaultValue(): T;
116
+ protected getNativeFieldById(id: number): jabilityintegerlevelfield;
117
+ protected getNativeFieldValue(instance: Ability, level: number): T;
118
+ protected setNativeFieldValue(instance: Ability, level: number, value: T): boolean;
119
+ static get valueChangeEvent(): ObjectLevelFieldValueChangeEvent<AbilityBooleanLevelField>;
120
+ }
121
+ export declare class AbilityBuffPolarityLevelField extends AbilityEnumLevelField<BuffPolarity> {
122
+ protected values: ReadonlyNonEmptyLinkedSet<BuffPolarity>;
123
+ }
124
+ export declare class AbilityBuffResistanceTypeLevelField extends AbilityEnumLevelField<BuffResistanceType> {
125
+ protected values: ReadonlyNonEmptyLinkedSet<BuffResistanceType>;
126
+ }
110
127
  export declare class AbilityCombatClassificationsLevelField extends AbilityLevelField<CombatClassifications, CombatClassifications, jabilityintegerlevelfield> {
111
128
  protected get defaultValue(): CombatClassifications;
112
129
  protected getNativeFieldById(id: number): jabilityintegerlevelfield;