• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

Fortress Defense Help

Status
Not open for further replies.
Level 5
Joined
Feb 22, 2013
Messages
161
So I am making a map and a problem that I am stuck on is how to trigger a gold amount per 30 seconds with a text tag... Here's how it's supposed to work, you build a gold mine, the gold mine generates 50 gold every thirty seconds and after the thirty seconds, that 50 gold will be added to your current gold amount. The problem is, how do I go about triggering this? I have 4 players that will all be able to build gold mines, so I have no idea how to start this
 
Level 4
Joined
Jan 5, 2014
Messages
79
what about this: every 30 sec pick every gold mine and add 50 gold to its owner?
 
Level 5
Joined
Feb 22, 2013
Messages
161
Upgrades, my friend.. Upgrades adds 50 more gold every 30 seconds: level 2 gold mine gives 100 gold and so on.. Also, Text Tags, and it's 30 seconds after that gold mine is built, not 30 seconds of game time
 
Level 4
Joined
Jan 5, 2014
Messages
79
Do you mean a global upgrade (something which applies for all units) or upgraded version of the gold mine (like gold mine lvl1, gold mine lvl2 and so on)?

EDIT: Does is make a big diffrence if the income is counted separately for each unit and not for all of them at once?
 
Level 5
Joined
Feb 22, 2013
Messages
161
No, each individual gold mine is able to be upgraded dependent on whether the player chooses to upgrade or not... Each player can have up to a total of three gold mines near end game, and each gold mine has a total of five upgrades, also near end game.
 
Level 4
Joined
Jan 5, 2014
Messages
79
i would use this hashtable workaround:

  • Untitled Trigger 001
    • Events
      • Unit - A unit Finishes construction
    • Conditions
      • (Unit-type of (Constructed structure)) Equal to Goldmine lvl1
    • Actions
      • Hashtable - Save 30.00 as 1 of (Key (Constructed structure)) in h
  • Untitled Trigger 002
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Set TempGroup1 = (Units in (Playable map area))
      • Unit Group - Pick every unit in TempGroup1 and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Unit-type of (Picked unit)) Equal to Gold mine lvl1
                  • (Unit-type of (Picked unit)) Equal to Gold mine lvl2
                  • (Unit-type of (Picked unit)) Equal to Gold mine lvl3
                  • (Unit-type of (Picked unit)) Equal to Gold mine lvl4
                  • (Unit-type of (Picked unit)) Equal to Gold mine lvl5
            • Then - Actions
              • Hashtable - Save ((Load 1 of (Key (Picked unit)) from h) - 1.00) as 1 of (Key (Picked unit)) in h
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Load 1 of (Key (Picked unit)) from h) Less than or equal to 0
                • Then - Actions
                  • Hashtable - Save 30.00 as 1 of (Key (Picked unit)) in h
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Unit-type of (Picked unit)) Equal to Gold mine lvl1
                    • Then - Actions
                      • Player - Add 50 to (Owner of (Picked unit)) Current gold
                    • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Unit-type of (Picked unit)) Equal to Gold mine lvl2
                    • Then - Actions
                      • Player - Add 100 to (Owner of (Picked unit)) Current gold
                    • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Unit-type of (Picked unit)) Equal to Gold mine lvl3
                    • Then - Actions
                      • Player - Add 150 to (Owner of (Picked unit)) Current gold
                    • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Unit-type of (Picked unit)) Equal to Gold mine lvl4
                    • Then - Actions
                      • Player - Add 200 to (Owner of (Picked unit)) Current gold
                    • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Unit-type of (Picked unit)) Equal to Gold mine lvl5
                    • Then - Actions
                      • Player - Add 250 to (Owner of (Picked unit)) Current gold
                    • Else - Actions
                • Else - Actions
            • Else - Actions
      • Custom script: call DestroyGroup(udg_TempGroup1)
  • Untitled Trigger 003
    • Events
      • Unit - A unit Dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Gold mine lvl1
          • (Unit-type of (Triggering unit)) Equal to Gold mine lvl2
          • (Unit-type of (Triggering unit)) Equal to Gold mine lvl3
          • (Unit-type of (Triggering unit)) Equal to Gold mine lvl4
          • (Unit-type of (Triggering unit)) Equal to Gold mine lvl5
    • Actions
      • Hashtable - Clear all child hashtables of child (Key (Dying unit)) in (Last created hashtable)
 
Level 5
Joined
Feb 22, 2013
Messages
161
Slight problem. I am running on JNGP 2.07... I guess it's not optimal for version 1.26a of Warcraft because It doesn't list anything in the Key Handle in the function where you save a real handle. However, if I start up the regular WE I can see the extra listings for handle id's just fine.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
Use JASS directly. JNGP has no problem handling hashtable calls as custom script.

Although far from optimal, you could use the normal WorldEdit to make the trigger, then export those particular hashtable actions as custom script. You can then insert them in your JNGP map as an action of custom script. Obviously you can also write the custom script directly if you know JASS but this assumes you do not.
 
Level 5
Joined
Feb 22, 2013
Messages
161
I know how to write JASS, but I just don't know every function in the system to implement of Warcraft.. I was thinking about doing it that way, it was just weird that JNGP doesn't have the Handle Id action, but normal one does
 
Level 25
Joined
May 11, 2007
Messages
4,651
Add a hidden passive to the gold mines, when you build them set the level of this ability to the 50 x level you want.

Then Add all units of Gold Types to a goldGroupPlayer[player] for every player, then just:
Pick every unit in goldGroupPlayer[player]
Player - Add 50 x Unit level of gold ability (hidden) to player.
 
Level 5
Joined
Feb 22, 2013
Messages
161
By the way MB. I noticed that the one second periodic check will activate before a gold mine is even complete because it's still considered a unit before it's complete. So it'll add gold before it's complete
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
Unless completion is a major part of the income system then that would not really be an issue. The solution in that case would be to keep track of the buildings based on the various completion events adding them to counters or groups. The group based approach can get away with checking unit death every iteration but the counter based approach will need an on death event trigger to decrement the counters correctly.
 
Level 5
Joined
Feb 22, 2013
Messages
161
Completion is a want and a need in my case just because I want the gold timer for giving gold to start after the completion, and it is needed because it will give players extra gold otherwise which I do not want.. Here is what I have so far of this income system so far, it consists of two triggers:

JASS:
function periodicCheckCallBack takes nothing returns boolean
    if GetUnitTypeId(GetEnumUnit()) == 'hgm0' or GetUnitTypeId(GetEnumUnit()) == 'hgm1' or GetUnitTypeId(GetEnumUnit()) == 'hgm2' or GetUnitTypeId(GetEnumUnit()) == 'hgm3' or GetUnitTypeId(GetEnumUnit()) == 'hgm4' then
        call SaveReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1, LoadReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1) - 1.00)
        if LoadReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1) <= 0.00 then
            call SaveReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1, 30.00)
            if GetUnitTypeId(GetEnumUnit()) == 'hgm0' then
                call SetPlayerState(GetOwningPlayer(GetEnumUnit()), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(GetEnumUnit()), PLAYER_STATE_RESOURCE_GOLD) + 50)
                call BJDebugMsg("Gold added.")    
            endif
        endif
    endif
    return false
endfunction

function periodicCheckActions takes nothing returns nothing
    local group g
    
    set g = CreateGroup()
    call GroupEnumUnitsInRect(g, gg_rct_fortressRevealArea, null)
    call ForGroup(g, function periodicCheckCallBack)
    
    call DestroyGroup(g)
    set g = null
endfunction

//===========================================================================
function InitTrig_periodicGoldCheck takes nothing returns nothing
    set gg_trg_periodicGoldCheck = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_periodicGoldCheck, 1.00 )
    call TriggerAddAction( gg_trg_periodicGoldCheck, function periodicCheckActions )
endfunction

JASS:
function addCompletedGM takes nothing returns boolean
    
    if GetUnitTypeId(GetConstructedStructure()) == 'hgm0' then
        call SaveReal(udg_goldMineHash, GetHandleId(GetConstructedStructure()), 1, 30.00)
        call BJDebugMsg("Gold timer started.")
    endif
     
    return false  
endfunction

//===========================================================================
function InitTrig_addCompletedGM takes nothing returns nothing
    set gg_trg_addCompletedGM = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_addCompletedGM, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
    call TriggerAddAction( gg_trg_addCompletedGM, function addCompletedGM )
endfunction
 
Level 5
Joined
Feb 22, 2013
Messages
161
I have not cleared handles because I need to figure out how to do this by order of: Completion, gold given timer loop start, and then after all that then I can worry about clearing child hash tables
 
Level 4
Joined
Mar 20, 2014
Messages
67
RupTure,
I have the exact thing in my map, I used a point value of the unit (The thing you can set in the object editor), it's under Stats - Point Value, set it to your desired income. Then make a unit group. Here's what I would do.
JASS:
globals
    unit group array GoldMines[# Of Players]
endglobals

function AddGM takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer array gmtype
local integer i = 1
local integer stop = 3 (# of gold mine levels)
set gmtype[1] = ''
set gmtype[2] = ''
set gmtype[3] = ''
loop
    exitwhen i > stop
    if (gmtype[i] == GetUnitTypeId(u)) then
        call GroupAddUnit(GoldMines[GetPlayerId(GetOwningPlayer(u))], u)
    endif
    set i = i + 1
endloop
set u = null
endfunction

function GMSetup takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
local integer z = GetPlayers()
loop
     exitwhen i > z
     set GoldMines[i] = CreateGroup()
     set z = z + 1
endloop
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_UPGRADE_START )
call TriggerAddCondition( t, Condition(function AddGM))
return false
endfunction

And then a timer for it

JASS:
function GiveGold takes nothing returns nothing
local unit u = GetEnumUnit()
local integer p = GetUnitPointValue(u)
    call AdjustPlayerStateBJ( p, Player(GetPlayerId(GetOwningPlayer(u))), PLAYER_STATE_RESOURCE_GOLD)
set u = null
endfunction

function GMIncome takes nothing returns boolean
local integer i = 0
local integer stop = GetPlayers()
loop
    exitwhen i > stop
    call ForGroup(GoldMines[i], function GiveGold)
    set i = i + 1
endloop
return false
endfunction

function TimerIncome takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterTimerEventPeriodic( t, 30.00 )
call TriggerAddCondition(t, Condition(function GMIncome))
endfunction

That should work. Just paste into separate triggers each block of JASS code. If not let me know and I'll debug it. For the first trigger make sure you input the unit type ID's of the Gold Mine units, and then it should work. You get those by pressing Control + D if you were unsure.

What this does is when the units finish construction or being upgraded to another gold mine it adds it / readds it to the group which is then looped through every 30 seconds and adjusts the players gold.

Make sure you don't forget to set the units point value in the Object Editor either. Also GoldMines is a group, which is adjusted for each player. In the globals field make sure you set the number of players 0-11 (In JASS Player(0) is Red.)

- Zach
 
Level 5
Joined
Feb 22, 2013
Messages
161
Alright, I can do it this way I suppose.. However this all begs the question I had still: how can I add a text tag to this to signify that gold has been added?
 
Level 5
Joined
Feb 22, 2013
Messages
161
So I finally got it to do what I want. However, I tried to put a text tag in there. This is what I have:

JASS:
function addGoldMine takes nothing returns boolean
    local integer i = 0
    local integer array goldMineId
    local integer maxUpgrade = 4
    
    set goldMineId[0] = 'hgm0'
    set goldMineId[1] = 'hgm1'
    set goldMineId[2] = 'hgm2'
    set goldMineId[3] = 'hgm3'
    set goldMineId[4] = 'hgm4'
    loop
        exitwhen i > 4
        if goldMineId[i] == GetUnitTypeId(GetTriggerUnit()) then
            call GroupAddUnit(udg_playerGoldMines[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))], GetTriggerUnit())
            call SaveReal(udg_goldMineHash, GetHandleId(GetTriggerUnit()), 1, 30.00)
            set udg_goldTextTag[GetHandleId(GetTriggerUnit())] = CreateTextTag()
        endif
        set i = i + 1
    endloop
    return false
endfunction

//===========================================================================
function InitTrig_addGoldMine takes nothing returns nothing
    set gg_trg_addGoldMine = CreateTrigger(  )
    
    set udg_playerGoldMines[1] = CreateGroup()
    set udg_playerGoldMines[9] = CreateGroup()
    
    call TriggerRegisterAnyUnitEventBJ( gg_trg_addGoldMine, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_addGoldMine, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
    call TriggerAddCondition( gg_trg_addGoldMine, Condition(function addGoldMine ))
endfunction

JASS:
function goldMineIncomeCB takes nothing returns nothing
    call SaveReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1, LoadReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1) - 1.00)
    if LoadReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1) <= 0 then
        call SaveReal(udg_goldMineHash, GetHandleId(GetEnumUnit()), 1, 30.00)
        call SetPlayerState(GetOwningPlayer(GetEnumUnit()), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(GetEnumUnit()), PLAYER_STATE_RESOURCE_GOLD) + GetUnitPointValue(GetEnumUnit()))
        call SetTextTagText(udg_goldTextTag[GetHandleId(GetEnumUnit())], I2S(GetUnitPointValue(GetEnumUnit())), 0.023)
        call SetTextTagPos(udg_goldTextTag[GetHandleId(GetEnumUnit())], GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()) - 128.00, 128.00)
        call SetTextTagColor(udg_goldTextTag[GetHandleId(GetEnumUnit())], 255, 204, 0, 255)
        call SetTextTagVisibility(udg_goldTextTag[GetHandleId(GetEnumUnit())], true)
    endif
endfunction

function goldMineIncome takes nothing returns nothing
    call ForGroup(udg_playerGoldMines[1], function goldMineIncomeCB)
    call ForGroup(udg_playerGoldMines[9], function goldMineIncomeCB)
endfunction

//===========================================================================
function InitTrig_goldMineIncome takes nothing returns nothing
    set gg_trg_goldMineIncome = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_goldMineIncome, 1.00 )
    call TriggerAddAction( gg_trg_goldMineIncome, function goldMineIncome )
endfunction

I am not worried about leaks, I will fix them later on. Anyways, the floating text does not show itself in-game for some reason...
 
Status
Not open for further replies.
Top