Castle Defense Spawn Code Problem

kirinelf

New Member
Reaction score
10
Well, I'm making a Castle Defense, and the problem is that the spawn doesn't work. It's similar in theory to the spawning system in a tower defense: At a certain point in time, a wave of creeps is spawned and ordered to move to a certain point. The key difference between my CD and conventional TDs is that most TDs have that 'certain time' as a time interval, every minute, say, or 30 seconds. My CD has it said 'certain time' as when all the units on the field belonging to a certain player has gone south.

I also decided to spice things up a bit by adding a -spawn command. This will override the default spawn settings, immediately spawning the next wave of creeps whether or not there're any left living. If done at the beginning of a wave, in effect, it'd be taking on two waves at once.

These are my triggers. The Spawn Initialization and Spawn Commands are in GUI, and the actual spawning is in JASS:

Trigger:
  • Spawn Initialization
    • Events
      • Time - Elapsed game time is 5.00 seconds
      • Player - Player 12 (Brown)'s Food used becomes Equal to 0.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • LevelCount Greater than 0
        • Then - Actions
          • Game - Display to inGamePlayers for 5.00 seconds the text: Wave complete. Well...
          • Set LevelCount = (LevelCount + 1)
          • Set BonusIncome = (BonusIncome + 200)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • LevelCount Equal to (CreepCount_LastIndex + 1)
            • Then - Actions
              • Wait 2.00 seconds
              • Player Group - Pick every player in inGamePlayers and do (Actions)
                • Loop - Actions
                  • Game - Victory (Picked player) (Show dialogs, Show scores)
            • Else - Actions
              • Player Group - Pick every player in inGamePlayers and do (Actions)
                • Loop - Actions
                  • Player - Add BonusIncome to (Picked player) Current gold
              • Countdown Timer - Create a timer window for CreepTimer with title (Wave + ((String(LevelCount)) + ( - + ( ( + (CreepName[LevelCount] + ))))))
              • Countdown Timer - Start CreepTimer as a One-shot timer that will expire in 10.00 seconds
              • Set CreepTimerWindow = (Last created timer window)
              • Countdown Timer - Show CreepTimerWindow
        • Else - Actions
          • Set LevelCount = (LevelCount + 1)
          • Set BonusIncome = (BonusIncome + 200)
          • Countdown Timer - Create a timer window for CreepTimer with title (Wave + ((String(LevelCount)) + ( - + ( ( + (CreepName[LevelCount] + ))))))
          • Countdown Timer - Start CreepTimer as a One-shot timer that will expire in 10.00 seconds
          • Set CreepTimerWindow = (Last created timer window)
          • Countdown Timer - Show CreepTimerWindow


Trigger:
  • Spawn Command
    • Events
      • Player - Player 1 (Red) types a chat message containing -spawn as An exact match
    • Conditions
      • LevelCount Greater than 0
      • LevelCount Less than CreepCount_LastIndex
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Remaining time for CreepTimer) Less than or equal to 0.00
        • Then - Actions
          • Set LevelCount = (LevelCount + 1)
          • Set BonusIncome = (BonusIncome + 200)
          • Trigger - Run Spawn Creeps <gen> (ignoring conditions)
        • Else - Actions
          • Trigger - Run Spawn Creeps <gen> (ignoring conditions)


JASS:
function Trig_Spawn_Creeps_Actions takes nothing returns nothing
    local integer i
    local integer unitspawn
    local integer unitamount

    // Destroy the timer window, to make room for the next one, when the time comes.
    set unitspawn = udg_CreepArray[udg_LevelCount]
    set unitamount = udg_CreepAmount[udg_LevelCount]
    call DestroyTimerDialog(udg_CreepTimerWindow)
    set udg_CreepTimer = CreateTimer()
    // Lets have a small wait between each spawn.
    // Reduces lagg by reducing the amount of units created per second.
    set i = 1
    loop
        exitwhen i > unitamount
        call TriggerSleepAction(1)
        call CreateUnitAtLoc(udg_HostileCreeps, unitspawn, udg_creepSpawn[1], 0.00 )
        call CreateUnitAtLoc(udg_HostileCreeps, unitspawn, udg_creepSpawn[2], 0.00 )
        call CreateUnitAtLoc(udg_HostileCreeps, unitspawn, udg_creepSpawn[3], 0.00 )
        call CreateUnitAtLoc(udg_HostileCreeps, unitspawn, udg_creepSpawn[4], 0.00 )
        set i = i + 1
    endloop
endfunction

//===========================================================================
function InitTrig_Spawn_Creeps takes nothing returns nothing
    set gg_trg_Spawn_Creeps = CreateTrigger()
    call TriggerRegisterTimerExpireEvent(gg_trg_Spawn_Creeps, udg_CreepTimer)
    call TriggerAddAction(gg_trg_Spawn_Creeps, function Trig_Spawn_Creeps_Actions)
endfunction


Now, the problem is this: The game successfully detects that the units are dead and starts the timer. All good. The thing is, once the timer hits zero, nothing happens. The Timer Window just stays there at 0, and I know that there's a line of code in the Spawn Creeps trigger that kills it. From what I gather, the Spawn Creeps trigger (The one in JASS) just plain isn't being run after the timer hits 0. The -spawn command works perfectly though, probably because it forces the trigger to run...?

Anyways, this is rather crucial to the map, unless I decide to make it so that only Red can decide when the next wave comes. So I'd really appreciate some help with this. +Rep for helpers! ^^;;
 

Jesus4Lyf

Good Idea™
Reaction score
397
Hi, since no one else replied, I'll take a stab.

>call TriggerRegisterTimerExpireEvent(gg_trg_Spawn_Creeps, udg_CreepTimer)
That sets the event for the timer currently in the variable udg_CreepTimer, not the variable itself. If you change the value of this variable, you lose access to the timer the trigger has its event registered for.

Also, if the variable does not hold a timer value at map initialisation, it basically won't work.

Is this the problem?
 

kirinelf

New Member
Reaction score
10
Hmm... I'm not sure what you mean by 'the timer currently in the variable udg_CreepTimer, not the variable itself'. I'm still rather a newbie at coding, even after reading through the manuals, although for the most part I can edit fine.

Would it help if I converted the other two triggers to JASS?

Edit: I decided to convert the Spawn Initialization Trigger to JASS, and played around with it to remove as many of the red text (Mostly BJs) that I could. Not sure if I did a good job of it, but I sure as heck tried.

JASS:
function Bonus_Gold_Income takes nothing returns nothing
        call SetPlayerState(GetEnumPlayer(), PLAYER_STATE_GOLD_GATHERED, GetPlayerState(GetEnumPlayer(), PLAYER_STATE_GOLD_GATHERED) + 200)
endfunction

function Victory takes nothing returns nothing
    call CustomVictoryBJ( GetEnumPlayer(), true, true )
endfunction

function Victory_Condition takes nothing returns boolean
    if ( not ( udg_LevelCount == ( udg_CreepCount_LastIndex + 1 ) ) ) then
        return false
    endif
    return true
endfunction

function Second_Wave_And_Higher takes nothing returns boolean
    if ( not ( udg_LevelCount > 0 ) ) then
        return false
    endif
    return true
endfunction

function Wave_End_Message takes nothing returns nothing
    if (IsPlayerInForce(GetLocalPlayer(), udg_inGamePlayers)) then
    call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5.00, "Congratulations, you have survived this wave. Well done. You have recieved " + I2S(udg_BonusIncome) + " gold.")
    endif
endfunction

//function Create_CreepTimer takes nothing returns timer
//    set bj_lastStartedTimer = CreateTimer()
//    call TimerStart(bj_lastStartedTimer, 10.00, false, function Spawn_Creeps)
//    return bj_lastStartedTimer
//endfunction

function Timer_Start takes nothing returns timerdialog
    local integer LevelCount 
    local string CreepName
    
    set CreepName = udg_CreepName[udg_LevelCount]
    set LevelCount = udg_LevelCount
    
    call CreateTimerDialog(udg_CreepTimer)
    set bj_lastCreatedTimerDialog = CreateTimerDialog(udg_CreepTimer)
    call TimerStart(udg_CreepTimer, 10.00, false, null)
    call TimerDialogSetTitle(bj_lastCreatedTimerDialog, ( "Wave " + I2S(LevelCount) + " - (" + CreepName + ")" ))
    call TimerDialogDisplay(bj_lastCreatedTimerDialog, true)
    set udg_CreepTimerWindow = bj_lastCreatedTimerDialog
    return bj_lastCreatedTimerDialog
endfunction

function Trig_Spawn_Initialization_JASS_Actions takes nothing returns nothing
    if ( Second_Wave_And_Higher() ) then
        call Wave_End_Message()
        set udg_LevelCount = ( udg_LevelCount + 1 )
        set udg_BonusIncome = ( udg_BonusIncome + 200 )
        if ( Victory_Condition() ) then
            call TriggerSleepAction( 2 )
            call ForForce( udg_inGamePlayers, function Victory )
        else
            call ForForce( udg_inGamePlayers, function Bonus_Gold_Income )
            call Timer_Start()
        endif
    else
        set udg_LevelCount = ( udg_LevelCount + 1 )
        set udg_BonusIncome = ( udg_BonusIncome + 200 )
        call Timer_Start()
    endif
endfunction

//===========================================================================
function InitTrig_Spawn_Initialization_JASS takes nothing returns nothing
    set gg_trg_Spawn_Initialization_JASS = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Spawn_Initialization_JASS, 5.00 )
    call TriggerRegisterPlayerStateEvent( gg_trg_Spawn_Initialization_JASS, Player(11), PLAYER_STATE_RESOURCE_FOOD_USED, EQUAL, 0.00 )
    call TriggerAddAction( gg_trg_Spawn_Initialization_JASS, function Trig_Spawn_Initialization_JASS_Actions )
endfunction


What I've changed I'm still not really sure, but nothing's actually changed gameplay-wise: The first wave has a countdown timer and the creeps come out when the clock hits zero, the timer window disappears, I kill them all, the timer window appears again and starts counting down, and when it hits 0 it stays there and the next wave doesn't come out.

Makes me sad. =(
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
Are you able to use NewGen (I.E. do you not run a mac? xD) I'll give it a stab in the morning, but I just want to know :D oh, and is it possible to copy/paste in the original JASS fresh after the conversion with no editing?
 

kirinelf

New Member
Reaction score
10
Yes, I'm using NewGen. No, I do not run a Mac. xD I edited my above post a bit with further changes I've made that does nothing to actually help. ^^"

This is the original code that I had just after converting to Custom Text (It was originally GUI):

JASS:
function Trig_Spawn_Initialization_Copy_Func001Func004Func001A takes nothing returns nothing
    call AdjustPlayerStateBJ( udg_BonusIncome, GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD )
endfunction

function Trig_Spawn_Initialization_Copy_Func001Func004Func007A takes nothing returns nothing
    call CustomVictoryBJ( GetEnumPlayer(), true, true )
endfunction

function Trig_Spawn_Initialization_Copy_Func001Func004C takes nothing returns boolean
    if ( not ( udg_LevelCount == ( udg_CreepCount_LastIndex + 1 ) ) ) then
        return false
    endif
    return true
endfunction

function Trig_Spawn_Initialization_Copy_Func001C takes nothing returns boolean
    if ( not ( udg_LevelCount > 0 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Spawn_Initialization_Copy_Actions takes nothing returns nothing
    if ( Trig_Spawn_Initialization_Copy_Func001C() ) then
        call DisplayTimedTextToForce( udg_inGamePlayers, 5.00, "TRIGSTR_1189" )
        set udg_LevelCount = ( udg_LevelCount + 1 )
        set udg_BonusIncome = ( udg_BonusIncome + 200 )
        if ( Trig_Spawn_Initialization_Copy_Func001Func004C() ) then
            call TriggerSleepAction( 2 )
            call ForForce( udg_inGamePlayers, function Trig_Spawn_Initialization_Copy_Func001Func004Func007A )
        else
            call ForForce( udg_inGamePlayers, function Trig_Spawn_Initialization_Copy_Func001Func004Func001A )
            call CreateTimerDialogBJ( udg_CreepTimer, ( "Wave " + ( I2S(udg_LevelCount) + ( " -" + ( " (" + ( udg_CreepName[udg_LevelCount] + ")" ) ) ) ) ) )
            call StartTimerBJ( udg_CreepTimer, false, 10.00 )
            set udg_CreepTimerWindow = GetLastCreatedTimerDialogBJ()
            call TimerDialogDisplayBJ( true, udg_CreepTimerWindow )
        endif
    else
        set udg_LevelCount = ( udg_LevelCount + 1 )
        set udg_BonusIncome = ( udg_BonusIncome + 200 )
        call CreateTimerDialogBJ( udg_CreepTimer, ( "Wave " + ( I2S(udg_LevelCount) + ( " -" + ( " (" + ( udg_CreepName[udg_LevelCount] + ")" ) ) ) ) ) )
        call StartTimerBJ( udg_CreepTimer, false, 10.00 )
        set udg_CreepTimerWindow = GetLastCreatedTimerDialogBJ()
        call TimerDialogDisplayBJ( true, udg_CreepTimerWindow )
    endif
endfunction

//===========================================================================
function InitTrig_Spawn_Initialization_Copy takes nothing returns nothing
    set gg_trg_Spawn_Initialization_Copy = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Spawn_Initialization_Copy, 5.00 )
    call TriggerRegisterPlayerStateEvent( gg_trg_Spawn_Initialization_Copy, Player(11), PLAYER_STATE_RESOURCE_FOOD_USED, EQUAL, 0.00 )
    call TriggerAddAction( gg_trg_Spawn_Initialization_Copy, function Trig_Spawn_Initialization_Copy_Actions )
endfunction
 

kirinelf

New Member
Reaction score
10
Not too sure what initializing means to be honest. If by initializing you mean I've declared it like this:
Trigger:
  • set LevelCount = 0


Then no, I haven't. But if you're asking what kind of variable it is, it's an Integer, and is supposed to start at 0.

(Sorry, still trying to get my head around most of the terminology.)

The general system is based on a modified system of Andrewgosu's, located here.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top