- Joined
- May 9, 2014
- Messages
- 1,820
Made in JASS, these are the following snippets:
onInit trigger
onSignal
User-Defined Variables
The mission "Unit Spawn" requires that 20 creeps and 4 bases should be spawned on map initialization (no pre-placed units), with units periodically spawning in order to kill those creeps. Those units that are spawned periodically are owned by either player 1, 2, 3, or 4. The mission ends when the creeps die out and a victory message is displayed.
v.1.00 - Submission of thread.
v.1.01 - Added documentation, and comments on the script..
Changed Generated Variables to User-Defined Variables
- Removed real SIGNAL as ExecuteFunc made it easier to initialize things...
- Removed debug messages.
v.1.02 - Added nulling of some reference leaks that escaped the coder.
Script
Documentation
Changelog
onInit trigger
JASS:
// Modified as per insight of Jampion
function onInit_SetAllies takes nothing returns nothing
local integer i = 0
local integer i2 = 1
loop
exitwhen i > (4 - 1)
loop
exitwhen i2 > (4 - 1)
// Sets alliance of first player and next player to a passive state, and grants shared vision...
call SetPlayerAlliance(Player(i ), Player(i2), ALLIANCE_PASSIVE, true)
call SetPlayerAlliance(Player(i), Player(i2), ALLIANCE_SHARED_VISION, true)
call SetPlayerAlliance(Player(i2), Player(i), ALLIANCE_PASSIVE, true)
call SetPlayerAlliance(Player(i2), Player(i), ALLIANCE_SHARED_VISION, true)
set i2 = i2 + 1
endloop
call SetPlayerTeam(Player(i), 0)
set i = i + 1
set i2 = i + 1
endloop
endfunction
function onInit_SpawnCreeps takes nothing returns nothing
set bj_groupCountUnits = 0
loop
exitwhen bj_groupCountUnits >= 20
// Create the creeps
set bj_lastCreatedUnit = CreateUnit(Player(12), ChooseRandomCreep(-1), 0, 0, 0)
call GroupAddUnit(bj_lastCreatedGroup, bj_lastCreatedUnit)
set bj_groupCountUnits = bj_groupCountUnits + 1
endloop
endfunction
function onInit_SpawnBases takes nothing returns nothing
local integer i = 1
local trigger t
loop
exitwhen i > 4
// We save the newly-created barracks inside the hashtable..
call SaveUnitHandle(udg_HASH, 1, i, CreateUnit(Player(i - 1), 'hbar', 3000 * Cos(((I2R(i - 1)*90) + 45) * bj_DEGTORAD), 3000 * Sin(((I2R(i - 1)*90) + 45) * bj_DEGTORAD), bj_UNIT_FACING))
// As efficiency is not required, 4 triggers are created instead of having one manage all of the buildings' death event.
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t, LoadUnitHandle(udg_HASH, 1, i), EVENT_UNIT_DEATH)
call SaveTriggerHandle(udg_HASH, 2, i, t)
set t = null
set i = i + 1
endloop
// We proceed to the next Initialization
call ExecuteFunc("onSignal_InitTrig_onSignal")
endfunction
function onInit_GenerateGroups takes nothing returns nothing
local integer i = 1
loop
exitwhen i > 4
// We initialize the groups to be used later...
call SaveGroupHandle(udg_HASH, 0, i, CreateGroup())
set i = i + 1
endloop
endfunction
function InitTrig_onInit takes nothing returns nothing
// Initialize the Hashtable before anything else...
set udg_HASH = InitHashtable()
// Set the time of day to 12:00 and pause the day-night cycle
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, 12.)
call SuspendTimeOfDay(true)
// Personal Preference
call SetPlayerRaceSelectable(Player(0), false)
call SetPlayerRacePreference(Player(0), RACE_PREF_UNDEAD)
// Sets Allies
call ExecuteFunc("onInit_SetAllies")
// Spawns the Creeps
call ExecuteFunc("onInit_SpawnCreeps")
// Generates the group of units to be exploded later
call ExecuteFunc("onInit_GenerateGroups")
// Spawns the Bases
call ExecuteFunc("onInit_SpawnBases")
endfunction
onSignal
JASS:
function onSignal_UnitsExplode takes integer index returns nothing
local group g = LoadGroupHandle(udg_HASH, 0, index)
local unit u
loop
set u = FirstOfGroup(g)
exitwhen u == null
call SetUnitExploded(u, true)
call KillUnit(u)
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
call RemoveSavedHandle(udg_HASH, 0, index)
set g = null
endfunction
function onSignal_Base_onDeath takes nothing returns nothing
local integer i = GetPlayerId(GetOwningPlayer(GetTriggerUnit())) + 1
call DestroyTrigger(GetTriggeringTrigger())
call RemoveSavedHandle(udg_HASH, 2, i)
call RemoveSavedHandle(udg_HASH, 1, i)
call onSignal_UnitsExplode(i)
endfunction
function onSignal_Timer_onTick takes nothing returns nothing
local integer i = 1
local integer i2
loop
exitwhen i > 4
if HaveSavedHandle(udg_HASH, 2, i) then
set i2 = GetRandomInt(0, 1)
if i2 == 0 then
set bj_lastCreatedUnit = CreateUnit(Player(i - 1), 'hfoo', 3000 * Cos((I2R(i - 1)*90 + 45)*bj_DEGTORAD), 3000 * Sin((I2R(i - 1)*90 + 45)*bj_DEGTORAD), bj_UNIT_FACING)
else
set bj_lastCreatedUnit = CreateUnit(Player(i - 1), 'hrif', 3000 * Cos((I2R(i - 1)*90 + 45)*bj_DEGTORAD), 3000 * Sin((I2R(i - 1)*90 + 45)*bj_DEGTORAD), bj_UNIT_FACING)
endif
call GroupAddUnit(LoadGroupHandle(udg_HASH, 0, i), bj_lastCreatedUnit)
call IssuePointOrder(bj_lastCreatedUnit, "attack", 0, 0)
endif
set i = i + 1
endloop
endfunction
function onSignal_Cond takes nothing returns nothing
local timer t = CreateTimer()
local integer i = 1
call SaveTimerHandle(udg_HASH, 3, 0, t)
loop
exitwhen i > 4
call TriggerAddCondition(LoadTriggerHandle(udg_HASH, 2, i), Filter(function onSignal_Base_onDeath))
set i = i + 1
endloop
call TimerStart(t, 2.5, true, function onSignal_Timer_onTick)
set t = null
endfunction
function onSignal_onVictory_Click takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
// The dilemma of destroying a handle inside the local player setting is negated
// by the dilemma of destroying it globally, preventing others from voting...
// This could be thought of as a one trigger to four clicks...
call DestroyTrigger(GetTriggeringTrigger())
call DialogDisplay(GetTriggerPlayer(), LoadDialogHandle(udg_HASH, 4, 0), false)
endif
if GetClickedButton() == LoadButtonHandle(udg_HASH, 5, 0) then
set bj_lastCreatedFogModifier = CreateFogModifierRect(GetTriggerPlayer(), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, false, false)
call FogModifierStart(bj_lastCreatedFogModifier)
endif
call FlushParentHashtable(udg_HASH)
endfunction
function onSignal_Victory_Display takes nothing returns nothing
local integer i = 1
local dialog display = DialogCreate()
local trigger t = CreateTrigger()
loop
exitwhen i > 4
// The trigger exists, so the barracks has not yet exploded...
if HaveSavedHandle(udg_HASH, 2, i) then
call SetUnitExploded(LoadUnitHandle(udg_HASH, 1, i), true)
call KillUnit(LoadUnitHandle(udg_HASH, 1, i))
// Just to be safe...
call TriggerEvaluate(LoadTriggerHandle(udg_HASH, 2, i))
endif
set i = i + 1
endloop
call DialogSetMessage(display, "Victory!")
call StartSound(bj_victoryDialogSound)
// We save the dialog and its' buttons in the hashtable...
call SaveDialogHandle(udg_HASH, 4, 0, display)
call SaveButtonHandle(udg_HASH, 5, 0, DialogAddButton(display, "Continue Game!", 0))
call SaveButtonHandle(udg_HASH, 5, 1, DialogAddQuitButton(display, true, "Quit Game!", 0))
if GetPlayerId(GetLocalPlayer()) <= 3 then
call DialogDisplay(GetLocalPlayer(), display, true)
endif
call TriggerRegisterDialogEvent(t, display)
call TriggerAddCondition(t, Filter(function onSignal_onVictory_Click))
// Since the timer is the same timer from the hashtable, stored at parent 3, child 0, we can destroy it and remove saved handle...
call DestroyTimer(GetExpiredTimer())
call RemoveSavedHandle(udg_HASH, 3, 0)
// We have already saved the dialog inside the hashtable, so it's okay to null it.
// Remember that this is done to remove reference leaks...
set display = null
endfunction
function onSignal_onDeath_Cond takes nothing returns nothing
local integer i = GetPlayerId(GetTriggerPlayer())
local group g
local unit u = GetTriggerUnit()
local timer t
if i <= (4 - 1) then
// Since the PlayerId returns an index - 1, we add it back by 1 so as to cancel the effect of the index...
set g = LoadGroupHandle(udg_HASH, 0, i + 1)
if IsUnitInGroup(u, g) then
call GroupRemoveUnit(g, u)
endif
set g = null
else
// The neutral hostile creep has died..
if IsUnitInGroup(u, bj_lastCreatedGroup) then
call GroupRemoveUnit(bj_lastCreatedGroup, u)
// We remove the instance, since we already have the amount of units in the group
// and deduct by 1 instead of counting how many units are left...
// Since no other operations modify bj_groupCountUnits, it's safe to use it as the
// number of creeps left...
// It's an O(1) vs. O(n) case scenario
set bj_groupCountUnits = bj_groupCountUnits - 1
endif
if bj_groupCountUnits == 0 then
call DestroyTrigger(GetTriggeringTrigger())
set t = LoadTimerHandle(udg_HASH, 3, 0)
// We only want to display the message to the players...
if GetPlayerId(GetLocalPlayer()) <= 3 then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "You have won!")
endif
// We pause and reuse the periodically spawning timer for the victory message!
call PauseTimer(t)
call TimerStart(t, 2.5, false, function onSignal_Victory_Display)
set t = null
endif
endif
set u = null
endfunction
function onSignal_InitTrig_onSignal takes nothing returns nothing
local trigger t = CreateTrigger()
call onSignal_Cond()
// This tracks those units who will die...
// Since Reincarnation events do not fire a death event, we're okay with tracking the death of a unit...
call TriggerRegisterPlayerUnitEvent(t, Player(12), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(t, Player(1), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(t, Player(2), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(t, Player(3), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddCondition(t, Filter(function onSignal_onDeath_Cond))
set t = null
endfunction
function InitTrig_onSignal takes nothing returns nothing
// Does nothing
endfunction
User-Defined Variables
JASS:
// used vanilla JASS
hashtable udg_HASH = null
The mission "Unit Spawn" requires that 20 creeps and 4 bases should be spawned on map initialization (no pre-placed units), with units periodically spawning in order to kill those creeps. Those units that are spawned periodically are owned by either player 1, 2, 3, or 4. The mission ends when the creeps die out and a victory message is displayed.
v.1.00 - Submission of thread.
v.1.01 - Added documentation, and comments on the script..
Changed Generated Variables to User-Defined Variables
- Removed real SIGNAL as ExecuteFunc made it easier to initialize things...
- Removed debug messages.
v.1.02 - Added nulling of some reference leaks that escaped the coder.
Attachments
Last edited: