• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[system] Alliance System

Level 11
Joined
Nov 4, 2007
Messages
337
Requirements: Dialog System, Table

Description:
This is a system that handles making alliances ingame.
The players can build alliances using the commands '-ally' and '-war'.
Actually it is a very simple thing, but I think there are more things necessary to make the ally system be a good ally system that appears well and does not fail under certain circumstances. Following you can see a list with the features that are useful in my opinion.

Features

  • Players can't change initial alliances when forbidden by a constant. This means they can not declare war on initial allies.
  • The messages that appear when players ally appear well (colored player names, correct english (I hope))
  • A player declares automatically war on a player he allied that attacks him.
  • The system supports numbers, color names and playernames in the commands.
  • I think most players are going to use colors: Colors have extra support. Different names for the same color is possible (like grey and gray or lightblue and light blue)
  • If a player a allies another player b there is a peace time: A period in which the player a can't declare war manually on player b
  • If allying fails, the player that tried to ally gets explicit error messages
  • Players have an ally limit that forbids building too big alliances
  • Not all players can be in the same team. There is always struggle
  • You can forbid partial alliances. If partial alliances are forbidden, a player sends an ally request to another player if he wants to ally him. If the other player confirms the request, then both players ally each other. If a player declares war on the other player, the alliance dissolves for both sides.

Testing
This has been tested intensively. Everything works as it should.
So you can trust to the system.

Future plans

I will eventually add an option that makes that only whole alliances are allowed.
Example: player A and B are allied, player B and C are allied, player A and C are at war
==> The alliance is not totally complete.
The constant will force everybody in an alliance to confirm the ally.

Code
Can be found in the testmap which includes an example, too.

JASS:
library AllianceSystem initializer Init requires DialogSystem, Table
//===========================================================================
// Information: 
//==============
// Requirements: Dialog System (which requires Table)
//
//  Most alliance systems suck and have some mistakes that occur when the maker
//  of the system didn't think well before making it.
//  I thought clearly about the things I wanted to make and that'd be good for an
//  ally system before I made this;
//  - You can't change initial alliances when permitted
//  - A player is auto-warred if he attacks a player he did not ally that allied him.
//  - Supports different ways of allying: player numbers, player names and color names
//  - Supports different names for the same color (like lightblue and light blue or grey and gray)
//  - If a player a allies another player b there is a peace time: Player a can't
//    declare war on player b during that time.
//  - If allying fails, exact information why it fails are displayed to the player who tried to ally.
//  - Players have an ally-limit that permits making too big forces.
//  - Not all players can be allied with each other.
//
//===========================================================================
// Implementation: 
//===============
//
//  1. Download a tool called 'JassNewGen', and unpack it somewhere. You need that
//     edit to use this tool. The 'JassNewGen' is used very commonly and offers other
//     nice features. You can find it at:
//     [url]http://www.wc3c.net/showthread.php?t=90999[/url]
//
//  2. Make a new trigger, and convert it to custom text. Insert everything
//     the library contains into that trigger.
//
//  3. Download a system called 'Table' from this link:
//     [url]http://www.wc3c.net/showthread.php?t=101246[/url]
//     Do the same installation stuff for 'Table' as for this system.
//
//  4. Save your map and enjoy :-)
//
//===========================================================================
    globals
        // If this is set to false, players can't declare war on players
        // they had an initial alliance with.
        private constant boolean ALLOW_CHANGING_INITIAL_ALLIANCES = true
        // If you do not allow partial alliance and a player a wants to ally a player b,
        // player b gets a request in form of a dialog (Do you want to ally bla?).
        // If player b rejects the request, he is not allied.
        // When they built an alliance and one of the player declares war, the
        // other player declares war automatically, too.
        // This permits building partial alliances; Only full alliances are
        // allowed if this is set to false.
        private constant boolean ALLOW_PARTIAL_ALLIANCES          = true
        // Players can't have more than MAX_ALLY_COUNT allies and they can't
        // ally everybody. So if there are just two players left, they can't ally
        // each other.
        private constant integer MAX_ALLY_COUNT                   = 2
        // If a player allies another player he has to wait PEACE_TIME seconds in
        // order to declare war.
        private constant real    PEACE_TIME                       = 120.
    endglobals
    
    globals
        private trigger AllyTrigger = CreateTrigger()
        private trigger WarTrigger = CreateTrigger()
        private trigger AttackTrigger = CreateTrigger()
        private trigger LeaveTrigger = CreateTrigger()
        private timer array Wartimer
        private boolean array DeclareWarOnExpire
        private boolean array InitialAlly
        private integer array AllyCount
        private string array ColorString
        private integer Playercount = 0
        private HandleTable TimerData
        private constant integer SIZE = 12
    endglobals
    
    // I use colorcodes of a blizz map.
    // The ARGB Playercolors totally suck. Vexorian should update them,
    // they don't look natural. Teal e.g looks like green.
    private function ColorPlayer takes player p returns string
        return ColorString[GetPlayerId(p)]+GetPlayerName(p)+"|r"
    endfunction

    private struct UserMethods
        // These both methods are used if ALLOW_PARTIAL_ALLIANCES is true
        static method onAlly takes player allying, player allied returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(allying)+" has allied "+ColorPlayer(allied))
        endmethod
        
        static method onWar takes player warring, player warred returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(warring)+" has declared war on "+ColorPlayer(warred))
        endmethod
        
        // These both methods are used if ALLOW_PARTIAL_ALLIANCES is false
        static method onAllyEx takes player allying, player allied returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(allying)+" and "+ColorPlayer(allied)+" have built an alliance.")
        endmethod
        
        static method onWarEx takes player warring, player warred returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,"The alliance between "+ColorPlayer(warring)+" and "+ColorPlayer(warred)+" has dissolved.")
        endmethod
    endstruct
    
    // Makes a single index from two indexes, where a has a certain size.
    // We need this to store Data that are relevant between two players.
    // We can turn the index back to the two integers the index was created of.
    private function Index2D takes integer a, integer b returns integer
        return a + b*SIZE
    endfunction
    
    private function IndexA takes integer Matrize returns integer
        return ModuloInteger(Matrize,SIZE)
    endfunction
    
    private function IndexB takes integer Matrize returns integer
        return (Matrize/SIZE)
    endfunction
    
    function GetLabelPlayer takes string label returns player
        local integer i = 0
        
        // integers
        if S2I(label) != 0 then
            if S2I(label)-1 < 12 and S2I(label)-1 > 0 then
                return Player(S2I(label)-1)
            endif
        endif
            
        set label = StringCase(label,false)
        // Colors
        if label == "red" then
            return Player(0)
        elseif label == "blue" then
            return Player(1)
        elseif label == "teal" then
            return Player(2)
        elseif label == "purple" then
            return Player(3)
        elseif label == "yellow" then
            return Player(4)
        elseif label == "orange" then
            return Player(5)
        elseif label == "green" then
            return Player(6)
        elseif label == "pink" then
            return Player(7)
        elseif label == "grey" then
            return Player(8)
        elseif label == "gray" then
            return Player(8)
        elseif label == "lightblue" then
            return Player(9)
        elseif label == "light blue" then
            return Player(9)
        elseif label == "light-blue" then
            return Player(9)
        elseif label == "darkgreen" then
            return Player(10)
        elseif label == "dark green" then
            return Player(10)
        elseif label == "dark-green" then
            return Player(10)
        elseif label == "brown" then
            return Player(11)
        endif
        
        //Playernames
        loop
            exitwhen i > 11
            if label == StringCase(GetPlayerName(Player(i)),false) then
                return Player(i)
            endif
            set i = i + 1
        endloop
        return null
    endfunction
    
    private function onWartimerExpire takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer index = TimerData[t]
        if DeclareWarOnExpire[index] then
            // Ahahaha
            // Mwaahahaha I'm a genius. Really.
            call SetAlliance.execute(Player(IndexA(index)),Player(IndexB(index)),false)
        endif
    endfunction
    
    function interface SetAllianceInterface takes player from, player towards, boolean ally returns nothing
    
    // This is a very important function. It sets alliance conditions, starts the wartimers,
    // handles the allycount and the usermethods.
    function SetAlliance takes player from, player towards, boolean ally returns nothing
        local integer index = Index2D(GetPlayerId(from),GetPlayerId(towards))
        if ally then
            call SetPlayerAlliance(from,towards,ALLIANCE_PASSIVE,true)
            call SetPlayerAlliance(from,towards,ALLIANCE_SHARED_VISION,true)
            set AllyCount[GetPlayerId(from)] = AllyCount[GetPlayerId(from)] + 1
            if ALLOW_PARTIAL_ALLIANCES then
                call UserMethods.onAlly(from,towards)
                if Wartimer[index] == null then
                    set Wartimer[index] = CreateTimer()
                    set TimerData[Wartimer[index]] = index
                endif
                set DeclareWarOnExpire[index] = false
                // Restarting the timer = Refreshing period.
                call TimerStart(Wartimer[index],PEACE_TIME,false,function onWartimerExpire)
            elseif GetPlayerAlliance(towards,from,ALLIANCE_PASSIVE) == true then
                call UserMethods.onAllyEx(from,towards)
            endif
        else
            call SetPlayerAlliance(from,towards,ALLIANCE_PASSIVE,false)
            call SetPlayerAlliance(from,towards,ALLIANCE_SHARED_VISION,false)
            set AllyCount[GetPlayerId(from)] = AllyCount[GetPlayerId(from)] - 1
            if ALLOW_PARTIAL_ALLIANCES then
                call UserMethods.onWar(from,towards)
            else
                set AllyCount[GetPlayerId(towards)] = AllyCount[GetPlayerId(towards)] - 1
                call SetPlayerAlliance(towards,from,ALLIANCE_PASSIVE,false)
                call SetPlayerAlliance(towards,from,ALLIANCE_SHARED_VISION,false)
                call UserMethods.onWarEx(from,towards)
            endif
        endif
    endfunction
    
    function ConfirmAlly takes integer value, Dialog confirm returns nothing
        local player p2 = Player(confirm.GetData())
        if value == 1 then
            call SetAlliance(GetClickingPlayer(),p2,true)
            call SetAlliance(p2,GetClickingPlayer(),true)
        else
            call DisplayTextToPlayer(p2,0,0,ColorPlayer(GetClickingPlayer())+" has refused your request.")
        endif
    endfunction
    
    // OnAlly and onWar are a mess, I know, but all the safety things are neccessary and useful
    private function OnAlly takes nothing returns nothing
        local player ally = GetLabelPlayer(SubString(GetEventPlayerChatString(),6,StringLength(GetEventPlayerChatString())))
        local integer index = 0
        local Dialog D
        
        set index = Index2D(GetPlayerId(GetTriggerPlayer()),GetPlayerId(ally))
        
        if ally == null then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r This player does not exist.")
            return
        elseif AllyCount[GetPlayerId(GetTriggerPlayer())] == MAX_ALLY_COUNT then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't have more than "+I2S(MAX_ALLY_COUNT)+" allies.")
            return
        elseif ally == GetTriggerPlayer() then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't ally yourself.")
            return
        // May seem strange that I use -2.
        // We have to subtract one because the allying player is not valid.
        // And another one because We are GOING to have everybody-allied who if it was -1
        // 4 Players. A player may have 2 allies. If red has three allies, he allied everybody.
        elseif AllyCount[GetPlayerId(GetTriggerPlayer())] >= Playercount-2 then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't ally everybody.")
            return
        elseif GetPlayerSlotState(ally) != PLAYER_SLOT_STATE_PLAYING then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r "+ColorPlayer(ally)+" is not playing.")
            return
        elseif GetPlayerController(ally) != MAP_CONTROL_USER then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't ally Computer Players.")
            return
        elseif GetPlayerAlliance(GetTriggerPlayer(),ally,ALLIANCE_PASSIVE) == true then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You already allied "+ColorPlayer(ally)+".")
            return
        endif

        if ALLOW_PARTIAL_ALLIANCES then
            call SetAlliance(GetTriggerPlayer(),ally,true)
        else
            set D = Dialog.create("Would you like to ally "+ColorPlayer(GetTriggerPlayer())+"?",ConfirmAlly,0.)
            call D.AddOption("Yes",1)
            call D.AddOption("No",2)
            call D.SetData(GetPlayerId(ally))
            call D.ShowFor(ally)
        endif

    endfunction
    
    private function OnWar takes nothing returns nothing
        local player ally
        local integer index
        if SubString(GetEventPlayerChatString(),0,4) == "-war" then
            set ally = GetLabelPlayer(SubString(GetEventPlayerChatString(),5,StringLength(GetEventPlayerChatString())))
        else
            set ally = GetLabelPlayer(SubString(GetEventPlayerChatString(),8,StringLength(GetEventPlayerChatString())))
        endif
        
        set index = Index2D(GetPlayerId(GetTriggerPlayer()),GetPlayerId(ally))
        
        if ally == null then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r This player does not exist.")
            return
        elseif ally == GetTriggerPlayer() then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't declare war on yourself.")
            return
        elseif GetPlayerSlotState(ally) != PLAYER_SLOT_STATE_PLAYING then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r "+ColorPlayer(ally)+" is not playing.")
            return
        elseif InitialAlly[index] == true then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r Changing initial alliances is not allowed.")
            return
        elseif GetPlayerAlliance(GetTriggerPlayer(),ally,ALLIANCE_PASSIVE) == false then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You are not an ally of "+ColorPlayer(ally)+"s.")
            return
        elseif TimerGetRemaining(Wartimer[index]) > 0. then
            set DeclareWarOnExpire[index] = true
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't declare war on "+ColorPlayer(ally)+" yet. War will be automatically declared in "+I2S(R2I(TimerGetRemaining(Wartimer[index])))+" seconds.")
            return
        endif
        
        call SetAlliance(GetTriggerPlayer(),ally,false)

    endfunction
    
    private function OnAttack takes nothing returns nothing
        local integer index
        local player p1 = GetOwningPlayer(GetTriggerUnit())
        local player p2 = GetOwningPlayer(GetAttacker())
        if GetPlayerAlliance(p1,p2,ALLIANCE_PASSIVE) == true then
            if GetPlayerAlliance(p2,p1,ALLIANCE_PASSIVE) == false then
                set index = Index2D(GetPlayerId(p1),GetPlayerId(p2))
                set DeclareWarOnExpire[index] = false
                // Refresh the timeout.
                call PauseTimer(Wartimer[index])
                call SetAlliance(p1,p2,false)
            endif
        endif
    endfunction
    
    // This prevents that everybody is in a team.
    // It's a slow function but it's fired rarely.
    // Speed bonuses are neglegible
    private function OnLeave takes nothing returns nothing
        local integer i = 0
        local integer i2
        local integer allyCount
        local integer array allies
        local integer random
        set Playercount = Playercount - 1
        loop
            exitwhen i > 11
            // Player i allied everybody. BÖP!
            if GetPlayerAlliance(Player(i),GetTriggerPlayer(),ALLIANCE_PASSIVE) == true then
                set AllyCount[i] = AllyCount[i] - 1
            endif
            if AllyCount[i] == Playercount-1 then
                set i2 = 0
                set allyCount = 0
                loop
                    exitwhen i2 > 11
                    if GetPlayerAlliance(Player(i),Player(i2),ALLIANCE_PASSIVE) == true then
                        // We store the allies to pick a random ally and make him be an enemy
                        set allyCount = allyCount + 1
                        set allies[allyCount] = i2
                    endif
                    set i2 = i2 + 1
                endloop
                set random = allies[GetRandomInt(1,allyCount)]
                call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(Player(i))+" declares automatically war on "+ColorPlayer(Player(random))+", because "+ColorPlayer(Player(i))+" allied everybody.")
                call SetAlliance(Player(i),Player(random),false)
            endif
            set i = i + 1
        endloop
    endfunction
    
    private function Init takes nothing returns nothing
        local integer i = 0
        local integer i2
        local integer index
        loop
            exitwhen i > 11
            if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                set Playercount = Playercount + 1
                call TriggerRegisterPlayerChatEvent( AllyTrigger  , Player(i), "-ally"  , false )
                call TriggerRegisterPlayerChatEvent( WarTrigger   , Player(i), "-unally", false )
                call TriggerRegisterPlayerChatEvent( WarTrigger   , Player(i), "-war"   , false )
                call TriggerRegisterPlayerUnitEvent( AttackTrigger, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)
                call TriggerRegisterPlayerEvent    ( LeaveTrigger , Player(i), EVENT_PLAYER_LEAVE)
                call TriggerRegisterPlayerEvent    ( LeaveTrigger , Player(i), EVENT_PLAYER_DEFEAT)
        
                    set i2 = 0
                    loop
                        exitwhen i2 > 11
                        if i2 != i then
                            if IsPlayerAlly(Player(i),Player(i2)) then
                                set InitialAlly[Index2D(i,i2)] = true
                                set Allies[i] = Allies[i] + 1
                            endif
                        endif
                        set i2 = i2 + 1
                    endloop
            endif
            set i = i + 1
        endloop
        call TriggerAddAction(AllyTrigger,function OnAlly)
        call TriggerAddAction(WarTrigger,function OnWar)
        call TriggerAddAction(LeaveTrigger,function OnLeave)
        if ALLOW_PARTIAL_ALLIANCES then
            call TriggerAddAction(AttackTrigger,function OnAttack)
        else
            call DestroyTrigger(AttackTrigger)
        endif
        
        set TimerData = Table.create()
        
        // PlayerColors
        set ColorString[0] = "|cffff0000"    //red
        set ColorString[1] = "|cff0000ff"    //blue
        set ColorString[2] = "|cff00f5ff"    //Teal
        set ColorString[3] = "|cff551A8B"    //Purple
        set ColorString[4] = "|cffffff00"    //Yellow
        set ColorString[5] = "|cffEE9A00"    //Orange
        set ColorString[6] = "|cff00CD00"    //Green
        set ColorString[7] = "|cffFF69B4"    //Pink
        set ColorString[8] = "|cffC0C0C0"    //Gray
        set ColorString[9] = "|cffB0E2FF"    //Light Blue
        set ColorString[10] = "|cff006400"    //Dark Green
        set ColorString[11] = "|cff8B4513"    //Brown
    endfunction
endscope

I am happy about suggestions and feedback :emote_grin:.
If the dialog system is not approved, Ill update the code.
 
Last edited:
1st:
JASS:
scope AllianceSystem initializer Init
//===========================================================================
// Information:
//==============
// Requirements: Dialog System (which requires Table)
Then please, add requirements to the system. Also, the system should be a library.
(All systems should be librarys, that what they are thought for)

2nd:
Please add [ HIDDEN=""][/ HIDDEN] Tags to your JASS-Code.

3rd:
Please rename the Table TimerData, it doesn't fit at all.

4th:
The indexing seems awful for me.
(The whole stuff with matrize etc)
 
Last edited:
Level 8
Joined
Oct 3, 2008
Messages
367
JASS:
function GetLabelPlayer takes string label returns player
        local integer i = 0

        // integers
        if S2I(label) != 0 then
            if S2I(label)-1 < 12 and S2I(label)-1 > 0 then
                return Player(S2I(label)-1)
            endif
        endif

        set label = StringCase(label,false)
        // Colors
        if label == "red" then
            return Player(0)
        elseif label == "blue" then
            return Player(1)
        elseif label == "teal" then
            return Player(2)
        elseif label == "purple" then
            return Player(3)
        elseif label == "yellow" then
            return Player(4)
        elseif label == "orange" then
            return Player(5)
        elseif label == "green" then
            return Player(6)
        elseif label == "pink" then
            return Player(7)
        elseif label == "grey" then
            return Player(8)
        elseif label == "gray" then
            return Player(8)
        elseif label == "lightblue" then
            return Player(9)
        elseif label == "light blue" then
            return Player(9)
        elseif label == "light-blue" then
            return Player(9)
        elseif label == "darkgreen" then
            return Player(10)
        elseif label == "dark green" then
            return Player(10)
        elseif label == "dark-green" then
            return Player(10)
        elseif label == "brown" then
            return Player(11)
        endif

        //Playernames
        loop
            exitwhen i > 11
            if label == StringCase(GetPlayerName(Player(i)),false) then
                return Player(i)
            endif
            set i = i + 1
        endloop
        return null
    endfunction

So... inefficient...

O(n)... killing... me...
 
I stopped the O(n) search. This is the new GetLabelPlayer function plus a safety thing for when player names change:
JASS:
function GetLabelPlayer takes string label returns player
        local integer i = 0
        local integer num = S2I(label) - 1

        // integers
        if num < 12 and num >= 0 then
            return Player(num)
        endif

        set num = StringHash(StringCase(label,false))
        if HaveSavedHandle(PlayerData, 0, num) then
            return LoadPlayerHandle(PlayerData, 0, num)
        endif

        //Playernames
        set num = StringHash(StringCase(GetPlayerName(Player(i)),false))
        if HaveSavedHandle(PlayerData, 1, num) then
            return LoadPlayerHandle(PlayerData, 1, num)
        endif
        
        return null
    endfunction

    //just in case the player names change
    private function SetPlayerName_hook takes player whichPlayer, string name returns nothing
        local integer i = GetPlayerId(whichPlayer)
        local integer hash = StringHash(name)
        if hash != PlayerNames[i] then
            call RemoveSavedHandle(PlayerData, 1, PlayerNames[i])
            call SavePlayerHandle(PlayerData, 1, hash, whichPlayer)
            set PlayerNames[i] = hash
        endif
    endfunction
    
    hook SetPlayerName SetPlayerName_hook
and put this in the init function at the bottom:
JASS:
//Player color names
        call SavePlayerHandle(PlayerData, 0, StringHash("red"),         Player(0))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("blue"),        Player(1))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("teal"),        Player(2))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("purple"),      Player(3))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("yellow"),      Player(4))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("orange"),      Player(5))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("green"),       Player(6))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("pink"),        Player(7))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("grey"),        Player(8))
        call SavePlayerHandle(PlayerData, 0, StringHash("gray"),        Player(8))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("lightblue"),   Player(9))
        call SavePlayerHandle(PlayerData, 0, StringHash("light blue"),  Player(9))
        call SavePlayerHandle(PlayerData, 0, StringHash("light-blue"),  Player(9))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("darkgreen"),   Player(10))
        call SavePlayerHandle(PlayerData, 0, StringHash("dark green"),  Player(10))
        call SavePlayerHandle(PlayerData, 0, StringHash("dark-green"),  Player(10))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("brown"),       Player(11))
        
        //Player names
        set i = 0
        loop
            exitwhen i >= 12
            
            set PlayerNames[i] = StringHash(GetPlayerName(Player(i)))
            call SavePlayerHandle(PlayerData, 1, PlayerNames[i], Player(i))
            
            set i = i + 1
        endloop
Of course you need 2 new globals:
JASS:
private hashtable PlayerData = InitHashtable()
private integer array PlayerNames
It uses hashtables like I said.

EDIT: I just realised you had a few silly syntax errors with names. I fixed them. This also includes my new GetLabelPlayer method:
JASS:
library AllianceSystem initializer Init requires DialogSystem, Table
//===========================================================================
// Information:
//==============
// Requirements: Dialog System (which requires Table)
//
// Most alliance systems suck and have some mistakes that occur when the maker
// of the system didn't think well before making it.
// I thought clearly about the things I wanted to make and that'd be good for an
// ally system before I made this;
// - You can't change initial alliances when permitted
// - A player is auto-warred if he attacks a player he did not ally that allied him.
// - Supports different ways of allying: player numbers, player names and color names
// - Supports different names for the same color (like lightblue and light blue or grey and gray)
// - If a player a allies another player b there is a peace time: Player a can't
// declare war on player b during that time.
// - If allying fails, exact information why it fails are displayed to the player who tried to ally.
// - Players have an ally-limit that permits making too big forces.
// - Not all players can be allied with each other.
//
//===========================================================================
// Implementation:
//===============
//
// 1. Download a tool called 'JassNewGen', and unpack it somewhere. You need that
// edit to use this tool. The 'JassNewGen' is used very commonly and offers other
// nice features. You can find it at:
// [url]http://www.wc3c.net/showthread.php?t=90999[/url]
//
// 2. Make a new trigger, and convert it to custom text. Insert everything
// the library contains into that trigger.
//
// 3. Download a system called 'Table' from this link:
// [url]http://www.wc3c.net/showthread.php?t=101246[/url]
// Do the same installation stuff for 'Table' as for this system.
//
// 4. Save your map and enjoy :-)
//
//===========================================================================
    globals
        // If this is set to false, players can't declare war on players
        // they had an initial alliance with.
        private constant boolean ALLOW_CHANGING_INITIAL_ALLIANCES = true
        // If you do not allow partial alliance and a player a wants to ally a player b,
        // player b gets a request in form of a dialog (Do you want to ally bla?).
        // If player b rejects the request, he is not allied.
        // When they built an alliance and one of the player declares war, the
        // other player declares war automatically, too.
        // This permits building partial alliances; Only full alliances are
        // allowed if this is set to false.
        private constant boolean ALLOW_PARTIAL_ALLIANCES = true
        // Players can't have more than MAX_ALLY_COUNT allies and they can't
        // ally everybody. So if there are just two players left, they can't ally
        // each other.
        private constant integer MAX_ALLY_COUNT = 2
        // If a player allies another player he has to wait PEACE_TIME seconds in
        // order to declare war.
        private constant real PEACE_TIME = 120.
    endglobals

    globals
        private trigger AllyTrigger = CreateTrigger()
        private trigger WarTrigger = CreateTrigger()
        private trigger AttackTrigger = CreateTrigger()
        private trigger LeaveTrigger = CreateTrigger()
        private timer array Wartimer
        private boolean array DeclareWarOnExpire
        private boolean array InitialAlly
        private integer array AllyCount
        private string array ColorString
        private integer Playercount = 0
        private HandleTable TimerData
        private hashtable PlayerData = InitHashtable()
        private integer array PlayerNames
        private constant integer SIZE = 12
    endglobals

    // I use colorcodes of a blizz map.
    // The ARGB Playercolors totally suck. Vexorian should update them,
    // they don't look natural. Teal e.g looks like green.
    private function ColorPlayer takes player p returns string
        return ColorString[GetPlayerId(p)]+GetPlayerName(p)+"|r"
    endfunction

    private struct UserMethods
        // These both methods are used if ALLOW_PARTIAL_ALLIANCES is true
        static method onAlly takes player allying, player allied returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(allying)+" has allied "+ColorPlayer(allied))
        endmethod

        static method onWar takes player warring, player warred returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(warring)+" has declared war on "+ColorPlayer(warred))
        endmethod

        // These both methods are used if ALLOW_PARTIAL_ALLIANCES is false
        static method onAllyEx takes player allying, player allied returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(allying)+" and "+ColorPlayer(allied)+" have built an alliance.")
        endmethod

        static method onWarEx takes player warring, player warred returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(),0,0,"The alliance between "+ColorPlayer(warring)+" and "+ColorPlayer(warred)+" has dissolved.")
        endmethod
    endstruct

    // Makes a single index from two indexes, where a has a certain size.
    // We need this to store Data that are relevant between two players.
    // We can turn the index back to the two integers the index was created of.
private function Index2D takes integer a, integer b returns integer
        return a + b*SIZE
    endfunction

    private function IndexA takes integer Matrize returns integer
        return ModuloInteger(Matrize,SIZE)
    endfunction

    private function IndexB takes integer Matrize returns integer
        return (Matrize/SIZE)
    endfunction

    function GetLabelPlayer takes string label returns player
        local integer i = 0
        local integer num = S2I(label) - 1

        // integers
        if num < 12 and num >= 0 then
            return Player(num)
        endif

        set num = StringHash(StringCase(label,false))
        if HaveSavedHandle(PlayerData, 0, num) then
            return LoadPlayerHandle(PlayerData, 0, num)
        endif

        //Playernames
        set num = StringHash(StringCase(GetPlayerName(Player(i)),false))
        if HaveSavedHandle(PlayerData, 1, num) then
            return LoadPlayerHandle(PlayerData, 1, num)
        endif
        
        return null
    endfunction
    
    //just in case the player names change
    private function SetPlayerName_hook takes player whichPlayer, string name returns nothing
        local integer i = GetPlayerId(whichPlayer)
        local integer hash = StringHash(name)
        if hash != PlayerNames[i] then
            call RemoveSavedHandle(PlayerData, 1, PlayerNames[i])
            call SavePlayerHandle(PlayerData, 1, hash, whichPlayer)
            set PlayerNames[i] = hash
        endif
    endfunction
    
    hook SetPlayerName SetPlayerName_hook

    private function onWartimerExpire takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer index = TimerData[t]
        if DeclareWarOnExpire[index] then
            // Ahahaha
            // Mwaahahaha I'm a genius. Really.
            call SetAlliance.execute(Player(IndexA(index)),Player(IndexB(index)),false)
        endif
    endfunction

    function interface SetAllianceInterface takes player from, player towards, boolean ally returns nothing

    // This is a very important function. It sets alliance conditions, starts the wartimers,
    // handles the allycount and the usermethods.
    function SetAlliance takes player from, player towards, boolean ally returns nothing
        local integer index = Index2D(GetPlayerId(from),GetPlayerId(towards))
        if ally then
            call SetPlayerAlliance(from,towards,ALLIANCE_PASSIVE,true)
            call SetPlayerAlliance(from,towards,ALLIANCE_SHARED_VISION,true)
            set AllyCount[GetPlayerId(from)] = AllyCount[GetPlayerId(from)] + 1
            if ALLOW_PARTIAL_ALLIANCES then
                call UserMethods.onAlly(from,towards)
                if Wartimer[index] == null then
                    set Wartimer[index] = CreateTimer()
                    set TimerData[Wartimer[index]] = index
                endif
                set DeclareWarOnExpire[index] = false
                // Restarting the timer = Refreshing period.
                call TimerStart(Wartimer[index],PEACE_TIME,false,function onWartimerExpire)
            elseif GetPlayerAlliance(towards,from,ALLIANCE_PASSIVE) == true then
                call UserMethods.onAllyEx(from,towards)
            endif
        else
            call SetPlayerAlliance(from,towards,ALLIANCE_PASSIVE,false)
            call SetPlayerAlliance(from,towards,ALLIANCE_SHARED_VISION,false)
            set AllyCount[GetPlayerId(from)] = AllyCount[GetPlayerId(from)] - 1
            if ALLOW_PARTIAL_ALLIANCES then
                call UserMethods.onWar(from,towards)
            else
                set AllyCount[GetPlayerId(towards)] = AllyCount[GetPlayerId(towards)] - 1
                call SetPlayerAlliance(towards,from,ALLIANCE_PASSIVE,false)
                call SetPlayerAlliance(towards,from,ALLIANCE_SHARED_VISION,false)
                call UserMethods.onWarEx(from,towards)
            endif
        endif
    endfunction

    function ConfirmAlly takes integer value, Dialog confirm returns nothing
        local player p2 = Player(confirm.GetAttachedData())
        if value == 1 then
            call SetAlliance(GetClickingPlayer(),p2,true)
            call SetAlliance(p2,GetClickingPlayer(),true)
        else
            call DisplayTextToPlayer(p2,0,0,ColorPlayer(GetClickingPlayer())+" has refused your request.")
        endif
    endfunction

    // OnAlly and onWar are a mess, I know, but all the safety things are neccessary and useful
    private function OnAlly takes nothing returns nothing
        local player ally = GetLabelPlayer(SubString(GetEventPlayerChatString(),6,StringLength(GetEventPlayerChatString())))
        local integer index = 0
        local Dialog D

        set index = Index2D(GetPlayerId(GetTriggerPlayer()),GetPlayerId(ally))

        if ally == null then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r This player does not exist.")
            return
        elseif AllyCount[GetPlayerId(GetTriggerPlayer())] == MAX_ALLY_COUNT then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't have more than "+I2S(MAX_ALLY_COUNT)+" allies.")
            return
        elseif ally == GetTriggerPlayer() then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't ally yourself.")
            return
        // May seem strange that I use -2.
        // We have to subtract one because the allying player is not valid.
        // And another one because We are GOING to have everybody-allied who if it was -1
        // 4 Players. A player may have 2 allies. If red has three allies, he allied everybody.
        elseif AllyCount[GetPlayerId(GetTriggerPlayer())] >= Playercount-2 then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't ally everybody.")
            return
        elseif GetPlayerSlotState(ally) != PLAYER_SLOT_STATE_PLAYING then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r "+ColorPlayer(ally)+" is not playing.")
            return
        elseif GetPlayerController(ally) != MAP_CONTROL_USER then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't ally Computer Players.")
            return
        elseif GetPlayerAlliance(GetTriggerPlayer(),ally,ALLIANCE_PASSIVE) == true then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You already allied "+ColorPlayer(ally)+".")
            return
        endif

        if ALLOW_PARTIAL_ALLIANCES then
            call SetAlliance(GetTriggerPlayer(),ally,true)
        else
            set D = Dialog.create("Would you like to ally "+ColorPlayer(GetTriggerPlayer())+"?",ConfirmAlly,0.)
            call D.AddOption("Yes",1)
            call D.AddOption("No",2)
            call D.AttachData(GetPlayerId(ally))
            call D.ShowFor(ally)
        endif

    endfunction

    private function OnWar takes nothing returns nothing
        local player ally
        local integer index
        if SubString(GetEventPlayerChatString(),0,4) == "-war" then
            set ally = GetLabelPlayer(SubString(GetEventPlayerChatString(),5,StringLength(GetEventPlayerChatString())))
        else
            set ally = GetLabelPlayer(SubString(GetEventPlayerChatString(),8,StringLength(GetEventPlayerChatString())))
        endif

        set index = Index2D(GetPlayerId(GetTriggerPlayer()),GetPlayerId(ally))

        if ally == null then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r This player does not exist.")
            return
        elseif ally == GetTriggerPlayer() then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't declare war on yourself.")
            return
        elseif GetPlayerSlotState(ally) != PLAYER_SLOT_STATE_PLAYING then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r "+ColorPlayer(ally)+" is not playing.")
            return
        elseif InitialAlly[index] == true then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r Changing initial alliances is not allowed.")
            return
        elseif GetPlayerAlliance(GetTriggerPlayer(),ally,ALLIANCE_PASSIVE) == false then
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You are not an ally of "+ColorPlayer(ally)+"s.")
            return
        elseif TimerGetRemaining(Wartimer[index]) > 0. then
            set DeclareWarOnExpire[index] = true
            call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"|cffff0000Error:|r You can't declare war on "+ColorPlayer(ally)+" yet. War will be automatically declared in "+I2S(R2I(TimerGetRemaining(Wartimer[index])))+" seconds.")
            return
        endif

        call SetAlliance(GetTriggerPlayer(),ally,false)

    endfunction

    private function OnAttack takes nothing returns nothing
        local integer index
        local player p1 = GetOwningPlayer(GetTriggerUnit())
        local player p2 = GetOwningPlayer(GetAttacker())
        if GetPlayerAlliance(p1,p2,ALLIANCE_PASSIVE) == true then
            if GetPlayerAlliance(p2,p1,ALLIANCE_PASSIVE) == false then
                set index = Index2D(GetPlayerId(p1),GetPlayerId(p2))
                set DeclareWarOnExpire[index] = false
                // Refresh the timeout.
                call PauseTimer(Wartimer[index])
                call SetAlliance(p1,p2,false)
            endif
        endif
    endfunction

    // This prevents that everybody is in a team.
    // It's a slow function but it's fired rarely.
    // Speed bonuses are neglegible
    private function OnLeave takes nothing returns nothing
        local integer i = 0
        local integer i2
        local integer allyCount
        local integer array allies
        local integer random
        set Playercount = Playercount - 1
        loop
            exitwhen i > 11
            // Player i allied everybody. BÖP!
            if GetPlayerAlliance(Player(i),GetTriggerPlayer(),ALLIANCE_PASSIVE) == true then
                set AllyCount[i] = AllyCount[i] - 1
            endif
            if AllyCount[i] == Playercount-1 then
                set i2 = 0
                set allyCount = 0
                loop
                    exitwhen i2 > 11
                    if GetPlayerAlliance(Player(i),Player(i2),ALLIANCE_PASSIVE) == true then
                        // We store the allies to pick a random ally and make him be an enemy
                        set allyCount = allyCount + 1
                        set allies[allyCount] = i2
                    endif
                    set i2 = i2 + 1
                endloop
                set random = allies[GetRandomInt(1,allyCount)]
                call DisplayTextToPlayer(GetLocalPlayer(),0,0,ColorPlayer(Player(i))+" declares automatically war on "+ColorPlayer(Player(random))+", because "+ColorPlayer(Player(i))+" allied everybody.")
                call SetAlliance(Player(i),Player(random),false)
            endif
            set i = i + 1
        endloop
    endfunction

    private function Init takes nothing returns nothing
        local integer i = 0
        local integer i2
        local integer index
        loop
            exitwhen i > 11
            if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                set Playercount = Playercount + 1
                call TriggerRegisterPlayerChatEvent( AllyTrigger , Player(i), "-ally" , false )
                call TriggerRegisterPlayerChatEvent( WarTrigger , Player(i), "-unally", false )
                call TriggerRegisterPlayerChatEvent( WarTrigger , Player(i), "-war" , false )
                call TriggerRegisterPlayerUnitEvent( AttackTrigger, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)
                call TriggerRegisterPlayerEvent ( LeaveTrigger , Player(i), EVENT_PLAYER_LEAVE)
                call TriggerRegisterPlayerEvent ( LeaveTrigger , Player(i), EVENT_PLAYER_DEFEAT)

                    set i2 = 0
                    loop
                        exitwhen i2 > 11
                        if i2 != i then
                            if IsPlayerAlly(Player(i),Player(i2)) then
                                set InitialAlly[Index2D(i,i2)] = true
                                set AllyCount[i] = AllyCount[i] + 1
                            endif
                        endif
                        set i2 = i2 + 1
                    endloop
            endif
            set i = i + 1
        endloop
        call TriggerAddAction(AllyTrigger,function OnAlly)
        call TriggerAddAction(WarTrigger,function OnWar)
        call TriggerAddAction(LeaveTrigger,function OnLeave)
        if ALLOW_PARTIAL_ALLIANCES then
            call TriggerAddAction(AttackTrigger,function OnAttack)
        else
            call DestroyTrigger(AttackTrigger)
        endif

        set TimerData = Table.create()

        // PlayerColors
        set ColorString[0] = "|cffff0000" //red
        set ColorString[1] = "|cff0000ff" //blue
        set ColorString[2] = "|cff00f5ff" //Teal
        set ColorString[3] = "|cff551A8B" //Purple
        set ColorString[4] = "|cffffff00" //Yellow
        set ColorString[5] = "|cffEE9A00" //Orange
        set ColorString[6] = "|cff00CD00" //Green
        set ColorString[7] = "|cffFF69B4" //Pink
        set ColorString[8] = "|cffC0C0C0" //Gray
        set ColorString[9] = "|cffB0E2FF" //Light Blue
        set ColorString[10] = "|cff006400" //Dark Green
        set ColorString[11] = "|cff8B4513" //Brown
        
        //Player color names
        call SavePlayerHandle(PlayerData, 0, StringHash("red"),         Player(0))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("blue"),        Player(1))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("teal"),        Player(2))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("purple"),      Player(3))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("yellow"),      Player(4))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("orange"),      Player(5))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("green"),       Player(6))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("pink"),        Player(7))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("grey"),        Player(8))
        call SavePlayerHandle(PlayerData, 0, StringHash("gray"),        Player(8))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("lightblue"),   Player(9))
        call SavePlayerHandle(PlayerData, 0, StringHash("light blue"),  Player(9))
        call SavePlayerHandle(PlayerData, 0, StringHash("light-blue"),  Player(9))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("darkgreen"),   Player(10))
        call SavePlayerHandle(PlayerData, 0, StringHash("dark green"),  Player(10))
        call SavePlayerHandle(PlayerData, 0, StringHash("dark-green"),  Player(10))
        
        call SavePlayerHandle(PlayerData, 0, StringHash("brown"),       Player(11))
        
        //Player names
        set i = 0
        loop
            exitwhen i >= 12
            
            set PlayerNames[i] = StringHash(GetPlayerName(Player(i)))
            call SavePlayerHandle(PlayerData, 1, PlayerNames[i], Player(i))
            
            set i = i + 1
        endloop
    endfunction
endlibrary
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
This would actually benefit from Player Tracking

JASS:
        loop
            exitwhen i > 11
            if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
                set Playercount = Playercount + 1

Player Tracking does that, but more efficiently. It also has a global player leave trigger you could latch on to : \.

JASS:
        call TriggerAddAction(AllyTrigger,function OnAlly)
        call TriggerAddAction(WarTrigger,function OnWar)
        call TriggerAddAction(LeaveTrigger,function OnLeave)

As you have no conditions, you shouldn't be using actions here. These should actually be conditions.

JASS:
call TriggerRegisterPlayerUnitEvent( AttackTrigger, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)

Could use a filter here instead of a null

i also don't see why you are using the interface and executing a function. It only appears to be slowing down your entire system : \.

Finally, I don't believe hooks are a good practice.
 
Level 11
Joined
Nov 4, 2007
Messages
337
I won't use PlayerTracking.
It's not approved at wc3c.
I won't use conditions. The speed bonus is so awesomely small..

i also don't see why you are using the interface and executing a function. It only appears to be slowing down your entire system : \.

Think!
It doesn't slow down the entire system.

Player Tracking does that, but more efficiently

No. Even more slowly.

I am thankful for reviewing this, but all the changes would be useless.
The speed bonus would be like 0,00001%.
And no player is able to spam 100 times per second.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Quote:player Tracking does that, but more efficiently

No. Even more slowly.

Actually, it does it almost 2x faster...

And when using the player tracking stuff, it'd be even faster in regards to how many players are in the game -.-.

w/e, I was going to make a team utility when I got the latest player tracking modifications done anyways -.-.

Also, I suggest you split up some of the functionality. You are doing too much ; |. When someone just needs features for tracking alliances (teams), they don't need extra stuff. I suggest you put some static ifs in there so people can enable and disable whatever features they need.

Furthermore, a lot of it is poorly done -.-

Many of the ifs in the script should be static ifs

Moving on

JASS:
// integers
        if S2I(label) != 0 then
            if S2I(label)-1 < 12 and S2I(label)-1 > 0 then
                return Player(S2I(label)-1)
            endif
        endif

        set label = StringCase(label,false)
        // Colors
        if label == "red" then
            return Player(0)
        elseif label == "blue" then
            return Player(1)
        elseif label == "teal" then
            return Player(2)
        elseif label == "purple" then
            return Player(3)
        elseif label == "yellow" then
            return Player(4)
        elseif label == "orange" then
            return Player(5)
        elseif label == "green" then
            return Player(6)
        elseif label == "pink" then
            return Player(7)
        elseif label == "grey" then
            return Player(8)
        elseif label == "gray" then
            return Player(8)
        elseif label == "lightblue" then
            return Player(9)
        elseif label == "light blue" then
            return Player(9)
        elseif label == "light-blue" then
            return Player(9)
        elseif label == "darkgreen" then
            return Player(10)
        elseif label == "dark green" then
            return Player(10)
        elseif label == "dark-green" then
            return Player(10)
        elseif label == "brown" then
            return Player(11)
        endif

        //Playernames
        loop
            exitwhen i > 11
            if label == StringCase(GetPlayerName(Player(i)),false) then
                return Player(i)
            endif
            set i = i + 1
        endloop

This is probably the worst of the functions

Part 1, stop typecasting the string over and over again, store it in a var if you are going to typecast it 50 times. . .

Part 2, use a hashtable instead of the billion and 1 else ifs. It'll actually be faster, I promise -.-.

Part 3, hashtable instead of a loop

Part 4, don't force not everyone allowed to be allied... What if there are computers and people may be on opposing teams or may not be?


You really need to make your script more flexible (don't force all this stuff), more modular (static ifs), and more efficient (hashtables and use of Player Tracking or atleast go through the Player Tracking script and use some of the methods I was talking about because your current method for retrieving playing players sucks ><).

That's about all for now -.-, but go ahead and ignore me like you've been ignoring everyone else ^_^.


Oh and finally, your executes are completely pointless. I'm sure I said that before though, didn't I. There's a much better way to do it...
 
Level 11
Joined
Nov 4, 2007
Messages
337
Part 1: Understand!
2: I don't care
3: No.
4: Read...

Oh and finally, your executes are completely pointless
No.

I don't have to do anything you listed.

The least amount of feedback at the hive is really very valuable.
Wc3c has got more users that post always useful feedback (Vexorian, Grim, Rising_Dusk. And also users like Antiarf or Anachron. And evene far more.).
 
Level 11
Joined
Apr 29, 2007
Messages
826
Part 1: Understand!
2: I don't care
3: No.
4: Read...

Oh and finally, your executes are completely pointless
No.

I don't have to do anything you listed.

The least amount of feedback at the hive is really very valuable.
Wc3c has got more users that post always useful feedback (Vexorian, Grim, Rising_Dusk. And also users like Antiarf or Anachron. And evene far more.).

Why bother uploading your stuff here when you don't like it? Just gtfo, noone will cry after you.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
#1- not everyone on the hive is a noob. That includes me and quite a lot of others, lol. In fact, mostly modelers gather on the hive, not coders, so it's not about everyone being a noob, but about most everyone here being a modeler, lol.

#2-
wtf-code-1.jpg




#3-
Not all of your resources seem bad to me ><. This just happens to be one of the resources that does seem poorly done to me, lol.

Here's a prime example that deserves a wtf from me, lol
JASS:
if ALLOW_PARTIAL_ALLIANCES then //static if??

JASS:
static if ALLOW_PARTIAL_ALLIANCES then //like this??

The other is that big set of elseifs that many people on this thread have commented on and have even gone so far as to rewrite it for you pleading you to fix it ><.

This is another wth from me, but probably only from me because I've dealt with players a lot-
JASS:
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then

JASS:
if GetPlayerTeam(Player(i)) > -1 and GetPlayerController(Player(i)) == MAP_CONTROL_USER then

But that's probably a trivial thing. In my opinion, there are tons of mistakes all over your code, so calling it pristine and saying "ur all noobs" isn't going to solve anything ><.
 
Level 11
Joined
Nov 4, 2007
Messages
337
not everyone on the hive is a noob. That includes me
:D
Made my day +rep
(Sorry for being spiteful)

Ok, many good modelers here, that's true.
Please don't write lol everywhere, lol. Seems a bit nerdy.

3) First suggestion is a nice one, second one doesn't improve the code.
Thanks for the first one, after all.

In my opinion, there are tons of mistakes all over your code
In my opinion, your codes are far worse, so I can't take you seriously.
 
Level 8
Joined
Oct 3, 2008
Messages
367
This doesn't work correctly if player colors are different from the default. IE: if player 0 is colored yellow, if player 1 is colored pink, etc.

The code is rather long and somewhat inefficient, but making sure something works is much more important than making sure it runs incredibly fast.
 
Top