System Assistance System 1.20

Discussion in 'Systems and Snippets' started by emjlr3, Apr 22, 2008.

  1. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    Assistance System 1.20

    [​IMG]

    A completely customizable assistance system.​

    What is an Assistance System you ask? Well quite simply, when you have allies on your team with heroes, and more often, when the game is specifically designed to just use heroes, people can get angry when they help to get hero kills yet reap no reward for doing so. This system allows you to display who helped make kills, record how many times each player has done so, and divvy out rewards for said help.

    Read Me:
    Assistance System 1.20
    by: emjlr3

    Setup is very simple. Just copy the AssistanceSystem trigger to your map. If you do not have the GetPlayerNameColored library, you must copy that over too, but if you already have that trigger you do not need to.
    Save your map. if it saves, everything is ready, if not, delete it all and try again. Once it saves, go through the Config. options and set them to whatever you want.

    To use the system, simply call:

    AssistanceSystem_Register(unit to register)

    to allow players who help kill that unit to get assists for doing so.

    The system is then loaded for that unit. You can only do this once per unit, and doing so more often will result in error messages.

    The system stores the number of assists a unit has in the integer array AssitanceSystem_Assists[playerid]
    This system is not MUI currently, it is PUI. Only 1 unit can be registered per player.
    And that is all, the system is setup, and your heroes are registered. Enjoy!

    System Code:
    JASS:
    library AssistanceSystem initializer Init_AssistanceSystem, needs GetPlayerNameColored
    
    //=====Assistance System 1.20=====\\
    
    globals
        // Configuration Options:
        private constant real Time = 10. // Time after latest damage after which no more assistance given
        private constant integer Award = 125 // Bonus gold for getting an assist
        private constant boolean Split = true // Whether to split award gold between all players who get an assist
        private constant string Msg1 = "With assistance from " // Starting portion of assistance message
        private constant string Msg2 = " gold!" // Message after the amount of gold is displayed
        private constant string Msg3 = " gold a piece!" // Same as above, except for multiple assisters
        private constant string GoldColor = "" // Color code for the color you would like the bounty value displayed in
        
    //=====Don't touch past this point=====\\
        private unit array Targets
        private timer array Timers
        private timer array T
        private trigger Trigger1 = CreateTrigger() 
        private trigger Trigger2 = CreateTrigger()
        private group Heroes = CreateGroup()
        private integer Skip
        private integer Total
        
        public integer array Assists // Can be accessed publically as AssistanceSystem_Assists[playerid]
    endglobals
    //*************************************************************************
    
    private function Reset takes nothing returns nothing
        local integer i = 0
        local timer t = GetExpiredTimer()
        
        loop
            exitwhen Timers[i]==t
            
            if i>Total then
                call BJDebugMsg("AS Error: |cffff0000No reset timer found.")
                set t = null
                return
            endif
            set i = i + 1
        endloop
        
        call PauseTimer(t)
        set t = null
        set Timers[i] = null
        set Targets[i] = null
    endfunction
    private function Timer takes nothing returns nothing
        local unit dam = GetEventDamageSource()
        local player pdam = GetOwningPlayer(dam)
        local unit targ = GetTriggerUnit()
        local player ptarg = GetOwningPlayer(targ)
        local integer i = GetPlayerId(ptarg)+(Skip*GetPlayerId(pdam))
        
        if not IsUnitEnemy(dam,ptarg) or pdam==ptarg or GetEventDamage()<.1 then
            set targ = null
            set dam = null
            return
        endif
        
        if Timers[i]==null then
            if T[i]==null then
                set T[i] = CreateTimer()
            endif
            set Timers[i] = T[i]
            set Targets[i] = targ
            call TimerStart(Timers[i],Time,false,function Reset)
        else
            call PauseTimer(Timers[i])
            call TimerStart(Timers[i],Time,false,function Reset)
        endif
        
        set dam = null
        set targ = null
    endfunction
    
    private function Death takes nothing returns nothing
        local unit killer = GetKillingUnit()
        local player pkill = GetOwningPlayer(killer)
        local unit dieer = GetTriggerUnit()
        local integer i = GetPlayerId(GetOwningPlayer(dieer))
        local integer id = i
        local player array pa
        local integer count = 0
        local integer playid
        local string msg 
        local string endmsg = Msg2
        local integer gold = Award
        
        loop
            exitwhen i>Total
            if Targets[i]==dieer then
                if pkill!=Player((i-id)/Skip) then
                    set count = count + 1
                    set playid = (i-id)/Skip
                    set pa[count] = Player(playid)
                    set Assists[playid] = Assists[playid] + 1
                endif
                set Targets[i] = null
                call PauseTimer(Timers[i])
                set Timers[i] = null
            endif
            
            set i = i + Skip
        endloop
        
        if count==0 then
            set killer = null
            set dieer = null
            return
        elseif count>1 then
            set endmsg = Msg3
        endif
        if Split then
            set gold = Award/count
        endif
        
        set i = 1
        set msg = Msg1 + GetPlayerNameColored(pa[i])
        loop
            exitwhen i>count
            call SetPlayerState(pa[i], ConvertPlayerState(1), GetPlayerState(pa[i], ConvertPlayerState(1)) + gold)
            set i = i + 1
        endloop
        set i = 2
        set count = count - 1
        loop
            exitwhen i>count
            set msg = msg + ", " + GetPlayerNameColored(pa[i])
            set i = i + 1
        endloop
        if count>0 then
            set msg = msg + " and " + GetPlayerNameColored(pa[i])
        endif
        set msg = msg + ".  +"+GoldColor+I2S(gold)+"|r"+endmsg 
        call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,msg)
        
        set killer = null
        set dieer = null
    endfunction
    
    // Start the system for the unit
    public function Register takes unit u returns nothing
        if IsUnitInGroup(u,Heroes) then
            call BJDebugMsg("AS Error: |cffff0000"+GetUnitName(u)+" has already been registered with the system.")
            return
        endif
        call GroupAddUnit(Heroes,u)
        call TriggerRegisterUnitEvent(Trigger1, u, EVENT_UNIT_DAMAGED)
        call TriggerRegisterUnitEvent(Trigger2, u, EVENT_UNIT_DEATH)
    endfunction
    
    private function Init_AssistanceSystem takes nothing returns nothing
        local integer i = GetPlayers()-1
        
        call TriggerAddAction( Trigger1, function Timer)
        call TriggerAddAction( Trigger2, function Death)
        
        set Skip = i+1
        set Total = (Skip*i)+i-1
    endfunction
    
    endlibrary

    Version History:
    • 1.20 - Minor coding updates
      More configuration options, mainly message oriented
      No longer creates and destroys timers dynamically, reuses the same ones
      Minor test map updates, and an easter egg added
    • 1.10b - Slight Read Me updates
    • 1.10 - Users no longer need to manually input the number of players
      Fixed a minor bug in the displayed message when only 1 player got an assist
      Minor coding updates
      Assists are now recorded and can be accessed globally
      Minor updates to the test map, including a proper minimap image and a multiboard to display assists and other stats
    • 1.00 - Initial Release
     

    Attached Files:

    • Like Like x 8
  2. Ghostwind

    Ghostwind o________o

    Ratings:
    +171 / 0 / -0
    It works.
     
    • Like Like x 1
  3. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    lol that is sort of the idea
     
    • Like Like x 1
  4. Larcenist

    Larcenist REP: Respect, Envy, Prosperity?

    Ratings:
    +211 / 0 / -0
    tried it and it looked great. Preformed a lot better than my GUI crap I wrote for assistance system too. One question since I do not know much JASS myself, is it possible to change an assist-score in a multiboard for each player with this system? So that is shows kills/deaths/assists?
     
  5. linamus

    linamus I r bak!

    Ratings:
    +57 / 0 / -0
  6. Vestras

    Vestras Retired

    Ratings:
    +249 / 0 / -0
    Are you doin' some kind of AoS with all those systems? (duh, two -.-)
     
  7. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    thnx for trying, id hope it was better then your "GUI Crap"
    it would be a good idea for me to have assistance values interally to the system, which are maintaned and can be retrieved globally

    good idea

    ty

    not really, but i sort of needed these, so i figured if i was going to make em, i might as well release em too
     
  8. Larcenist

    Larcenist REP: Respect, Envy, Prosperity?

    Ratings:
    +211 / 0 / -0
    It's a lot better than my GUI system, the only thing it lacks is assistance values to add to a multiboard. If you would add this I'd surely be using this system instead. Keep up the good work.
     
  9. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    ill update it tonight to include those, its a simple addition, but a good one

    I am surprised no one has commented on my storage algorithm, i thought it was ingenious :) maybe thats just me, I know Viles was simply retarded in that department
     
  10. Joker(Div)

    Joker(Div) Always Here..

    Ratings:
    +86 / 0 / -0
    Several Questions.

    1. Why don't you use CCSafety? Your not pausing the timer before destroying and also why do you null globals timers (and units)? (all in Reset)

    2. Any reason to not null local unit dam? (In Timer)

    3. Any reason not to null local unit dieer? (In Death)

    4. What's up with this? Why a seperate function for your actions?
    JASS:
    private function Init_AssistanceSystem takes nothing returns nothing
        call TriggerAddAction( Trigger1, function Timer)
        call TriggerAddAction( Trigger2, function Death)
    endfunction


    5. ConvertPlayerState(1), Keep those as w/e the bj vars were. Variables > calls

    Your system seems a bit limited, but at least its short and does the job.
     
  11. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    UPDATED!!!!

    1. Who cares if I do not pause the timer??? You need to null it to see when it was expired, if you don't null it how are you to tell? Use a unit group/registered unit, and add/remove units from it? Its an option I suppose, but this is how I did it, if you can really think of a better method speak up. I suppose I could use a CSSafety variant, specifically for this system, though that would really be a case for nulling the globals stored in the array, else there would be huge problems
    2 & 3. I figured for 99% of ppl this would be used for heroes, thus, they never leave, and do not need to be nulled. diier and dam will always be said hero. I updated it though just incase, to keep you happy
    4. What???? I need to initiate the system, no? If you mean why not use 1 function for deaths and timer expiration? In that case, why doesn't everyone just use 1 function for their entire map???
    5. Its a native, im not too worried, and its only called a few times every few seconds, tops. Its really not a big deal

    Limited, in what sense of the word, the sense that it has no limits?? I fail to see what you mean by this....
     
  12. Joker(Div)

    Joker(Div) Always Here..

    Ratings:
    +86 / 0 / -0
    1. I thought not pausing timers caused bugs ingame. You could use the TimerGetRemaining or TimerGetElapsed natives.
    2/3. Eh..I guess its not all too important.
    4. I don't see why you don't just put those actions in your function Register. (I guess since your using a global trigger it doesnt matter..)

    I was a bit confused at first glance because I'm not used to seeing global useage like this.

    @Limited
    I meant it doesn't have much features.
     
  13. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    what features is it lacking?

    ive had problems with timergetremaining and elapsed before not giving me correct values

    why would i want to add the actions function to the trigger each time a unit is registered, that makes no sense
     
  14. waaaks!

    waaaks! Zinctified

    Ratings:
    +256 / 0 / -0
    just the system im waiting for....i asked vile to fix it, but he didnt replied :( poor me...
    now u made it, ill try it...

    EDIT: works well
     
  15. Uberplayer

    Uberplayer -

    Ratings:
    +454 / 0 / -0
    "Read me" could tell what this system does, because I have no idea.
     
  16. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    guess i could answer that a few ways

    1. if u dont know what one is, you prolly dont need it
    2. read the code and find out
    3. you dont know what an assistance system is???
    4. cant tell from the screenshot??
    5. cant tell from testing the map??
    6. maybe i should explain....
    7. rinse and repeat
     
  17. AceHart

    AceHart Your Friendly Neighborhood Admin

    Ratings:
    +1,489 / 0 / -0
    > maybe I should explain

    Well, yes. Would be an idea, now, wouldn't it?

    My random guess here says:
    - I get some extra Gold from being nearby some kill
    - If I also damaged that special target unit
    - And within 10 seconds of... of its... of... well, how knows what the heck. There's some timer involved. Somehow.

    How much do I get? Don't ask me, I have no idea.
    What about that timer?

    No need to count the players? Nice... though I can't say I see why that would be needed anyway.


    Anyway, some more details as to what exactly, and why, is going on wouldn't hurt.
     
  18. cr4xzZz

    cr4xzZz Also known as azwraith_ftL.

    Ratings:
    +51 / 0 / -0
    Perfect! D*mn, you make such nice systems, and systems that I needed... ^^
    Nobody knows what an Assistance System is if they don't play DotA (probably). I think this needs a long explanation, well, a decent one. Don't get me wrong, it does really show perfectly what it does but if some people are asking what it is... Well, nvm. Gj again :thup:
     
  19. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    when I eventually need to find out what timer expired, the less things I need to loop through the better

    Ima add an explanation to the post now

    **UPDATED!!!**
     
  20. Larcenist

    Larcenist REP: Respect, Envy, Prosperity?

    Ratings:
    +211 / 0 / -0
    This is probably one of the most useful non-code enhancing systems around. This is going straight into my current project. Keep up the good work.
     

Share This Page