Reputation System 1.0

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
This is a system made to make peoples life with maps like RPG a little bit easier providing 4 different libraries with API for a Reputation System

you can keep track of reputation to some faction(per player) or to reputation per unit with each reputation having its own unit(those can be shared so one unit can be used in multiple reputation)

Together with some techtree magic and some good ideas(which I lack) you can even make a shops with items that will show up only if you have enough reputation for it

this system requires:

UnitIndexer: http://www.hiveworkshop.com/forums/jass-resources-412/system-unit-indexer-172090/
Table: http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/

The source code:

ReputationSystem

RepSys function API

Unit Reputation System

URepSys function API

JASS:
library ReputationSystem requires Table, UnitIndexer //by edo494
/*      
        Table by Bribe - http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
        UnitIndexer by Nestharus - http://www.hiveworkshop.com/forums/jass-resources-412/system-unit-indexer-172090/

        This is wrote mainly for my own needs
        
        This system allows you to create factions(reputations) for instance shops with requirements of some reputation,
        gain reputation when we kill some monster and also gain some reputation when for isntance quests are done
        
        You can also decrease reputation to punish not good done job and other stuff.
        
        Together with custom units and techtree, you can even have shops with items which require you to have some amount
        of reputation in order to buy those items.
        
        note: When I say in API reputation I most likely mean reputation as currency and reputation itself is
        referred as faction.


*/
//------------------------------------------------------------------------
/*
    
API: First is struct API, if you are too lazy to use it, under it is a normal funcion API

struct reputation

Normal API:
    
    (static) function(arguments) -> return type(if any)                  description
    
    
    static create(string) -> Reputation                             //Creates a new faction with name
    
    static createEx(string, integer) -> Reputation                  //Creates a new faction with name at starting value of reputation
    
    remove()                                                        //Destroys a given faction
    
    static setRank(integer rank, string, integer tonextrank)        //Creates a new rank(currently globally), like hostile, friendly, revered ...
                                                                    //has a protection of overriding ranks(in debug displays message)
    
    increase(integer howmany, integer forplayer)                    //Adds reputation in given faction for a player
    
    decrease(integer howmany, integer forplayer)                    //Lowers reputation in given faction for a player
    
    getName() -> string                                             //returns a name of a faction
    
    repS2I(string name) -> integer                              //turns a name of a faction into an integer(id of a faction), if invalid returns 0
                                                                //This method can be used to get a non referenced reputation by knowing its name.
    
    getRep(integer ofplayer) -> integer                     //returns a current standing of a player to faction(not Rank but value)
    
    getTotalRep(integer playerindex) -> integer             //returns total reputation of player gained
    
    getTypeById(integer id) -> string                       //returns a name of a rank by id(this is not bound to faction)
    
    getRankTypeOfPlayer(integer ofplayer) -> string         //returns name of a current rank in given faction of player
    
    getRankOfPlayer(integer ofplayer) -> integer            //returns a current rank in given faction of player(the same as GetCurrentRepTypeOfPlayer but as integer)

Trigger API:
    
    global private constant boolean wanttoregister = true       //if you want to use TriggerRegisterRepChange, let it true, otherwise set to false
                                                                //to shorten the code a little bit
    
    registerRepChangeEvent(code c, integer rankchange, boolean upside)      //registers a rankchange to trigger, the boolean tells
                                                                            //if it is upside or downside, whenever the reputation rank is changed
                                                                            //all functions registered to that reputation are executed regardless of how much
                                                                            //times the same function is there
    
Single Player API:
    
    Those commands shouldnt be used in multiplayer games because they are not changed for each player differently
    and doing so could desync the game.
            
    addToFaction(unit toadd) -> boolean                     //Bounds a unit to that faction. One unit can be in any number of factions
                                                            //but that may cause problems in changing aggresivity.
                                                            //If successful returns true, if already saved or invalid unit(null) returns false.
    
    removeFromFaction(unit toremove) -> boolean             //Removes a unit from a faction. If successful returns true, otherwise returns false.
    
    defineHostility(integer rank)                           //Defines at which rank the units start to be friendly/hostile in that faction. Default is: friendly at all time.
    
    changeFaction(boolean good)                             //Immedietally forces the system to swtich all units in given faction to
                                                            //friendly(true) or hostile(false)

    static getOriginalOwner(unit u) -> player               //returns a original owner of a unit bound to faction
    
    static getOriginalOwnerId(unit u) -> integer            //returns Id of original owner of a unit bound to faction

                                                        
    In case you dont like to use structs or methods, there is library with a function API for this system(it requires this system tho).
    
    
*/
//------------------------------------------------------------------------
/*
    Change note:
    
        Version Log:

            122812  - rewrote the documentation
                    - made some fixes
                    - rereleased
            
            121108  - fixed a bug with reqxp variable in .remove() method
                    - fixed a bugged .remove() method destroying a Rank as well
                    - fixed a badly scripted .increase() and .decrease() not working properly
                    - fixed .getName() and .getS2I() not working correctly
        
            121107b - lighted up .update() method, making it O(n) (was O(O(n)) before)
            
            121107  - fixed a bug with CreateNewRepEx(121107 and later, createEx) not
                      setting name of the reputation
                    - renamed all methods(check API to see new names)
                    - moved function API into separated library
                    - reworked how repS2I works ( O(n) -> O(1) )
            
            121104  - remoworked how .ChangeFaction() works in AddRep and LowerRep methods
                    - added 2 new methods: GetOriginalOwner and GetOriginalOwnerId as well as 2 functions
                      with the same name
            
            121103  - Intial release
*/
//------------------------------------------------------------------------

    globals
        private constant boolean wanttoregister = true  //If you plan on using RegisterRepChangeEvent let this true, otherwise set to false
    endglobals

    struct Reputation
        private static string array reptypename
        private static Table repname
        private static integer maxreptype = 0
        private static TableArray tab
        private static TableArray tac
        private static integer array pointtoname        //sololy for .getName() so we can point to every instance, otherwise
                                                        //method repS2I would be O(n)
        private static integer array repreq
        private static integer array reqxp
        
        /*  
            why all arrays instead of normal variables as reptypename may you ask?
            I like array syntax more then struct syntax, also I dont need to declare another
            integer(thistype) in every function Im passing integers not reputation or without allocation
            and still can access the desired index. Example is in setRank
            If I didnt have arrays I would have to declare another integer = waste of memory
        */
        
        static method create takes string name returns thistype
            local integer i = 0
            local thistype this = .allocate()
            set pointtoname[this] = StringHash(name)
            set repname[pointtoname[this]] = this
            set repname.string[this] = name
            loop
                set tac[i][this] = 0
                exitwhen i == 15
                set i = i + 1
            endloop
            return this
        endmethod
        
        static method createEx takes string name, integer startingrep returns thistype
            local integer i = 0
            local thistype this = .allocate()
            set pointtoname[this] = StringHash(name)
            set repname[pointtoname[this]] = this
            set repname.string[this] = name
            loop
                set tac[i][this] = startingrep
                exitwhen i == 15
                set i = i + 1
            endloop
            return this
        endmethod
        
        method remove takes nothing returns nothing
            local integer i = 0
            set repname.string[this] = ""
            set repname[pointtoname[this]] = 0
            set pointtoname[this] = 0
            loop
				set tab[i][this] = 0
                exitwhen i == 15
                set i = i + 1
            endloop
            call .deallocate()
        endmethod
        
        static method setRank takes integer rank, string name, integer xpto returns nothing
            
            //protection
            
            if repreq[rank] == -1 then
                debug call BJDebugMsg("rank in Reputation" + I2S(rank) + " already exists")
                return
            endif
            
            set repreq[rank] = -1
            set reptypename[rank] = name
            
            // to ensure that even when we get over the rep needed it will show the correct rep
            
            set reptypename[rank+1] = name
            
            
            set reqxp[rank] = xpto
            set maxreptype = maxreptype + 1
        endmethod
        
        method changeFaction takes boolean good returns nothing
            local unit u
            local integer i = 1
            loop
                set u = GetUnitById(saver[this][i])
                if good then
                    call SetUnitOwner(u, Player(15), true)
                else
                    call SetUnitOwner(u, Player(12), true)
                endif
                exitwhen i == hunit[this]
                set i = i + 1
            endloop
        endmethod
        
        method increase takes integer howmany, integer forplayer returns nothing
            local integer a = tac[forplayer][this]
            local integer b = tab[forplayer][this]
            set a = a + howmany
            loop
                exitwhen a < reqxp[b] or maxreptype == b
                if a > reqxp[b] then
                    set a = a - reqxp[b]
                    set b = b + 1
                endif
            endloop
            if b > hostile[this] and not changed[this] then
                call .changeFaction(true)
                set changed[this] = true
            endif
        static if wanttoregister then
            if b > (tac[forplayer][this]) then
                if regist[this].trigger[b*2-1] != null then
                    call TriggerEvaluate(regist[this].trigger[b*2-1])
                endif
            endif
        endif
            set tac[forplayer][this] = a
            set tab[forplayer][this] = b
        endmethod
        
        method decrease takes integer howmany, integer forplayer returns nothing
            local integer a = tac[forplayer][this]
            local integer b = tab[forplayer][this]
            set a = a - howmany
            loop
                exitwhen a > 0 or b == 0
                if b <= 0 and a < 0 then
                    set a = 0
                endif
                set a = a + reqxp[b]
                set b = b - 1
            endloop
            if b < hostile[this] and changed[this] then
                call .changeFaction(false)
                set changed[this] = false
            endif
        static if wanttoregister then
            if b < (tac[forplayer][this]) then
                if regist[this].trigger[b*2] != null then
                    call TriggerEvaluate(regist[this].trigger[b*2])
                endif
            endif
        endif
            set tac[forplayer][this] = a
            set tab[forplayer][this] = b
        endmethod
        
        method getName takes nothing returns string
            return repname.string[repname[pointtoname[this]]]
        endmethod
    
        static method repS2I takes string name returns integer
            return repname[StringHash(name)]
        endmethod
        
        method getRep takes integer playerindex returns integer
            return tac[playerindex][this]
        endmethod
        
        method getTotalRep takes integer playerindex returns integer
            local integer a = tab[this][playerindex]
            local integer total = tac[this][playerindex]
            loop
                exitwhen a == 0
                set total = total + reqxp[a]
            endloop
            return total
        endmethod
        
        static method getTypeById takes integer id returns string
            return reptypename[id]
        endmethod
        
        method getRankTypeOfPlayer takes integer forplayer returns string
            return reptypename[tab[forplayer][this]]
        endmethod
        
        method getRankOfPlayer takes integer ofplayer returns integer
            return tab[ofplayer][this]
        endmethod
        
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        
        private static method onInit takes nothing returns nothing
            set tab = TableArray[16]
            set tac = TableArray[16]
            set saver = TableArray[0x2000]
            set repname = Table.create()
        static if wanttoregister then
            set regist = TableArray[0x2000]
        endif
        endmethod
        
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
    //Single Player commands:
    
        private static TableArray saver
        private static integer array hostile
        private static integer array hunit
        private static player array origown
        private static boolean array changed
        
        private method update takes nothing returns nothing
            local integer forplayer = 0
            local integer q
            set forplayer = 0
            set q = tab[forplayer][this]
            loop
                if hostile[this] >= q and not changed[this] then
                    call .changeFaction(true)
                elseif hostile[this] < q and changed[this] then
                    call .changeFaction(false)
                endif
                exitwhen forplayer == 15
                set forplayer = forplayer + 1
            endloop
        endmethod
        
        method addToFaction takes unit u returns boolean
            
            //double save protection
            
            if saver[this][GetUnitUserData(u)] != GetUnitUserData(u) and u != null then
                set saver[this][GetUnitUserData(u)] = GetUnitUserData(u)
                set origown[GetUnitUserData(u)] = GetOwningPlayer(u)
                set hunit[this] = hunit[this] + 1
                call .update()
                return true
            else
                return false
            endif
        endmethod
        
        method removeFromFaction takes unit u returns boolean
            
            //double free protection
            
            if saver[this][GetUnitUserData(u)] == 0 or u == null then
                return false
            else
                set saver[this][GetUnitUserData(u)] = 0
                set hunit[this] = hunit[this] - 1
                set origown[this] = null
                return true
            endif
        endmethod
        
        method defineHostility takes integer rank returns nothing
            set hostile[this] = rank
            call .update()
        endmethod
        
        // Register command:
        
    static if wanttoregister then
        private static TableArray regist
    
        method registerRepChangeEvent takes code c, integer rankchange, boolean upside returns nothing
            if upside then
                if regist[this].trigger[rankchange*2-1] == null then
                    set regist[this].trigger[rankchange*2-1] = CreateTrigger()
                endif
                call TriggerAddCondition(regist[this].trigger[rankchange*2-1], Condition(c))
            else
                if regist[this].trigger[rankchange*2] == null then
                    set regist[this].trigger[rankchange*2] = CreateTrigger()
                endif
                call TriggerAddCondition(regist[this].trigger[rankchange*2], Condition(c))
            endif
        endmethod
    endif
        
        static method getOriginalOwner takes unit u returns player
            return origown[GetUnitUserData(u)]
        endmethod
        
        static method getOriginalOwnerId takes unit u returns integer
            return GetPlayerId(origown[GetUnitUserData(u)])
        endmethod
    
    endstruct
    
endlibrary
JASS:
library ReputationSystemFunctionAPI requires ReputationSystem //by edo494
    
/*
    Im not going to say what each function does, if you want to know, please reffer to their counterparts in struct
    API:
        
           function(arguments) -> return type(if any)...................................what the function does
        
        CreateNewReputation(string name) -> reputation                              return Reputation.create(name)
        
        CreateNewReputationEx(string name, integer startingrep) -> reputation       return Reputation.createEx(name, startingrep)
        
        RemoveReputation(Reputation rep)                                            call rep.remove()
        
        SetReputationRank(integer rank, string name, integer xpto)                  call Reputation.setRank(rank, name, xpto)
        
        IncreaseReputation(Reputation rep, integer value, integer forplayer)        call rep.increase(value, forplayer)
        
        LowerReputation(Reputation rep, integer value, integer forplayer)           call rep.decrease(value, forplayer)
        
        GetReputationName(Reputation rep) -> string                                 return rep.getName()
        
        ReputationS2I(string s) -> integer                                          return Reputation.repS2I(s)
        
        GetCurrentReputation(Reputation rep, integer playerindex) -> integer        return rep.getRep(playerindex)
        
        GetTotalReputation(Reputation rep, integer playerindex) -> integer          return rep.getTotalXp(playerindex)
        
        GetRepTypeById(integer id) -> string                                        return Reputation.getTypeById(id)
        
        GetCurrentRepTypeOfPlayer(Reputation rep, integer playerindex) -> string    return rep.getRankTypeOfPlayer(playerindex)
        
        GetCurrentRankOfPlayer(Reputation rep, integer playerindex) -> integer      return rep.getRankOfPlayer(playerindex)

//----------------------------------------------------------

    Single Player API(Should not be used in multiplayer for 100% correct result)
        
        ChangeFaction(Reputation rep, boolean flag)         call rep.changeFaction(flag)
        
        AddUnitToFaction(Reputation rep, unit u)            call rep.addToFaction(u)
        
        RemoveUnitFromFaction(Reputation rep, unit u)       call rep.removeFromFaction(u)
        
        DefineHostility(Reputation rep, integer rank)       call rep.defineHostility(rank)
                
        GetOriginalOwner(unit u) -> player                  return Reputation.getOriginalOwner(u)
    
        GetOriginalOwnerId(unit u) -> integer               return Reputation.getOriginalOwnerId(u)

//----------------------------------------------------------

    Trigger API, only works with global called wanttoregister == true
        
        RegisterRepChangeEvent(reputation rep, code c, integer rank, boolean good)  call rep.registerRepChangeEvent(c, rank, flag)
*/

    // Function API:
    
    function CreateNewReputation takes string name returns Reputation
        return Reputation.create(name)
    endfunction
    
    function CreateNewReputationEx takes string name, integer startingrep returns Reputation
        return Reputation.createEx(name, startingrep)
    endfunction
    
    function RemoveReputation takes Reputation rep returns nothing
        call rep.remove()
    endfunction
    
    function SetReputationRank takes integer rank, string name, integer xpto returns nothing
        call Reputation.setRank(rank, name, xpto)
    endfunction
    
    function IncreaseReputation takes Reputation rep, integer value, integer forplayer returns nothing
        call rep.increase(value, forplayer)
    endfunction
    
    function LowerReputation takes Reputation rep, integer value, integer forplayer returns nothing
        call rep.decrease(value, forplayer)
    endfunction
    
    function GetReputationName takes Reputation rep returns string
        return rep.getName()
    endfunction
    
    function ReputationS2I takes string s returns integer
        return Reputation.repS2I(s)
    endfunction
    
    function GetCurrentReputation takes Reputation rep, integer playerindex returns integer
        return rep.getRep(playerindex)
    endfunction
    
    function GetRepTypeById takes integer id returns string
        return Reputation.getTypeById(id)
    endfunction
    
    function GetCurrentRepTypeOfPlayer takes Reputation rep, integer playerindex returns string
        return rep.getRankTypeOfPlayer(playerindex)
    endfunction
    
    function GetCurrentRankOfPlayer takes Reputation rep, integer playerindex returns integer
        return rep.getRankOfPlayer(playerindex)
    endfunction
    
    function ChangeFaction takes Reputation rep, boolean flag returns nothing
        call rep.changeFaction(flag)
    endfunction
    
    function AddUnitToFaction takes Reputation rep, unit u returns nothing
        call rep.addToFaction(u)
    endfunction
    
    function RemoveUnitFromFaction takes Reputation rep, unit u returns nothing
        call rep.removeFromFaction(u)
    endfunction
    
    function DefineHostility takes Reputation rep, integer rank returns nothing
        call rep.defineHostility(rank)
    endfunction

    static if wanttoregister then
        function RegisterRepChangeEvent takes Reputation rep, code c, integer rank, boolean flag returns nothing
            call rep.registerRepChangeEvent(c, rank, flag)
        endfunction
    endif
    
    function GetOriginalOwner takes unit u returns player
        return Reputation.getOriginalOwner(u)
    endfunction
    
    function GetOriginalOwnerId takes unit u returns integer
        return Reputation.getOriginalOwnerId(u)
    endfunction
    
    function GetTotalReputation takes Reputation rep, integer playerindex returns integer
        return rep.getTotalRep(playerindex)
    endfunction

endlibrary
JASS:
library ReputationForUnit requires Table, UnitIndexer
/*      
        Table by Bribe - http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
        UnitIndexer by Nestharus - http://www.hiveworkshop.com/forums/jass-resources-412/system-unit-indexer-172090/
    
    This library does the same as the Reputation library but this one works for unit rather then player per instance.
    
    One unit for one instace of this struct
    
    The name is URep to keep it intuitive(Unit based Reputation System, shortly URep) yet short enough to make it easy
    to type while creating maps.
    
    
    API:
    
        static create(string name, unit holder) -> URep     //registers a unit and a name to unique URep and returns
                                                            //it as a struct
        
        static createEx (string name, integer startingrep, unit registerer) -> URep //does the same as create but with
                                                                                    //addition of choosing your own starting reputation
                                                                                    
        remove()                                            //removes instance of URep(does not destroy ranks!)
        
        static setRank(integer rank, string name, integer xpto)     //creates a new rank globally for your URep struct with
                                                                    //desired rank, name and xp required to gain next rank
                                                                    //has a protection of setting the same rank twice
                                                                    //(in debug mode will display debug message)
        
        increase(integer howmuch)                           //increases a reputation(not rank!) by given value
                                                            //if a flag for having a registering trigger is set to on,
                                                            //this will also fire TriggerEvaluate in case the rank increased
        
        decrease(integer howmuch)                           //decreses a reputation(not rank!) by a given value
                                                            //if a flag for having a registering trigger is set to on,
                                                            //this will also fire TriggerEvaluate in case the rank decreased
    
        getName() -> string                                 //returns a name of URep(string registered in create(Ex))
        
        repS2I(string name) -> integer                      //returns an id of URep found by name, in case there is no
                                                            //UReps with the name, returns 0
        
        getRep() -> integer                                 //returns current reputation(not rank! or instance!)
                                                            //however, returned value is only a reputation from 0 to (rep to next rank)
      
        getTotalRep() -> integer                            //returns total reputation of unit
      
      
        getTypeById(integer id) -> string                   //returns a name of a rank(not reputation or isntance!) by its id
        
        getRankType() -> string                             //returns current rank of unit bound to the current instance of URep
        
        getUnit() -> unit                                   //returns unit bound to current URep
        
        getUnitId() -> integer                              //returns an index of unit bound to current URep in Unit Indexer
        

/--------------------------------------------------------------------
    
    Trigger API:
        
        constant boolean wanttoregister = true          //if set to false, functionality with registering
                                                        //events to the system will not be avaliable
        
        registerRepChangeEvent(code c, integer rankchange, boolean upside)
        
                                                        //registers function c to system
                                                        //when a unit gains or loses reputation and rank changes,
                                                        //this will be Evaluated depending on if it is upside or not
                                                        //true - if rank increases
                                                        //false - if rank decreases
    
    
    Unlike Reputation struct, this one doesnt provide a single player commands
        
    In case you dont like to use structs or methods, there is library with a function API for this system(it requires this system tho).
    
*/
    
    globals
        private constant boolean wanttoregister = true  //If you plan on using RegisterURepChangeEvent let this true, otherwise set to false
    endglobals

    struct URep
        private static unit array holding
        
        private static string array reptypename
        private static Table repname
        private static integer maxreptype = 0
        
        private static integer array xps
        private static integer array rank
        
        private static integer array pointtoname        //sololy for .getName() so we can point to every instance, otherwise
                                                        //method repS2I would be O(n)
        private static integer array repreq
        private static integer array reqxp
        
        private static integer array totalxp
        
        /*  
            why all arrays instead of normal variables as repname may you ask?
            I like array syntax more then struct syntax, also I dont need to declare another
            integer(thistype) in every function Im passing integers not reputation or without allocation
            and still can access the desired index. Example is in setRank
            If I didnt have arrays I would have to declare another integer = waste of memory
        */
        
        static method create takes string name, unit registerer returns thistype
            local thistype this = .allocate()
            set pointtoname[this] = StringHash(name)
            set repname[pointtoname[this]] = this
            set repname.string[this] = name
            set xps[this] = 0
            set holding[this] = registerer
            set totalxp[this] = 0
            return this
        endmethod
        
        static method createEx takes string name, integer startingrep, unit registerer returns thistype
            local thistype this = .allocate()
            set pointtoname[this] = StringHash(name)
            set repname[pointtoname[this]] = this
            set repname.string[this] = name
            set xps[this] = startingrep
            set holding[this] = registerer
            set totalxp[this] = 0
            return this
        endmethod
        
        method remove takes nothing returns nothing
            set repname.string[this] = ""
            set repname[pointtoname[this]] = 0
            set pointtoname[this] = 0
            set xps[this] = 0
            set holding[this] = null
            set totalxp[this] = 0
            call .deallocate()
        endmethod
        
        static method setRank takes integer rank, string name, integer xpto returns nothing
            
            //protection
            
            if repreq[rank] == -1 then
                debug call BJDebugMsg("rank in URep" + I2S(rank) + " already exists.")
                return
            endif
            
            set repreq[rank] = -1
            set reptypename[rank] = name
            
            // to ensure that even when we get over the rep needed it will show the correct rep
            
            set reptypename[rank+1] = name
            
            
            set reqxp[rank] = xpto
            set maxreptype = maxreptype + 1
        endmethod
        
        method increase takes integer howmany returns nothing
            local integer a = xps[this] + howmany
            local integer b = rank[this]
            set totalxp[this] = totalxp[this] + a
            loop
                exitwhen a < reqxp[b] or maxreptype == b
                if a > reqxp[b] then
                    set a = a - reqxp[b]
                    set b = b + 1
                endif
            endloop
        static if wanttoregister then
            if b > (rank[this]) then
                if regist[this].trigger[b*2-1] != null then
                    call TriggerEvaluate(regist[this].trigger[b*2-1])
                endif
            endif
        endif
            set xps[this] = a
            set rank[this] = b
        endmethod
        
        method decrease takes integer howmany returns nothing
            local integer a = xps[this] + howmany
            local integer b = rank[this]
            set totalxp[this] = totalxp[this] - a
            loop
                exitwhen a > 0 or b == 0
                if b <= 0 and a < 0 then
                    set a = 0
                endif
                set a = a + reqxp[b]
                set b = b - 1
            endloop
        static if wanttoregister then
            if b < (rank[this]) then
                if regist[this].trigger[b*2] != null then
                    call TriggerEvaluate(regist[this].trigger[b*2])
                endif
            endif
        endif
            set xps[this] = a
            set rank[this] = b
        endmethod
        
        method getName takes nothing returns string
            return repname.string[repname[pointtoname[this]]]
        endmethod
    
        static method repS2I takes string name returns integer
            return repname[StringHash(name)]
        endmethod
        
        method getRep takes nothing returns integer
            return xps[this]
        endmethod
        
        method getTotalRep takes nothing returns integer
            return totalxp[this]
        endmethod
        
        static method getTypeById takes integer id returns string
            return reptypename[id]
        endmethod
        
        method getRankType takes nothing returns string
            return reptypename[rank[this]]
        endmethod
        
        method getRank takes nothing returns integer
            return rank[this]
        endmethod
        
        method getUnit takes nothing returns unit
            return holding[this]
        endmethod
        
        method getUnitId takes nothing returns integer
            return GetUnitId(holding[this])
        endmethod
        
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        
        private static method onInit takes nothing returns nothing
            set repname = Table.create()
        static if wanttoregister then
            set regist = TableArray[0x2000]
        endif
        endmethod
        
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        
        // Register command:
        
    static if wanttoregister then
        private static TableArray regist
    
        method registerRepChangeEvent takes code c, integer rankchange, boolean upside returns nothing
            if upside then
                if regist[this].trigger[rankchange*2-1] == null then
                    set regist[this].trigger[rankchange*2-1] = CreateTrigger()
                endif
                call TriggerAddCondition(regist[this].trigger[rankchange*2-1], Condition(c))
            else
                if regist[this].trigger[rankchange*2] == null then
                    set regist[this].trigger[rankchange*2] = CreateTrigger()
                endif
                call TriggerAddCondition(regist[this].trigger[rankchange*2], Condition(c))
            endif
        endmethod
    endif
    
    endstruct
    
endlibrary
JASS:
library URepSystemFunctionAPI requires ReputationForUnit //by edo494
    
/*
    Im not going to say what each function does, if you want to know, please reffer to their counterparts in struct
    API:
        
           function(arguments) -> return type(if any)...................................what the function does
        
        CreateUnitReputation(string name, unit toregister) -> URep              return URep.create(name)
        
        CreateUnitReputationEx(string name, integer startingrep, unit toregister) -> URep   return URep.createEx(name, startingrep)
        
        RemoveUnitReputation(URep rep)                                          call rep.remove()
        
        SetUnitReputationRank(integer rank, string name, integer xpto)          call URep.setRank(rank, name, xpto)
        
        IncreaseUnitReputation(URep rep, integer value)                         call rep.increase(value)
        
        LowerUnitReputation(URep rep, integer value)                            call rep.decrease(value, forplayer)
        
        GetUnitReputationName(URep rep) -> string                               return rep.getName()
        
        UnitReputationS2I(string s) -> integer                                  return URep.repS2I(s)
        
        GetCurrentUnitReputation(URep rep) -> integer                           return rep.getRep(playerindex)
        
        GetUnitTotalRep(URep rep) -> integer                                    return rep.getTotalRep()
        
        URepTypeById(integer id) -> string                                      return URep.getTypeById(id)
        
        GetCurrentURepType(URep rep) -> string                                  return rep.getRankTypeOfPlayer(playerindex)
        
        GetCurrentRankOfUnit(URep rep) -> integer                               return rep.getRankOfPlayer(playerindex)

        UnitOfRep(Urep rep) -> unit                                             return rep.getUnit()
        
        UnitIdOfRep(Urep rep) -> integer                                        return rep.getUnitId()
        

    Trigger API, only works with global called wanttoregister == true
        
        RegisterURepChangeEvent(URep rep, code c, integer rank, boolean good)    call urep.registerRepChangeEvent(c, rank, flag)
*/

    // Function API:
    
    function CreateUnitReputation takes string name, unit u returns Reputation
        return URep.create(name, u)
    endfunction
    
    function CreateUnitReputationEx takes string name, integer startingrep, unit u returns Reputation
        return URep.createEx(name, startingrep, u)
    endfunction
    
    function RemoveUnitReputation takes URep rep returns nothing
        call rep.remove()
    endfunction
    
    function SetUnitReputationRank takes integer rank, string name, integer xpto returns nothing
        call URep.setRank(rank, name, xpto)
    endfunction
    
    function IncreaseUnitReputation takes URep rep, integer value returns nothing
        call rep.increase(value)
    endfunction
    
    function LowerUnitReputation takes URep rep, integer value returns nothing
        call rep.decrease(value)
    endfunction
    
    function GetUnitReputationName takes URep rep returns string
        return rep.getName()
    endfunction
    
    function UnitReputationS2I takes string s returns integer
        return URep.repS2I(s)
    endfunction
    
    function GetCurrentUnitReputation takes URep rep returns integer
        return rep.getRep()
    endfunction
    
    function URepTypeById takes integer id returns string
        return URep.getTypeById(id)
    endfunction
    
    function GetCurrentURepType takes URep rep returns string
        return rep.getRankType()
    endfunction
    
    function GetCurrentRankOfUnit takes URep rep returns integer
        return rep.getRank()
    endfunction

    static if wanttoregister then
        function RegisterURepChangeEvent takes URep rep, code c, integer rank, boolean flag returns nothing
            call rep.registerRepChangeEvent(c, rank, flag)
        endfunction
    endif
    
    function UnitOfRep takes URep rep returns unit
        return rep.getUnit()
    endfunction
    
    function UnitIdOfRep takes URep rep returns integer
        return rep.getUnitId()
    endfunction
    
    function GetUnitTotalRep takes URep rep returns integer
        return rep.getTotalRep()
    endfunction

endlibrary



1.0 - intial release


Keywords:
Reputation, System, Reputation System, Unit Indexer, Table, World Bounds, Event, vJass, Jass
Contents

Just another Warcraft III map (Map)

Reviews
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected. 15:50, 17th Feb 2013 Magtheridon96: wanttoregister should be WANT_TO_REGISTER because that's how constant booleans are written in JASS. All your struct member names should be...

Moderator

M

Moderator

12th Dec 2015
IcemanBo: Too long as NeedsFix. Rejected.

15:50, 17th Feb 2013
Magtheridon96:

  • wanttoregister should be WANT_TO_REGISTER because that's how constant booleans are written in JASS.
  • All your struct member names should be camelCased. (reptypename -> repTypeName, repname -> repName, etc...)
    This is JASS convention and it would make them easier to read.
  • I think it would be more suitable to make a single rep change event and have a boolean as event response data to tell you whether it's increasing or decreasing.
    This way, you satisfy people who just want to detect whether the rank is equal to something or not while still keeping the people who want specific code to run for each type of change happy :p (Optional change, just throwing in my opinion)
  • JASS:
    if saver[this][GetUnitUserData(u)] == 0 or u == null then
        return false
    else
        set saver[this][GetUnitUserData(u)] = 0
        set hunit[this] = hunit[this] - 1
        set origown[this] = null
        return true
    endif
    ->
    JASS:
    if saver[this][GetUnitUserData(u)] == 0 or u == null then
        return false
    endif
    
    set saver[this][GetUnitUserData(u)] = 0
    set hunit[this] = hunit[this] - 1
    set origown[this] = null
    
    return true
    You can do similar things for most of your functions as well.
  • The documentation should be updated because at least one of the API elements is incorrectly listed (struct reputation -> struct Reputation)
  • Can't the API listing just be the function definitions with descriptions that go under to avoid annoying scrolling? :/
    JASS:
    /*
    *   static method create takes string name returns Reputation
    *       - Description.
    *
    *   static method createEx takes string name, integer something returns Reputation
    *       - Description.
    *
    */
    I think the above is better because it would assure that the entire API listing is uniform, clean and easy to understand.
    (Also, not everyone knows the func(args, args2, args3) notation :p
  • remove should be named destroy to comply to Struct method naming standards :/
    Whenever a user calls something that is not "destroy", he is going to expect the instance to remain unrecycled.
  • Player(15) and Player(12) should probably be configurable in the globals block at the top.
  • In the addToFaction method, you would benefit (readability and efficiency) if you were to cache the unit user data into a local integer.
  • In the addToFaction method, you can discard the "else" and return false at the end of the function.

I think this covers most things :v
 
Level 13
Joined
Aug 8, 2010
Messages
1,022
Uhhh... i was waiting for a resource from you for a looong time, edo! But i wanna see how it works ingame.. When i test the map nothing happens. Just fog of war appears. Is it a bug, do i have to type something or you just simply didn't put anything in there, just code. I don't know jass at all so i don't know what to do.
You can consider giving an example in the next version of the system (if there isn't in that one). :grin:
 
Level 12
Joined
Feb 11, 2008
Messages
810
JASS:
method addToFaction takes unit u returns boolean
            
            //double save protection
            
            if saver[this][GetUnitUserData(u)] != GetUnitUserData(u) and u != null then
                set saver[this][GetUnitUserData(u)] = GetUnitUserData(u)
                set origown[GetUnitUserData(u)] = GetOwningPlayer(u)
                set hunit[this] = hunit[this] + 1
                call .update()
                return true
            else
                return false
            endif
        endmethod

This has way too many calls in it set the GetUnitUserData(u) into a variable then use the variable in place of all the calls to increase efficiency.

EDIT*

Other than that 1 fix this system looks great so ill vote for approval 4/5 for originality once coding is cleaned up will change to 5/5.
 
Top