• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Player(i) Leaves, do <this>

Status
Not open for further replies.
Level 6
Joined
Jun 30, 2006
Messages
230
JASS:
function PlayerAllianceLeavesGold takes nothing returns nothing
    local integer gold = (GetPlayerState( Player(0), PLAYER_STATE_RESOURCE_GOLD ) + 500) / {stuck here, should be the number of the players in the group udg_Alliance after removing the leaving player}
    call SetPlayerState( GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD ) + gold )
endfunction

function PlayerAllianceLeavesActions takes nothing returns nothing
    call ForceRemovePlayerSimple( Player(0), GetPlayersAll() )
    call ForForce( udg_Alliance, function PlayerAllianceLeavesGold )
    // the following set the research level to zero so that creeps for that player quit spawning
    call SetPlayerTechResearchedSwap( 'R004', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R005', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R007', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R008', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R009', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00A', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00B', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00C', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00D', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00E', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00F', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00G', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00H', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00V', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00W', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R00Y', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R011', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R012', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R013', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R014', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R018', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R019', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R01E', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R01F', 0, Player(0) )
    call SetPlayerTechResearchedSwap( 'R01I', 0, Player(0) )
endfunction

//===========================================================================
function InitTrig_PlayerAllianceLeaves takes nothing returns nothing
    set gg_trg_PlayerAllianceLeaves = CreateTrigger(  )
    call TriggerRegisterPlayerEventLeave( gg_trg_PlayerAllianceLeaves, Player(0) )
    call TriggerAddAction( gg_trg_PlayerAllianceLeaves, function PlayerAllianceLeavesActions )
endfunction
I'm stuck in two parts. The first being the how do you count the number of players in a group?
Second part would be replacing Player(0) with something dynamic such as Player(i), i being an integer from 0-4(the numbers of the players I want), and setting the actions accordingly. I do know how to do loops, but I've never succesfully done one for an event or such. Help?
 
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
Part 1;

JASS:
local force f = <some force>
local force bak = CreateForce()
local player p
local integer pc = 0 //pc stands for player count, name your variable whatever you wish
loop
    set p = ForcePickRandomPlayer( f )
    exitwhen p == null
    set pc = pc + 1
    call ForceAddPlayer( bak, p )
    call ForceRemovePlayer( f, p )
endloop
set <some force> = bak //restore the old force should you need it again. Any reference to bak can be removed if you don't.
call DestroyForce( f )
//do whatever with pc
set f = null
set bak = null

Part 2;

(removed the nasty disassociator/wrapper function TriggerRegisterPlayerEventLeave)

JASS:
function InitTrig_PlayerAllianceLeaves takes nothing returns nothing
    local integer i = 0
    set gg_trg_PlayerAllianceLeaves = CreateTrigger()
    loop
        exitwhen i > (a number)
        call TriggerRegisterPlayerEvent( gg_trg_PlayerAllianceLeaves, Player( i ), EVENT_PLAYER_LEAVE )
        set i = i + 1
    endloop
    call TriggerAddAction( gg_trg_PlayerAllianceLeaves, function PlayerAllianceLeaves )
endfunction

Side note;

JASS:
function SetPlayerTechResearchedSwap takes integer techid, integer levels, player whichPlayer returns nothing
    call SetPlayerTechResearched(whichPlayer, techid, levels)
endfunction
 
Level 6
Joined
Jun 30, 2006
Messages
230
Thanks, purple, but I don't understand Part 1. Why ForcePickRandomPlayer() instead of the leaving player? I stumbled across CountPlayersInForceBJ. It's code:
JASS:
function CountPlayersInForceBJ takes force f returns integer
    set bj_forceCountPlayers = 0
    call ForForce(f, function CountPlayersInForceEnum)
    return bj_forceCountPlayers
endfunction
Isn't that more efficient that what you gave me? With the BJ junk removed, of course.
I don't understand why bak? What good is creating a force, create a backup of the same force, and destroying the first? Doesn't that have the same problem of not destroying it at all?

If I understand the rest, you simply hooked me up with a dynamic Player Leaves event. +rep :) But, shouldn't
JASS:
call TriggerAddAction( gg_trg_PlayerAllianceLeaves, function PlayerAllianceLeaves )
be:
JASS:
call TriggerAddAction( gg_trg_PlayerAllianceLeaves, function PlayerAllianceLeavesActions )
?

There's a problem with my logic in setting the research to lvl 0. Once it's been researched, it can't be set back. The solution? I think it's to add another level to the research, set the max research at 1, and when the player leaves, set the max to 2, set all the researches to lvl 2, set max back to 1, and change my spawn trigger so that the units only spawn when the research is lvl 1 versus setting it to Greater than Zero? Am I right?

What I'm using now:
JASS:
function PlayerAllianceLeavesGold takes integer i returns nothing
    local force f = udg_Alliance
    local force bak = CreateForce()
    local player p
    local integer pc = 0
    local integer Gold
    loop
        set p = ForcePickRandomPlayer( f )
        exitwhen p == null
        set pc = pc + 1
        call ForceAddPlayer( bak, p )
        call ForceRemovePlayer( f, p )
    endloop
    call DestroyForce( f )
    set f = null
    set bak = null
    set Gold = (GetPlayerState( Player(i), PLAYER_STATE_RESOURCE_GOLD ) + 500) / (pc)
    call SetPlayerState( GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState( GetEnumPlayer(), PLAYER_STATE_RESOURCE_GOLD ) + Gold )
endfunction
function PlayerAllianceLeavesActions takes integer i returns nothing
    local integer u = 0
    call ForceRemovePlayer( udg_Alliance, Player(i) )
    call ForForce( udg_Alliance, function PlayerAllianceLeavesGold(i) )
    loop
        exitwhen u > 49
        call SetPlayerTechResearched( Player(i), udg_ResearchId[u], 2 )
        set u = u + 1
    endloop
endfunction

//===========================================================================
function InitTrig_PlayerAllianceLeaves takes nothing returns nothing
    local integer i = 0
    set gg_trg_PlayerAllianceLeaves = CreateTrigger()
    loop
        exitwhen i > (4)
        call TriggerRegisterPlayerEvent( gg_trg_PlayerAllianceLeaves, Player( i ), EVENT_PLAYER_LEAVE )
        call TriggerAddAction( gg_trg_PlayerAllianceLeaves, function PlayerAllianceLeavesActions(i) )
        set i = i + 1
    endloop
endfunction
Doesn't work, gives me syntax errors when I try to pass i onto other functions :/
 
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
Mine just loops through the force and such, but yeah, the other way is slightly more efficient.

Actions -- yeah, I was typing from scratch and I didn't notice the Actions at the end of the function name >_>

For spawning, you could always just not spawn if (condition) that has no relation to the upgrade, because no, you can't decrease the level of an upgrade

And Actions can't have parameters.

Take the actions out of the loop.

i == GetPlayerId(GetTriggerPlayer())
 
Level 6
Joined
Jun 30, 2006
Messages
230
Problem: taking the action out of the loop destroys the ability to add all the Actions according to the player who left, see? Without it, lets say Player One leaves. What happens? All players on his team get some gold, he's removed from the force, and ALL players researches are set to lvl 2, see? Because the Actions aren't done according to the player who leaves. Without it, it would say if any of these players leave, do whatever for.... oh wait. It just clicked. Thanks again, I get no errors now, but my other 3 comps crashed (yes, ALL of them on the same day. Now that's a bad day), so I can't test it. Could someone help me out?

It's designed so when a player leaves, his force gets the leaving players gold plus some more divided by the amount of remaining players, and the leaving player's creeps quit spawning. The Map
 
Level 6
Joined
Jun 30, 2006
Messages
230
Yeah, it clicked half-way through the post. Could you test my map for me? Meaning test to see if when a player leaves, is teammates( must be active players) get some gold and they quit spawning units?

The Map
 
Last edited:
Status
Not open for further replies.
Top