Results 1 to 10 of 154
Thread: Source: Damage Given/Taken/Killed/Etc
- 03-17-10, 09:28 PM #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:
Note: Basically everything I asked in this thread was addressed in "Python Questions"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

- 03-17-10, 11:52 PM #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).
- 03-18-10, 12:49 AM #3
Re: Source: Damage Given/Taken/Killed/Etc
This is the newest version of the code... lemme know if you see any errors.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
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']
- 03-18-10, 11:50 AM #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
- 03-18-10, 12:40 PM #5
Re: Source: Damage Given/Taken/Killed/Etc
Ok. I'll write up a reply later... short on time right now.

- 03-18-10, 05:26 PM #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]
- 03-18-10, 06:07 PM #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 = [] 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.
- 03-18-10, 07:51 PM #8
Re: Source: Damage Given/Taken/Killed/Etc
What is the exact error?
Originally Posted by Imisnew2
- 03-18-10, 07:58 PM #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 = []
self.killedBy = [None, 0]
- 03-18-10, 08:01 PM #10
Re: Source: Damage Given/Taken/Killed/Etc
The map_voting.py extension uses events to track when a round ends:
Originally Posted by Imisnew2
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
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.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()
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
Thread Information
Users Browsing this Thread
There are currently 1 users browsing this thread. (0 members and 1 guests)


LinkBack URL
About LinkBacks



Reply With Quote


















Bookmarks