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)
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 62f7007392e88829951855f9bd5eab3e7a5552aa - fix: add user force singleton
Remove code duplication related to accessing user force (collection of
presently playing live human players), without sacrificing correctness.

Player force is a mutable collection. This caused concernes of
correctness at runtime. Add a function that unifies all access to the
collection.
Author: Vladyslav Bondarenko
Author date (UTC): 2023-12-17 13:02
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2023-12-17 13:02
Parent(s): d8caf093082f02efc919b01cc7bfddd9193d0531
Signer:
Signing key: EFF9624877D25D02
Signing status: E
Tree: f4cb8709e50658f4ef940d3a1b8ae37e88e5d7b8
File Lines added Lines deleted
src/altar.j 1 1
src/defeat.j 5 35
src/user.j 28 11
src/victory.j 3 37
File src/altar.j changed (mode: 100644) (index 757133b..7724912)
... ... function altar_structure_init takes nothing returns nothing
119 119 loop loop
120 120 exitwhen i >= bj_MAX_PLAYERS exitwhen i >= bj_MAX_PLAYERS
121 121 set p = Player(i) set p = Player(i)
122 if MAP_CONTROL_USER == GetPlayerController(p) and PLAYER_SLOT_STATE_EMPTY != GetPlayerSlotState(p) then
122 if user_player_is_user_check(p) then
123 123 set altar = altar_player_structure_init(p) set altar = altar_player_structure_init(p)
124 124 if altar != null and train_trig != null then if altar != null and train_trig != null then
125 125 call TriggerRegisterUnitEvent(train_trig, altar, EVENT_UNIT_TRAIN_START) call TriggerRegisterUnitEvent(train_trig, altar, EVENT_UNIT_TRAIN_START)
File src/defeat.j changed (mode: 100644) (index cbe6b62..c037222)
1 1 // src/defeat.j // src/defeat.j
2 // requires src/user.j
2 3 // requires src/revive.j // requires src/revive.j
3 4
4 5 globals globals
 
... ... endglobals
9 10
10 11 // src/defeat.j functions // src/defeat.j functions
11 12
12 function defeat_player_user_check takes player p returns boolean
13 local boolean flag = false
14 if null == p then
15 return false
16 endif
17 set flag = MAP_CONTROL_USER == GetPlayerController(p)
18 set flag = PLAYER_SLOT_STATE_EMPTY != GetPlayerSlotState(p) and flag
19 set flag = not IsPlayerObserver(p) and flag
20 return flag
21 endfunction
22
23 function defeat_user_force_filter takes nothing returns boolean
24 return defeat_player_user_check(GetFilterPlayer())
25 endfunction
26
27 13 function defeat_trig_filter takes nothing returns boolean function defeat_trig_filter takes nothing returns boolean
28 14 local unit u = GetFilterUnit() local unit u = GetFilterUnit()
29 15 local player p = null local player p = null
 
... ... function defeat_trig_filter takes nothing returns boolean
36 22 set flag = IsHeroUnitId(GetUnitTypeId(u)) and flag set flag = IsHeroUnitId(GetUnitTypeId(u)) and flag
37 23 set flag = IsUnitType(u, UNIT_TYPE_HERO) and flag set flag = IsUnitType(u, UNIT_TYPE_HERO) and flag
38 24 set p = GetOwningPlayer(u) set p = GetOwningPlayer(u)
39 set flag = defeat_player_user_check(p) and flag
25 set flag = user_player_is_user_check(p) and flag
40 26 return flag return flag
41 27 endfunction endfunction
42 28
 
... ... function defeat_check takes nothing returns boolean
60 46 loop loop
61 47 exitwhen i >= bj_MAX_PLAYERS exitwhen i >= bj_MAX_PLAYERS
62 48 set p = Player(i) set p = Player(i)
63 if defeat_player_user_check(p) then
49 if user_player_is_user_check(p) then
64 50 set y = y + 1 set y = y + 1
65 51 set q = GetPlayerUnitCount(p, true) + q set q = GetPlayerUnitCount(p, true) + q
66 52 set g = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) + g set g = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) + g
 
... ... function defeat_check takes nothing returns boolean
71 57 return y > 0 and 0 == q and g < revive_price_min return y > 0 and 0 == q and g < revive_price_min
72 58 endfunction endfunction
73 59
74 function defeat_user_enum takes force f returns force
75 local filterfunc filter = null
76
77 set filter = Filter(function defeat_user_force_filter)
78 call ForceEnumPlayers(f, filter)
79
80 call DestroyFilter(filter)
81
82 return f
83 endfunction
84
85 60 function defeat_dialog_force_callback takes nothing returns nothing function defeat_dialog_force_callback takes nothing returns nothing
86 61 local player p = GetEnumPlayer() local player p = GetEnumPlayer()
87 62 local string fluff = "All heroes are dead and cannot afford to revive." local string fluff = "All heroes are dead and cannot afford to revive."
 
... ... endfunction
90 65
91 66 // Force defeat dialog on all users. // Force defeat dialog on all users.
92 67 function defeat_dialog takes nothing returns nothing function defeat_dialog takes nothing returns nothing
93 local force f = CreateForce()
94 call defeat_user_enum(f)
68 local force f = user_force_get()
95 69 call ForForce(f, function defeat_dialog_force_callback) call ForForce(f, function defeat_dialog_force_callback)
96 call DestroyForce(f)
97 70 endfunction endfunction
98 71
99 72 function defeat_timer_callback takes nothing returns nothing function defeat_timer_callback takes nothing returns nothing
 
... ... endfunction
108 81 // Show defeat message to all users. // Show defeat message to all users.
109 82 function defeat_quest_msg takes nothing returns nothing function defeat_quest_msg takes nothing returns nothing
110 83 local string fluff = null local string fluff = null
111 local force f = CreateForce()
112 call defeat_user_enum(f)
84 local force f = user_force_get()
113 85
114 86 set fluff = "|cffffcc00MISSION FAILED|r\n" set fluff = "|cffffcc00MISSION FAILED|r\n"
115 87 set fluff = fluff + "All heroes are dead and cannot afford to revive" set fluff = fluff + "All heroes are dead and cannot afford to revive"
116 88 call QuestMessageBJ(f, bj_QUESTMESSAGE_MISSIONFAILED, fluff) call QuestMessageBJ(f, bj_QUESTMESSAGE_MISSIONFAILED, fluff)
117
118 call DestroyForce(f)
119 89 endfunction endfunction
120 90
121 91 // End the game with defeat for all users. // End the game with defeat for all users.
File src/user.j changed (mode: 100644) (index ae3c804..cf1f44e)
... ... globals
3 3 // src/user.j fields // src/user.j fields
4 4 // Unit groups or player forces are mutable collections. // Unit groups or player forces are mutable collections.
5 5 // They may never be effectively constant. // They may never be effectively constant.
6 force USER_FORCE = null
6 7 endglobals endglobals
7 8
8 9 // src/user.j functions // src/user.j functions
 
... ... function user_force_filter takes nothing returns boolean
24 25 return user_player_is_user_check(p) return user_player_is_user_check(p)
25 26 endfunction endfunction
26 27
28 function user_force_enum takes force user_force returns force
29 local filterfunc filter = null
30 if null == user_force then
31 return null
32 endif
33 set filter = Filter(function user_force_filter)
34 call ForceEnumPlayers(user_force, filter)
35 call DestroyFilter(filter)
36 return user_force
37 endfunction
38
39 function user_force_get takes nothing returns force
40 local force f = null
41
42 if null == USER_FORCE then
43 set USER_FORCE = CreateForce()
44 endif
45
46 set f = USER_FORCE
47 call ForceClear(f)
48 call user_force_enum(f)
49 if null == f then
50 call BJDebugMsg("src/user.j: invalid state: force object missing")
51 endif
52 return f
53 endfunction
54
27 55 function user_init_player takes player p returns nothing function user_init_player takes player p returns nothing
28 56 local location loc = null local location loc = null
29 57 local integer start = 0 local integer start = 0
 
... ... function user_init_player_callback takes nothing returns nothing
44 72 call user_init_player(p) call user_init_player(p)
45 73 endfunction endfunction
46 74
47 function user_force_enum takes force user_force returns force
48 local filterfunc filter = null
49 if null == user_force then
50 return null
51 endif
52 set filter = Filter(function user_force_filter)
53 call ForceEnumPlayers(user_force, filter)
54 call DestroyFilter(filter)
55 return user_force
56 endfunction
57
58 75 // Blizzard.j:function CountPlayersInForceBJ serves the same purpose. // Blizzard.j:function CountPlayersInForceBJ serves the same purpose.
59 76 // The benefit of this alternative implementation is that is avoids mutable global variables. // The benefit of this alternative implementation is that is avoids mutable global variables.
60 77 function user_force_count takes force anyforce returns integer function user_force_count takes force anyforce returns integer
File src/victory.j changed (mode: 100644) (index 44f5e8b..88c9489)
... ... endglobals
8 8
9 9 // src/victory.j functions // src/victory.j functions
10 10
11 function victory_force_filter takes nothing returns boolean
12 local player p = GetFilterPlayer()
13 local boolean flag = true
14 if null == p then
15 return false
16 endif
17 set flag = MAP_CONTROL_USER == GetPlayerController(p) and flag
18 set flag = PLAYER_SLOT_STATE_EMPTY != GetPlayerSlotState(p) and flag
19 set flag = not IsPlayerObserver(p) and flag
20 return flag
21 endfunction
22
23 function victory_user_force_enum takes force f returns force
24 local filterfunc filter = null
25
26 if null == f then
27 return null
28 endif
29
30 set filter = Filter(function victory_force_filter)
31 call ForceEnumPlayers(f, filter)
32 call DestroyFilter(filter)
33
34 return f
35 endfunction
36
37 11 function victory_player takes player p returns nothing function victory_player takes player p returns nothing
38 12 if null == p then if null == p then
39 13 return return
 
... ... function victory_quest_complete_timer_callback takes nothing returns nothing
53 27 set t = GetExpiredTimer() set t = GetExpiredTimer()
54 28 call DestroyTimer(t) call DestroyTimer(t)
55 29
56 set f = CreateForce()
57 call victory_user_force_enum(f)
30 set f = user_force_get()
58 31 call ForForce(f, function victory_force_callback) call ForForce(f, function victory_force_callback)
59
60 call DestroyForce(f)
61 32 endfunction endfunction
62 33
63 34 function victory_quest_complete_msg takes nothing returns nothing function victory_quest_complete_msg takes nothing returns nothing
64 35 local force f = null local force f = null
65 36
66 set f = CreateForce()
67 call victory_user_force_enum(f)
37 set f = user_force_get()
68 38
69 39 call QuestMessageBJ(f, bj_QUESTMESSAGE_COMPLETED, "|cffffcc00MAIN QUEST COMPLETED|r\nDemon") call QuestMessageBJ(f, bj_QUESTMESSAGE_COMPLETED, "|cffffcc00MAIN QUEST COMPLETED|r\nDemon")
70
71 call DestroyForce(f)
72 40 endfunction endfunction
73 41
74 42 function victory takes nothing returns nothing function victory takes nothing returns nothing
 
... ... function victory_quest_discover_msg takes nothing returns nothing
92 60 local force f = null local force f = null
93 61 local string fluff = null local string fluff = null
94 62
95 set f = CreateForce()
96 call victory_user_force_enum(f)
63 set f = user_force_get()
97 64
98 65 set fluff = "|cffffcc00MAIN QUEST|r\nDemon\n- defeat demon villain" set fluff = "|cffffcc00MAIN QUEST|r\nDemon\n- defeat demon villain"
99 66 call QuestMessageBJ(f, bj_QUESTMESSAGE_DISCOVERED, fluff) call QuestMessageBJ(f, bj_QUESTMESSAGE_DISCOVERED, fluff)
100 call DestroyForce(f)
101 67 endfunction endfunction
102 68
103 69 function victory_quest_discover_timer_callback takes nothing returns nothing function victory_quest_discover_timer_callback takes nothing returns nothing
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