Page 1 of 16 12345611 ... LastLast
Results 1 to 10 of 154

Thread: Source: Damage Given/Taken/Killed/Etc

  1. #1

    Source: Damage Given/Taken/Killed/Etc

    This is a class I have setup to hold all the variables... but I need a little help:
    Code:
    class playerStats(object):
    	playerName = ""
    	dmgGiven = []
    	dmgGivenTo = []
    	dmgRecieved = []
    	dmgRecievedFrom = []
    	killedPlayers = []
    	killedBy = ""
    	
    	def damageGiven(self, dmg, dmgTo):
    		for playerIndex in self.dmgGivenTo:
    			if playerIndex is dmgTo:
    				self.dmgGiven[0] += dmg
    				break;
    		else:	
    			self.dmgGiven.append(dmg)
    			self.dmgGivenTo.append(dmgTo)
    			
    	def damageTaken(self, dmg, dmgFrom):
    		for playerIndex in self.dmgRecievedFrom:
    			if playerIndex is dmgFrom:
    				self.dmgRecieved[0] += dmg
    				break;
    		else:	
    			self.dmgRecieved.append(dmg)
    			self.dmgRecievedFrom.append(dmgFrom)
    			
    	def killedPlayer(self, killed):
    		self.killedPlayers.append(killed)
    		
    	def playerDied(self, killer):
    		self.killedBy = killer
    Note: Basically everything I asked in this thread was addressed in "Python Questions"

  2. #2

    Re: Source: Damage Given/Taken/Killed/Etc

    So first you need a python constructor for the class, which is always called __init__ (two underscores on each side)

    Second, you define instance variables in python within a __init__ method, and you always prefix them with self.

    If you have anything defined at the top level of a class, they become class attributes (think static members in other languages).

  3. #3

    Re: Source: Damage Given/Taken/Killed/Etc

    Code:
    #
    #******************************************************************
    #Created By: Imisnew2
    #Creation Date: 3/17/2010
    #Modification Date: 3/18/2010
    #
    #This class will be used outside of the player object class.
    #This class will exist for each player.
    #The purpose of this class is contain all the information needed
    #to display the message below once the player is killed or the
    #round ends.
    #
    #-Damage Given-
    #PlayerName1: 80 damage in 4 shots.
    #PlayerName2: 152 damage in 3 shots.
    #-Damage Taken-
    #PlayerName3: 15 damage in 1 shots.
    #PlayerName4: 101 damage in 2 shots.
    #-Killed-
    #PlayerName1: Killing Blow was 10 damage.
    #PlayerName2: Killing Blow was 102 damage.
    #-Killed By-
    #PlayerName4: Killing Blow was 100 damage.
    #******************************************************************
    #
    class playerStats(object):
      #
      #******************************************************************
      #player: The Object of this player.
      #dmgGiven: Dict of {Player Object Damage Was Given To:
      #    [ Total Damage Given, Total Hits On Player, Final Hit ] }
      #dmgTaken: Dict of {Player Object Damage Was Taken From:
      #    [ Total Damage Taken, Total Hits From Player ] }
      #killedPlayers: Array of Player Objects Who Were Killed By This
      #    Player.
      #killedBy: 2-Size Array of [ Player Object, Killing Dmg ]
      #******************************************************************
      #
      def __init__(self):
        self.player = ""      #This will be a player Object
        self.dmgGiven = {}
        self.dmgTaken = {}
        self.killedPlayers = []
        self.killedBy = [None, 0]
      
      #
      #******************************************************************
      #This method will update the total damage, number of hits, and
      #final damage given to a player if the victim was already shot by
      #this player. If the victim has not been hit by this specific
      #player yet, then add the victim to the list.
      #
      #"'Player': 'Total Damage' damage in 'Number Of Hits' shots."
      #******************************************************************
      #
      def damageGiven(self, dmg, plyrDmgd):
        if plyrDmgd in self.dmgGiven:
          self.dmgGiven[plyrDmgd][0] += dmg
          self.dmgGiven[plyrDmgd][1] += 1
          self.dmgGiven[plyrDmgd][2] = dmg
        else:
          self.dmgGiven[plyrDmgd] = [dmg, 1, dmg]
      
      #
      #******************************************************************
      #This method will update the total damage, number of hits, and
      #final damage taken from an aggressor if this player was already
      #shot by this aggressor. If this player has not been hit by this
      #specific aggressor, then add the aggressor to the list.
      #
      #"'Player': 'Total Damage' damage in 'Number Of Hits' shots."
      #******************************************************************
      #
      def damageTaken(self, dmg, plyrDmgdBy):
        if plyrDmgdBy in self.dmgTaken:
          self.dmgTaken[plyrDmgdBy][0] += dmg
          self.dmgTaken[plyrDmgdBy][1] += 1
          self.killedBy[1] = dmg
        else:
          self.dmgTaken[plyrDmgdBy] = [dmg, 1]
    			
      #
      #******************************************************************
      #This method will update the list of victims killed by this player.
      #
      #"'Player': Killing Blow was 'dmgGiven[killed][2]' damage."
      #******************************************************************
      #
      def killedPlayer(self, killed):
        self.killedPlayers.append(killed)
    		
      #
      #******************************************************************
      #This method will keep track of who killed this player.
      #The killing blow is recorded every time this player is hit.
      #Only the last hit (therefore the killing blow) is saved.
      #See "def damageTaken(self, dmg, plyrDmgdBy)"
      #
      #"'Player': Killing Blow was '[1]' damage."
      #******************************************************************
      #
      def killedByPlayer(self, killer):
        self.killedBy[0] = killer
    This is the newest version of the code... lemme know if you see any errors.

    Some example input and debugging info:
    >>> p1 = playerStats()
    >>> p1.damageGiven(10,"Bob")
    >>> p1.damageGiven(20,"Sally")
    >>> p1.damageGiven(20,"Bob")
    >>> p1.damageGiven(16,"Sally")
    >>> p1.damageGiven(90,"Jim")
    >>> p1.damageGiven(2,"Markus")
    >>> p1.damageGiven(16,"Imisnew2")
    >>> p1.damageGiven(53,"Jim")
    >>> p1.killedPlayer("Jim")
    >>> p1.damageGiven(5321,"Imisnew2")
    >>> p1.killedPlayer("Imisnew2")
    >>> p1.damageGiven(153,"Bob")
    >>> p1.killedPlayer("Bob")
    >>> print p1.dmgGiven
    {'Markus': [2, 1, 2], 'Bob': [183, 3, 153], 'Jim': [143, 2, 53], 'Sally': [36, 2, 16], 'Imisnew2': [5337, 2, 5321]}
    >>> print p1.killedPlayers
    ['Jim', 'Imisnew2', 'Bob']

  4. #4

    Re: Source: Damage Given/Taken/Killed/Etc

    It's a really good start


    - Could you add the standard top-of-the-file comment block the other LS files have and then merge your description into it?
    - the player object should be switched to actual player objects instead of using names (it's being initialized to a string instead of None still)
    - Classes need to start with a capital letter
    - It's better to spell everything out, so where dmg => damage everywhere
    - For python function docs, you actually put the docs right below the function signature and use triple quote. By putting it right below the function, python actually associates that doc with the function (and you can get the comment at runtime actually). By using triple quote, it preserves all newlines so you can have a block of formatted text
    Example:
    def myFunction(...):
    """Here are my docs
    with embedded newlines
    that will be preserved."""
    # actual code


    Next step, hook it up to events

    To get player objects you want to use the "playerManager" singleton object that is found in clients.py. It has utility methods for finding the player object of a given user id (which is what events store and will give you).

    from lonestar.clients import playerManager
    playerManager.findPlayerByUid(...) # or something like that, search clients.py for find* to see all the ways you can find a player

  5. #5

    Re: Source: Damage Given/Taken/Killed/Etc

    Ok. I'll write up a reply later... short on time right now.

  6. #6

    Re: Source: Damage Given/Taken/Killed/Etc

    My comments are not compiling when I use triple quote comments

    def __init__(self):
    """player: The Object of this player.
    dmgGiven: Dict of {Player Object Damage Was Given To:
    [ Total Damage Given, Total Hits On Player, Final Hit ] }
    dmgTaken: Dict of {Player Object Damage Was Taken From:
    [ Total Damage Taken, Total Hits From Player ] }
    killedPlayers: Array of Player Objects Who Were Killed By This
    Player.
    killedBy: 2-Size Array of [ Player Object, Killing Dmg ]"""
    self.player = None
    self.dmgGiven = {}
    self.dmgTaken = {}
    self.killedPlayers = []
    self.killedBy = [None, 0]

  7. #7

    Re: Source: Damage Given/Taken/Killed/Etc

    How would I link a method to execute on an event?
    And how do I access the events?

    Third iteration:

    Code:
    #
    #***********************************************************************
    # $Id: .py 196 2010-3-17 Imisnew2 $
    # Copyright 2008-2009 Tim Thelin
    #
    # This file is part of LoneStar.
    #
    # LoneStar is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # LoneStar is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with LoneStar. If not, see <http://www.gnu.org/licenses/>.
    #
    # === Class Description ===
    #
    # client.py needs to be executed before this.
    # This class will exist for each player that has taken/given damage.
    # The purpose of this class is contain all the information needed
    # to display the message below once the player is killed or the
    # round ends.
    #
    # -Damage Given-
    # PlayerName1: 80 damage in 4 shots.
    # PlayerName2: 152 damage in 3 shots.
    # -Damage Received-
    # PlayerNam03: 15 damage in 1 shots.
    # PlayerName4: 101 damage in 2 shots.
    # -Killed-
    # PlayerName1: Killing Blow was 10 damage.
    # PlayerName2: Killing Blow was 102 damage.
    # -Killed By-
    # PlayerName4: Killing Blow was 100 damage.
    #***********************************************************************
    #
    class PlayerKillStats(object):
      #
      #***********************************************************************
      #player     The Object of this player.
      #damageGiven  Dict of {Player That Was Damaged (Key),
      #        [Total Damage, Total Hits, Final Hit Damage] (Values)}
      #damageTaken:  Dict of {Player Damage Was Taken From:
      #        [Total Damage, Total Hits] (Values)}
      #playersKilled: Array of Player Objects this player has killed.
      #killedBy:   2-Size Array containing [Player, Final Hit Damage]
      #***********************************************************************
      #
      def __init__(self, thePlayer):
        self.player = thePlayer
        self.damageGiven = {}
        self.damageTaken = {}
        self.playersKilled = &#91;]
        self.killedBy = [None, 0]
      
      #
      #***********************************************************************
      #This method is called when the player gives damage to another
      #player. This method records:
      #  totalDamage   (Given to the victim)
      #  totalHits    (Given to the victim)
      #  lastDamageDone (By this player to the victim)
      #
      #"'Player': 'Total Damage' damage in 'Number Of Hits' shots."
      #***********************************************************************
      #
      def playerGaveDamage(self, damageDealt, playerDamaged):
        if playerDamaged in self.damageGiven:
          self.damageGiven[playerDamaged][0] += damageDealt
          self.damageGiven[playerDamaged][1] += 1
          self.damageGiven[playerDamaged][2] = damageDealt
        else:
          self.damageGiven[playerDamaged] = [damageDealt, 1, damageDealt]
      
      #
      #***********************************************************************
      #This method is called when this player takes damage from another
      #player. This method records:
      #  totalDamage   (Taken from the aggressor)
      #  totalHits    (Taken from the aggressor)
      #  lastDamageDone (By the aggressor to this player)
      #
      #"'Player': 'Total Damage' damage in 'Number Of Hits' shots."
      #***********************************************************************
      #
      def playerTookDamage(self, damageDealt, playerDamagedBy):
        if playerDamagedBy in self.damageTaken:
          self.damageTaken[playerDamagedBy][0] += damageDealt
          self.damageTaken[playerDamagedBy][1] += 1
        else:
          self.damageTaken[playerDamagedBy] = [damageDealt, 1]  
        self.killedBy[1] = damageDealt
    			
      #
      #***********************************************************************
      #This method will update the list of victims killed by this player.
      #
      #"'Player': Killing Blow was 'damageGiven[killed][2]' damage."
      #***********************************************************************
      #
      def playerKilledPlayer(self, killed):
        self.playersKilled.append(killed)
    		
      #
      #***********************************************************************
      #This method will keep track of who killed this player.
      #The killing blow is recorded every time this player is hit.
      #Only the last hit (therefore the killing blow) is saved.
      #See "def playerTookDamage(self, damage, playerDamagedBy)"
      #
      #"'Player': Killing Blow was '[1]' damage."
      #***********************************************************************
      #
      def playerDied(self, killer):
        self.killedBy[0] = killer
    		
      #
      #***********************************************************************
      #This method will format all the stats in this class and return a string
      #that can be displayed back to the user that looks like the example in
      #the class description.
      #***********************************************************************
      #
      def getStats(self):
        stats = ""
        if len(self.damageGiven) is not 0:
          stats += "-Damage Given-"
          for damageStats in self.damageGiven:
            stats += "\n%s: %s damage in %s shots." % (damageStats, self.damageGiven[damageStats][0], self.damageGiven[damageStats][1])
        if len(self.damageTaken) is not 0:
          stats += "\n-Damage Received-"
          for damageStats in self.damageTaken:
            stats += "\n%s: %s damage in %s shots." % (damageStats, self.damageTaken[damageStats][0], self.damageTaken[damageStats][1])
        if len(self.playersKilled) is not 0:
          stats += "\n-Killed-"
          for damageStats in self.playersKilled:
            stats += "\n%s: Killing Blow was %s damage." % (damageStats, self.damageGiven[damageStats][2])
        if self.killedBy[0] is not None:
          stats += "\n-Killed By-"
          stats += "\n%s: Killing Blow was %s damage." % (self.killedBy[0], self.killedBy[1])
        return stats
    >>> execfile("clientKillWindow.py")
    >>> p1 = PlayerKillStats("Imisnew2")
    >>> p1.playerGaveDamage(100,"Bob")
    >>> p1.playerKilledPlayer("Bob")
    >>> p1.playerGaveDamage(40,"Sally")
    >>> p1.playerTookDamage(15,"Sally")
    >>> p1.playerGaveDamage(60,"Sally")
    >>> p1.playerKilledPlayer("Sally")
    >>> p1.playerGaveDamage(20,"Markus")
    >>> p1.playerGaveDamage(20,"Markus")
    >>> p1.playerTookDamage(50,"Markus")
    >>> p1.playerGaveDamage(20,"Markus")
    >>> p1.playerTookDamage(6,"Markus")
    >>> p1.playerGaveDamage(20,"Markus")
    >>> p1.playerTookDamage(9,"Markus")
    >>> p1.playerGaveDamage(20,"Markus")
    >>> p1.playerKilledPlayer("Markus")
    >>> p1.playerGaveDamage(25,"Phillip")
    >>> p1.playerGaveDamage(25,"Joe")
    >>> p1.playerTookDamage(5, "Phillip")
    >>> p1.playerTookDamage(11, "Joe")
    >>> p1.playerGaveDamage(50,"Joe")
    >>> p1.playerGaveDamage(75,"Phillip")
    >>> p1.playerKilledPlayer("Phillip")
    >>> p1.playerTookDamage(3,"Joe")
    >>> p1.playerGaveDamage(25,"Joe")
    >>> p1.playerKilledPlayer("Joe")
    >>> p1.playerTookDamage(345, "vafaskillz")
    >>> p1.playerDied("vafaskillz")
    >>> print p1.getStats()
    -Damage Given-
    Markus: 100 damage in 5 shots.
    Bob: 100 damage in 1 shots.
    Sally: 100 damage in 2 shots.
    Joe: 100 damage in 3 shots.
    Phillip: 100 damage in 2 shots.
    -Damage Received-
    Markus: 65 damage in 3 shots.
    vafaskillz: 345 damage in 1 shots.
    Sally: 15 damage in 1 shots.
    Joe: 14 damage in 2 shots.
    Phillip: 5 damage in 1 shots.
    -Killed-
    Bob: Killing Blow was 100 damage.
    Sally: Killing Blow was 60 damage.
    Markus: Killing Blow was 20 damage.
    Phillip: Killing Blow was 75 damage.
    Joe: Killing Blow was 25 damage.
    -Killed By-
    vafaskillz: Killing Blow was 345 damage.

  8. #8

    Re: Source: Damage Given/Taken/Killed/Etc

    Quote Originally Posted by Imisnew2
    My comments are not compiling when I use triple quote comments

    def __init__(self):
    """player: The Object of this player.
    dmgGiven: Dict of {Player Object Damage Was Given To:
    [ Total Damage Given, Total Hits On Player, Final Hit ] }
    dmgTaken: Dict of {Player Object Damage Was Taken From:
    [ Total Damage Taken, Total Hits From Player ] }
    killedPlayers: Array of Player Objects Who Were Killed By This
    Player.
    killedBy: 2-Size Array of [ Player Object, Killing Dmg ]"""
    self.player = None
    self.dmgGiven = {}
    self.dmgTaken = {}
    self.killedPlayers = &#91;]
    self.killedBy = [None, 0]
    What is the exact error?

  9. #9

    Re: Source: Damage Given/Taken/Killed/Etc

    >>> execfile("clientKillWindow.py")
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "clientKillWindow.py", line 50
    killedBy 2-Size Array containing [Player, Final Hit Damage]"""
    ^
    IndentationError: expected an indented block
    >>>

    With:

    class PlayerKillStats(object):
    def __init__(self, thePlayer):
    """player The Object of this player.
    damageGiven Dict of {Player That Was Damaged (Key),
    [Total Damage, Total Hits, Final Hit Damage] (Values)}
    damageTaken Dict of {Player Damage Was Taken From:
    [Total Damage, Total Hits] (Values)}
    playersKilled Array of Player Objects this player has killed.
    killedBy 2-Size Array containing [Player, Final Hit Damage]"""
    self.player = thePlayer
    self.damageGiven = {}
    self.damageTaken = {}
    self.playersKilled = &#91;]
    self.killedBy = [None, 0]

  10. #10

    Re: Source: Damage Given/Taken/Killed/Etc

    Quote Originally Posted by Imisnew2
    How would I link a method to execute on an event?
    And how do I access the events?
    The map_voting.py extension uses events to track when a round ends:
    https://ttp.devguard.com/trac/lonest..._voting.py#L86
    sdk.createGameEventListener("round_end", self._handleRoundEnd)

    The first parameter is the name of the events to get notified of, the second paramter is the callback to call when the event with that name fires.

    This is the callback specified above:
    https://ttp.devguard.com/trac/lonest...voting.py#L124
    Code:
    124	  def _handleRoundEnd(self, event):
    125	    self._totalRounds += 1
    126	    if event.getName() == "teamplay_round_win" or event.getName() == "dod_round_win":
    127	      team = event.getInt("team")
    128	    else:
    129	      team = event.getInt("winner")
    130	    teamData = teamManager.findTeamById(team).data
    131	    teamData[_KEY_ROUND_WINS] += 1
    132	    
    133	    if self._watchRoundLimits:
    134	      roundsLeft = nextMapVote_roundsLeft.intValue
    135	      if self._maxRounds:
    136	        maxRounds = self._maxRounds.intValue
    137	        if maxRounds != 0 and self._totalRounds >= maxRounds - roundsLeft:
    138	          self.startNextMapVote()
    139	          return
    140	      if self._winLimit:
    141	        winLimit = self._winLimit.intValue
    142	        if winLimit != 0 and teamData[_KEY_ROUND_WINS] >= winLimit - roundsLeft:
    143	          self.startNextMapVote()
    Callbacks get exactly one parameter: the event object. Technically this one gets two because its a member function: so its first argument is going to be self, and the second argument is the event object.

    Because the sdk call asked to be notifed of "round_end", you know the event object holds data according to the docs for "round_end" events as documented here:
    http://wiki.alliedmods.net/Generic_S...ents#round_end
    http://wiki.alliedmods.net/Day_of_De...#dod_round_win
    http://wiki.alliedmods.net/Team_Fort...play_round_win
    (Different mods use different events for round end, most mods (including CSS) use round_end, tf uses teamplay_round_win, and dod uses dod_round_win, so this callback handles any of them as they are largely the same)

    The rest of the function shows how you can extract the data out of the event using the keys found in the above docs.


    In your case, you need to register to receive callbacks for player_hurt and player_death events, which are also in the above docs

Page 1 of 16 12345611 ... LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336