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.
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top