• 🏆 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!

[cJASS][WIP]Team Manager Feedback

Status
Not open for further replies.
Level 31
Joined
Jul 10, 2007
Messages
6,306
Edit
Official 1.0

JASS:
library TeamManager uses PlayerTracker { 
/*Utility Information
===================================================================
Name: C Team Player Manager
Version: 1.0
Author: Nestharus

Settings:
*///===================================================================
    define private TEAM_MAX_SIZE = 12 //how many players can be in a team, should be max players for your current game
    define private DO_TEAM_ALLIANCES = true //can teams ally and be neutral to each other?
    define private AUTO_REMOVE_TEAMS = true //if a team has no players after a player is removed, remove that team?
    define private AUTO_GAME_OVER_CHECK = true //if a team is destroyed and all remaining teams are allies, game over?
    define private DO_PLAYER_DRIVEN_SETUP = true //if this is enabled, use TeamManager.playerSetup to set your teams up
    
    //Whether or not to do specific team alliance properties. If something here is false, it is removed from system
    define private DO_SHARED_XP = true
    define private DO_SHARED_SPELLS = true
    define private DO_SHARED_VISION = true
    define private DO_SHARED_CONTROL = false
    define private DO_SHARED_ADV_CONTROL = false
    
    //these will only run if AUTO_GAME_OVER_CHECK is true
    //////////////////////////////////////////////////////////////////////////////
    //Code to run when game is over and there are winners. ActiveTeams will always be winners
    //! textmacro GAME_OVER_CODE
    //! endtextmacro
    
    //Code to run when there is no winner
    //! textmacro GAME_OVER_CODE_NO_WINNER
    //! endtextmacro
    //////////////////////////////////////////////////////////////////////////////
    
    //What PLAYER_TYPE do you want?
    //Supported Player Types- Human, Computer, InactivePlayer, ActivePlayer
    define <TeamManager.PLAYER_TYPE> = Human
    
    //these will only be applicable if DO_PLAYER_DRIVEN_SETUP
    //////////////////////////////////////////////////////////////////////////////
    define private PlayerDrivenInterfaceData = {//This is where you put your structs and globals etc for your interface code
        //Put stuff here
        //Put stuff here
    }//PlayerDrivenInterfaceData
    
    define private PlayerDrivenInterfaceCode = {//this is where run time code goes for your interface
        //Do stuff
        //Do stuff
    }//PlayerDrivenInterfaceCode
    
    define private PlayerDrivenInterfaceProperties = {
        private int GetPlayerVoteCount() {//used to retrieve total vote count
            return Get##TeamManager.PLAYER_TYPE##Count() //default value, can change it but not suggested
        }//GetPlayerVoteCount
    }//PlayerDrivenInterfaceProperties
    //////////////////////////////////////////////////////////////////////////////
    
    //Default Values for Team Alliance Properties
    define private TEAM_DEFAULT_ALLIANCE_VALUES = {
        #if DO_SHARED_XP
            public static constant bool SHARED_XP = true
        #endif
        #if DO_SHARED_SPELLS
            public static constant bool SHARED_SPELLS = true
        #endif
        #if DO_SHARED_VISION
            public static constant bool SHARED_VISION = true
        #endif
        #if DO_SHARED_CONTROL
            public static constant bool SHARED_CONTROL = false
        #endif
        #if DO_SHARED_ADV_CONTROL
            public static constant bool SHARED_ADV_CONTROL = false
        #endif
    }
/*//===================================================================

Description:
    Team Manager requires that all players that are to be in TeamManager teams be unallied. This can be done in
    Force Properties under Scenario. Uncheck all the check boxes if you want the force to run.
    
    Automatic Management of Alliances
        When DO_TEAM_ALLIANCES is marked as true, TeamManager will manage alliances between teams quickly and easily.
        Alliances include neutral and allied alliance. If a team is neither of those, it's an enemy. As players
        are added and removed from teams, their alliances with all players on all teams with a standing to the team
        they are joining/leaving will be modified.
        
        Team 1 is allied to Team 2
        Team 2 has player 6
        Player 1 joins Team 1
        Player 6 and Player 1 are automatically allied
        
        When allying/unallying two teams, all players on each team will be modified accordingly
        Team 1 unallies Team 2
        Player 6 and Player 1 are no longer allies
        
    Automatic Team Removal
        If AUTO_REMOVE_TEAMS is true, teams will be automatically destroyed when there are no players left in them
        as .removePlayer is used.
        
    Automatic Game Over Check
        If AUTO_GAME_OVER_CHECK is true, TeamManager will automatically check if the game is over as teams
        are destroyed by seeing if all remaining teams are allied or if there is only one team left.
        
        GAME_OVER_CODE is run when the game ends and all active teams are the winners.
        
        GAME_OVER_CODE_NO_WINNER is run if for some reason there are no active teams left (no winners)
        
    Automatic Team Setup with 3 ways of doing it and an open interface
        StaticSetup-
            1- The teams will be set up based on what teams the players are in in the game lobby (your forces)
            2- The teams will be set up based on a team count. In this case, players are put into teams based on their
                player id. If team count is 4, players 0-2 will be on team 1, 3-5 on team 2, etc.
                
        DynamicSetup-
            Balances out the teams as much as possible given a team count. If there are 10 players and 6 teams,
            teams 1 through 5 will have 2 players and team 6 will have 0
            2, 2, 2, 2
            1, 1 -> 2
            
        PlayerDrivenSetup-
            Players vote for how big they want their teams to be and teams are set up accordingly so
            everyone is as happy as possible. It allows a user defined interface (data area and run time area)
            and provides an API for recording votes. It also has a time limit feature.

        Loops-
            tloop(team loop)- loop through active teams
            tploop(team's players loop)- loop through players on a team
            ptloop(player's teams loop)- loop through teams a player is on 
            taloop(team alliances)- loop through a team's alliance teams
            tnloop(team neutrals)- loop through a team's neutral teams
        
Requirements: PlayerTracker

Installation: Unallied Forces
    
API
------------------------------------------------------------------
ActiveTeam-
public int operator count()
    Returns how many teams there are
    
public int get(int index)
    Retrieves an active team given an indexed index
    
    Example-
        Team myTeam = ActiveTeam.get(ActiveTeam.count-1)
        
TeamPlayer-
------------------------------------------------------------------
public int operator teamCount()
    Returns how many teams the player is on
    
    Example-
        int playerTeamCount = TeamPlayer[0].teamCount
        
public int getTeam(int index)
    Retrieves a team a player is on given an indexed id
    
    Example-
        Team myTeam = TeamPlayer[0].getTeam(TeamPlayer[0].teamCount)
        
public bool isOnTeam(int teamId)
    Determines whether or not a player is on a team
    
    Example-
        bool isOnTeam = Player[0].isOnTeam(GetActiveTeam(0))
        
public bool isAllied(int playerId)
    Determines whether a player is allied or not to another player
    
    Example-
        if TeamPlayer[0].isAllied(1) {
            prinf("Player 0 is allied to Player 1")
        }//if
        else {
            printf("Player 0 is not allied to Player 1")
        }//else
        
public bool isNeutral(int playerId) - DO_TEAM_ALLIANCES
    Determines whether a player is neutral or not to another player
    
    Example-
        if TeamPlayer[0].isNeutral(1) {
            prinf("Player 0 is neutral to Player 1")
        }//if
        else {
            printf("Player 0 is not neutral to Player 1")
        }//else
        
Team-
------------------------------------------------------------------
Default Team Alliance Values-
    public static constant bool SHARED_XP - DO_SHARED_XP
    public static constant bool SHARED_SPELLS - DO_SHARED_SPELLS
    public static constant bool SHARED_VISION - DO_SHARED_VISION
    public static constant bool SHARED_CONTROL - DO_SHARED_CONTROL
    public static constant bool SHARED_ADV_CONTROL - DO_SHARED_ADV_CONTROL
    
Team Specific Alliance Values-
    public bool sharedXp - DO_SHARED_XP
    public bool sharedSpells - DO_SHARED_SPELLS
    public bool sharedVision - DO_SHARED_VISION
    public bool sharedControl - DO_SHARED_CONTROL
    public bool sharedAdvControl - DO_SHARED_ADV_CONTROL

public int teamNumber-
    A number that can be assigned to a team. Doesn't do anything, but useful for games with specific areas
    for different teams.
    
public int operator size()
    Retrieves how many players are on the team
    
public int operator neutralCount() - DO_TEAM_ALLIANCES
    Retrieves how many neutral alliances the team has with other teams
    
public int operator allyCount() - DO_TEAM_ALLIANCES
    Retrieves how many allied alliances the team has with other teams
    
public int getPlayer(int index)
    Retrieves a player id from a team given an indexed id for that team
    
    Example-
        int myPlayerId = myTeam.getPlayer(myTeam.size-1)
        
public int getNeutral(int index) - DO_TEAM_ALLIANCES
    Retrieves a team that has a neutral alliance with this team given an indexed id for this team
    
    Example-
        Team neutralTeam = myTeam.getNeutral(myTeam.neutralCount-1)
        
public int getAlly(int index) - DO_TEAM_ALLIANCES
    Retrieves a team that has an allied alliance with this team given an indexed id for this team
    
    Example-
        Team alliedTeam = myTeam.getAlly(myTeam.allyCount-1)

public void destroy()
    Destroys the team clearing out all alliancs and players
    
public bool isAllied(Team team2) - DO_TEAM_ALLIANCES
    Determines whether this team is allied with another team
    
    Example-
        bool areTheyAllied = myTeam.isAllied(shadyTeam)
        
public bool isNeutral(Team team2) - DO_TEAM_ALLIANCES
    Determines whether this team is neutral to another team
    
    Example-
        bool areTheyNeutral = myTeam.isNeutral(shadyTeam)
        
public static void neutralTeam(Team team1, Team team2) - DO_TEAM_ALLIANCES
    Adds a neutral flag to two teams. The teams won't be neutral unless they aren't allies, but the flag
    will be there in case they stop being allies.
    
    Example-
        Team.neutralTeam(myTeam, shadyTeam)
    
public static void allyTeams(Team team1, Team team2) - DO_TEAM_ALLIANCES
    Adds an ally flag to two teams. The teams will become allies no matter what.
    
    Example-
        Team.allyTeams(myTeam, shadyTeam)
        
public static void unallyTeams(Team team1, Team team2) - DO_TEAM_ALLIANCES
    Removes an ally flag from two teams. The teams will stop being allies. If they have a neutral flag,
    they will become neutral rather than become enemies.
    
    Example-
        Team.unallyTeams(myTeam, shadyTeam)
        
public static void removeNeutralTeams(Team team1, Team team2) - DO_TEAM_ALLIANCES
    Removes a neutral flag from two teams. If the teams are allied, they will still be allied.
    
    Example-
        Team.removeNeutralTeams(myTeam, shadyTeam)

public void addPlayer(int playerId)
    Adds a player to a team given a player id. Players added to teams will automatically have their alliances
    altered in regards to all players on that team. The alliances will also be altered for all players on allied and
    neutral teams for that team.
    
    Example-
        myTeam.addPlayer(4)
        
public void removePlayer(int playerId)
    Removes a player from a team given a player id. Players removed from teams will automatically have their alliances
    altered in regards to all players on that team. The alliances will also be altered for all players on allied and
    neutral teams for that team.
    
    Example-
        myTeam.removePlayer(4)
        
public static Team create()
    Creates a new team

Team Setups-
------------------------------------------------------------------
TeamManager.staticSetup
    Generates run time code for automatically setting up teams. Teams set up in this way
    will be based on the forces they are on in the game lobby.
    
    Force 1-
        Player 0
        Empty
        Empty
    
    Force 2-
        Player 2
        Empty
        Player 3
        
    With automatic team setup-
        Force 1- Player 0
        Force 2- Player 2, 3
        
    scope Test initializer Initialization {
        private void Initialization() {
            TeamManager.staticSetup
        }//Initialization
    }//Test
        
TeamManager.staticSetup(teamCount)
    Generates run time code for automatically setting up teams. Teams set up in this way
    will be based on the player ids and the teamCount specified.
    
    Team Count = 6
    
    Force 1-
        Player 0
        Empty
        Empty
        
    Force 2-
        Player 2
        Player 3
        Player 6
        
    With automatic team setup-
        Force 1- Player 0
        Force 2- Player 2, 3
        Force 3- Empty
        Force 4- Player 6
        
    scope Test initializer Initialization {
        private void Initialization() {
            TeamManager.staticSetup(6)
        }//Initialization
    }//Test
        
TeamManager.dynamicSetup(teamCount, teamSize)
    Generates run time code for automatically setting up teams. Teams set up in this way
    will be based on the total player count and team count. The teams will be as balanced as possible across
    as many teams as possible
    
    Team Count = 3
    Team Size = 4
    
    Force 1-
        Player 0
        Empty
        Empty
        
    Force 2-
        Player 2
        Player 3
        Player 6
        
    With automatic team setup-
        Force 1- Player 0, 2
        Force 2- Player 3, 6
    
    scope Test initializer Initialization {
        private void Initialization() {
            TeamManager.dynamicSetup(3, 4)
        }//Initialization
    }//Test

DO_PLAYER_DRIVEN_SETUP-
------------------------------------------------------------------
These are accessible only from within DO_PLAYER_DRIVEN_SETUP areas

private void SetVoteTimeLimit(real timeLimit)
    Sets a time limit for voting
    
    Example-
        SetVoteTimeLimit(20)
        
private void SetPlayerVote(int playerId, int vote)
    Sets how big of a team a player votes for
    
    Player 6 votes for a team size of 3
    Example-
        SetPlayerVote(6, 3)
        
void TeamManager.playerSetup()
    Runs player driven auto team creation
    
    scope Test initializer Initialization {
        private void Initialization() {
            TeamManager.playerSetup()
        }//Initialization
    }//Test
    
PlayerDrivenInterfaceData
    Place all of your interface data like structs, globals, functions, and etc goes here
    
    define private PlayerDrivenInterfaceData = {
        dialog crappyMenu = DialogCreate()
        trigger crappyMenuButtonEvent = CreateTrigger()
        
        private bool DialogClicked() {
        }//DialogClicked
    }//PlayerDrivenInterfaceData

PlayerDrivenInterfaceCode
    Place all of your run time code here
    
    define private PlayerDrivenInterfaceCode = {
        TriggerRegisterDialogButtonEvent(crappyMenuButtonEvent, DialogAddButton(crappyMenu, "0", '0'))
        TriggerAddCondition(crappyMenuButtonEvent, Condition(function DialogClicked))
    }//PlayerDrivenInterfaceCode
    
PlayerDrivenInterfaceProperties
    Place various interface properties for the system and tinker with default ones.

AUTO_GAME_OVER_CHECK-
------------------------------------------------------------------
//! textmacro GAME_OVER_CODE
    Place code to run for when the game is over
    
    //! textmacro GAME_OVER_CODE
        bool playerWon[]
        int curTeam
        ploop(curPlayer, Human, true)
            tloop(curTeam, false)
                if TeamPlayer[curPlayer].isOnTeam[curTeam] {
                    DisplayTextToPlayer(Player(curPlayer), 0, 0, "YOU WON "+GetPlayerName(Player(curPlayer))+"!!")
                    playerWon[curPlayer] = true
                    exitwhen true
                }//if
            endtloop(curTeam)
        endploop(curPlayer)
        ploop(curPlayer, Human, false)
            if !playerWon[curPlayer] {
                DisplayTextToPlayer(Player(curPlayer), 0, 0, "YOU LOST "+GetPlayerName(Player(curPlayer))+"!!")
            }//if
        endploop(curPlayer)
    //! endtextmacro
    
//! textmacro GAME_OVER_CODE_NO_WINNER
    Place code to run for when the game is over and there is no winner
    
    //! textmacro GAME_OVER_CODE_NO_WINNER
        printf("You lost " + GetPlayerName(GetLocalHuman())+"!!")
    //! endtextmacro

Syntax Features
------------------------------------------------------------------
    tloop(processVar, processDeclare)
        loop through active teams
        
    tploop(processTeam, processVar, processDeclare)
        loop through players on a team
    
    ptloop(processTeamPlayer, processVar, processDeclare)
        loop through teams a player is on
    
    taloop(processTeam, processVar, processDeclare)
        loop through a team's alliance teams
    
    tnloop(processTeam, processVar, processDeclare)
        loop through a team's neutral teams
===================================================================*/
    private constant int TEAM_COUNT = 89 //max amount of teams
    private int curPlayerId
    private int curPlayerId2
    private int runPlayerId
    private int runPlayerId2
    private int curTeamId
    private int curTeam
    private int winTeam
    
    private player curPlayer1
    private player curPlayer2
    
    private int activeTeamCount = 0
    private int activeTeam[TEAM_COUNT]
    
    private struct Players extends array {//stores player information
        public static int teamCount[TEAM_MAX_SIZE] //how many teams player is in
        public static int alliance[TEAM_MAX_SIZE][TEAM_MAX_SIZE] //alliance between 2 players
        #if DO_TEAM_ALLIANCES
            public static int neutral[TEAM_MAX_SIZE][TEAM_MAX_SIZE] //neutrality between 2 players
        #endif
        
        public static bool playerTeamCheck[TEAM_MAX_SIZE][TEAM_COUNT] //is player in team
        public static int playerTeamId[TEAM_MAX_SIZE][TEAM_COUNT] //the player's indexed id in a team
        public static int indexedTeam[TEAM_MAX_SIZE][TEAM_COUNT] //stored team for a player
        public static int teamId[TEAM_MAX_SIZE][TEAM_COUNT] //use team id to retrieve indexed team id for a player
    }//Players
    
    struct TeamPlayer extends array {
        public int operator teamCount() {
            return Players.teamCount[this]
        }//teamCount
        
        public int getTeam(int index) {//retrieves a team the player is on via an index
            return Players.indexedTeam[this][index]
        }//getTeam
        
        public bool isOnTeam(int teamId) {//checks to see if a player is on a team
            return Players.playerTeamCheck[this][teamId]
        }//isOnTeam
        
        public bool isAllied(int playerId) {//checks if two players are allied
            return Players.alliance[this][playerId] > 0
        }//isAllied
        
        #if DO_TEAM_ALLIANCES
            public bool isNeutral(int playerId) {//checks if two players are neutral
                return Players.alliance[this][playerId] == 0 && Players.neutral[this][playerId] > 0
            }//isNeutral
        #endif
    }//PlayerManager
    
    #if DO_TEAM_ALLIANCES
        private int teamNeutralAlliance[TEAM_COUNT][TEAM_COUNT]
        private int teamAlliedAlliance[TEAM_COUNT][TEAM_COUNT]
        private int teamNeutralAllianceId[TEAM_COUNT][TEAM_COUNT]
        private int teamAlliedAllianceId[TEAM_COUNT][TEAM_COUNT]
    #endif
        
    struct ActiveTeam extends array {//determines game status by teams
        public int operator count() {//returns how many teams are active
            return activeTeamCount
        }//activeCount
        
        public int get(int index) {//returns an active team given an index
            return activeTeam[index]
        }//active
    }//TeamGame
    
    struct Team extends array {
        private static int teamCount = 0 //count of teams
        private static int teamRecycleCount = 0 //recycled team count
        private static int teamRecycle[TEAM_COUNT] //stores a recycled team id
        #if DO_TEAM_ALLIANCES
            private static int neutralAlliances[TEAM_COUNT] //neutral alliance count
            private static int alliedAlliances[TEAM_COUNT] //allied alliance count
        #endif
        private static int activeId[TEAM_COUNT] //active team id
        
        private static int teamSize[TEAM_COUNT] //how many players currently in team
        private static int teamPlayers[TEAM_COUNT][TEAM_MAX_SIZE] //stores player ids
        
        public int teamNumber
        
        TEAM_DEFAULT_ALLIANCE_VALUES
        
        public int operator size() {
            return Team.teamSize[this]
        }//size
        
        #if DO_TEAM_ALLIANCES
            public int operator neutralCount() {
                return Team.neutralAlliances[this]
            }//neutralCount
            
            public int operator allyCount() {
                return Team.alliedAlliances[this]
            }//allianceCount
            
            public int getNeutral(int index) {
                return teamNeutralAlliance[this][index]
            }//getNeutral
            
            public int getAlly(int index) {
                return teamAlliedAlliance[this][index]
            }//getAlly
        #endif
        
        public int getPlayer(int index) {//returns player via an index
            return Team.teamPlayers[this][index]
        }//getPlayer
        
        #if DO_SHARED_XP
            public bool sharedXp
        #endif
        #if DO_SHARED_SPELLS
            public bool sharedSpells
        #endif
        #if DO_SHARED_VISION
            public bool sharedVision
        #endif
        #if DO_SHARED_CONTROL
            public bool sharedControl
        #endif
        #if DO_SHARED_ADV_CONTROL 
            public bool sharedAdvControl
        #endif
        
        public void destroy() {
            int playerId
            int team1
            int team2
            if Team.activeId[this] != --activeTeamCount {
                activeTeam[Team.activeId[this]] = activeTeam[activeTeamCount]
                Team.activeId[activeTeam[activeTeamCount]] = Team.activeId[this]
            }//if
            Team.activeId[this] = 0
            Team.teamRecycle[Team.teamRecycleCount++] = this
            
            #if DO_TEAM_ALLIANCES
                team1 = this
                //Neutral Alliances
                ////////////////////////////////////////////////////////////////////////
                whilenot Team.neutralAlliances[team1] == 0 {//clear out neutral alliances
                    team2 = teamNeutralAlliance[team1][Team.neutralAlliances[team1]]
                    if teamNeutralAllianceId[team2][team1] != Team.neutralAlliances[team2] {//try to index team
                        teamNeutralAllianceId[team2][Team.neutralAlliances[team2]] = teamNeutralAllianceId[team2][team1]
                        teamNeutralAlliance[team2][teamNeutralAllianceId[team2][team1]] = teamNeutralAlliance[team2][Team.neutralAlliances[team2]]
                    }//if
                    teamNeutralAllianceId[team1][team2] = 0
                    teamNeutralAllianceId[team2][team1] = 0
                    Team.neutralAlliances[team1]--
                    Team.neutralAlliances[team2]--
                    curPlayerId = Team.teamSize[team1]
                    whilenot curPlayerId == 0 {//cycle through team 1
                        curPlayerId--
                        runPlayerId = Team.teamPlayers[team1][curPlayerId]
                        curPlayer1 = Player(runPlayerId)
                        curPlayerId2 = Team.teamSize[team2]
                        whilenot curPlayerId2 == 0 {//cycle through team 2
                            curPlayerId2--
                            runPlayerId2 = Team.teamPlayers[team2][curPlayerId2]
                            if runPlayerId != runPlayerId2 {//make sure players aren't the same
                                Players.neutral[runPlayerId][runPlayerId2]--
                                Players.neutral[runPlayerId2][runPlayerId]--
                                curPlayer2 = Player(runPlayerId2)
                                if Players.neutral[runPlayerId][runPlayerId2] == 0 && Players.alliance[runPlayerId][runPlayerId2] == 0 {//make sure not allied or neutral
                                    teamNeutral(curPlayer1, curPlayer2, false)
                                }//if
                            }//if
                        }//whilenot
                    }//whilenot
                }//whilenot
                ////////////////////////////////////////////////////////////////////////
                
                //Allied Alliances
                ////////////////////////////////////////////////////////////////////////
                whilenot Team.alliedAlliances[team1] == 0 {//clear out allied alliances
                    team2 = teamAlliedAlliance[team1][Team.alliedAlliances[team1]]
                    if teamAlliedAllianceId[team2][team1] != Team.alliedAlliances[team2] {//try to index team
                        teamAlliedAllianceId[team2][Team.alliedAlliances[team2]] = teamAlliedAllianceId[team2][team1]
                        teamAlliedAlliance[team2][teamAlliedAllianceId[team2][team1]] = teamAlliedAlliance[team2][Team.alliedAlliances[team2]]
                    }//if
                    teamAlliedAllianceId[team1][team2] = 0
                    teamAlliedAllianceId[team2][team1] = 0
                    Team.alliedAlliances[team1]--
                    Team.alliedAlliances[team2]--
                    curPlayerId = Team.teamSize[team1]
                    whilenot curPlayerId == 0 {//cycle through team 1
                        curPlayerId--
                        runPlayerId = Team.teamPlayers[team1][curPlayerId]
                        curPlayer1 = Player(runPlayerId)
                        curPlayerId2 = Team.teamSize[team2]
                        whilenot curPlayerId2 == 0 {//cycle through team 2
                            curPlayerId2--
                            runPlayerId2 = Team.teamPlayers[team2][curPlayerId2]
                            if runPlayerId != runPlayerId2 {//make sure players aren't the same
                                Players.alliance[runPlayerId][runPlayerId2]--
                                Players.alliance[runPlayerId2][runPlayerId]--
                                if Players.alliance[runPlayerId][runPlayerId2] == 0 {//make sure not allied
                                    curPlayer2 = Player(runPlayerId2)
                                    if Players.neutral[runPlayerId][runPlayerId2] > 0 {//try to make them neutral
                                        teamNeutral(curPlayer1, curPlayer2, true)
                                    }//if
                                    else {
                                        teamAlly(curPlayer1, curPlayer2, false, team1, team2)
                                    }//else
                                }//if
                            }//if
                        }//whilenot
                    }//whilenot
                }//whilenot
                ////////////////////////////////////////////////////////////////////////
            #endif
            
            //Remove All Players
            ////////////////////////////////////////////////////////////////////////
            whilenot TEAM_PLAYER_COUNT == 0 {//remove players
                //Team Alliances
                PLAYER_TEAM_COUNT--
                playerId = Team.teamPlayers[this][--TEAM_PLAYER_COUNT]
                curPlayer1 = Player(playerId)
                curPlayerId = TEAM_PLAYER_COUNT
                whilenot curPlayerId == 0 {//unally players on the same team
                    curPlayerId--
                    //decrease the alliance count between the two players
                    Players.alliance[playerId][Team.teamPlayers[this][curPlayerId]]--
                    Players.alliance[Team.teamPlayers[this][curPlayerId]][playerId]--
                    if Players.alliance[playerId][Team.teamPlayers[this][curPlayerId]] == 0 {//if they have no more ties, unally
                        curPlayer2 = Player(Team.teamPlayers[this][curPlayerId])
                        teamAlly(curPlayer1, curPlayer2, false, this, this)
                    }//if
                }//whilenot

                if TEAM_ID != PLAYER_TEAM_COUNT {//remove the team from an indexed array for player and index
                    Players.indexedTeam[playerId][TEAM_ID] = Players.indexedTeam[playerId][PLAYER_TEAM_COUNT]
                }//if
                //mark the team flag for player as false for this team
                Players.playerTeamCheck[playerId][TEAM_ID] = false
                
                //reset PLAYER_ID and TEAM_ID
                PLAYER_ID = 0
                TEAM_ID = 0
            }//whilenot
            ////////////////////////////////////////////////////////////////////////
            #if AUTO_GAME_OVER_CHECK
                //see if a fast game over check is possible
                if activeTeamCount != 0 {
                    #if DO_TEAM_ALLIANCES
                        curTeam = activeTeamCount
                        whilenot curTeam == 0 {//go through all the teams
                            //check to see if they aren't allied/neutral and that the activeTeam isn't this team
                            if activeTeam[curTeam] != this && teamAlliedAllianceId[this][activeTeam[curTeam]] == 0 {
                                return
                            }//if
                            curTeam--
                        }//whilenot
                        //! runtextmacro GAME_OVER_CODE()
                    #else
                        if activeTeamCount == 1 {
                            //! runtextmacro GAME_OVER_CODE()
                        }//if
                    #endif
                }//if
                else {//no winners
                    //! runtextmacro GAME_OVER_CODE_NO_WINNER()
                }//else
            #endif
        }//destroy

        #if DO_TEAM_ALLIANCES
            public bool isAllied(Team team2) {//checks if team is allied with another team
                return teamAlliedAllianceId[this][team2] > 0
            }//isAllied
            
            public bool isNeutral(Team team2) {//checks if team is neutral with another team
                return teamAlliedAllianceId[this][team2] == 0 && teamNeutralAllianceId[this][team2] > 0
            }//isNeutral
            
            public static void neutralTeam(Team team1, Team team2) {//makes two teams neutral. Will only run if they aren't allied
                if teamNeutralAllianceId[team1][team2] == 0 {//make sure two teams aren't neutral
                    teamNeutralAllianceId[team1][team2] = ++Team.neutralAlliances[team1]
                    teamNeutralAllianceId[team2][team1] = ++Team.neutralAlliances[team2]
                    teamNeutralAlliance[team1][Team.neutralAlliances[team1]] = team2
                    teamNeutralAlliance[team2][Team.neutralAlliances[team2]] = team1
                    curPlayerId = Team.teamSize[team1]
                    whilenot curPlayerId == 0 {//cycle through team 1
                        curPlayerId--
                        runPlayerId = Team.teamPlayers[team1][curPlayerId]
                        curPlayer1 = Player(runPlayerId)
                        curPlayerId2 = Team.teamSize[team2]
                        whilenot curPlayerId2 == 0 {//cycle through team 2
                            curPlayerId2--
                            runPlayerId2 = Team.teamPlayers[team2][curPlayerId2]
                            if runPlayerId != runPlayerId2 {//make sure players aren't the same
                                if Players.alliance[runPlayerId][runPlayerId2] == 0 && Players.neutral[runPlayerId][runPlayerId2] == 0 {//make sure not allied and not neutral
                                    curPlayer2 = Player(runPlayerId2)
                                    teamNeutral(curPlayer1, curPlayer2, true)
                                }//if
                                Players.neutral[runPlayerId][runPlayerId2]++
                                Players.neutral[runPlayerId2][runPlayerId]++
                            }//if
                        }//whilenot
                    }//whilenot
                }//if
            }//neutralTeam
            
            public static void allyTeams(Team team1, Team team2) {//makes two teams allied
                if teamAlliedAllianceId[team1][team2] == 0 {//make sure two teams aren't allied
                    teamAlliedAllianceId[team1][team2] = ++Team.alliedAlliances[team1]
                    teamAlliedAllianceId[team2][team1] = ++Team.alliedAlliances[team2]
                    teamAlliedAlliance[team1][Team.alliedAlliances[team1]] = team2
                    teamAlliedAlliance[team2][Team.alliedAlliances[team2]] = team1
                    curPlayerId = Team.teamSize[team1]
                    whilenot curPlayerId == 0 {//cycle through team 1
                        curPlayerId--
                        runPlayerId = Team.teamPlayers[team1][curPlayerId]
                        curPlayer1 = Player(runPlayerId)
                        curPlayerId2 = Team.teamSize[team2]
                        whilenot curPlayerId2 == 0 {//cycle through team 2
                            curPlayerId2--
                            runPlayerId2 = Team.teamPlayers[team2][curPlayerId2]
                            if runPlayerId != runPlayerId2 {//make sure players aren't the same
                                if Players.alliance[runPlayerId][runPlayerId2] == 0 {//make sure not allied
                                    curPlayer2 = Player(runPlayerId2)
                                    teamAlly(curPlayer1, curPlayer2, true, team1, team2)
                                }//if
                                Players.alliance[runPlayerId][runPlayerId2]++
                                Players.alliance[runPlayerId2][runPlayerId]++
                            }//if
                        }//whilenot
                    }//whilenot
                }//if
            }//allyTeams
            
            public static void unallyTeams(Team team1, Team team2) {//makes two teams unallied
                if teamAlliedAllianceId[team1][team2] > 0 {//make sure two teams are allied
                    if teamAlliedAllianceId[team1][team2] != Team.alliedAlliances[team1] {//try to index team
                        teamAlliedAllianceId[team1][Team.alliedAlliances[team1]] = teamAlliedAllianceId[team1][team2]
                        teamAlliedAlliance[team1][teamAlliedAllianceId[team1][team2]] = teamAlliedAlliance[team1][Team.alliedAlliances[team1]]
                    }//if
                    if teamAlliedAllianceId[team2][team1] != Team.alliedAlliances[team2] {//try to index team
                        teamAlliedAllianceId[team2][Team.alliedAlliances[team2]] = teamAlliedAllianceId[team2][team1]
                        teamAlliedAlliance[team2][teamAlliedAllianceId[team2][team1]] = teamAlliedAlliance[team2][Team.alliedAlliances[team2]]
                    }//if
                    teamAlliedAllianceId[team1][team2] = 0
                    teamAlliedAllianceId[team2][team1] = 0
                    Team.alliedAlliances[team1]--
                    Team.alliedAlliances[team2]--
                    curPlayerId = Team.teamSize[team1]
                    whilenot curPlayerId == 0 {//cycle through team 1
                        curPlayerId--
                        runPlayerId = Team.teamPlayers[team1][curPlayerId]
                        curPlayer1 = Player(runPlayerId)
                        curPlayerId2 = Team.teamSize[team2]
                        whilenot curPlayerId2 == 0 {//cycle through team 2
                            curPlayerId2--
                            runPlayerId2 = Team.teamPlayers[team2][curPlayerId2]
                            if runPlayerId != runPlayerId2 {//make sure players aren't the same
                                Players.alliance[runPlayerId][runPlayerId2]--
                                Players.alliance[runPlayerId2][runPlayerId]--
                                if Players.alliance[runPlayerId][runPlayerId2] == 0 {//make sure not allied
                                    curPlayer2 = Player(runPlayerId2)
                                    if Players.neutral[runPlayerId][runPlayerId2] > 0 {//try to make them neutral
                                        teamNeutral(curPlayer1, curPlayer2, true)
                                    }//if
                                    else {
                                        teamAlly(curPlayer1, curPlayer2, false, team1, team2)
                                    }//else
                                }//if
                            }//if
                        }//whilenot
                    }//whilenot
                }//if
            }//unally teams
            
            public static void removeNeutralTeams(Team team1, Team team2) {//removes neutrality between two teams
                if teamNeutralAllianceId[team1][team2] > 0 {//make sure two teams are allied
                    if teamNeutralAllianceId[team1][team2] != Team.neutralAlliances[team1] {//try to index team
                        teamNeutralAllianceId[team1][Team.neutralAlliances[team1]] = teamNeutralAllianceId[team1][team2]
                        teamNeutralAlliance[team1][teamNeutralAllianceId[team1][team2]] = teamNeutralAlliance[team1][Team.neutralAlliances[team1]]
                    }//if
                    if teamNeutralAllianceId[team2][team1] != Team.neutralAlliances[team2] {//try to index team
                        teamNeutralAllianceId[team2][Team.neutralAlliances[team2]] = teamNeutralAllianceId[team2][team1]
                        teamNeutralAlliance[team2][teamNeutralAllianceId[team2][team1]] = teamNeutralAlliance[team2][Team.neutralAlliances[team2]]
                    }//if
                    teamNeutralAllianceId[team1][team2] = 0
                    teamNeutralAllianceId[team2][team1] = 0
                    Team.neutralAlliances[team1]--
                    Team.neutralAlliances[team2]--
                    curPlayerId = Team.teamSize[team1]
                    whilenot curPlayerId == 0 {//cycle through team 1
                        curPlayerId--
                        runPlayerId = Team.teamPlayers[team1][curPlayerId]
                        curPlayer1 = Player(runPlayerId)
                        curPlayerId2 = Team.teamSize[team2]
                        whilenot curPlayerId2 == 0 {//cycle through team 2
                            curPlayerId2--
                            runPlayerId2 = Team.teamPlayers[team2][curPlayerId2]
                            if runPlayerId != runPlayerId2 {//make sure players aren't the same
                                Players.neutral[runPlayerId][runPlayerId2]--
                                Players.neutral[runPlayerId2][runPlayerId]--
                                curPlayer2 = Player(runPlayerId2)
                                if Players.neutral[runPlayerId][runPlayerId2] == 0 && Players.alliance[runPlayerId][runPlayerId2] == 0 {//make sure not allied or neutral
                                    teamNeutral(curPlayer1, curPlayer2, false)
                                }//if
                            }//if
                        }//whilenot
                    }//whilenot
                }//if
            }//removeNeutralTeams
        #endif

        define private teamIni(instance) = {//does team initialization
            Team.teamSize[instance] = 0
            Team.activeId[instance] = activeTeamCount
            activeTeam[activeTeamCount++] = instance
            #if DO_SHARED_XP
                Team[instance].sharedXp = Team.SHARED_XP
            #endif
            #if DO_SHARED_SPELLS
                Team[instance].sharedSpells = Team.SHARED_SPELLS
            #endif
            #if DO_SHARED_VISION
                Team[instance].sharedVision = Team.SHARED_VISION
            #endif
            #if DO_SHARED_CONTROL
                Team[instance].sharedControl = Team.SHARED_CONTROL
            #endif
            #if DO_SHARED_ADV_CONTROL
                Team[instance].sharedAdvControl = Team.SHARED_ADV_CONTROL
            #endif
            return instance
        }//teamIni
        
        //retrieve current player's team count
        define private PLAYER_TEAM_COUNT = Players.teamCount[playerId]
        
        //retrieve the current team's player count
        define private TEAM_PLAYER_COUNT = Team.teamSize[this]
        
        //team id for current team on player
        define private TEAM_ID = Players.teamId[playerId][this]
        
        //player id for current player on team
        define private PLAYER_ID = Players.playerTeamId[playerId][TEAM_ID]
        
        define private teamNeutral(player1, player2, flag) = {
            SetPlayerAlliance(player1, player2, ALLIANCE_HELP_REQUEST,  false)
            SetPlayerAlliance(player1, player2, ALLIANCE_HELP_RESPONSE, false)
            SetPlayerAlliance(player2, player1, ALLIANCE_HELP_REQUEST,  false)
            SetPlayerAlliance(player2, player1, ALLIANCE_HELP_RESPONSE, false)
            
            #if DO_SHARED_XP
                SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_XP,     false)
                SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_XP,     false)
            #endif
            #if DO_SHARED_SPELLS
                SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_SPELLS, false)
                SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_SPELLS, false)
            #endif
            #if DO_SHARED_VISION
                SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_VISION, false)
                SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_VISION, false)
            #endif
            #if DO_SHARED_CONTROL
                SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_CONTROL, false)
                SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_CONTROL, false)
            #endif
            #if DO_SHARED_ADV_CONTROL
                SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_ADVANCED_CONTROL, false)
                SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_ADVANCED_CONTROL, false)
            #endif
            
            SetPlayerAlliance(player1, player2, ALLIANCE_PASSIVE, flag)
            SetPlayerAlliance(player2, player1, ALLIANCE_PASSIVE, flag)
        }//teamNeutral

        define private teamAlly(player1, player2, flag, instance, instance2) = {
            SetPlayerAlliance(player1, player2, ALLIANCE_PASSIVE,       flag)
            SetPlayerAlliance(player1, player2, ALLIANCE_HELP_REQUEST,  flag)
            SetPlayerAlliance(player1, player2, ALLIANCE_HELP_RESPONSE, flag)
            
            SetPlayerAlliance(player2, player1, ALLIANCE_PASSIVE,       flag)
            SetPlayerAlliance(player2, player1, ALLIANCE_HELP_REQUEST,  flag)
            SetPlayerAlliance(player2, player1, ALLIANCE_HELP_RESPONSE, flag)
            #if instance != instance2
                #if DO_SHARED_XP
                    if Team[instance].sharedXp {SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_XP,     flag)}
                    if Team[instance2].sharedXp {SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_XP,     flag)}
                #endif
                #if DO_SHARED_SPELLS
                    if Team[instance].sharedSpells {SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_SPELLS, flag)}
                    if Team[instance2].sharedSpells {SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_SPELLS, flag)}
                #endif
                #if DO_SHARED_VISION
                    if Team[instance].sharedVision {SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_VISION, flag)}
                    if Team[instance2].sharedVision {SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_VISION, flag)}
                #endif
                #if DO_SHARED_CONTROL
                    if Team[instance].sharedControl {SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_CONTROL, flag)}
                    if Team[instance2].sharedControl {SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_CONTROL, flag)}
                #endif
                #if DO_SHARED_ADV_CONTROL
                    if Team[instance].sharedAdvControl {SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_ADVANCED_CONTROL, flag)}
                    if Team[instance2].sharedAdvControl {SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_ADVANCED_CONTROL, flag)}
                #endif
            #else
                #if DO_SHARED_XP
                    if Team[instance].sharedXp {
                        SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_XP,     flag)
                        SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_XP,     flag)
                    }
                #endif
                #if DO_SHARED_SPELLS
                    if Team[instance].sharedSpells {
                        SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_SPELLS, flag)
                        SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_SPELLS, flag)
                    }
                #endif
                #if DO_SHARED_VISION
                    if Team[instance].sharedVision {
                        SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_VISION, flag)
                        SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_VISION, flag)
                    }
                #endif
                #if DO_SHARED_CONTROL
                    if Team[instance].sharedControl {
                        SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_CONTROL, flag)
                        SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_CONTROL, flag)
                    }
                #endif
                #if DO_SHARED_ADV_CONTROL
                    if Team[instance].sharedAdvControl {
                        SetPlayerAlliance(player1, player2, ALLIANCE_SHARED_ADVANCED_CONTROL, flag)
                        SetPlayerAlliance(player2, player1, ALLIANCE_SHARED_ADVANCED_CONTROL, flag)
                    }
                #endif
            #endif
        }//teamAlly
        
        public void addPlayer(int playerId) {
            debug if !Players.playerTeamCheck[playerId][this] && TEAM_PLAYER_COUNT < TEAM_MAX_SIZE
                //Team Alliances
                curPlayer1 = Player(playerId)
                curPlayerId = TEAM_PLAYER_COUNT
                whilenot curPlayerId == 0 {//ally players on the same team
                    curPlayerId--
                    //if the two players aren't allied then ally them
                    if Players.alliance[playerId][Team.teamPlayers[this][curPlayerId]] == 0 {
                        curPlayer2 = Player(Team.teamPlayers[this][curPlayerId])
                        teamAlly(curPlayer1, curPlayer2, true, this, this)
                    }//if
                    //increase the alliance count between the two players
                    Players.alliance[playerId][Team.teamPlayers[this][curPlayerId]]++
                    Players.alliance[Team.teamPlayers[this][curPlayerId]][playerId]++
                }//whilenot
                
                #if DO_TEAM_ALLIANCES
                //Allied Alliances
                    curTeamId = Team.alliedAlliances[this]
                    whilenot curTeamId == 0 {//ally players on allied teams
                        curTeamId--
                        curTeam = teamAlliedAlliance[this][curTeamId]
                        curPlayerId = Team.teamSize[curTeam]
                        whilenot curPlayerId == 0 {//ally players on allied teams
                            curPlayerId--
                            if Team.teamPlayers[curTeam][curPlayerId] != playerId {//make sure players aren't the same
                                //if two players aren't allied then ally them
                                if Players.alliance[playerId][Team.teamPlayers[curTeam][curPlayerId]] == 0 {//make sure not allied
                                    curPlayer2 = Player(Team.teamPlayers[curTeam][curPlayerId])
                                    teamAlly(curPlayer1, curPlayer2, true, this, this)
                                }//if
                                Players.alliance[playerId][Team.teamPlayers[curTeam][curPlayerId]]++
                                Players.alliance[Team.teamPlayers[curTeam][curPlayerId]][playerId]++
                            }//if
                        }//whilenot
                    }//whilenot
                    
                    //Neutral Alliances
                    curTeamId = Team.neutralAlliances[this]
                    whilenot curTeamId == 0 {//make players on neutral teams neutral
                        curTeamId--
                        curTeam = teamNeutralAlliance[this][curTeamId]
                        curPlayerId = Team.teamSize[curTeam]
                        whilenot curPlayerId == 0 {//make players on neutral teams neutral
                            curPlayerId--
                            if Team.teamPlayers[curTeam][curPlayerId] != playerId {//make sure players aren't the same
                                //if two players aren't neutral and not allied then make them neutral them
                                if Players.alliance[playerId][Team.teamPlayers[curTeam][curPlayerId]] == 0 && Players.neutral[playerId][Team.teamPlayers[curTeam][curPlayerId]] == 0 {//make sure not allied or neutral
                                    curPlayer2 = Player(Team.teamPlayers[curTeam][curPlayerId])
                                    teamNeutral(curPlayer1, curPlayer2, true)
                                }//if
                                Players.neutral[playerId][Team.teamPlayers[curTeam][curPlayerId]]++
                                Players.neutral[Team.teamPlayers[curTeam][curPlayerId]][playerId]++
                            }//if
                        }//whilenot
                    }//whilenot
                #endif
                
                //make player id equal to team size
                PLAYER_ID = TEAM_PLAYER_COUNT
                //make team id equal to player team count
                TEAM_ID = PLAYER_TEAM_COUNT
                //add player to team
                Team.teamPlayers[this][TEAM_PLAYER_COUNT] = playerId
                //store the team into an indexed array for player
                Players.indexedTeam[playerId][PLAYER_TEAM_COUNT] = this
                
                //mark the team flag for player as true for this team
                Players.playerTeamCheck[playerId][PLAYER_TEAM_COUNT] = true
                
                //increase the size of this team
                TEAM_PLAYER_COUNT++
                //increase how many teams the player is in
                PLAYER_TEAM_COUNT++
            debug endif
        }//addPlayer
        
        public void removePlayer(int playerId) {
            debug if !Players.playerTeamCheck[playerId][this] && TEAM_PLAYER_COUNT > 0
                #if AUTO_REMOVE_TEAMS
                    if TEAM_PLAYER_COUNT == 1 {//if only one player left and auto remove is on, just destroy the team
                        .destroy()
                        return
                    }//if
                #endif
                //Team Alliances
                curPlayer1 = Player(playerId)
                curPlayerId = TEAM_PLAYER_COUNT
                whilenot curPlayerId == 0 {//unally players on the same team
                    curPlayerId--
                    //decrease the alliance count between the two players
                    Players.alliance[playerId][Team.teamPlayers[this][curPlayerId]]--
                    Players.alliance[Team.teamPlayers[this][curPlayerId]][playerId]--
                    if Players.alliance[playerId][Team.teamPlayers[this][curPlayerId]] == 0 {//if they have no more ties, unally
                        curPlayer2 = Player(Team.teamPlayers[this][curPlayerId])
                        teamAlly(curPlayer1, curPlayer2, false, this, this)
                    }//if
                }//whilenot
                
                #if DO_TEAM_ALLIANCES
                    //Allied Alliances
                    curTeamId = Team.alliedAlliances[this]
                    whilenot curTeamId == 0 {//unally players on allied teams
                        curTeamId--
                        curTeam = teamAlliedAlliance[this][curTeamId]
                        curPlayerId = Team.teamSize[curTeam]
                        whilenot curPlayerId == 0 {//unally players on allied teams
                            curPlayerId--
                            if Team.teamPlayers[curTeam][curPlayerId] != playerId {//make sure players aren't the same
                                //if two players are allied then unally them
                                Players.alliance[playerId][Team.teamPlayers[curTeam][curPlayerId]]--
                                Players.alliance[Team.teamPlayers[curTeam][curPlayerId]][playerId]--
                                if Players.alliance[playerId][Team.teamPlayers[curTeam][curPlayerId]] == 0 {//make sure no more ties
                                    curPlayer2 = Player(Team.teamPlayers[curTeam][curPlayerId])
                                    if Players.neutral[playerId][Team.teamPlayers[curTeam][curPlayerId]] > 0 {//try to make them neutral
                                        teamNeutral(curPlayer1, curPlayer2, true)
                                    }//if
                                    else {
                                        teamAlly(curPlayer1, curPlayer2, false, this, this)
                                    }//else
                                }//if
                            }//if
                        }//whilenot
                    }//whilenot
                    
                    //Neutral Alliances
                    curTeamId = Team.neutralAlliances[this]
                    whilenot curTeamId == 0 {//make players on neutral teams not neutral
                        curTeamId--
                        curTeam = teamNeutralAlliance[this][curTeamId]
                            curPlayerId = Team.teamSize[curTeam]
                            whilenot curPlayerId == 0 {//make players on neutral teams not neutral
                                curPlayerId--
                                if Team.teamPlayers[curTeam][curPlayerId] != playerId {//make sure players aren't the same
                                    Players.neutral[playerId][Team.teamPlayers[curTeam][curPlayerId]]++
                                    Players.neutral[Team.teamPlayers[curTeam][curPlayerId]][playerId]++
                                    if Players.alliance[playerId][Team.teamPlayers[curTeam][curPlayerId]] == 0 && Players.neutral[playerId][Team.teamPlayers[curTeam][curPlayerId]] == 0 {//make sure not allied or neutral
                                        curPlayer2 = Player(Team.teamPlayers[curTeam][curPlayerId])
                                        teamNeutral(curPlayer1, curPlayer2, false)
                                    }//if
                                }//if
                            }//whilenot
                    }//whilenot
                #endif
                
                //decrase the size of this team
                TEAM_PLAYER_COUNT--
                //decrease how many teams the player is in
                PLAYER_TEAM_COUNT--
                
                
                if PLAYER_ID != TEAM_PLAYER_COUNT {//remove player from team and index
                    Team.teamPlayers[this][PLAYER_ID] = Team.teamPlayers[this][TEAM_PLAYER_COUNT]
                }//if
                if TEAM_ID != PLAYER_TEAM_COUNT {//remove the team from an indexed array for player and index
                    Players.indexedTeam[playerId][TEAM_ID] = Players.indexedTeam[playerId][PLAYER_TEAM_COUNT]
                }//if
                //mark the team flag for player as false for this team
                Players.playerTeamCheck[playerId][TEAM_ID] = false
                
                //reset PLAYER_ID and TEAM_ID
                PLAYER_ID = 0
                TEAM_ID = 0
            debug endif
        }//removePlayer
        
        public static Team create() {
            if Team.teamRecycleCount != 0 {
                teamIni(Team.teamRecycle[--Team.teamRecycleCount])
            }
            Team.teamCount++
            teamIni(Team.teamCount-1)
        }//create
    }//Team
    
    define <TeamManager.staticSetup> = {//static team setup
        Team TeamManager_curTeam
        int TeamManager_curPlayerTeam = -1
        ploop(TeamManager_curPlayer, TeamManager.PLAYER_TYPE, true)
            if GetPlayerTeam(Get##TeamManager.PLAYER_TYPE##(TeamManager_curPlayer)) != TeamManager_curPlayerTeam {//new team?
                TeamManager_curPlayerTeam = GetPlayerTeam(Get##TeamManager.PLAYER_TYPE##(TeamManager_curPlayer))
                TeamManager_curTeam = Team.create()
                TeamManager_curTeam.teamNumber = TeamManager_curPlayerTeam
            }//if
            TeamManager_curTeam.addPlayer(Get##TeamManager.PLAYER_TYPE##Id(TeamManager_curPlayer))
        endploop(TeamManager_curPlayer)
    }//staticSetup
    
    define <TeamManager.staticSetup>(teamCount) = {//static setup with team count
        Team TeamManager_curTeam
        int TeamManager_curPlayerTeam = -1
        ploop(TeamManager_curPlayer, TeamManager.PLAYER_TYPE, true)
            if Get##TeamManager.PLAYER_TYPE##Id(TeamManager_curPlayer)/teamCount > curPlayerTeam {//new team?
                TeamManager_curPlayerTeam = Get##TeamManager.PLAYER_TYPE##Id(TeamManager_curPlayer)/teamCount
                TeamManager_curTeam = Team.create()
                TeamManager_curTeam.teamNumber = TeamManager_curPlayerTeam
            }//if
            TeamManager_curTeam.addPlayer(Get##TeamManager.PLAYER_TYPE##Id(TeamManager_curPlayer))
        endploop(TeamManager_curPlayer)
    }//staticSetup
    
    define <TeamManager.dynamicSetup>(teamCount, teamSize) = {//keep the teams as even as possible given a team count
        Team TeamManager_curTeam
        int TeamManager_curPlayerTeam = 0
        int TeamManager_teamCount = 0
        int TeamManager_teamSize = Get##TeamManager.PLAYER_TYPE##Count/teamCount
        int TeamManager_unevenTeams = Get##TeamManager.PLAYER_TYPE##Count-(TeamManager_teamSize*teamCount)
        bool TeamManager_doUneven
        int curTryBalance = teamCount
        
        if TeamManager_unevenTeams > 0 {//try to make uneven teams 0
            whilenot curTryBalance > 1 && Get##TeamManager.PLAYER_TYPE##Count/curTryBalance <= teamSize {
                if I2R(Get##TeamManager.PLAYER_TYPE##Count)/curTryBalance-Get##TeamManager.PLAYER_TYPE##Count/curTryBalance == 0 {
                    exitwhen true
                }//if
                curTryBalance--
            }//whilenot
            if Get##TeamManager.PLAYER_TYPE##Count/curTryBalance <= teamSize {//can perfectly balance
                TeamManager_teamSize = curTryBalance
                TeamManager_unevenTeams = 0
            }//if
        }//if
        
        ploop(TeamManager_curPlayer, TeamManager.PLAYER_TYPE, true)
            if TeamManager_curPlayerTeam == 0 {//new team?
                TeamManager_doUneven = true
                TeamManager_curTeam = Team.create()
                TeamManager_curTeam.teamNumber = TeamManager_teamCount++
                TeamManager_curPlayerTeam = TeamManager_teamSize
            }//if
            if !(TeamManager_unevenTeams > 0 && TeamManager_doUneven) {
                TeamManager_curPlayerTeam--
            }//if
            TeamManager_doUneven = false
            TeamManager_curTeam.addPlayer(Get##TeamManager.PLAYER_TYPE##Id(TeamManager_curPlayer))
        endploop(TeamManager_curPlayer)
    }//dynamicSetup
    
    #if DO_PLAYER_DRIVEN_SETUP
        scope PlayerDrivenSetup {
            PlayerDrivenInterfaceData
            PlayerDrivenInterfaceProperties
            
            private int orderedPlayerVotesCount = 1
            private int playerVotes[TEAM_MAX_SIZE] //stores player votes given a player id
            private int playersVoted = 0 //how many players have voted
            private timer voteTimerLimit = null //should there be a time limit
            private int curPlayer
            private int curTeamMaxSize[TEAM_COUNT]
            
            private void RunVotes() {
                if voteTimerLimit != null {
                    PauseTimer(voteTimerLimit)
                    DestroyTimer(voteTimerLimit)
                    voteTimerLimit = null
                }//if
                ploop(curPlayer, TeamManager.PLAYER_TYPE, false) //first make all invalid values valid
                    if playerVotes[curPlayer] < 1 || playerVotes[curPlayer] > TEAM_MAX_SIZE {
                        playerVotes[curPlayer] = TEAM_MAX_SIZE
                    }//if
                endploop(curPlayer)
                
                ploop(curPlayer, TeamManager.PLAYER_TYPE, false) //now make the teams
                    if IsPlayerActive(Get##TeamManager.PLAYER_TYPE##Id) {//is the player still around?
                        curTeam = 0 //reset curTeam since a search will commence
                        
                        /* either the current team does not exist or
                         * the max size is less than or equal to playerVotes, lower votes get priority
                         * and the current size is less than the max size, meaning there is a spot for them */
                        whilenot curTeamMaxSize[curTeam] == 0 || (curTeamMaxSize[curTeam] <= playerVotes[curPlayer] && Team[curTeam].size < curTeamMaxSize[curTeam]) {
                            curTeam++
                        }//whilenot
                        if curTeamMaxSize[curTeam] == 0 {//new team?
                            curTeam = Team.create()
                            curTeamMaxSize[curTeam] = playerVotes[curPlayer] //set the max size to the first player's vote who enters the team
                        }//if
                        Team[curTeam].addPlayer(curPlayer)
                    }//if
                endploop(curPlayer)
            }//RunVotes
            
            private void SetVoteTimeLimit(real timeLimit) {
                voteTimerLimit = CreateTimer()
                TimerStart(voteTimerLimit, timeLimit, false, function RunVotes)
            }//SetVoteTimeLimit
            
            private void SetPlayerVote(int playerId, int vote) {
                playerVotes[playerId] = vote
                if ++playersVoted == GetPlayerVoteCount() {
                    RunVotes()
                }//if
            }//SetPlayerVote
            
            struct TeamManager extends array {
                public static void playerSetup() {
                    PlayerDrivenInterfaceCode
                }//Initialization
            }//TeamManager
        }//PlayerDrivenSetup
    #endif
    
    //ActiveTeam- count, get
    //////////////////////////////////////////////////
    define tloop(processVar, processDeclare) = {
        #if processDeclare
            int processVar = ActiveTeam.count
        #else
            processVar = ActiveTeam.count
        #endif
        loop
            processVar--
    }//tloop
    
    define endtloop(processVar) = {
            exitwhen processVar == 0
        endloop
    }//endtloop
    
    //Team- size, getPlayer
    //////////////////////////////////////////////////
    define tploop(processTeam, processVar, processDeclare) = {
        #if processDeclare
            int processVar = processTeam.size
        #else
            processVar = processTeam.size
        #endif
        loop
            processVar--
    }//tploop
    
    define endtploop(processVar) = {
            exitwhen processVar == 0
        endloop
    }//endtploop
    
    //TeamPlayer- teamCount, getTeam
    //////////////////////////////////////////////////
    define ptloop(processTeamPlayer, processVar, processDeclare) = {
        #if processDeclare
            int var = processTeamPlayer.teamCount
        #else
            processVar = processTeamPlayer.teamCount
        #endif
        loop
            processVar--
    }//ptloop
    
    define endptloop(processVar) = {
            exitwhen processVar == 0
        endloop
    }//endptloop
    
    //Team- allyCount, getAlly
    //////////////////////////////////////////////////
    define taloop(processTeam, processVar, processDeclare) = {
        #if processDeclare
            int processVar = processTeam.allyCount
        #else
            processVar = processTeam.allyCount
        #endif
        loop
    }//taloop
    
    define endtaloop(processVar) = {
            exitwhen --processVar == 0
        endloop
    }//endtaloop
    
    //Team- neutralCount, getNeutral
    //////////////////////////////////////////////////
    define tnloop(processTeam, processVar, processDeclare) = {
        #if processDeclare
            int processVar = processTeam.neutralCount
        #else
            processVar = processTeam.neutralCount
        #endif
        loop
    }//tnloop
    
    define endtnloop(processVar) = {
            exitwhen --processVar == 0
        endloop
    }//endtnloop
}//TeamManager
 
Last edited:
Status
Not open for further replies.
Top