vrtc / honeydew (public) (License: CC0) (since 2023-12-20) (hash sha1)
Warcraft 3: The Frozen Throne 1.27 custom scenario.
List of commits:
Subject Hash Author Date (UTC)
feat: add arcane blast spell 1c2e8853a32b2c35ffdb1ea9d2342ff9bd9b8669 Vladyslav Bondarenko 2023-12-19 13:07:09
fix: unique hero per player c7910812bf1957513aab9067e817ca57634d4834 Vladyslav Bondarenko 2023-12-19 13:05:50
feat: heroes do not require resources to hire 717364a931afcde3496058a3f6100d95c92f7fe7 Vladyslav Bondarenko 2023-12-18 15:47:54
fix: add user force singleton 62f7007392e88829951855f9bd5eab3e7a5552aa Vladyslav Bondarenko 2023-12-17 13:02:08
doc: update design notes to self d8caf093082f02efc919b01cc7bfddd9193d0531 Vladyslav Bondarenko 2023-12-17 12:35:50
feat: add victory script 8d0299b42a3e61ffee708395017967dc288ed1b8 Vladyslav Bondarenko 2023-12-17 12:28:18
feat: summon any hero instantly b3657cf44de4558f3e6a2eac5d7916a036aa3dad Vladyslav Bondarenko 2023-12-16 04:19:10
fix: remove debug trace 7022f33a403d9d37f3f84acda98501ca76e1f981 Vladyslav Bondarenko 2023-12-16 04:18:53
feat: add hero selection 230e7f365c3b564c39edeb7a5d76ceb343234da1 Vladyslav Bondarenko 2023-12-14 16:26:23
build: Use git-archive to package bundles 666f7110532eba52212a35290a9e194170a00bc7 Vladyslav Bondarenko 2023-12-14 12:11:09
feat!: build skeleton project da405d9978fcb6c8414249ceda4e07848e34f62a Vladyslav Bondarenko 2023-12-14 11:59:17
Commit 1c2e8853a32b2c35ffdb1ea9d2342ff9bd9b8669 - feat: add arcane blast spell
Author: Vladyslav Bondarenko
Author date (UTC): 2023-12-19 13:07
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2023-12-19 13:07
Parent(s): c7910812bf1957513aab9067e817ca57634d4834
Signer:
Signing key: EFF9624877D25D02
Signing status: E
Tree: 8da3f5455258fe90d59359f6f0534f6f22411437
File Lines added Lines deleted
Makefile 2 0
honeydew-0_0WIP-1_27-en.w3x 0 0
src/abla.j 200 0
src/main.j 4 0
src/spell.j 28 0
src/war3map.m4 2 0
File Makefile changed (mode: 100644) (index 3f33a7b..309475f)
... ... NAMEFULL=$(NAME)-$(VERSION)-$(CLASSIFIER)-$(LANG)
9 9 PJASS_OPTS=etc/common.j etc/Blizzard.j -rb +filter +shadow +checkglobalsinit +checkstringhash PJASS_OPTS=etc/common.j etc/Blizzard.j -rb +filter +shadow +checkglobalsinit +checkstringhash
10 10
11 11 SNIPPETS= \ SNIPPETS= \
12 src/spell.j \
13 src/abla.j \
12 14 src/user.j \ src/user.j \
13 15 src/altar.j \ src/altar.j \
14 16 src/revive.j \ src/revive.j \
File honeydew-0_0WIP-1_27-en.w3x changed (mode: 100644) (index 104a4df..faa72cd)
File src/abla.j added (mode: 100644) (index 0000000..64a83d8)
1 // src/abla.j
2 // requires src/spell.j
3
4 // Spell Arcane blast.
5 // Deal damage to units in target area.
6 // Given unit that is immune to magic, heal the unit instead.
7 // This spell may heal enemies.
8 // This spell may harm allies.
9
10 globals
11
12 // src/abla.j fields
13
14 constant integer ABLA_ABILITY_ID = 'A000'
15
16 constant integer ABLA_GROUP_LIMIT = 12
17 constant real ABLA_AREA_MAX = 8192.0
18 constant real ABLA_AREA_MIN = 64.0
19 constant real ABLA_DAMAGE_AMOUNT_MAX = 100000.0
20 constant real ABLA_DAMAGE_AMOUNT_MIN = 0.0
21 constant real ABLA_HEAL_AMOUNT_MAX = 100000.0
22 constant real ABLA_HEAL_AMOUNT_MIN = 0.0
23 integer abla_super_abilityid = 0
24 real abla_super_damage = 0.0
25 real abla_super_heal = 0.0
26 unit abla_super_caster = null
27 endglobals
28
29 // src/abla.j functions
30
31 function abla_harm_check takes unit u returns boolean
32 local boolean flag = true
33 //local player p = null
34
35 if null == u then
36 return false
37 endif
38
39 set flag = not IsUnitType(u, UNIT_TYPE_DEAD) and flag
40 set flag = GetUnitState(u, UNIT_STATE_LIFE) > 0 and flag
41 set flag = not IsUnitType(u, UNIT_TYPE_STRUCTURE) and flag
42 set flag = not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and flag
43 // TODO Consider making Arcane Blast to never harm allies, but allow it to heal enemies.
44 //set p = GetOwningPlayer(abla_super_caster)
45 //set flag = IsUnitEnemy(u, p) and flag
46
47 return flag
48 endfunction
49
50 function abla_heal_check takes unit u returns boolean
51 local boolean flag = true
52
53 if null == u then
54 return false
55 endif
56
57 set flag = not IsUnitType(u, UNIT_TYPE_DEAD) and flag
58 set flag = GetUnitState(u, UNIT_STATE_LIFE) > 0 and flag
59 set flag = not IsUnitType(u, UNIT_TYPE_STRUCTURE) and flag
60 set flag = IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and flag
61
62 return flag
63 endfunction
64
65 function abla_harm_group_filter takes nothing returns boolean
66 local unit u = GetFilterUnit()
67 return abla_harm_check(u) and not abla_heal_check(u)
68 endfunction
69
70 function abla_heal_group_filter takes nothing returns boolean
71 local unit u = GetFilterUnit()
72 return abla_heal_check(u) and not abla_harm_check(u)
73 endfunction
74
75 function abla_harm_group_callback takes nothing returns nothing
76 local integer abilityid = 0
77 local unit caster = null
78 local unit u = null
79 local real damage = 0.0
80 local boolean attack = true
81 local boolean ranged = true
82 local effect e = null
83
84 set u = GetEnumUnit()
85 if null == u then
86 return
87 endif
88
89 set caster = abla_super_caster
90 set damage = RMinBJ(RMaxBJ(ABLA_DAMAGE_AMOUNT_MIN, abla_super_damage), ABLA_DAMAGE_AMOUNT_MAX)
91
92 call UnitDamageTarget(caster, u, damage, attack, ranged, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
93
94 set abilityid = abla_super_abilityid
95 set e = AddSpellEffectTargetById(abilityid, EFFECT_TYPE_TARGET, u, "origin")
96 call DestroyEffect(e)
97 endfunction
98
99 function abla_heal_group_callback takes nothing returns nothing
100 local unit caster = null
101 local unit u = null
102 local real heal = 0.0
103 local real a = 0.0
104 local real b = 0.0
105 local effect e = null
106
107 set u = GetEnumUnit()
108 if null == u then
109 return
110 endif
111
112 set heal = RMinBJ(RMaxBJ(ABLA_HEAL_AMOUNT_MIN, abla_super_heal), ABLA_HEAL_AMOUNT_MAX)
113 set a = GetUnitState(u, UNIT_STATE_LIFE)
114 call SetUnitState(u, UNIT_STATE_LIFE, a + heal)
115 set b = GetUnitState(u, UNIT_STATE_LIFE)
116
117 // Only show healing graphics when the amount of health effectively changed.
118 if b > a then
119 set e = AddSpellEffectTargetById('AIhx', EFFECT_TYPE_TARGET, u, "origin")
120 call DestroyEffect(e)
121 endif
122 endfunction
123
124 function abla_apply takes integer abilityid, unit caster, location destination, real area, real damage, real healing returns nothing
125 local group g = null
126 local real radius = 0.0
127 local filterfunc filter = null
128 local integer limit = 1
129 local effect e = null
130
131 if null == destination then
132 return
133 endif
134
135 set area = RMinBJ(RMaxBJ(ABLA_AREA_MIN, area), ABLA_AREA_MAX)
136 set radius = area * 0.5
137 set damage = RMinBJ(RMaxBJ(ABLA_DAMAGE_AMOUNT_MIN, damage), ABLA_DAMAGE_AMOUNT_MAX)
138 set healing = RMinBJ(RMaxBJ(ABLA_HEAL_AMOUNT_MIN, healing), ABLA_HEAL_AMOUNT_MAX)
139 set limit = ABLA_GROUP_LIMIT
140
141 // Implicit arguments (upvalues) for group callbacks.
142 set abla_super_abilityid = abilityid
143 set abla_super_caster = caster
144 set abla_super_damage = damage
145 set abla_super_heal = healing
146
147 set g = CreateGroup()
148
149 call GroupClear(g)
150 set filter = Filter(function abla_harm_group_filter)
151 call GroupEnumUnitsInRangeOfLocCounted(g, destination, radius, filter, limit)
152 call ForGroup(g, function abla_harm_group_callback)
153 call DestroyFilter(filter)
154
155 call GroupClear(g)
156 set filter = Filter(function abla_heal_group_filter)
157 call GroupEnumUnitsInRangeOfLocCounted(g, destination, radius, filter, limit)
158 call ForGroup(g, function abla_heal_group_callback)
159 call DestroyFilter(filter)
160
161 set abla_super_abilityid = 0
162 set abla_super_caster = null
163 set abla_super_damage = 0.0
164 set abla_super_heal = 0.0
165 call DestroyGroup(g)
166
167 set e = AddSpellEffectByIdLoc(abilityid, EFFECT_TYPE_SPECIAL, destination)
168 call DestroyEffect(e)
169 endfunction
170
171 function abla_trig_filter takes nothing returns boolean
172 return ABLA_ABILITY_ID == GetSpellAbilityId()
173 endfunction
174
175 function abla_trig_action takes nothing returns nothing
176 local integer abilityid = 0
177 local unit caster = null
178 local location destination = null
179 local real area = 0.0
180 local real damage = 0.0
181 local real healing = 0.0
182 local integer level = 0
183
184 set abilityid = GetSpellAbilityId()
185 set caster = GetSpellAbilityUnit()
186 set level = GetUnitAbilityLevel(caster, abilityid)
187 set destination = GetSpellTargetLoc()
188 set area = 512.0
189 set damage = 50.0 + 50 * level
190 set healing = 50.0 * level
191
192 call abla_apply(abilityid, caster, destination, area, damage, healing)
193
194 call RemoveLocation(destination)
195 endfunction
196
197 function abla_init takes nothing returns nothing
198 local conditionfunc filter = Condition(function abla_trig_filter)
199 call spell_trig_init(filter, function abla_trig_action)
200 endfunction
File src/main.j changed (mode: 100644) (index d5acb96..c288f2f)
... ... endfunction
30 30
31 31 function init takes nothing returns nothing function init takes nothing returns nothing
32 32 local unit demon = null local unit demon = null
33
34 // Spells
35 call abla_init()
36
33 37 call user_init() call user_init()
34 38 set demon = init_demon(PLAYER_DEMON) set demon = init_demon(PLAYER_DEMON)
35 39 call herotoken_init() call herotoken_init()
File src/spell.j added (mode: 100644) (index 0000000..45d83b6)
1 // Filter checks ability id or maybe caster.
2 function spell_trig_init takes conditionfunc filter, code action returns trigger
3 local trigger t = null
4 local player p = null
5 local integer i = 0
6
7 if null == action then
8 return null
9 endif
10
11 set t = CreateTrigger()
12 set i = 0
13 loop
14 // bj_MAX_PLAYERS is max amount of users.
15 // bj_MAX_PLAYER_SLOTS is max amount players, including neutral utility presets.
16 exitwhen i >= bj_MAX_PLAYER_SLOTS
17 set p = Player(i)
18 call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
19 set i = i + 1
20 endloop
21
22 if filter != null then
23 call TriggerAddCondition(t, filter)
24 endif
25 call TriggerAddAction(t, action)
26
27 return t
28 endfunction
File src/war3map.m4 changed (mode: 100644) (index a58fd75..8f35e87)
... ... define(endglobals, `divert(0)divert(2)')dnl
3 3 divert(2)dnl divert(2)dnl
4 4 dnl # WARNING: included files must never contain the tilde glyph, dnl # WARNING: included files must never contain the tilde glyph,
5 5 dnl # otherwise this m4 script produces malformed *.j snippet dnl # otherwise this m4 script produces malformed *.j snippet
6 include(`src/spell.j')dnl
7 include(`src/abla.j')dnl
6 8 include(`src/user.j')dnl include(`src/user.j')dnl
7 9 include(`src/herotoken.j')dnl include(`src/herotoken.j')dnl
8 10 include(`src/altar.j')dnl include(`src/altar.j')dnl
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/vrtc/honeydew

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/vrtc/honeydew

Clone this repository using git:
git clone git://git.rocketgit.com/user/vrtc/honeydew

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main