File src/altar.j added (mode: 100644) (index 0000000..353d984) |
|
1 |
|
// src/altar.j |
|
2 |
|
// requires src/user.j |
|
3 |
|
globals |
|
4 |
|
// src/altar.j fields |
|
5 |
|
unit array altar_player_structure |
|
6 |
|
endglobals |
|
7 |
|
|
|
8 |
|
// src/altar.j functions |
|
9 |
|
|
|
10 |
|
function altar_player_altar_type_get takes player p returns integer |
|
11 |
|
return 'halt' |
|
12 |
|
endfunction |
|
13 |
|
|
|
14 |
|
function altar_player_altar_unit_get takes player p returns unit |
|
15 |
|
if null == p then |
|
16 |
|
return null |
|
17 |
|
endif |
|
18 |
|
|
|
19 |
|
return altar_player_structure[GetPlayerId(p)] |
|
20 |
|
endfunction |
|
21 |
|
|
|
22 |
|
function altar_player_structure_init takes player p returns unit |
|
23 |
|
local unit u = null |
|
24 |
|
local integer utype = 0 |
|
25 |
|
local location loc = null |
|
26 |
|
|
|
27 |
|
if null == p then |
|
28 |
|
return null |
|
29 |
|
endif |
|
30 |
|
|
|
31 |
|
set u = altar_player_structure[GetPlayerId(p)] |
|
32 |
|
|
|
33 |
|
if u != null then |
|
34 |
|
return u |
|
35 |
|
endif |
|
36 |
|
|
|
37 |
|
set utype = altar_player_altar_type_get(p) |
|
38 |
|
set loc = GetStartLocationLoc(GetPlayerStartLocation(p)) |
|
39 |
|
set u = CreateUnitAtLoc(p, utype, loc, bj_UNIT_FACING) |
|
40 |
|
|
|
41 |
|
call SetUnitInvulnerable(u, true) |
|
42 |
|
|
|
43 |
|
if p == GetLocalPlayer() then |
|
44 |
|
call ClearSelection() |
|
45 |
|
call SelectUnit(u, true) |
|
46 |
|
endif |
|
47 |
|
|
|
48 |
|
call RemoveLocation(loc) |
|
49 |
|
|
|
50 |
|
set altar_player_structure[GetPlayerId(p)] = u |
|
51 |
|
|
|
52 |
|
return u |
|
53 |
|
endfunction |
|
54 |
|
|
|
55 |
|
function altar_user_force_callback takes nothing returns nothing |
|
56 |
|
local player p = GetEnumPlayer() |
|
57 |
|
|
|
58 |
|
call altar_player_structure_init(p) |
|
59 |
|
endfunction |
|
60 |
|
|
|
61 |
|
function altar_structure_init takes nothing returns nothing |
|
62 |
|
local force user_force = null |
|
63 |
|
|
|
64 |
|
set user_force = CreateForce() |
|
65 |
|
call user_force_enum(user_force) |
|
66 |
|
|
|
67 |
|
call ForForce(user_force, function altar_user_force_callback) |
|
68 |
|
|
|
69 |
|
call DestroyForce(user_force) |
|
70 |
|
endfunction |
|
71 |
|
|
|
72 |
|
function altar_init takes nothing returns nothing |
|
73 |
|
call altar_structure_init() |
|
74 |
|
endfunction |
File src/config.j changed (mode: 100644) (index 3339546..d10fc70) |
|
1 |
|
// src/config.j |
|
2 |
|
|
1 |
3 |
globals |
globals |
|
4 |
|
|
|
5 |
|
// src/config.j fields |
|
6 |
|
|
2 |
7 |
constant integer TEAM_ENEMY = 1 |
constant integer TEAM_ENEMY = 1 |
3 |
8 |
constant integer TEAM_USER = 0 |
constant integer TEAM_USER = 0 |
4 |
9 |
constant integer USER_QUANTITY_MAX = 3 |
constant integer USER_QUANTITY_MAX = 3 |
5 |
|
constant player PLAYER_DEMON = Player(3) |
|
6 |
|
constant player USER0 = Player(0) |
|
7 |
|
constant player USER1 = Player(1) |
|
8 |
|
constant player USER2 = Player(2) |
|
9 |
10 |
endglobals |
endglobals |
10 |
11 |
|
|
|
12 |
|
// src/config.j functions |
|
13 |
|
|
11 |
14 |
function config_slot_user takes integer n returns nothing |
function config_slot_user takes integer n returns nothing |
12 |
15 |
local integer i = 0 |
local integer i = 0 |
13 |
16 |
local player p = null |
local player p = null |
|
... |
... |
function config_slot_user takes integer n returns nothing |
21 |
24 |
|
|
22 |
25 |
call SetPlayerStartLocation(p, n) |
call SetPlayerStartLocation(p, n) |
23 |
26 |
call SetPlayerColor(p, ConvertPlayerColor(n)) |
call SetPlayerColor(p, ConvertPlayerColor(n)) |
24 |
|
call SetPlayerRacePreference(p, RACE_PREF_HUMAN) |
|
|
27 |
|
call SetPlayerRacePreference(p, RACE_PREF_RANDOM) |
25 |
28 |
call SetPlayerRaceSelectable(p, true) |
call SetPlayerRaceSelectable(p, true) |
26 |
29 |
call SetPlayerController(p, MAP_CONTROL_USER) |
call SetPlayerController(p, MAP_CONTROL_USER) |
27 |
30 |
call SetPlayerTeam(p, TEAM_USER) |
call SetPlayerTeam(p, TEAM_USER) |
|
... |
... |
function config_slot_computer takes integer n returns nothing |
52 |
55 |
set p = Player(n) |
set p = Player(n) |
53 |
56 |
|
|
54 |
57 |
call SetPlayerStartLocation(p, n) |
call SetPlayerStartLocation(p, n) |
|
58 |
|
call ForcePlayerStartLocation(p, n) |
55 |
59 |
call SetPlayerColor(p, PLAYER_COLOR_BLUE) |
call SetPlayerColor(p, PLAYER_COLOR_BLUE) |
56 |
60 |
call SetPlayerRacePreference(p, RACE_PREF_UNDEAD) |
call SetPlayerRacePreference(p, RACE_PREF_UNDEAD) |
57 |
61 |
call SetPlayerRaceSelectable(p, false) |
call SetPlayerRaceSelectable(p, false) |
58 |
62 |
call SetPlayerController(p, MAP_CONTROL_COMPUTER) |
call SetPlayerController(p, MAP_CONTROL_COMPUTER) |
59 |
63 |
call SetPlayerTeam(p, TEAM_ENEMY) |
call SetPlayerTeam(p, TEAM_ENEMY) |
|
64 |
|
call SetPlayerName(p, "Demon") |
|
65 |
|
call SetPlayerOnScoreScreen(p, true) |
60 |
66 |
endfunction |
endfunction |
61 |
67 |
|
|
62 |
68 |
function config_every_start takes nothing returns nothing |
function config_every_start takes nothing returns nothing |
|
... |
... |
function config_every_start takes nothing returns nothing |
72 |
78 |
loop |
loop |
73 |
79 |
exitwhen i >= USER_QUANTITY_MAX |
exitwhen i >= USER_QUANTITY_MAX |
74 |
80 |
set x = GetLocationX(origin_loc) + 128.0 * (i + 1) |
set x = GetLocationX(origin_loc) + 128.0 * (i + 1) |
75 |
|
set y = GetLocationY(origin_loc) - 128.0 |
|
|
81 |
|
set y = GetLocationY(origin_loc) - 512.0 * 4.0 |
76 |
82 |
set loc = Location(x, y) |
set loc = Location(x, y) |
77 |
83 |
call DefineStartLocationLoc(i, loc) |
call DefineStartLocationLoc(i, loc) |
78 |
84 |
call RemoveLocation(loc) |
call RemoveLocation(loc) |
79 |
85 |
set i = i + 1 |
set i = i + 1 |
80 |
86 |
endloop |
endloop |
81 |
87 |
|
|
|
88 |
|
set x = GetLocationX(origin_loc) |
|
89 |
|
set y = GetLocationY(origin_loc) + 512.0 * 4.0 |
|
90 |
|
set loc = Location(x, y) |
82 |
91 |
call DefineStartLocationLoc(3, origin_loc) |
call DefineStartLocationLoc(3, origin_loc) |
|
92 |
|
call RemoveLocation(loc) |
83 |
93 |
|
|
84 |
94 |
call RemoveLocation(origin_loc) |
call RemoveLocation(origin_loc) |
85 |
95 |
endfunction |
endfunction |
|
... |
... |
endfunction |
99 |
109 |
function config takes nothing returns nothing |
function config takes nothing returns nothing |
100 |
110 |
call SetMapName( "TRIGSTR_001" ) |
call SetMapName( "TRIGSTR_001" ) |
101 |
111 |
call SetMapDescription( "TRIGSTR_003" ) |
call SetMapDescription( "TRIGSTR_003" ) |
102 |
|
call SetTeams(1) |
|
103 |
|
call SetPlayers(USER_QUANTITY_MAX) |
|
104 |
|
call SetGamePlacement(MAP_PLACEMENT_USE_MAP_SETTINGS) |
|
|
112 |
|
call SetTeams(2) |
|
113 |
|
call SetPlayers(USER_QUANTITY_MAX + 1) |
|
114 |
|
call SetGamePlacement(MAP_PLACEMENT_TEAMS_TOGETHER) |
105 |
115 |
|
|
106 |
116 |
call SetGameTypeSupported(GAME_TYPE_USE_MAP_SETTINGS, true) |
call SetGameTypeSupported(GAME_TYPE_USE_MAP_SETTINGS, true) |
107 |
117 |
|
|
File src/defeat.j added (mode: 100644) (index 0000000..aca3219) |
|
1 |
|
// src/defeat.j |
|
2 |
|
// requres src/revive.j |
|
3 |
|
|
|
4 |
|
globals |
|
5 |
|
|
|
6 |
|
// src/defeat.j fields |
|
7 |
|
|
|
8 |
|
|
|
9 |
|
endglobals |
|
10 |
|
|
|
11 |
|
// src/defeat.j functions |
|
12 |
|
|
|
13 |
|
function defeat_trig_filter takes nothing returns boolean |
|
14 |
|
local unit u = GetFilterUnit() |
|
15 |
|
local player p = null |
|
16 |
|
local boolean flag = true |
|
17 |
|
|
|
18 |
|
if null == u then |
|
19 |
|
return false |
|
20 |
|
endif |
|
21 |
|
|
|
22 |
|
set flag = IsHeroUnitId(GetUnitTypeId(u)) and flag |
|
23 |
|
set flag = IsUnitType(u, UNIT_TYPE_HERO) and flag |
|
24 |
|
set p = GetOwningPlayer(u) |
|
25 |
|
set flag = (MAP_CONTROL_USER == GetPlayerController(p) or PLAYER_SLOT_STATE_LEFT == GetPlayerSlotState(p)) and flag |
|
26 |
|
return flag |
|
27 |
|
endfunction |
|
28 |
|
|
|
29 |
|
// Users are considered defeated when there are no units left alive, |
|
30 |
|
// and no gold left to revive dead heroes, |
|
31 |
|
// and no revivals are ongoing, across all user force. |
|
32 |
|
function defeat_check takes nothing returns boolean |
|
33 |
|
local integer revive_price_min = 170 |
|
34 |
|
local integer q = 0 |
|
35 |
|
local integer i = 0 |
|
36 |
|
local integer g = 0 |
|
37 |
|
local player p = null |
|
38 |
|
local integer y = 0 |
|
39 |
|
|
|
40 |
|
if revive_ongoing_check() then |
|
41 |
|
return false |
|
42 |
|
endif |
|
43 |
|
|
|
44 |
|
set i = 0 |
|
45 |
|
loop |
|
46 |
|
exitwhen i >= bj_MAX_PLAYERS |
|
47 |
|
set p = Player(i) |
|
48 |
|
if MAP_CONTROL_USER == GetPlayerController(p) and PLAYER_SLOT_STATE_EMPTY != GetPlayerSlotState(p) then |
|
49 |
|
set y = y + 1 |
|
50 |
|
set q = GetPlayerUnitCount(p, true) + q |
|
51 |
|
set g = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) + g |
|
52 |
|
call BJDebugMsg("i:" + I2S(i) + "q:" + I2S(GetPlayerTechCount(p, 'HERO', false)) + "g:" + I2S(GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD))) |
|
53 |
|
endif |
|
54 |
|
set i = i + 1 |
|
55 |
|
endloop |
|
56 |
|
|
|
57 |
|
return y > 0 and 0 == q and g < revive_price_min |
|
58 |
|
endfunction |
|
59 |
|
|
|
60 |
|
// Force defeat dialog on all users. |
|
61 |
|
function defeat takes nothing returns nothing |
|
62 |
|
local integer i = 0 |
|
63 |
|
local player p = null |
|
64 |
|
|
|
65 |
|
set i = 0 |
|
66 |
|
loop |
|
67 |
|
exitwhen i >= bj_MAX_PLAYERS |
|
68 |
|
set p = Player(i) |
|
69 |
|
if MAP_CONTROL_USER == GetPlayerController(p) and PLAYER_SLOT_STATE_EMPTY != GetPlayerSlotState(p) then |
|
70 |
|
call CustomDefeatDialogBJ(p, "All heroes are dead and cannot revive.") |
|
71 |
|
endif |
|
72 |
|
set i = i + 1 |
|
73 |
|
endloop |
|
74 |
|
endfunction |
|
75 |
|
|
|
76 |
|
function defeat_trig_action takes nothing returns nothing |
|
77 |
|
if defeat_check() then |
|
78 |
|
call defeat() |
|
79 |
|
endif |
|
80 |
|
endfunction |
|
81 |
|
|
|
82 |
|
function defeat_init takes nothing returns trigger |
|
83 |
|
local trigger t = null |
|
84 |
|
local integer i = 0 |
|
85 |
|
local boolexpr filter = null |
|
86 |
|
|
|
87 |
|
set t = CreateTrigger() |
|
88 |
|
|
|
89 |
|
set filter = Condition(function defeat_trig_filter) |
|
90 |
|
|
|
91 |
|
loop |
|
92 |
|
exitwhen i >= bj_MAX_PLAYERS |
|
93 |
|
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_DEATH, null) |
|
94 |
|
set i = i + 1 |
|
95 |
|
endloop |
|
96 |
|
call TriggerAddAction(t, function defeat_trig_action) |
|
97 |
|
|
|
98 |
|
return t |
|
99 |
|
endfunction |
File src/herotoken.j added (mode: 100644) (index 0000000..a99f4fd) |
|
1 |
|
// src/herotoken.j |
|
2 |
|
// requires src/user.j |
|
3 |
|
globals |
|
4 |
|
// src/herotoken.j fields |
|
5 |
|
constant integer HEROTOKEN_QUANTITY_MAX = 3 |
|
6 |
|
endglobals |
|
7 |
|
|
|
8 |
|
// src/herotoken.j functions |
|
9 |
|
|
|
10 |
|
// Every player will only have one hero of the same type. |
|
11 |
|
function herotoken_unique_hero_trig_init takes nothing returns nothing |
|
12 |
|
call MeleeStartingHeroLimit() |
|
13 |
|
// TODO Add custom heroes to the list of limited units. |
|
14 |
|
endfunction |
|
15 |
|
|
|
16 |
|
// Live users at any time may buy or summon at most HEROTOKEN_QUANTITY_MAX hero units total across all users. |
|
17 |
|
// function herotoken_init distributes these hero slots evenly among all present users. |
|
18 |
|
function herotoken_hero_limit_init takes nothing returns nothing |
|
19 |
|
local integer hero_slot_available_quantity = HEROTOKEN_QUANTITY_MAX |
|
20 |
|
local integer user_quantity = 0 |
|
21 |
|
local integer i = 0 |
|
22 |
|
local integer q = 0 |
|
23 |
|
local player p = null |
|
24 |
|
|
|
25 |
|
set user_quantity = user_quantity_get() |
|
26 |
|
set hero_slot_available_quantity = HEROTOKEN_QUANTITY_MAX |
|
27 |
|
if user_quantity > hero_slot_available_quantity then |
|
28 |
|
call BJDebugMsg("FIXME too many users and not enough hero slots available") |
|
29 |
|
endif |
|
30 |
|
|
|
31 |
|
loop |
|
32 |
|
exitwhen hero_slot_available_quantity <= 0 or user_quantity < 1 |
|
33 |
|
set i = 0 |
|
34 |
|
loop |
|
35 |
|
exitwhen i >= bj_MAX_PLAYERS |
|
36 |
|
set p = Player(i) |
|
37 |
|
if user_player_is_user_check(p) then |
|
38 |
|
set q = GetPlayerTechMaxAllowed(p, 'HERO') + 1 |
|
39 |
|
call SetPlayerTechMaxAllowed(p, 'HERO', q) |
|
40 |
|
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 425 * q) |
|
41 |
|
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, 100 * q) |
|
42 |
|
set hero_slot_available_quantity = hero_slot_available_quantity - 1 |
|
43 |
|
endif |
|
44 |
|
set i = i + 1 |
|
45 |
|
endloop |
|
46 |
|
endloop |
|
47 |
|
endfunction |
|
48 |
|
|
|
49 |
|
function herotoken_init takes nothing returns nothing |
|
50 |
|
call herotoken_hero_limit_init() |
|
51 |
|
call herotoken_unique_hero_trig_init() |
|
52 |
|
|
|
53 |
|
call BJDebugMsg("HERO: Player0:" + I2S(GetPlayerTechMaxAllowed(Player(0), 'HERO'))) |
|
54 |
|
call BJDebugMsg("HERO: Player1:" + I2S(GetPlayerTechMaxAllowed(Player(1), 'HERO'))) |
|
55 |
|
call BJDebugMsg("HERO: Player2:" + I2S(GetPlayerTechMaxAllowed(Player(2), 'HERO'))) |
|
56 |
|
endfunction |
File src/main.j changed (mode: 100644) (index b0b672a..83a88e0) |
1 |
|
//*************************************************************************** |
|
2 |
|
//* |
|
3 |
|
//* Global Variables |
|
4 |
|
//* |
|
5 |
|
//*************************************************************************** |
|
6 |
|
|
|
|
1 |
|
// src/main.j |
|
2 |
|
// requires src/user.j |
|
3 |
|
// requires src/herotoken.j |
|
4 |
|
// requires src/defeat.j |
|
5 |
|
// requires src/revive.j |
|
6 |
|
// requires src/altar.j |
7 |
7 |
globals |
globals |
8 |
|
// Generated |
|
9 |
|
trigger gg_trg_Melee_Initialization = null |
|
|
8 |
|
// src/main.j fields |
|
9 |
|
constant player PLAYER_DEMON = Player(3) |
10 |
10 |
endglobals |
endglobals |
11 |
11 |
|
|
12 |
|
function InitGlobals takes nothing returns nothing |
|
13 |
|
endfunction |
|
14 |
|
|
|
15 |
|
//*************************************************************************** |
|
16 |
|
//* |
|
17 |
|
//* Triggers |
|
18 |
|
//* |
|
19 |
|
//*************************************************************************** |
|
20 |
|
|
|
21 |
|
//=========================================================================== |
|
22 |
|
// Trigger: Melee Initialization |
|
23 |
|
//=========================================================================== |
|
24 |
|
function Trig_Melee_Initialization_Actions takes nothing returns nothing |
|
25 |
|
endfunction |
|
26 |
|
|
|
27 |
|
//=========================================================================== |
|
28 |
|
function InitTrig_Melee_Initialization takes nothing returns nothing |
|
29 |
|
set gg_trg_Melee_Initialization = CreateTrigger( ) |
|
30 |
|
call TriggerAddAction( gg_trg_Melee_Initialization, function Trig_Melee_Initialization_Actions ) |
|
31 |
|
endfunction |
|
32 |
|
|
|
33 |
|
//=========================================================================== |
|
34 |
|
function InitCustomTriggers takes nothing returns nothing |
|
35 |
|
call InitTrig_Melee_Initialization( ) |
|
|
12 |
|
// src/main.j functions |
|
13 |
|
|
|
14 |
|
function init_demon takes player p returns nothing |
|
15 |
|
local location loc = null |
|
16 |
|
local integer start = 0 |
|
17 |
|
local unit u = null |
|
18 |
|
set start = GetPlayerStartLocation(p) |
|
19 |
|
set loc = GetStartLocationLoc(start) |
|
20 |
|
set u = CreateUnitAtLoc(p, 'Udre', loc, bj_UNIT_FACING) |
|
21 |
|
call SetUnitScale(u, 1.3, 1.3, 1.3) |
|
22 |
|
call SetHeroLevel(u, 10, false) |
|
23 |
|
call SetHeroStr(u, GetHeroStr(u, false) + 36, true) |
|
24 |
|
call SetHeroInt(u, GetHeroInt(u, false) + 12, true) |
|
25 |
|
call SetUnitUseFood(u, false) |
|
26 |
|
call SetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP, 200) |
|
27 |
|
call RemoveLocation(loc) |
36 |
28 |
endfunction |
endfunction |
37 |
29 |
|
|
38 |
|
//=========================================================================== |
|
39 |
|
function RunInitializationTriggers takes nothing returns nothing |
|
40 |
|
call ConditionalTriggerExecute( gg_trg_Melee_Initialization ) |
|
|
30 |
|
function init takes nothing returns nothing |
|
31 |
|
call user_init() |
|
32 |
|
call init_demon(PLAYER_DEMON) |
|
33 |
|
call herotoken_init() |
|
34 |
|
call altar_init() |
|
35 |
|
call revive_init() |
|
36 |
|
call defeat_init() |
41 |
37 |
endfunction |
endfunction |
42 |
38 |
|
|
43 |
39 |
function main takes nothing returns nothing |
function main takes nothing returns nothing |
|
... |
... |
function main takes nothing returns nothing |
48 |
44 |
call SetAmbientNightSound( "LordaeronWinterNight" ) |
call SetAmbientNightSound( "LordaeronWinterNight" ) |
49 |
45 |
call SetMapMusic( "Music", true, 0 ) |
call SetMapMusic( "Music", true, 0 ) |
50 |
46 |
call InitBlizzard( ) |
call InitBlizzard( ) |
51 |
|
call InitGlobals( ) |
|
52 |
|
call InitCustomTriggers( ) |
|
53 |
|
call RunInitializationTriggers( ) |
|
|
47 |
|
call init() |
54 |
48 |
endfunction |
endfunction |
File src/revive.j added (mode: 100644) (index 0000000..5080e63) |
|
1 |
|
// src/revive.j |
|
2 |
|
// requires src/user.j |
|
3 |
|
globals |
|
4 |
|
// src/revive.j fields |
|
5 |
|
constant real REVIVE_DURATION_SEC_MIN = 12.0 |
|
6 |
|
constant real REVIVE_DURATION_SEC_MAX = 60.0 |
|
7 |
|
constant real REVIVE_DURATION_SEC_BASE = 12.0 |
|
8 |
|
constant real REVIVE_DURATION_SEC_COEF = 6.0 |
|
9 |
|
|
|
10 |
|
integer array revive_player_count |
|
11 |
|
timer array revive_timer_list |
|
12 |
|
timerdialog array revive_dialog_list |
|
13 |
|
unit array revive_unit_list |
|
14 |
|
endglobals |
|
15 |
|
|
|
16 |
|
// src/revive.j functions |
|
17 |
|
|
|
18 |
|
// Check if any user has hero revival pending. |
|
19 |
|
function revive_ongoing_check takes nothing returns boolean |
|
20 |
|
local integer i = 0 |
|
21 |
|
local integer q = 0 |
|
22 |
|
|
|
23 |
|
set i = 0 |
|
24 |
|
loop |
|
25 |
|
exitwhen i >= bj_MAX_PLAYERS |
|
26 |
|
set q = q + revive_player_count[i] |
|
27 |
|
set i = i + 1 |
|
28 |
|
endloop |
|
29 |
|
return q > 0 |
|
30 |
|
endfunction |
|
31 |
|
|
|
32 |
|
// Calculate the revival duration for the given hero unit. |
|
33 |
|
function revive_duration_get takes unit u returns real |
|
34 |
|
local real duration = REVIVE_DURATION_SEC_MIN |
|
35 |
|
|
|
36 |
|
if null == u then |
|
37 |
|
set duration = 0.0 |
|
38 |
|
elseif IsHeroUnitId(GetUnitTypeId(u)) and IsUnitType(u, UNIT_TYPE_HERO) then |
|
39 |
|
set duration = REVIVE_DURATION_SEC_BASE + (GetHeroLevel(u) - 1) * REVIVE_DURATION_SEC_COEF |
|
40 |
|
else |
|
41 |
|
set duration = REVIVE_DURATION_SEC_BASE + (GetUnitLevel(u) - 1) * REVIVE_DURATION_SEC_COEF |
|
42 |
|
endif |
|
43 |
|
|
|
44 |
|
return RMinBJ(RMaxBJ(REVIVE_DURATION_SEC_MIN, duration), REVIVE_DURATION_SEC_MAX) |
|
45 |
|
endfunction |
|
46 |
|
|
|
47 |
|
// Calculate the revival gold price for the given hero unit. |
|
48 |
|
function revive_price_get takes unit u returns integer |
|
49 |
|
if null == u then |
|
50 |
|
return 0 |
|
51 |
|
endif |
|
52 |
|
|
|
53 |
|
if IsHeroUnitId(GetUnitTypeId(u)) and IsUnitType(u, UNIT_TYPE_HERO) then |
|
54 |
|
return 170 + (GetHeroLevel(u) - 1) * 42 |
|
55 |
|
endif |
|
56 |
|
|
|
57 |
|
return 0 |
|
58 |
|
endfunction |
|
59 |
|
|
|
60 |
|
// Instantly and without constraints or penalties |
|
61 |
|
// revive given hero unit at the owner's start location. |
|
62 |
|
function revive_unit takes unit u returns nothing |
|
63 |
|
local player p = null |
|
64 |
|
local integer start = -1 |
|
65 |
|
local location loc = null |
|
66 |
|
|
|
67 |
|
if null == u then |
|
68 |
|
return |
|
69 |
|
endif |
|
70 |
|
|
|
71 |
|
set p = GetOwningPlayer(u) |
|
72 |
|
set start = GetPlayerStartLocation(p) |
|
73 |
|
set loc = Location(GetStartLocationX(start), GetStartLocationY(start) - 128.0) |
|
74 |
|
|
|
75 |
|
call ReviveHeroLoc(u, loc, true) |
|
76 |
|
call RemoveLocation(loc) |
|
77 |
|
if not IsUnitAliveBJ(u) then |
|
78 |
|
return |
|
79 |
|
endif |
|
80 |
|
call SetUnitFacing(u, bj_UNIT_FACING) |
|
81 |
|
if p == GetLocalPlayer() then |
|
82 |
|
call PanCameraTo(GetUnitX(u), GetUnitY(u)) |
|
83 |
|
call SelectUnit(u, true) |
|
84 |
|
endif |
|
85 |
|
endfunction |
|
86 |
|
|
|
87 |
|
function revive_schedule_timer_callback takes nothing returns nothing |
|
88 |
|
local timer t = GetExpiredTimer() |
|
89 |
|
local unit u = null |
|
90 |
|
local integer i = 0 |
|
91 |
|
local timerdialog g = null |
|
92 |
|
local integer k = bj_MAX_PLAYERS |
|
93 |
|
|
|
94 |
|
if null == t then |
|
95 |
|
return |
|
96 |
|
endif |
|
97 |
|
|
|
98 |
|
set i = 0 |
|
99 |
|
loop |
|
100 |
|
exitwhen i >= JASS_MAX_ARRAY_SIZE or u != null or null == revive_timer_list[i] |
|
101 |
|
if t == revive_timer_list[i] then |
|
102 |
|
set u = revive_unit_list[i] |
|
103 |
|
set g = revive_dialog_list[i] |
|
104 |
|
endif |
|
105 |
|
set i = i + 1 |
|
106 |
|
endloop |
|
107 |
|
call DestroyTimer(t) |
|
108 |
|
call DestroyTimerDialog(g) |
|
109 |
|
|
|
110 |
|
set k = GetPlayerId(GetOwningPlayer(u)) |
|
111 |
|
set revive_player_count[k] = revive_player_count[k] - 1 |
|
112 |
|
|
|
113 |
|
call revive_unit(u) |
|
114 |
|
endfunction |
|
115 |
|
|
|
116 |
|
// Pay gold price for revival of the given hero unit, |
|
117 |
|
// then delay effective revival for some duration. |
|
118 |
|
function revive_schedule takes unit u returns timer |
|
119 |
|
local timer t = null |
|
120 |
|
local real duration = REVIVE_DURATION_SEC_MIN |
|
121 |
|
local timerdialog g = null |
|
122 |
|
local string label = null |
|
123 |
|
local integer i = 0 |
|
124 |
|
local integer j = JASS_MAX_ARRAY_SIZE |
|
125 |
|
local integer k = bj_MAX_PLAYERS |
|
126 |
|
|
|
127 |
|
if null == u then |
|
128 |
|
return null |
|
129 |
|
endif |
|
130 |
|
|
|
131 |
|
if IsHeroUnitId(GetUnitTypeId(u)) and IsUnitType(u, UNIT_TYPE_HERO) then |
|
132 |
|
set t = CreateTimer() |
|
133 |
|
set duration = revive_duration_get(u) |
|
134 |
|
set duration = RMinBJ(RMaxBJ(REVIVE_DURATION_SEC_MIN, duration), REVIVE_DURATION_SEC_MAX) |
|
135 |
|
|
|
136 |
|
set g = CreateTimerDialog(t) |
|
137 |
|
set label = GetPlayerName(GetOwningPlayer(u)) + " " + GetUnitName(u) |
|
138 |
|
call TimerDialogSetTitle(g, label) |
|
139 |
|
call TimerDialogDisplay(g, true) |
|
140 |
|
|
|
141 |
|
call TimerStart(t, duration, false, function revive_schedule_timer_callback) |
|
142 |
|
|
|
143 |
|
set k = GetPlayerId(GetOwningPlayer(u)) |
|
144 |
|
set revive_player_count[k] = revive_player_count[k] + 1 |
|
145 |
|
|
|
146 |
|
set i = 0 |
|
147 |
|
loop |
|
148 |
|
exitwhen i >= JASS_MAX_ARRAY_SIZE or (j < JASS_MAX_ARRAY_SIZE and j >= 0) |
|
149 |
|
if null == revive_timer_list[i] then |
|
150 |
|
set j = i |
|
151 |
|
set revive_timer_list[j] = t |
|
152 |
|
set revive_dialog_list[j] = g |
|
153 |
|
set revive_unit_list[j] = u |
|
154 |
|
endif |
|
155 |
|
set i = i + 1 |
|
156 |
|
endloop |
|
157 |
|
endif |
|
158 |
|
|
|
159 |
|
return t |
|
160 |
|
endfunction |
|
161 |
|
|
|
162 |
|
// Check if owning player has the gold to revive given hero unit. |
|
163 |
|
// If so, then schedule revival. |
|
164 |
|
function revive_request takes unit u returns boolean |
|
165 |
|
local integer gold_available = 0 |
|
166 |
|
local integer gold_price = 0 |
|
167 |
|
local boolean hero_flag = false |
|
168 |
|
local player p = null |
|
169 |
|
local timer t = null |
|
170 |
|
|
|
171 |
|
if null == u then |
|
172 |
|
return false |
|
173 |
|
endif |
|
174 |
|
|
|
175 |
|
set hero_flag = IsHeroUnitId(GetUnitTypeId(u)) and IsUnitType(u, UNIT_TYPE_HERO) |
|
176 |
|
|
|
177 |
|
set p = GetOwningPlayer(u) |
|
178 |
|
set gold_available = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) |
|
179 |
|
set gold_price = revive_price_get(u) |
|
180 |
|
|
|
181 |
|
if hero_flag and gold_available >= gold_price then |
|
182 |
|
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, gold_available - gold_price) |
|
183 |
|
set t = revive_schedule(u) |
|
184 |
|
return t != null |
|
185 |
|
endif |
|
186 |
|
|
|
187 |
|
return false |
|
188 |
|
endfunction |
|
189 |
|
|
|
190 |
|
function revive_retry_timer_callback takes nothing returns nothing |
|
191 |
|
local timer t = GetExpiredTimer() |
|
192 |
|
local unit u = null |
|
193 |
|
local boolean success = false |
|
194 |
|
local integer i = 0 |
|
195 |
|
|
|
196 |
|
if null == t then |
|
197 |
|
return |
|
198 |
|
endif |
|
199 |
|
|
|
200 |
|
set i = 0 |
|
201 |
|
loop |
|
202 |
|
exitwhen i >= JASS_MAX_ARRAY_SIZE or u != null or null == revive_timer_list[i] |
|
203 |
|
if t == revive_timer_list[i] then |
|
204 |
|
set u = revive_unit_list[i] |
|
205 |
|
endif |
|
206 |
|
set i = i + 1 |
|
207 |
|
endloop |
|
208 |
|
|
|
209 |
|
set success = revive_request(u) |
|
210 |
|
if success then |
|
211 |
|
call DestroyTimer(t) |
|
212 |
|
endif |
|
213 |
|
endfunction |
|
214 |
|
|
|
215 |
|
// Repeatedly request revival until the owning player has enough gold to schedule revival. |
|
216 |
|
// There are more clever and optimized ways of doing this, but this way is also robust and obvious. |
|
217 |
|
function revive_retry takes unit u returns nothing |
|
218 |
|
local timer t = null |
|
219 |
|
local integer i = 0 |
|
220 |
|
local integer j = JASS_MAX_ARRAY_SIZE |
|
221 |
|
|
|
222 |
|
if u != null and IsHeroUnitId(GetUnitTypeId(u)) and IsUnitType(u, UNIT_TYPE_HERO) then |
|
223 |
|
set t = CreateTimer() |
|
224 |
|
|
|
225 |
|
set i = 0 |
|
226 |
|
loop |
|
227 |
|
exitwhen i >= JASS_MAX_ARRAY_SIZE or (j < JASS_MAX_ARRAY_SIZE and j >= 0) |
|
228 |
|
if null == revive_timer_list[i] then |
|
229 |
|
set j = i |
|
230 |
|
set revive_timer_list[j] = t |
|
231 |
|
set revive_unit_list[j] = u |
|
232 |
|
endif |
|
233 |
|
set i = i + 1 |
|
234 |
|
endloop |
|
235 |
|
|
|
236 |
|
call TimerStart(t, 2.0, true, function revive_retry_timer_callback) |
|
237 |
|
endif |
|
238 |
|
endfunction |
|
239 |
|
|
|
240 |
|
function revive_trig_action takes nothing returns nothing |
|
241 |
|
local unit u = null |
|
242 |
|
local boolean success = false |
|
243 |
|
|
|
244 |
|
set u = GetRevivableUnit() |
|
245 |
|
|
|
246 |
|
if null == u then |
|
247 |
|
return |
|
248 |
|
endif |
|
249 |
|
|
|
250 |
|
set success = revive_request(u) |
|
251 |
|
|
|
252 |
|
if not success then |
|
253 |
|
call revive_retry(u) |
|
254 |
|
endif |
|
255 |
|
endfunction |
|
256 |
|
|
|
257 |
|
// Set up mechanism to conditionally revive player heroes. |
|
258 |
|
function revive_init takes nothing returns trigger |
|
259 |
|
local integer i = 0 |
|
260 |
|
local trigger t = null |
|
261 |
|
local player p = null |
|
262 |
|
|
|
263 |
|
set t = CreateTrigger() |
|
264 |
|
|
|
265 |
|
set i = 0 |
|
266 |
|
loop |
|
267 |
|
exitwhen i >= bj_MAX_PLAYERS |
|
268 |
|
set p = Player(i) |
|
269 |
|
set revive_player_count[i] = 0 |
|
270 |
|
if user_player_is_user_check(p) then |
|
271 |
|
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_HERO_REVIVABLE, null) |
|
272 |
|
endif |
|
273 |
|
set i = i + 1 |
|
274 |
|
endloop |
|
275 |
|
call TriggerAddAction(t, function revive_trig_action) |
|
276 |
|
|
|
277 |
|
return t |
|
278 |
|
endfunction |
File src/user.j added (mode: 100644) (index 0000000..4720733) |
|
1 |
|
// src/user.j |
|
2 |
|
globals |
|
3 |
|
// src/user.j fields |
|
4 |
|
// Unit groups or player forces are mutable collections. |
|
5 |
|
// They may never be effectively constant. |
|
6 |
|
endglobals |
|
7 |
|
|
|
8 |
|
// src/user.j functions |
|
9 |
|
|
|
10 |
|
function user_player_is_user_check takes player p returns boolean |
|
11 |
|
local boolean flag = true |
|
12 |
|
set flag = MAP_CONTROL_USER == GetPlayerController(p) and flag |
|
13 |
|
set flag = PLAYER_SLOT_STATE_PLAYING == GetPlayerSlotState(p) and flag |
|
14 |
|
set flag = not IsPlayerObserver(p) and flag |
|
15 |
|
return flag |
|
16 |
|
endfunction |
|
17 |
|
|
|
18 |
|
function user_force_filter takes nothing returns boolean |
|
19 |
|
local player p = GetFilterPlayer() |
|
20 |
|
return user_player_is_user_check(p) |
|
21 |
|
endfunction |
|
22 |
|
|
|
23 |
|
function user_init_player takes player p returns nothing |
|
24 |
|
local location loc = null |
|
25 |
|
local integer start = 0 |
|
26 |
|
|
|
27 |
|
call SetPlayerTechMaxAllowed(p, 'HERO', 0) |
|
28 |
|
call SetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP, 40) |
|
29 |
|
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 0) |
|
30 |
|
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, 0) |
|
31 |
|
|
|
32 |
|
set start = GetPlayerStartLocation(p) |
|
33 |
|
set loc = GetStartLocationLoc(start) |
|
34 |
|
|
|
35 |
|
call RemoveLocation(loc) |
|
36 |
|
endfunction |
|
37 |
|
|
|
38 |
|
function user_init_player_callback takes nothing returns nothing |
|
39 |
|
local player p = GetEnumPlayer() |
|
40 |
|
call user_init_player(p) |
|
41 |
|
endfunction |
|
42 |
|
|
|
43 |
|
function user_force_enum takes force user_force returns force |
|
44 |
|
local filterfunc filter = null |
|
45 |
|
if null == user_force then |
|
46 |
|
return null |
|
47 |
|
endif |
|
48 |
|
set filter = Filter(function user_force_filter) |
|
49 |
|
call ForceEnumPlayers(user_force, filter) |
|
50 |
|
call DestroyFilter(filter) |
|
51 |
|
return user_force |
|
52 |
|
endfunction |
|
53 |
|
|
|
54 |
|
// Blizzard.j:function CountPlayersInForceBJ serves the same purpose. |
|
55 |
|
// The benefit of this alternative implementation is that is avoids mutable global variables. |
|
56 |
|
function user_force_count takes force anyforce returns integer |
|
57 |
|
local integer i = 0 |
|
58 |
|
local player p = null |
|
59 |
|
local integer q = 0 |
|
60 |
|
|
|
61 |
|
if null == anyforce then |
|
62 |
|
return -1 |
|
63 |
|
endif |
|
64 |
|
|
|
65 |
|
set i = 0 |
|
66 |
|
loop |
|
67 |
|
exitwhen i >= bj_MAX_PLAYER_SLOTS |
|
68 |
|
set p = Player(i) |
|
69 |
|
if IsPlayerInForce(p, anyforce) then |
|
70 |
|
set q = q + 1 |
|
71 |
|
endif |
|
72 |
|
set i = i + 1 |
|
73 |
|
endloop |
|
74 |
|
|
|
75 |
|
return q |
|
76 |
|
endfunction |
|
77 |
|
|
|
78 |
|
function user_quantity_get takes nothing returns integer |
|
79 |
|
local force user_force = null |
|
80 |
|
local integer q = 0 |
|
81 |
|
|
|
82 |
|
set user_force = CreateForce() |
|
83 |
|
call user_force_enum(user_force) |
|
84 |
|
set q = user_force_count(user_force) |
|
85 |
|
|
|
86 |
|
call DestroyForce(user_force) |
|
87 |
|
return q |
|
88 |
|
endfunction |
|
89 |
|
|
|
90 |
|
function user_init takes nothing returns nothing |
|
91 |
|
local force user_force = CreateForce() |
|
92 |
|
call user_force_enum(user_force) |
|
93 |
|
|
|
94 |
|
call ForForce(user_force, function user_init_player_callback) |
|
95 |
|
call DestroyForce(user_force) |
|
96 |
|
endfunction |