warcraft-3-w3ts-utils 0.1.3 → 0.1.6

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/dist/index.d.ts +1 -0
  2. package/dist/index.js +18 -0
  3. package/dist/utils/abilities.d.ts +35 -0
  4. package/dist/utils/abilities.js +125 -0
  5. package/dist/utils/camera.d.ts +1 -0
  6. package/dist/utils/camera.js +37 -0
  7. package/dist/utils/chat-command.d.ts +12 -0
  8. package/dist/utils/chat-command.js +22 -0
  9. package/{src/utils/color.ts → dist/utils/color.d.ts} +109 -139
  10. package/dist/utils/color.js +141 -0
  11. package/dist/utils/index.d.ts +15 -0
  12. package/dist/utils/index.js +32 -0
  13. package/dist/utils/item.d.ts +9 -0
  14. package/dist/utils/item.js +124 -0
  15. package/dist/utils/math.d.ts +13 -0
  16. package/dist/utils/math.js +17 -0
  17. package/dist/utils/minimapIcons.d.ts +13 -0
  18. package/dist/utils/minimapIcons.js +27 -0
  19. package/dist/utils/misc.d.ts +56 -0
  20. package/dist/utils/misc.js +175 -0
  21. package/dist/utils/physics.d.ts +52 -0
  22. package/dist/utils/physics.js +194 -0
  23. package/dist/utils/players.d.ts +50 -0
  24. package/dist/utils/players.js +189 -0
  25. package/dist/utils/point.d.ts +15 -0
  26. package/dist/utils/point.js +74 -0
  27. package/dist/utils/quests.d.ts +2 -0
  28. package/dist/utils/quests.js +30 -0
  29. package/dist/utils/textTag.d.ts +29 -0
  30. package/dist/utils/textTag.js +72 -0
  31. package/dist/utils/timer.d.ts +5 -0
  32. package/dist/utils/timer.js +16 -0
  33. package/dist/utils/units.d.ts +26 -0
  34. package/dist/utils/units.js +81 -0
  35. package/package.json +12 -3
  36. package/tsconfig.json +2 -4
  37. package/src/utils/abilities.ts +0 -161
  38. package/src/utils/camera.ts +0 -63
  39. package/src/utils/chat-command.ts +0 -22
  40. package/src/utils/item.ts +0 -155
  41. package/src/utils/math.ts +0 -14
  42. package/src/utils/minimapIcons.ts +0 -34
  43. package/src/utils/misc.ts +0 -179
  44. package/src/utils/physics.ts +0 -295
  45. package/src/utils/players.ts +0 -214
  46. package/src/utils/point.ts +0 -81
  47. package/src/utils/quests.ts +0 -38
  48. package/src/utils/textTag.ts +0 -80
  49. package/src/utils/timer.ts +0 -14
  50. package/src/utils/units.ts +0 -109
  51. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,29 @@
1
+ import { Unit } from "w3ts";
2
+ /**
3
+ * https://www.hiveworkshop.com/threads/floating-text.149719/
4
+ *
5
+ * function CreateFloatingText takes string text, real x, real y, real heightOffset, real duration, real size returns nothing
6
+ local texttag tt = CreateTextTag()
7
+ call SetTextTagText(tt, text, size)
8
+ call SetTextTagPos(tt, x, y, heightOffset)
9
+ call SetTextTagColor(tt, 255, 255, 255, 255) // RGBA format
10
+ call SetTextTagVisibility(tt, true)
11
+ call SetTextTagLifespan(tt, duration)
12
+ call SetTextTagPermanent(tt, false)
13
+ endfunction
14
+
15
+ function ExampleUsage takes nothing returns nothing
16
+ call CreateFloatingText("Hello World", 0.0, 0.0, 25.0, 5.0, 10.0)
17
+ endfunction
18
+ * @param unit
19
+ * @param text
20
+ * @param duration
21
+ */
22
+ export declare function createFloatingTextTagOnUnit(unit: Unit, text: string, config?: {
23
+ duration?: number;
24
+ yVelocity?: number;
25
+ xVelocity?: number;
26
+ useFade?: boolean;
27
+ }): void;
28
+ export declare function createPermanentTextTagOnPoint(text: string, x: number, y: number): void;
29
+ export declare function setup_createTextForSpellCast(): void;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createFloatingTextTagOnUnit = createFloatingTextTagOnUnit;
4
+ exports.createPermanentTextTagOnPoint = createPermanentTextTagOnPoint;
5
+ exports.setup_createTextForSpellCast = setup_createTextForSpellCast;
6
+ const w3ts_1 = require("w3ts");
7
+ const misc_1 = require("./misc");
8
+ const timer_1 = require("./timer");
9
+ /**
10
+ * https://www.hiveworkshop.com/threads/floating-text.149719/
11
+ *
12
+ * function CreateFloatingText takes string text, real x, real y, real heightOffset, real duration, real size returns nothing
13
+ local texttag tt = CreateTextTag()
14
+ call SetTextTagText(tt, text, size)
15
+ call SetTextTagPos(tt, x, y, heightOffset)
16
+ call SetTextTagColor(tt, 255, 255, 255, 255) // RGBA format
17
+ call SetTextTagVisibility(tt, true)
18
+ call SetTextTagLifespan(tt, duration)
19
+ call SetTextTagPermanent(tt, false)
20
+ endfunction
21
+
22
+ function ExampleUsage takes nothing returns nothing
23
+ call CreateFloatingText("Hello World", 0.0, 0.0, 25.0, 5.0, 10.0)
24
+ endfunction
25
+ * @param unit
26
+ * @param text
27
+ * @param duration
28
+ */
29
+ function createFloatingTextTagOnUnit(unit, text, config) {
30
+ const tag = w3ts_1.TextTag.create();
31
+ tag?.setVisible(true);
32
+ tag?.setText(text, 10, true);
33
+ tag?.setLifespan(config?.duration === undefined ? 2 : config.duration);
34
+ if (config?.useFade !== false) {
35
+ tag?.setFadepoint(0.01);
36
+ }
37
+ tag?.setVelocity(config?.xVelocity === undefined ? 0 : config.xVelocity, config?.yVelocity === undefined ? 0.025 : config.yVelocity);
38
+ tag?.setPermanent(false);
39
+ tag?.setPosUnit(unit, 10);
40
+ if (config && config.duration && config.duration === 0) {
41
+ return;
42
+ }
43
+ (0, timer_1.delayedTimer)(config?.duration ?? 2, () => {
44
+ tag?.destroy();
45
+ });
46
+ }
47
+ function createPermanentTextTagOnPoint(text, x, y) {
48
+ const tag = w3ts_1.TextTag.create();
49
+ tag?.setVisible(true);
50
+ tag?.setText(text, 20, true);
51
+ tag?.setLifespan(2);
52
+ tag?.setVelocity(0, 0);
53
+ tag?.setPermanent(true);
54
+ tag?.setPos(x, y, 20);
55
+ }
56
+ function setup_createTextForSpellCast() {
57
+ const t = w3ts_1.Trigger.create();
58
+ t.registerAnyUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT);
59
+ t.addAction(() => {
60
+ const u = w3ts_1.Unit.fromEvent();
61
+ if (u) {
62
+ const spellNumber = GetSpellAbilityId();
63
+ const spellName = GetAbilityName(spellNumber);
64
+ if (!spellName || spellName === "Default String")
65
+ return;
66
+ //alt + 0164 ¤
67
+ //alt + 0149 •
68
+ createFloatingTextTagOnUnit(u, (0, misc_1.ptColor)(u.owner, "¤ ") + spellName);
69
+ }
70
+ });
71
+ }
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dFRhZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy90ZXh0VGFnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBd0JBLGtFQXdCQztBQUVELHNFQVVDO0FBRUQsb0VBaUJDO0FBL0VELCtCQUE4QztBQUM5QyxpQ0FBaUM7QUFDakMsbUNBQXVDO0FBRXZDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsU0FBZ0IsMkJBQTJCLENBQUMsSUFBVSxFQUFFLElBQVksRUFBRSxNQUF5RjtJQUMzSixNQUFNLEdBQUcsR0FBRyxjQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDN0IsR0FBRyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUV0QixHQUFHLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFN0IsR0FBRyxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFdkUsSUFBSSxNQUFNLEVBQUUsT0FBTyxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQzVCLEdBQUcsRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELEdBQUcsRUFBRSxXQUFXLENBQUMsTUFBTSxFQUFFLFNBQVMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckksR0FBRyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUV6QixHQUFHLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUUxQixJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDckQsT0FBTztJQUNYLENBQUM7SUFFRCxJQUFBLG9CQUFZLEVBQUMsTUFBTSxFQUFFLFFBQVEsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFO1FBQ3JDLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNuQixDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCxTQUFnQiw2QkFBNkIsQ0FBQyxJQUFZLEVBQUUsQ0FBUyxFQUFFLENBQVM7SUFDNUUsTUFBTSxHQUFHLEdBQUcsY0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzdCLEdBQUcsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFdEIsR0FBRyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzdCLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFcEIsR0FBRyxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkIsR0FBRyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QixHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUVELFNBQWdCLDRCQUE0QjtJQUN4QyxNQUFNLENBQUMsR0FBRyxjQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFM0IsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFFdkQsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDYixNQUFNLENBQUMsR0FBRyxXQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFM0IsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNKLE1BQU0sV0FBVyxHQUFHLGlCQUFpQixFQUFFLENBQUM7WUFDeEMsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxTQUFTLElBQUksU0FBUyxLQUFLLGdCQUFnQjtnQkFBRSxPQUFPO1lBQ3pELGNBQWM7WUFDZCxjQUFjO1lBQ2QsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLElBQUEsY0FBTyxFQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUM7UUFDeEUsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyJ9
@@ -0,0 +1,5 @@
1
+ import { Timer } from "w3ts";
2
+ /**
3
+ * @param duration milliseconds
4
+ */
5
+ export declare function delayedTimer(duration: number, cb: (...args: any[]) => any): Timer;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.delayedTimer = delayedTimer;
4
+ const w3ts_1 = require("w3ts");
5
+ /**
6
+ * @param duration milliseconds
7
+ */
8
+ function delayedTimer(duration, cb) {
9
+ const timer = w3ts_1.Timer.create();
10
+ timer.start(duration, false, () => {
11
+ cb();
12
+ timer.destroy();
13
+ });
14
+ return timer;
15
+ }
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdGltZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSxvQ0FRQztBQWJELCtCQUE2QjtBQUU3Qjs7R0FFRztBQUNILFNBQWdCLFlBQVksQ0FBQyxRQUFnQixFQUFFLEVBQTJCO0lBQ3RFLE1BQU0sS0FBSyxHQUFHLFlBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUM3QixLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFO1FBQzlCLEVBQUUsRUFBRSxDQUFDO1FBQ0wsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3BCLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQyJ9
@@ -0,0 +1,26 @@
1
+ import { MapPlayer, Unit } from "w3ts";
2
+ export declare function createUnits(quantity: number, useFood: boolean, ...args: Parameters<typeof Unit.create>): Unit[];
3
+ /**
4
+ * Refund unit's gold and wood cost.
5
+ * @param u
6
+ */
7
+ export declare function refundUnitCost(u: Unit): void;
8
+ /**
9
+ * Returns true if the ALIVE unit has the ability within their first 12 abilities
10
+ * @param unit
11
+ * @param abilityId
12
+ * @returns
13
+ */
14
+ export declare function unitHasAbility(unit: Unit, abilityId: number): boolean;
15
+ export declare function unitsInRange(x: number, y: number, radius: number, cb: (unit: Unit) => void): void;
16
+ /**
17
+ *
18
+ * @param cb
19
+ * @param abilityId
20
+ * @param owner
21
+ */
22
+ export declare function useTempDummyUnit(dummyUnitCode: number, cb: (dummy: Unit) => void, abilityId: number, owner: MapPlayer, x: number, y: number, config?: {
23
+ facing?: number;
24
+ abilityLevel?: number;
25
+ dummyLifeSpan?: number;
26
+ }): void;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createUnits = createUnits;
4
+ exports.refundUnitCost = refundUnitCost;
5
+ exports.unitHasAbility = unitHasAbility;
6
+ exports.unitsInRange = unitsInRange;
7
+ exports.useTempDummyUnit = useTempDummyUnit;
8
+ const w3ts_1 = require("w3ts");
9
+ const players_1 = require("./players");
10
+ function createUnits(quantity, useFood, ...args) {
11
+ const units = [];
12
+ for (let x = 0; x < quantity; x++) {
13
+ const u = w3ts_1.Unit.create(...args);
14
+ if (u) {
15
+ u.setUseFood(useFood);
16
+ units.push(u);
17
+ }
18
+ }
19
+ return units;
20
+ }
21
+ /**
22
+ * Refund unit's gold and wood cost.
23
+ * @param u
24
+ */
25
+ function refundUnitCost(u) {
26
+ const gold = GetUnitGoldCost(u.typeId);
27
+ const wood = GetUnitWoodCost(u.typeId);
28
+ (0, players_1.adjustGold)(u.owner, gold);
29
+ (0, players_1.adjustLumber)(u.owner, wood);
30
+ }
31
+ /**
32
+ * Returns true if the ALIVE unit has the ability within their first 12 abilities
33
+ * @param unit
34
+ * @param abilityId
35
+ * @returns
36
+ */
37
+ function unitHasAbility(unit, abilityId) {
38
+ for (let x = 0; x < 12; x++) {
39
+ const currentAbility = unit.getAbilityByIndex(x);
40
+ if (currentAbility &&
41
+ currentAbility === unit.getAbility(abilityId) &&
42
+ unit.isAlive()) {
43
+ return true;
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+ function unitsInRange(x, y, radius, cb) {
49
+ const g = w3ts_1.Group.create();
50
+ if (g) {
51
+ g.enumUnitsInRange(x, y, radius, () => {
52
+ const unit = w3ts_1.Unit.fromFilter();
53
+ if (unit) {
54
+ cb(unit);
55
+ }
56
+ return true;
57
+ });
58
+ g.destroy();
59
+ }
60
+ }
61
+ /**
62
+ *
63
+ * @param cb
64
+ * @param abilityId
65
+ * @param owner
66
+ */
67
+ function useTempDummyUnit(dummyUnitCode, cb, abilityId, owner, x, y, config) {
68
+ let dummy = undefined;
69
+ dummy = w3ts_1.Unit.create(owner, dummyUnitCode, x, y, config?.facing ?? 0);
70
+ const t = w3ts_1.Timer.create();
71
+ if (dummy) {
72
+ dummy.addAbility(abilityId);
73
+ dummy.setAbilityManaCost(abilityId, config?.abilityLevel ? config.abilityLevel - 1 : 0, 0);
74
+ cb(dummy);
75
+ t.start(config?.dummyLifeSpan ?? 2, false, () => {
76
+ dummy?.destroy();
77
+ t.destroy();
78
+ });
79
+ }
80
+ }
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdW5pdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFHQSxrQ0FnQkM7QUFNRCx3Q0FLQztBQVFELHdDQWNDO0FBRUQsb0NBa0JDO0FBUUQsNENBNEJDO0FBNUdELCtCQUFxRDtBQUNyRCx1Q0FBcUQ7QUFFckQsU0FBZ0IsV0FBVyxDQUN6QixRQUFnQixFQUNoQixPQUFnQixFQUNoQixHQUFHLElBQW9DO0lBRXZDLE1BQU0sS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUN6QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDbEMsTUFBTSxDQUFDLEdBQUcsV0FBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBRS9CLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDTixDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEIsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixjQUFjLENBQUMsQ0FBTztJQUNwQyxNQUFNLElBQUksR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sSUFBSSxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsSUFBQSxvQkFBVSxFQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDMUIsSUFBQSxzQkFBWSxFQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsY0FBYyxDQUFDLElBQVUsRUFBRSxTQUFpQjtJQUMxRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDNUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWpELElBQ0UsY0FBYztZQUNkLGNBQWMsS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQztZQUM3QyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQ2QsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFnQixZQUFZLENBQzFCLENBQVMsRUFDVCxDQUFTLEVBQ1QsTUFBYyxFQUNkLEVBQXdCO0lBRXhCLE1BQU0sQ0FBQyxHQUFHLFlBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN6QixJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ04sQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRTtZQUNwQyxNQUFNLElBQUksR0FBRyxXQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDL0IsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDVCxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDWCxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDLENBQUMsQ0FBQztRQUVILENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixnQkFBZ0IsQ0FDOUIsYUFBcUIsRUFDckIsRUFBeUIsRUFDekIsU0FBaUIsRUFDakIsS0FBZ0IsRUFDaEIsQ0FBUyxFQUNULENBQVMsRUFDVCxNQUEyRTtJQUUzRSxJQUFJLEtBQUssR0FBcUIsU0FBUyxDQUFDO0lBQ3hDLEtBQUssR0FBRyxXQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBRXJFLE1BQU0sQ0FBQyxHQUFHLFlBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUV6QixJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ1YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM1QixLQUFLLENBQUMsa0JBQWtCLENBQ3RCLFNBQVMsRUFDVCxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNsRCxDQUFDLENBQ0YsQ0FBQztRQUNGLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVWLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLGFBQWEsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtZQUM5QyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDakIsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQyJ9
package/package.json CHANGED
@@ -1,11 +1,20 @@
1
1
  {
2
2
  "name": "warcraft-3-w3ts-utils",
3
- "version": "0.1.3",
3
+ "version": "0.1.6",
4
4
  "description": "A library of utility functions for modding Warcraft 3 utilizing the W3TS template.",
5
- "main": "index.js",
5
+ "main": "./src/index.ts",
6
+ "keywords": [
7
+ "Warcraft 3"
8
+ ],
6
9
  "scripts": {
7
- "test": "npm run test"
10
+ "compile": "tsc",
11
+ "build": "npm run compile",
12
+ "prepare": "npm run build"
8
13
  },
14
+ "files": [
15
+ "dist",
16
+ "tsconfig.json"
17
+ ],
9
18
  "repository": {
10
19
  "type": "git",
11
20
  "url": "git+https://github.com/bertman12/WC3-W3TS-utils.git"
package/tsconfig.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "target": "esnext",
13
13
  "module": "commonjs",
14
14
  "lib": ["ESNext"],
15
- "moduleResolution": "node",
15
+ "moduleResolution": "node10",
16
16
  "paths": {
17
17
  "@objectdata/*": [
18
18
  "./node_modules/war3-objectdata-th/dist/cjs/generated/constants/*"
@@ -33,7 +33,5 @@
33
33
  "war3-transformer/types",
34
34
  "war3-objectdata-th/dist/cjs/objectdata"
35
35
  ]
36
- },
37
- "include": ["src"],
38
- "exclude": []
36
+ }
39
37
  }
@@ -1,161 +0,0 @@
1
- import { Timer, Trigger, Unit } from "w3ts";
2
-
3
-
4
- /**
5
- * Good for once a unit gets near you, but not good while they are near you since the event is only triggered on entry, not during
6
- * @param unit
7
- * @param range
8
- * @param cb
9
- * @param config
10
- * @returns
11
- */
12
- export function unitGetsNearThisUnit(
13
- unit: Unit,
14
- range: number,
15
- cb: (u: Unit) => void,
16
- config?: {
17
- uniqueUnitsOnly: boolean;
18
- filter?: boolexpr | (() => boolean);
19
- onDestroy?: (unitsEffected: Unit[]) => void;
20
- }
21
- ) {
22
- const trig = Trigger.create();
23
-
24
- /**
25
- * A unique set of the units effected
26
- */
27
- let effectedUnitPool: Unit[] = [];
28
-
29
- trig.registerUnitInRage(unit.handle, range, config?.filter ?? (() => true));
30
-
31
- trig.addAction(() => {
32
- const u = Unit.fromEvent();
33
-
34
- if (!u) {
35
- return;
36
- }
37
-
38
- if (!effectedUnitPool.includes(u)) {
39
- effectedUnitPool.push(u);
40
- }
41
-
42
- if (config?.uniqueUnitsOnly && !effectedUnitPool.includes(u)) {
43
- cb(u);
44
- } else {
45
- cb(u);
46
- }
47
- });
48
-
49
- const destroy = () => {
50
- if (config?.onDestroy) {
51
- config?.onDestroy(effectedUnitPool);
52
- }
53
-
54
- // print("destroying the trigger!");
55
- trig.destroy();
56
- // print("The trigger ref: ", trig);
57
- };
58
-
59
- const clearUniqueUnits = () => {
60
- effectedUnitPool = [];
61
- };
62
-
63
- return {
64
- cleanupUnitGetsNearThisUnit: (delay?: number) => {
65
- if (delay) {
66
- const timer = Timer.create();
67
- timer.start(delay, false, () => {
68
- destroy();
69
- timer.destroy();
70
- });
71
- return;
72
- }
73
-
74
- destroy();
75
- },
76
- clearUniqueUnits,
77
- };
78
- }
79
-
80
- /**
81
- *
82
- * @param cb
83
- * @param abilityId
84
- * @param dummyLifeTime Maybe be necessary to have a long lifetime so spells like chain lightning will have time to bounce to all targets
85
- * @param owner
86
- */
87
- // export function useTempDummyUnit(cb: (dummy: Unit) => void, abilityId: number, dummyLifeTime: number, owner: MapPlayer, x: number, y: number, facing: number, config?: { abilityLevel?: number; modelType?: "cenariusGhost" }) {
88
- // let dummy: Unit | undefined = undefined;
89
-
90
- // if (config?.modelType === "cenariusGhost") {
91
- // dummy = Unit.create(owner, UNITS.dummyCaster_cenariusGhost, x, y, facing);
92
- // dummy?.setScale(1, 1, 1);
93
- // } else {
94
- // dummy = Unit.create(owner, UNITS.dummyCaster, x, y, facing);
95
- // }
96
-
97
- // const t = Timer.create();
98
-
99
- // if (dummy) {
100
- // dummy.addAbility(abilityId);
101
- // dummy.setAbilityManaCost(abilityId, config?.abilityLevel ? config.abilityLevel - 1 : 0, 0);
102
- // cb(dummy);
103
-
104
- // t.start(dummyLifeTime, false, () => {
105
- // dummy?.destroy();
106
- // t.destroy();
107
- // });
108
- // }
109
- // }
110
-
111
- /**
112
- * Creates a trigger to monitor when a unit is attacked
113
- *
114
- * We could also have all functions execute in this single trigger's context instead of creating new triggers each time the function is used.
115
- * @param cb
116
- * @param config
117
- */
118
- export function onUnitAttacked(
119
- cb: (attacker: Unit, victim: Unit) => void,
120
- config: { attackerCooldown?: boolean; procChance?: number }
121
- ) {
122
- const attackerTriggerCooldown = new Set<Unit>();
123
- const t = Trigger.create();
124
-
125
- t.registerAnyUnitEvent(EVENT_PLAYER_UNIT_ATTACKED);
126
-
127
- t.addAction(() => {
128
- const attacker = Unit.fromHandle(GetAttacker());
129
- const victim = Unit.fromHandle(GetAttackedUnitBJ());
130
-
131
- if (!attacker || !victim) {
132
- return;
133
- }
134
-
135
- //Attack was not below the proc chance, and thus we will not use the cb function
136
- if (
137
- config.procChance &&
138
- Math.ceil(Math.random() * 100) >= config.procChance
139
- ) {
140
- return;
141
- }
142
-
143
- //Attacker has already used the trigger
144
- if (config.attackerCooldown && attackerTriggerCooldown.has(attacker)) {
145
- return;
146
- }
147
-
148
- attackerTriggerCooldown.add(attacker);
149
-
150
- //Finally, after all conditions have been met, use the cb function
151
- cb(attacker, victim);
152
-
153
- const t = Timer.create();
154
-
155
- //removes the attacker from the cooldown group after 1/3 of that units attack cooldown has passed.
156
- t.start(attacker.getAttackCooldown(0) / 3, false, () => {
157
- attackerTriggerCooldown.delete(attacker);
158
- t.destroy();
159
- });
160
- });
161
- }
@@ -1,63 +0,0 @@
1
- import { Trigger } from "w3ts";
2
- import { forEachPlayer } from "./players";
3
-
4
- type CameraDistances = "mid" | "far" | "max";
5
-
6
- export function enableCameraZoom() {
7
- const t = Trigger.create();
8
- forEachPlayer((p) => {
9
- SetCameraFieldForPlayer(p.handle, CAMERA_FIELD_FARZ, 10000, 0.25);
10
-
11
- t.registerPlayerChatEvent(p, "-cam", false);
12
-
13
- t.addAction(() => {
14
- const str = GetEventPlayerChatString();
15
- const triggeringPlayer = GetTriggerPlayer();
16
- if (str && triggeringPlayer) {
17
- const [command, distance] = str?.split(" ");
18
- SetCameraFieldForPlayer(
19
- triggeringPlayer,
20
- CAMERA_FIELD_FARZ,
21
- 10000,
22
- 0.25
23
- );
24
-
25
- if ((distance as CameraDistances) === "mid") {
26
- SetCameraFieldForPlayer(
27
- triggeringPlayer,
28
- CAMERA_FIELD_TARGET_DISTANCE,
29
- 4500,
30
- 0.25
31
- );
32
- return;
33
- } else if ((distance as CameraDistances) === "far") {
34
- SetCameraFieldForPlayer(
35
- triggeringPlayer,
36
- CAMERA_FIELD_TARGET_DISTANCE,
37
- 6000,
38
- 0.25
39
- );
40
- return;
41
- } else if ((distance as CameraDistances) === "max") {
42
- SetCameraFieldForPlayer(
43
- triggeringPlayer,
44
- CAMERA_FIELD_TARGET_DISTANCE,
45
- 7800,
46
- 0.25
47
- );
48
- return;
49
- }
50
-
51
- const distanceAsNumber = Number(distance);
52
- if (typeof distanceAsNumber !== "number") return;
53
-
54
- SetCameraFieldForPlayer(
55
- triggeringPlayer,
56
- CAMERA_FIELD_TARGET_DISTANCE,
57
- distanceAsNumber,
58
- 0.25
59
- );
60
- }
61
- });
62
- });
63
- }
@@ -1,22 +0,0 @@
1
- import { MapPlayer, Trigger } from "w3ts";
2
-
3
- /**
4
- * Setup trigger to listen for a chat command for the players specified in the array. Execute function when triggered
5
- * @param command -cam , -name, -start, etc
6
- * @param players
7
- * @param fn
8
- */
9
- export function createChatCommand(players: MapPlayer[], command: string, exact: boolean, fn: (player: MapPlayer, data: { trigger: Trigger; command: string; data?: string }) => void) {
10
- const trigger = Trigger.create();
11
-
12
- players.forEach((p) => {
13
- trigger.registerPlayerChatEvent(p, command, exact);
14
-
15
- trigger.addAction(() => {
16
- const str = GetEventPlayerChatString();
17
- const [_, data] = str?.split(" ") ?? [];
18
-
19
- fn(p, { trigger, command, data });
20
- });
21
- });
22
- }
package/src/utils/item.ts DELETED
@@ -1,155 +0,0 @@
1
- import { Effect, Item, Trigger, Unit } from "w3ts";
2
- import { notifyPlayer, useTempEffect } from "./misc";
3
-
4
- /**
5
- * Checks if the unit has an item in their item slots
6
- * @param u
7
- * @param itemTypeId
8
- * @returns
9
- */
10
- export function unitHasItem(u: Unit, itemTypeId: number): boolean {
11
- for (let x = 0; x < 6; x++) {
12
- if (u.getItemInSlot(x)?.typeId === itemTypeId) {
13
- return true;
14
- }
15
- }
16
-
17
- return false;
18
- }
19
-
20
- // Player should pick up recipes when needed. if they are missing items then the recipe cost is refunded
21
- export function trig_itemRecipeSystem() {
22
- //takes a set of items
23
- //unit or unit clicks
24
- const t = Trigger.create();
25
-
26
- t.registerAnyUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM);
27
- t.addAction(() => {
28
- const recipeItem = Item.fromEvent();
29
- const unit = Unit.fromHandle(GetTriggerUnit());
30
-
31
- if (!unit || !recipeItem) {
32
- return;
33
- }
34
-
35
- //for every item they have, if any has the word recipe, then we check to see if they have the items needed to satisfy the recipe
36
- for (let x = 0; x < 6; x++) {
37
- const currItem = unit?.getItemInSlot(x);
38
- if (currItem?.name.toLowerCase().includes("recipe")) {
39
- checkItemRecipeRequirements(unit, currItem);
40
- }
41
- }
42
- });
43
- }
44
-
45
- function checkItemRecipeRequirements(unit: Unit, recipeItem: Item) {
46
- if (recipeItem.name.toLowerCase().includes("recipe")) {
47
- let requiredItems: RecipeItemRequirement[] | null = null;
48
- let itemToCreateId: number | null = null;
49
-
50
- for (const [key, value] of itemRecipesMap.entries()) {
51
- if (key.recipeId === recipeItem.typeId) {
52
- requiredItems = value;
53
- itemToCreateId = key.itemId;
54
- }
55
- }
56
-
57
- if (!requiredItems) {
58
- print("Missing required items data for the recipe ", recipeItem.name);
59
- return;
60
- }
61
-
62
- /**
63
- * unique list of item types and their quantity and charges that we found on the unit
64
- */
65
- const matchingItems: RecipeItemRequirement[] = [];
66
-
67
- //Loop through the units item slots
68
- for (let x = 0; x < 6; x++) {
69
- const currItem = unit?.getItemInSlot(x);
70
-
71
- //Check that the current item matches at least one of the item types in the requirement list
72
- if (currItem && requiredItems.some((req) => req.itemTypeId === currItem.typeId)) {
73
- const alreadyStoredItemIndex = matchingItems.findIndex((itemReq) => itemReq.itemTypeId === currItem.typeId);
74
-
75
- //If we already came across this item in the unit inventory then increment the quantity
76
- if (alreadyStoredItemIndex && matchingItems[alreadyStoredItemIndex]) {
77
- matchingItems[alreadyStoredItemIndex].quantity++;
78
- }
79
- //otherwise it is our first match with this item type, so add it to our array of matching items
80
- else {
81
- matchingItems.push({ itemTypeId: currItem.typeId, quantity: 1, charges: 0 });
82
- }
83
- }
84
- }
85
-
86
- //Check that every item required is found in the units inventory satisfies the quantity requirement for the recipe
87
- const satisfiesRecipe =
88
- requiredItems.every((reqItemData) => {
89
- const matching = matchingItems?.find((matchingItemData) => matchingItemData.itemTypeId === reqItemData.itemTypeId);
90
-
91
- if (matching) {
92
- return matching.quantity >= reqItemData.quantity;
93
- }
94
-
95
- return false;
96
- }) && matchingItems.length > 0;
97
-
98
- if (!itemToCreateId) {
99
- print("Missing the item type id of the item to create for this recipe: ", recipeItem.name);
100
- }
101
-
102
- //destroys more items than it needds to
103
- if (satisfiesRecipe && itemToCreateId) {
104
- //add the item
105
- requiredItems.forEach((req: RecipeItemRequirement) => {
106
- for (let x = 0; x < req.quantity; x++) {
107
- for (let x = 0; x < 6; x++) {
108
- const currItem = unit?.getItemInSlot(x);
109
- if (currItem?.typeId === req.itemTypeId) {
110
- currItem?.destroy();
111
- break;
112
- }
113
- }
114
- }
115
- });
116
-
117
- recipeItem.destroy();
118
-
119
- unit.addItemById(itemToCreateId);
120
-
121
- useTempEffect(Effect.create("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", unit.x, unit.y));
122
- const clap = Effect.create("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl", unit.x, unit.y);
123
- clap?.setScaleMatrix(0.5, 0.5, 0.5);
124
- useTempEffect(clap);
125
- }
126
-
127
- if (!satisfiesRecipe) {
128
- //refund the gold
129
- notifyPlayer(`Missing recipe requirements for: ${recipeItem.name}.`);
130
- }
131
-
132
- //use if or rf to store item gold cost in the world editor
133
- }
134
- }
135
-
136
- interface RecipeItemRequirement {
137
- itemTypeId: number; //ITEMS;
138
- quantity: number;
139
- charges: number;
140
- }
141
-
142
- interface RecipeItem {
143
- recipeId: number;
144
- itemId: number;
145
- }
146
-
147
- const itemRecipesMap = new Map<RecipeItem, RecipeItemRequirement[]>([
148
- // [
149
- // { recipeId: ITEMS.recipe_blinkTreads, itemId: ITEMS.blinkTreads },
150
- // [
151
- // { itemTypeId: ITEMS.bootsOfSpeed, quantity: 1, charges: 0 }, //
152
- // { itemTypeId: ITEMS.blinkDagger, quantity: 1, charges: 0 }, //
153
- // ],
154
- // ],
155
- ]);