warscript 0.0.1-dev.47f470c → 0.0.1-dev.524f1b8

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 (51) hide show
  1. package/core/types/effect.d.ts +1 -3
  2. package/core/types/effect.lua +26 -29
  3. package/core/types/sound.d.ts +17 -25
  4. package/core/types/sound.lua +91 -46
  5. package/core/types/timer.d.ts +6 -7
  6. package/core/types/timer.lua +18 -21
  7. package/core/util.lua +6 -1
  8. package/engine/behaviour/ability/apply-unit-behavior.lua +1 -0
  9. package/engine/behaviour/ability/damage.d.ts +3 -0
  10. package/engine/behaviour/ability/damage.lua +2 -2
  11. package/engine/behaviour/ability.d.ts +5 -1
  12. package/engine/behaviour/ability.lua +18 -4
  13. package/engine/behaviour/unit.d.ts +2 -0
  14. package/engine/buff.d.ts +13 -8
  15. package/engine/buff.lua +81 -50
  16. package/engine/internal/mechanics/ability-duration.lua +1 -1
  17. package/engine/internal/unit.d.ts +6 -1
  18. package/engine/internal/unit.lua +8 -2
  19. package/engine/object-data/auxiliary/attachment-preset.d.ts +7 -2
  20. package/engine/object-data/auxiliary/attachment-preset.lua +4 -3
  21. package/engine/object-data/auxiliary/sound-eax.d.ts +10 -0
  22. package/engine/object-data/auxiliary/sound-eax.lua +2 -0
  23. package/engine/object-data/entry/ability-type/berserk.d.ts +2 -0
  24. package/engine/object-data/entry/ability-type/berserk.lua +13 -0
  25. package/engine/object-data/entry/ability-type/blank-configurable.lua +0 -9
  26. package/engine/object-data/entry/ability-type/carrion-swarm.d.ts +14 -0
  27. package/engine/object-data/entry/ability-type/carrion-swarm.lua +65 -0
  28. package/engine/object-data/entry/ability-type/curse.lua +2 -2
  29. package/engine/object-data/entry/ability-type/ensnare.d.ts +12 -0
  30. package/engine/object-data/entry/ability-type/ensnare.lua +52 -0
  31. package/engine/object-data/entry/ability-type/phase-shift.d.ts +10 -0
  32. package/engine/object-data/entry/ability-type/phase-shift.lua +39 -0
  33. package/engine/object-data/entry/ability-type/raise-dead.d.ts +17 -0
  34. package/engine/object-data/entry/ability-type/raise-dead.lua +78 -0
  35. package/engine/object-data/entry/ability-type/shock-wave.d.ts +4 -0
  36. package/engine/object-data/entry/ability-type/shock-wave.lua +26 -0
  37. package/engine/object-data/entry/ability-type/slow-poison.d.ts +10 -0
  38. package/engine/object-data/entry/ability-type/slow-poison.lua +58 -0
  39. package/engine/object-data/entry/ability-type/web.d.ts +12 -0
  40. package/engine/object-data/entry/ability-type/web.lua +52 -0
  41. package/engine/object-data/entry/ability-type.d.ts +18 -16
  42. package/engine/object-data/entry/ability-type.lua +73 -13
  43. package/engine/object-data/entry/buff-type/applicable.lua +9 -4
  44. package/engine/object-data/entry/sound-preset.d.ts +18 -2
  45. package/engine/object-data/entry/sound-preset.lua +105 -15
  46. package/engine/object-data/entry/unit-type.lua +3 -3
  47. package/engine/object-data/entry.d.ts +2 -2
  48. package/engine/object-data/entry.lua +14 -7
  49. package/objutil/unit.lua +2 -2
  50. package/package.json +2 -2
  51. package/utility/reflection.lua +11 -7
@@ -74,7 +74,7 @@ local applicatorAbilityTypeIdByApplicatorTypeByApplicableBuffTypeId, applicatorU
74
74
  abilityType.buttonPositionY = -11
75
75
  abilityType.casterAttachmentPresets = {}
76
76
  abilityType.targetEffectPresets = {}
77
- abilityType.soundPresetName = ""
77
+ abilityType.casterEffectSoundPresetId = nil
78
78
  abilityType.learnLevelMinimum = 6
79
79
  abilityType.race = "other"
80
80
  abilityType.shouldCheckTechTreeDependencies = false
@@ -104,7 +104,7 @@ local applicatorAbilityTypeIdByApplicatorTypeByApplicableBuffTypeId, applicatorU
104
104
  local applicatorAbilityType = prepareAbilityType(CurseAbilityType, applicableBuffType)
105
105
  applicatorAbilityType.missProbability = 0
106
106
  applicatorAbilityType.buffTypeIds = {applicableBuffType.id}
107
- applicatorAbilityTypeIdByApplicatorType[852189] = applicatorAbilityType.id
107
+ applicatorAbilityTypeIdByApplicatorType[852190] = applicatorAbilityType.id
108
108
  end
109
109
  if applicableBuffType.polarity == 1 or applicableBuffType.polarity == nil then
110
110
  local applicatorAbilityType = prepareAbilityType(BloodLustAbilityType, applicableBuffType)
@@ -121,6 +121,10 @@ local applicatorAbilityTypeIdByApplicatorTypeByApplicableBuffTypeId, applicatorU
121
121
  applicatorAbilityType.damagePerSecond = 0
122
122
  applicatorAbilityType.movementSpeedDecreaseFactor = 0
123
123
  applicatorAbilityType.attackSpeedDecreaseFactor = 0
124
+ applicatorAbilityType.isDamageStacking = false
125
+ applicatorAbilityType.isMovementSpeedFactorStacking = false
126
+ applicatorAbilityType.isAttackSpeedFactorStacking = false
127
+ applicatorAbilityType.isAbleToKill = false
124
128
  applicatorAbilityType.buffTypeIds = {applicableBuffType.id, applicableBuffType.id}
125
129
  applicatorAbilityTypeIdByApplicatorType[852173] = applicatorAbilityType.id
126
130
  end
@@ -128,6 +132,7 @@ local applicatorAbilityTypeIdByApplicatorTypeByApplicableBuffTypeId, applicatorU
128
132
  local applicatorAbilityType = prepareAbilityType(BerserkAbilityType, applicableBuffType)
129
133
  applicatorAbilityType.attackSpeedIncreaseFactor = 0
130
134
  applicatorAbilityType.movementSpeedIncreaseFactor = 0
135
+ applicatorAbilityType.receivedDamageIncreaseFactor = 0
131
136
  applicatorAbilityType.buffTypeIds = {applicableBuffType.id}
132
137
  if applicatorAbilityType.levelCount > 1 then
133
138
  multilevelPhysicalPositiveApplicatorAbilityTypes[#multilevelPhysicalPositiveApplicatorAbilityTypes + 1] = applicatorAbilityType
@@ -222,7 +227,7 @@ Unit.abilityCastingStartEvent[SEARING_ARROWS_DUMMY_ABILITY_TYPE_ID]:addListener(
222
227
  ---
223
228
  -- @internal For use by internal systems only.
224
229
  ____exports.internalApplyBuff = function(unit, applicableBuffTypeId, polarity, resistanceType, level, duration, spellStealPriority, learnLevelMinimum, missProbability)
225
- local applicatorType = polarity == 1 and (resistanceType == 1 and 852101 or 852100) or (polarity == 2 and (resistanceType == 1 and 852189 or 852173) or 0)
230
+ local applicatorType = polarity == 1 and (resistanceType == 1 and 852101 or 852100) or (polarity == 2 and (resistanceType == 1 and 852190 or 852173) or 0)
226
231
  local ____opt_1 = applicatorAbilityTypeIdByApplicatorTypeByApplicableBuffTypeId[applicableBuffTypeId]
227
232
  local applicatorAbilityTypeId = ____opt_1 and ____opt_1[applicatorType]
228
233
  if applicatorAbilityTypeId == nil then
@@ -274,7 +279,7 @@ ____exports.internalApplyBuff = function(unit, applicableBuffTypeId, polarity, r
274
279
  ability:setField(ABILITY_RLF_DURATION_HERO, level, actualDuration)
275
280
  ability:setField(ABILITY_IF_PRIORITY, spellStealPriority or 0)
276
281
  ability:setField(ABILITY_IF_REQUIRED_LEVEL, learnLevelMinimum or 6)
277
- if missProbability ~= nil and applicatorType == 852189 then
282
+ if missProbability ~= nil and applicatorType == 852190 then
278
283
  ability:setField(ABILITY_RLF_CHANCE_TO_MISS_CRS, missProbability)
279
284
  end
280
285
  end,
@@ -1,5 +1,6 @@
1
1
  /** @noSelfInFile */
2
- import { ObjectDataEntry, ObjectDataEntryConstructor, ObjectDataEntryId } from "../entry";
2
+ import { ObjectDataEntry, ObjectDataEntryId } from "../entry";
3
+ import { SoundEax } from "../auxiliary/sound-eax";
3
4
  export type SoundPresetId = ObjectDataEntryId & string & {
4
5
  readonly __soundPresetId: unique symbol;
5
6
  };
@@ -7,11 +8,26 @@ export type StandardSoundPresetId = SoundPresetId & {
7
8
  readonly __standardSoundPresetId: unique symbol;
8
9
  };
9
10
  export declare class SoundPreset extends ObjectDataEntry<SoundPresetId> {
10
- static readonly [id: StandardSoundPresetId]: ObjectDataEntryConstructor<SoundPreset>;
11
11
  static readonly BASE_ID: SoundPresetId;
12
12
  private static nextId;
13
13
  protected static generateId(): string;
14
14
  protected static getObjectData(map: WarMap): WarObjects;
15
15
  get filePaths(): string[];
16
16
  set filePaths(filePaths: string[]);
17
+ get volume(): number;
18
+ set volume(volume: number);
19
+ get pitch(): number;
20
+ set pitch(pitch: number);
21
+ get priority(): number;
22
+ set priority(priority: number);
23
+ get channel(): number;
24
+ set channel(channel: number);
25
+ get minimumDistance(): number;
26
+ set minimumDistance(minimumDistance: number);
27
+ get maximumDistance(): number;
28
+ set maximumDistance(maximumDistance: number);
29
+ get distanceCutoff(): number;
30
+ set distanceCutoff(distanceCutoff: number);
31
+ get eax(): SoundEax;
32
+ set eax(eax: SoundEax);
17
33
  }
@@ -5,8 +5,6 @@ local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor
5
5
  local ____exports = {}
6
6
  local ____entry = require("engine.object-data.entry")
7
7
  local ObjectDataEntry = ____entry.ObjectDataEntry
8
- local ____reflection = require("utility.reflection")
9
- local implementReadonlyNumberIndexSupplier = ____reflection.implementReadonlyNumberIndexSupplier
10
8
  ____exports.SoundPreset = __TS__Class()
11
9
  local SoundPreset = ____exports.SoundPreset
12
10
  SoundPreset.name = "SoundPreset"
@@ -19,19 +17,7 @@ function SoundPreset.generateId(self)
19
17
  end
20
18
  function SoundPreset.getObjectData(self, map)
21
19
  return map.objects.sound
22
- end;
23
- (function(self)
24
- implementReadonlyNumberIndexSupplier(
25
- ____exports.SoundPreset,
26
- function(id)
27
- local ____class_3 = __TS__Class()
28
- ____class_3.name = ____class_3.name
29
- __TS__ClassExtends(____class_3, ____exports.SoundPreset)
30
- ____class_3.BASE_ID = id
31
- return ____class_3
32
- end
33
- )
34
- end)(SoundPreset)
20
+ end
35
21
  SoundPreset.BASE_ID = "BlizzardWave"
36
22
  SoundPreset.nextId = 0
37
23
  __TS__SetDescriptor(
@@ -47,4 +33,108 @@ __TS__SetDescriptor(
47
33
  },
48
34
  true
49
35
  )
36
+ __TS__SetDescriptor(
37
+ SoundPreset.prototype,
38
+ "volume",
39
+ {
40
+ get = function(self)
41
+ return self:getNumberField("Volume")
42
+ end,
43
+ set = function(self, volume)
44
+ self:setNumberField("Volume", volume)
45
+ end
46
+ },
47
+ true
48
+ )
49
+ __TS__SetDescriptor(
50
+ SoundPreset.prototype,
51
+ "pitch",
52
+ {
53
+ get = function(self)
54
+ return self:getNumberField("Pitch")
55
+ end,
56
+ set = function(self, pitch)
57
+ self:setNumberField("Pitch", pitch)
58
+ end
59
+ },
60
+ true
61
+ )
62
+ __TS__SetDescriptor(
63
+ SoundPreset.prototype,
64
+ "priority",
65
+ {
66
+ get = function(self)
67
+ return self:getNumberField("Priority")
68
+ end,
69
+ set = function(self, priority)
70
+ self:setNumberField("Priority", priority)
71
+ end
72
+ },
73
+ true
74
+ )
75
+ __TS__SetDescriptor(
76
+ SoundPreset.prototype,
77
+ "channel",
78
+ {
79
+ get = function(self)
80
+ return self:getNumberField("Channel")
81
+ end,
82
+ set = function(self, channel)
83
+ self:setNumberField("Channel", channel)
84
+ end
85
+ },
86
+ true
87
+ )
88
+ __TS__SetDescriptor(
89
+ SoundPreset.prototype,
90
+ "minimumDistance",
91
+ {
92
+ get = function(self)
93
+ return self:getNumberField("MinDistance")
94
+ end,
95
+ set = function(self, minimumDistance)
96
+ self:setNumberField("MinDistance", minimumDistance)
97
+ end
98
+ },
99
+ true
100
+ )
101
+ __TS__SetDescriptor(
102
+ SoundPreset.prototype,
103
+ "maximumDistance",
104
+ {
105
+ get = function(self)
106
+ return self:getNumberField("MaxDistance")
107
+ end,
108
+ set = function(self, maximumDistance)
109
+ self:setNumberField("MaxDistance", maximumDistance)
110
+ end
111
+ },
112
+ true
113
+ )
114
+ __TS__SetDescriptor(
115
+ SoundPreset.prototype,
116
+ "distanceCutoff",
117
+ {
118
+ get = function(self)
119
+ return self:getNumberField("DistanceCutoff")
120
+ end,
121
+ set = function(self, distanceCutoff)
122
+ self:setNumberField("DistanceCutoff", distanceCutoff)
123
+ end
124
+ },
125
+ true
126
+ )
127
+ __TS__SetDescriptor(
128
+ SoundPreset.prototype,
129
+ "eax",
130
+ {
131
+ get = function(self)
132
+ return self:getStringField("EAXFlags")
133
+ end,
134
+ set = function(self, eax)
135
+ self:setStringField("EAXFlags", eax)
136
+ end
137
+ },
138
+ true
139
+ )
50
140
  return ____exports
@@ -810,7 +810,7 @@ __TS__SetDescriptor(
810
810
  set = function(self, modelPath)
811
811
  self:setStringField("umdl", modelPath)
812
812
  if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
813
- self:setStringField("upor", modelPath)
813
+ self:setStringField("upor", "")
814
814
  end
815
815
  end
816
816
  },
@@ -826,7 +826,7 @@ __TS__SetDescriptor(
826
826
  set = function(self, modelPathSD)
827
827
  self:setStringField("umdl:sd", modelPathSD)
828
828
  if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
829
- self:setStringField("upor:sd", modelPathSD)
829
+ self:setStringField("upor:sd", "")
830
830
  end
831
831
  end
832
832
  },
@@ -842,7 +842,7 @@ __TS__SetDescriptor(
842
842
  set = function(self, modelPathHD)
843
843
  self:setStringField("umdl:hd", modelPathHD)
844
844
  if not self.isPortraitModelPathSet and WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
845
- self:setStringField("upor:hd", modelPathHD)
845
+ self:setStringField("upor:hd", "")
846
846
  end
847
847
  end
848
848
  },
@@ -14,17 +14,17 @@ export declare const extractObjectDataEntryLevelArrayFieldValue: <T extends stri
14
14
  export declare abstract class ObjectDataEntry<Id extends ObjectDataEntryId = ObjectDataEntryId> {
15
15
  protected readonly object: WarObject;
16
16
  static readonly BASE_ID: ObjectDataEntryId;
17
- static readonly ID_TYPE: string;
18
17
  protected static readonly IS_SYNTHETIC: boolean;
19
18
  private readonly levelFieldParametersByField;
20
19
  private readonly maxAffectedLevelByField;
21
20
  private _isInternal;
22
21
  private get type();
23
22
  get isInternal(): boolean;
23
+ static get idType(): "number" | "string";
24
24
  protected static generateId(): number | string;
25
25
  protected static getObjectData(map: WarMap): WarObjects;
26
26
  static getAllIdsByBaseIds<T extends ObjectDataEntry>(this: ObjectDataEntryAbstractConstructor<T>, baseIds: number | number[] | string | string[]): ObjectDataEntryIdType<T>[];
27
- static create<T extends ObjectDataEntry>(this: ObjectDataEntryConstructor<T>, ...args: [id?: number, properties?: ObjectDataEntryProperties<T>] | [properties: ObjectDataEntryProperties<T>]): T;
27
+ static create<T extends ObjectDataEntry>(this: ObjectDataEntryConstructor<T>, ...args: [id?: number | string, properties?: ObjectDataEntryProperties<T>] | [properties: ObjectDataEntryProperties<T>]): T;
28
28
  static getAllByBaseIds<T extends ObjectDataEntry>(this: ObjectDataEntryAbstractConstructor<T>, baseIds: number | number[] | string | string[]): T[];
29
29
  static getAll<T extends ObjectDataEntry>(this: ObjectDataEntryAbstractConstructor<T>): T[];
30
30
  static of<T extends ObjectDataEntry>(this: ObjectDataEntryAbstractConstructor<T>, id: number | string): T | undefined;
@@ -7,6 +7,7 @@ local __TS__ClassExtends = ____lualib.__TS__ClassExtends
7
7
  local __TS__InstanceOf = ____lualib.__TS__InstanceOf
8
8
  local __TS__ArrayMap = ____lualib.__TS__ArrayMap
9
9
  local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor
10
+ local __TS__ObjectDefineProperty = ____lualib.__TS__ObjectDefineProperty
10
11
  local __TS__StringSplit = ____lualib.__TS__StringSplit
11
12
  local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
12
13
  local ____exports = {}
@@ -124,7 +125,7 @@ function ObjectDataEntry.getAllByBaseIds(self, baseIds)
124
125
  local constructor = self
125
126
  for id, object in pairs(constructor:getObjectData(currentMap).all) do
126
127
  if dataBaseIds[object.parentId or id] ~= nil then
127
- local objectDataEntry = self:of(dataToObjectDataEntryId(id, self.ID_TYPE))
128
+ local objectDataEntry = self:of(dataToObjectDataEntryId(id, self.idType))
128
129
  if objectDataEntry ~= nil and not objectDataEntry.isInternal then
129
130
  result[#result + 1] = objectDataEntry
130
131
  end
@@ -139,7 +140,7 @@ function ObjectDataEntry.getAll(self)
139
140
  local constructor = self
140
141
  local result = {}
141
142
  for id in pairs(constructor:getObjectData(currentMap).all) do
142
- local objectDataEntry = self:of(dataToObjectDataEntryId(id, self.ID_TYPE))
143
+ local objectDataEntry = self:of(dataToObjectDataEntryId(id, self.idType))
143
144
  if objectDataEntry ~= nil and not objectDataEntry.isInternal then
144
145
  result[#result + 1] = objectDataEntry
145
146
  end
@@ -156,9 +157,9 @@ function ObjectDataEntry.of(self, id)
156
157
  if object == nil then
157
158
  return nil
158
159
  end
159
- local objectDataEntry = objectDataEntryByObjectDataEntryId[dataToObjectDataEntryId(object.id, self.ID_TYPE)]
160
+ local objectDataEntry = objectDataEntryByObjectDataEntryId[dataToObjectDataEntryId(object.id, self.idType)]
160
161
  if objectDataEntry == nil then
161
- if not constructor.IS_SYNTHETIC and (self.BASE_ID == 0 or dataToObjectDataEntryId(object.parentId, self.ID_TYPE) == self.BASE_ID) then
162
+ if not constructor.IS_SYNTHETIC and (self.BASE_ID == 0 or dataToObjectDataEntryId(object.parentId, self.idType) == self.BASE_ID) then
162
163
  local AbstractObjectDataEntryView = __TS__Class()
163
164
  AbstractObjectDataEntryView.name = "AbstractObjectDataEntryView"
164
165
  __TS__ClassExtends(AbstractObjectDataEntryView, constructor)
@@ -475,7 +476,6 @@ function ObjectDataEntry.prototype.setLevelField(self, field, supplier, extracto
475
476
  end
476
477
  end
477
478
  ObjectDataEntry.BASE_ID = 0
478
- ObjectDataEntry.ID_TYPE = type(self.BASE_ID) == "number" and "number" or "string"
479
479
  ObjectDataEntry.IS_SYNTHETIC = false
480
480
  __TS__SetDescriptor(
481
481
  ObjectDataEntry.prototype,
@@ -503,11 +503,18 @@ __TS__SetDescriptor(
503
503
  },
504
504
  true
505
505
  )
506
+ __TS__ObjectDefineProperty(
507
+ ObjectDataEntry,
508
+ "idType",
509
+ {get = function(self)
510
+ return type(self.BASE_ID) == "number" and "number" or "string"
511
+ end}
512
+ )
506
513
  __TS__SetDescriptor(
507
514
  ObjectDataEntry.prototype,
508
515
  "id",
509
516
  {get = function(self)
510
- return dataToObjectDataEntryId(self.object.id, self.type.ID_TYPE)
517
+ return dataToObjectDataEntryId(self.object.id, self.type.idType)
511
518
  end},
512
519
  true
513
520
  )
@@ -515,7 +522,7 @@ __TS__SetDescriptor(
515
522
  ObjectDataEntry.prototype,
516
523
  "baseId",
517
524
  {get = function(self)
518
- return dataToObjectDataEntryId(self.object.parentId or self.object.id, self.type.ID_TYPE)
525
+ return dataToObjectDataEntryId(self.object.parentId or self.object.id, self.type.idType)
519
526
  end},
520
527
  true
521
528
  )
package/objutil/unit.lua CHANGED
@@ -596,7 +596,7 @@ __TS__SetDescriptor(
596
596
  set = function(self, v)
597
597
  self:setStringField("umdl", v)
598
598
  if WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
599
- self:setStringField("upor", v)
599
+ self:setStringField("upor", "")
600
600
  end
601
601
  end
602
602
  },
@@ -612,7 +612,7 @@ __TS__SetDescriptor(
612
612
  set = function(self, v)
613
613
  self.object:setField("umdl:hd", v)
614
614
  if WarscriptConfig.AUTOMATICALLY_SET_UNIT_TYPE_PORTRAIT_MODEL_PATH then
615
- self.object:setField("upor:hd", v)
615
+ self.object:setField("upor:hd", "")
616
616
  end
617
617
  end
618
618
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "warscript",
4
- "version": "0.0.1-dev.47f470c",
4
+ "version": "0.0.1-dev.524f1b8",
5
5
  "description": "A typescript library for Warcraft III using Warpack.",
6
6
  "keywords": [
7
7
  "warcraft",
@@ -24,7 +24,7 @@
24
24
  "@warscript/language-extensions": "^0.0.1",
25
25
  "@warscript/tstl-plugin": "^0.0.4",
26
26
  "lua-types": "^2.13.1",
27
- "warpack": "0.0.1-dev.57dfac2"
27
+ "warpack": "0.0.1-dev.8e8a660"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@typescript-eslint/eslint-plugin": "^8.13.0",
@@ -5,21 +5,25 @@ local checkNotNull = ____preconditions.checkNotNull
5
5
  -- @internal For use by internal systems only.
6
6
  ____exports.implementReadonlyNumberIndexSupplier = function(clazz, supplier)
7
7
  local metatable = checkNotNull(getmetatable(clazz))
8
- local originalIndex = checkNotNull(metatable.__index)
8
+ local originalIndex = checkNotNull(rawget(metatable, "__index"))
9
9
  local memoizedValueByKey = {}
10
- metatable.__index = setmetatable(
11
- memoizedValueByKey,
12
- {__index = function(self, key)
10
+ rawset(
11
+ metatable,
12
+ "__index",
13
+ function(self, key)
13
14
  if type(key) == "number" then
14
- local value = supplier(key)
15
- memoizedValueByKey[key] = value
15
+ local value = memoizedValueByKey[key]
16
+ if value == nil then
17
+ value = supplier(key)
18
+ memoizedValueByKey[key] = value
19
+ end
16
20
  return value
17
21
  end
18
22
  if type(originalIndex) == "function" then
19
23
  return originalIndex(self, key)
20
24
  end
21
25
  return originalIndex[key]
22
- end}
26
+ end
23
27
  )
24
28
  end
25
29
  ____exports.getClass = function(object)