• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Here We go...

Status
Not open for further replies.
Level 12
Joined
Dec 25, 2010
Messages
972
All right here we go:
I'm trying to do a test in that: i'm trying to replace the Town hall with a new building ("Outpost-type", being able to build workers and store resource but it doesn't give you much tech access, like barracks and farm) and limit the Town Hall and it's upgrades, Keep and Castle, to 1 so long as the starting town hall lives. If the Town Hall/Keep/Castle is destroyed. you can upgrade the "outpost-type" building to the town hall, but the limit will return when the upgrade begins.
is there any way to do this with scripts. because i'm having problems when i'm using the if/then/else multiple script
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
A good way to solve these techtree problems is by creating a dummy unit with the name "You can have only 1 town hall". To build a town hall you need as techtree requirements this dummy. When you have a townhall, you remove the dummy. If your town hall gets destroyed you create a dummy for this player.

Edit:
If multiple buildings are upgraded at the same time, all of them but one must be canceled.
Check the map out. You can only upgrade one guard tower.
 

Attachments

  • OnlyOne.w3x
    18.5 KB · Views: 37
Last edited:
Level 12
Joined
Dec 25, 2010
Messages
972
Clever
I'll test the system.
Thanks.

By the way @Jampion
How can I add new buildings to the system?
because I want to encompass the keep and the castle with the town hall.
 
Last edited:
Level 16
Joined
Mar 24, 2017
Messages
827
You could just limit the number of these buildings to 1 using a trigger if you dont want the player building more, also set up triggers such that if a keep or castle exist a new town hall cannot be built.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
By the way @Jampion
How can I add new buildings to the system?
because I want to encompass the keep and the castle with the town hall.
Sorry for the late response, I did not see it earlier.
Right now you can have only one guard tower. Upgrading this guard tower would be no problem, as there will always only be one guard tower, so you also can only upgrade this one.

1.
If you have guard tower + arcane tower and you only want one in total, you can just copy the Build/Kill/Cancel Triggers and change the unit type to arcane tower.
The UpgradeOnlyOne Trigger is independant of unit-type (at least in its functionality) so you don't have to copy or adjust it.

2.
If you have guard tower + arcane tower and you only want one of each type, you can do it like above, just that you need to use a different dummy unit type (onlyonearcanetower). This dummy unit must be initialized (see map initialization with the other dummy).
UpgradeOnlyOne will work here as well.

Which one do you need (1./2.)? Or did you mean something different?



You will need to edit the UpgradeOnlyOne trigger though to have the right amount of gold/lumber returned depending on the unit type.
 
Level 12
Joined
Dec 25, 2010
Messages
972
Sorry for the late response, I did not see it earlier.
Right now you can have only one guard tower. Upgrading this guard tower would be no problem, as there will always only be one guard tower, so you also can only upgrade this one.

1.
If you have guard tower + arcane tower and you only want one in total, you can just copy the Build/Kill/Cancel Triggers and change the unit type to arcane tower.
The UpgradeOnlyOne Trigger is independant of unit-type (at least in its functionality) so you don't have to copy or adjust it.

2.
If you have guard tower + arcane tower and you only want one of each type, you can do it like above, just that you need to use a different dummy unit type (onlyonearcanetower). This dummy unit must be initialized (see map initialization with the other dummy).
UpgradeOnlyOne will work here as well.

Which one do you need (1./2.)? Or did you mean something different?



You will need to edit the UpgradeOnlyOne trigger though to have the right amount of gold/lumber returned depending on the unit type.

i wanted to upgrade the town hall to keep and then to castle.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
i wanted to upgrade the town hall to keep and then to castle.
If you have already made it so only one keep can be upgraded from the townhalls, you do not have to worry about the castle upgrade (since you only have one keep that can be upgraded anyways). You will have to adjust the kill trigger though, because when the castle is killed you should be able to upgrade to keep again. Cancel trigger must not include the castle, because if canceled you still have a keep.

So basically:
Build trigger only for tier 2 (after building it's tier 2)
Cancel trigger only for tier 1 (after cancelling it's tier 1)
Kill trigger for all tiers >= 2
Tier 2 would be the first that is limited to only 1.

UpgradeOnlyOne needs only be adjusted for cancel refunds. In this case upgrade to 2 must be refunded. (refunds depend on cost of upgrade and cancel refund ratio (gameplay constants))
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
JASS:
function Trig_UpgradeOnlyOne_Actions takes nothing returns nothing
    local group g
    local unit u
    local player p
    set p = GetOwningPlayer(udg_NotCancel)
    call DisableTrigger(gg_trg_Cancel)
    set g=CreateGroup()
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g,u)
        if(u!=udg_NotCancel and GetOwningPlayer(u) == p and GetUnitTypeId(u)==GetUnitTypeId(udg_NotCancel)) then
            call IssueImmediateOrderById (u, 851976)
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+20)
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)+15)
        endif
    endloop
    call DestroyGroup(g)
    call EnableTrigger(gg_trg_Cancel)
    set p = null
    set g = null
    set u= null
endfunction
The lines
JASS:
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+20)
call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)+15)
refund gold/lumber. A guard tower costs 80/60 and default refund ratio is 25% so it's 20/15.
In your case if the keep is the only unit-type that is limited to one (castle does not count since it's a upgrade from a limited unit) you do not need to distiniguish between the unit-types that were canceled.

If you will have multiple unit-types limited to one you need to add conditions.
It's best to use local variables, so you do not have to always use these two lines.
The numbers (gold and lumber) are not correct. They should be 25% of the upgrade costs, but I was too lazy to look it up.
JASS:
function Trig_UpgradeOnlyOne_Actions takes nothing returns nothing
    local group g
    local unit u
    local player p
 
    local integer gold
    local integer lumber
 
    set p = GetOwningPlayer(udg_NotCancel)
    call DisableTrigger(gg_trg_Cancel)
    set g=CreateGroup()
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g,u)
        if(u!=udg_NotCancel and GetOwningPlayer(u) == p and GetUnitTypeId(u)==GetUnitTypeId(udg_NotCancel)) then
            call IssueImmediateOrderById (u, 851976)
         
            if(GetUnitTypeId(u)=='hkee') then //keep
                set gold = 100
                set lumber = 60
            elseif(GetUnitTypeId(u)=='ostr') then //stronghold
                set gold = 90
                set lumber = 70
            endif
         
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+gold)
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)+lumber)
        endif
    endloop
    call DestroyGroup(g)
    call EnableTrigger(gg_trg_Cancel)
    set p = null
    set g = null
    set u= null
endfunction
 
Level 12
Joined
Dec 25, 2010
Messages
972
JASS:
function Trig_UpgradeOnlyOne_Actions takes nothing returns nothing
    local group g
    local unit u
    local player p
    set p = GetOwningPlayer(udg_NotCancel)
    call DisableTrigger(gg_trg_Cancel)
    set g=CreateGroup()
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g,u)
        if(u!=udg_NotCancel and GetOwningPlayer(u) == p and GetUnitTypeId(u)==GetUnitTypeId(udg_NotCancel)) then
            call IssueImmediateOrderById (u, 851976)
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+20)
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)+15)
        endif
    endloop
    call DestroyGroup(g)
    call EnableTrigger(gg_trg_Cancel)
    set p = null
    set g = null
    set u= null
endfunction
The lines
JASS:
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+20)
call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)+15)
refund gold/lumber. A guard tower costs 80/60 and default refund ratio is 25% so it's 20/15.
In your case if the keep is the only unit-type that is limited to one (castle does not count since it's a upgrade from a limited unit) you do not need to distiniguish between the unit-types that were canceled.

If you will have multiple unit-types limited to one you need to add conditions.
It's best to use local variables, so you do not have to always use these two lines.
The numbers (gold and lumber) are not correct. They should be 25% of the upgrade costs, but I was too lazy to look it up.
JASS:
function Trig_UpgradeOnlyOne_Actions takes nothing returns nothing
    local group g
    local unit u
    local player p
 
    local integer gold
    local integer lumber
 
    set p = GetOwningPlayer(udg_NotCancel)
    call DisableTrigger(gg_trg_Cancel)
    set g=CreateGroup()
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g,u)
        if(u!=udg_NotCancel and GetOwningPlayer(u) == p and GetUnitTypeId(u)==GetUnitTypeId(udg_NotCancel)) then
            call IssueImmediateOrderById (u, 851976)
        
            if(GetUnitTypeId(u)=='hkee') then //keep
                set gold = 100
                set lumber = 60
            elseif(GetUnitTypeId(u)=='ostr') then //stronghold
                set gold = 90
                set lumber = 70
            endif
        
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)+gold)
            call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)+lumber)
        endif
    endloop
    call DestroyGroup(g)
    call EnableTrigger(gg_trg_Cancel)
    set p = null
    set g = null
    set u= null
endfunction

This system is exclusive to the Citadel (Human) Faction.
But thanks
 
Status
Not open for further replies.
Top