Scripts:ThreatAndWorth
Description
- Module
ThreatAndWorth.py
- Author
- SHAnders
- Version
- 1.01
Server side only admin script or mod addon, you deside the usage!
Features
Worth
This script will reward player kills based upon a worth schema. Each players will be assigned a 'worth' when they get killed or kill. If victim worth > attacker worth, the attacker is assigned a bonus. Worth is calculated by vehicle, and players position within it plus an addition if player is squadleader or commander, snipers are worth only to other snipers.
Threat
This script implements threat rating. The lower the attacker threat raking and the higher the victim threat rating, the higher the bonus and vice versa. Threat rating is based uppon a calculation of a player kills, deaths and scores compared to the average player in the game. Threat rating can be disabled by setting: USE_THREAT_RATING = False
.
Survival
At the end of the game players will be rewarded upon their survival rating. The more enemies you kill and the less you get killed, the higher the bonus.
Survivalrating can be disabled by setting : USE_SURVIVAL_RATING = False
Commander
To please a few people out there it is now possible to disable the commander in this script.
Commander can be disabled by setting: DISABLE_COMMANDER = True
Installation
Installation as Admin script -- not a mod, adds scoring changes to all games on server:
- Save this script as
ThreatAndWorth.py
in youradmin/standard_admin
directory. - Add the lines
import ThreatAndWorth
andThreatAndWorth.init()
to the fileadmin/standard_admin/__init__.py
.
Installation as Mod addon -- adds scoring changes only to your mod:
- Save this script as
ThreatAndWorth.py
in yourmods/<mod_lib>/python/game
directory. - Add the lines
import ThreatAndWorth
andThreatAndWorth.init()
to the filemods/<mod_lib>/python/game/__init__.py
.
TODO:
- Team score
- Additional points for actions made within 30-50 feet of a commander/squadleader attack/defend/fix/blowup/asembly order
Thanks To
Battlefield.no for inspiration from their pingkick.py script
The Code
# ------------------------------------------------------------------------ # Module: ThreatAndWorth.py # Author: SHAnders # # Version 1.01 # Changes # 1.0 -> 1.01 # Updated the messagetimer to only start once # # Description: # Server side only admin script or mod addon, you deside the usage ! # # This script will reward player kills based uppon a worthschema # Each players will be assigned a 'worth' when they get killed or kill # If victim worth > attacker worth, the attacker is assigned a bonus. # Worth is calculated by vehicle, and players position within it plus # an addition if player is squadleader or commander, snipers are worth only to other snipers. # # This script implement threat rating. The lower the attacker threat raking # and the higher the victim threat rating, the higher the bonus and vice versa. # Threat rating is based uppon a calculation of a player kills, deaths & scores # compared to the average player in the game. # # At the end of the game players will be rewarded uppon their survival rating. # The more enemies you kill and the less you get killed, the higher the bonus. # # To please a few people out there it is now posible to disable the commander in this script. # # The scoring system provided by ThreatAndWorth refines the idear and system # implemted by the earlier scoringBonuses v1.0 # ThreatAndWorth therfor replaces the scoringBonuses script. # # Requirements: # None. # # Installation as Admin script -- Not a mod, adds scoring changes to all games on server: # 1: Save this script as 'ThreatAndWorth.py' in your <bf2>/admin/standard_admin directory. # 2: Add the lines 'import ThreatAndWorth' and 'ThreatAndWorth.init()' to the file # '<bf2>/admin/standard_admin/__init__.py'. # # Installation as Mod addon -- adds scoring changes only to your mod: # 1: Save this script as 'ThreatAndWorth.py' in your <bf2>/mods/<mod_lib>/python/game directory. # 2: Add the lines 'import ThreatAndWorth' and 'ThreatAndWorth.init()' to the file # '<bf2>/mods/<mod_lib>/python/game/__init__.py'. # # TODO: # Team score: # Additional points for actions made within 30-50 feet of a commander/squadleader # attack/defend/fix/blowup/asembly order # # Thanks to: # Battlefield.no for inspiration from their pingkick.py script # # ------------------------------------------------------------------------ import host import bf2 from bf2.stats.constants import * from bf2 import g_debug from bf2.stats.stats import onGameStatusChanged # ------------------------------------------------------------------------ # Constants # ------------------------------------------------------------------------ WORTHSCHEMA = { VEHICLE_TYPE_ARMOR : [ 6, 3, 1, 1, 1, 1, 1, 1 ], VEHICLE_TYPE_AVIATOR : [ 8, 3, 1, 1, 1, 1, 1, 1 ], VEHICLE_TYPE_AIRDEFENSE : [ 1 ], VEHICLE_TYPE_HELICOPTER : [ 6, 3, 3, 1, 1, 1, 1, 1 ], VEHICLE_TYPE_TRANSPORT : [ 3, 3, 1, 1, 1, 1, 1, 1 ], VEHICLE_TYPE_ARTILLERY : [ 1 ], VEHICLE_TYPE_GRNDDEFENSE : [ 1 ], VEHICLE_TYPE_PARACHUTE : [ 1 ], VEHICLE_TYPE_SOLDIER : [ 0 ] } # index 0 is allways used for victim, 0-7 are all used for attacker # Aditional worth, only the greatest applies VICTIM_SNIPER = 2 # Only applies when attacker is sniper VICTIM_SQUADLEADER = 4 # Killing a squadleader in a jet gives good points, But why would he/she be there anyway ... squad members cant spawn there? VICTIM_COMMANDER = 6 # Killing a commander in a jet gives good points, But why would he/she be there anyway ... should he/she not bee doing something else? DEFAULT_VICTIM_WORTH = 1 # Victim will allways be worth this + whats in the WORTHSCHEMA USE_THREAT_RATING = True # Low threat rated players get more points for kills on higher threat rated players [True, False] PUBLIC_SCORES = 1 # Score earnings will be made public to the following: [0 = None, 1 = Team, 2 = All] USE_SURVIVAL_RATING = True # At end game players with high survivalrating will be rewarded with (SurvivalRating * (kills - deaths) / restraint) [True, False] SURVIVAL_RATING_RESTRAINT = 3 # The higher the number, the lower the bonus (without it the bonus can get very high) [1..*] DISABLE_COMMANDER = False # Not all like the commander, setting this to True will disable this posibility [True, False] WELCOME_MSG = "Server is using ThreatAndWorth script v1.0" # ------------------------------------------------------------------------ # Variables # ------------------------------------------------------------------------ MsgTimer = None # Welcome msg Timer # ------------------------------------------------------------------------ # Init # ------------------------------------------------------------------------ def init(): host.unregisterGameStatusHandler(onGameStatusChanged) # We need to unregister this to change endscores host.registerGameStatusHandler(onGameStatusChangedThreatAndWorth) host.registerGameStatusHandler(onGameStatusChanged) # We need to register it again after our own handler to make the game work :) MsgTimer = bf2.Timer(onMsgTimer,10,1) if g_debug: print "ThreatAndWort init" # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # onGameStatusChangedThreatAndWorth # ------------------------------------------------------------------------ def onGameStatusChangedThreatAndWorth(status): if status == bf2.GameStatus.Playing: host.registerHandler('PlayerKilled', onPlayerKilled) if DISABLE_COMMANDER: host.sh_setEnableCommander(0) elif status == bf2.GameStatus.EndGame: if USE_SURVIVAL_RATING: CalculateSurvivalRatingBonus() # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # onPlayerKilled # ------------------------------------------------------------------------ def onPlayerKilled(victim, attacker, weapon, assists, object): victimVehicle = victim.getVehicle() # killed by remote controlled vehicle, no score awarded in this game if victimVehicle and victimVehicle.getIsRemoteControlled(): pass # no attacker, killed by object elif attacker == None: pass # killed by self elif attacker == victim: pass # killed by own team elif attacker.getTeam() == victim.getTeam(): pass # killed by enemy else: CalculateThreatAndWorth(attacker, victim) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # addBonus # ------------------------------------------------------------------------ def addBonus(player, points): # commander doesnt get bonus for regular actions, only for pure commander tasks. if not player.isCommander(): player.score.score += points # commander score commander = bf2.playerManager.getCommander(player.getTeam()) if commander != None and commander.isValid() and player != commander and points > 0: preScore = commander.score.score numPlayers = bf2.playerManager.getNumberOfAlivePlayersInTeam(commander.getTeam()) if numPlayers > 0: commander.score.score += float(points) / numPlayers scoreGotten = commander.score.score - preScore if scoreGotten > 0: commander.score.cmdScore += scoreGotten # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Callback function for timer, that delays a message at round start: # I hope the fellows at Battlefield.no dont mind me using this ! # ------------------------------------------------------------------------ def onMsgTimer(data): global msgtimer sendMsgAll( WELCOME_MSG ) msgtimer.destroy() msgtimer = None # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Send message to all on server # ------------------------------------------------------------------------ def sendMsgAll(msg): host.rcon_invoke("game.sayAll \"" + str(msg) + "\"") # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Send message to all on a team # ------------------------------------------------------------------------ def sendMsgTeam(msg, team): host.rcon_invoke("game.sayTeam " + str(team) + " \"" + str(msg) + "\"") # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Calculate survival endgame points # ------------------------------------------------------------------------ def CalculateSurvivalRatingBonus(): playerArgs = bf2.playerManager.getPlayers() for p in playerArgs: survivalRating = GetPlayerSurvivalRating(p) if survivalRating > 0: points = round((p.score.kills - p.score.deaths) * survivalRating / SURVIVAL_RATING_RESTRAINT, 0) addBonus(p, int(points)) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Get a players survival rating # ------------------------------------------------------------------------ def GetPlayerSurvivalRating( player ): kills = float(player.score.kills + 1) deaths = float(player.score.deaths + 1) survivalRating = kills / deaths return round(survivalRating, 2) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Calculate threat and worth points # ------------------------------------------------------------------------ def CalculateThreatAndWorth(attacker, victim): victimVehicle = victim.getVehicle() victimRootVehicle = getRootParent(victimVehicle) attackerVehicle = attacker.getVehicle() attackerRootVehicle = getRootParent(attackerVehicle) points = 0 attackerWorth = GetPlayerWorth( attacker ) victimWorth = GetPlayerWorth( victim ) + GetAdditionalVictimWorth(attacker, victim) tmpPoints = victimWorth - attackerWorth if tmpPoints > 0: if USE_THREAT_RATING: attackerThreatRating = GetPlayerThreatRating( attacker ) victimThreatRating = GetPlayerThreatRating( victim ) threatRatingFactor = round((victimThreatRating / attackerThreatRating),3) if threatRatingFactor < 0.125: threatRatingFactor = 0 if threatRatingFactor < 0.25: threatRatingFactor = 0.125 elif threatRatingFactor < 0.5: threatRatingFactor = 0.25 elif threatRatingFactor < 0.75: threatRatingFactor = 0.5 elif threatRatingFactor < 1.5: threatRatingFactor = 1 elif threatRatingFactor < 2: threatRatingFactor = 1.5 else: threatRatingFactor = 2 tmpPoints = int(round( threatRatingFactor * tmpPoints,0)) points = tmpPoints if points > 0: addBonus(attacker, points) if PUBLIC_SCORES == 2: sendMsgAll( attacker.getName() + " earn points: " + str(points)) elif PUBLIC_SCORES == 1: sendMsgTeam( attacker.getName() + " earn points: " + str(points), attacker.getTeam()) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Calculate additional victim worth # ------------------------------------------------------------------------ def GetAdditionalVictimWorth(attacker, victim): attackerKitType = getKitType(attacker.getKit().templateName) attackerVehicle = attacker.getVehicle() attackerVehicleType = getVehicleType(attackerVehicle.templateName) victimKitType = getKitType(victim.getKit().templateName) victimVehicle = victim.getVehicle() victimVehicleType = getVehicleType(victimVehicle.templateName) attackerTeamMsg = "" victimTeamMsg = "" worth = DEFAULT_VICTIM_WORTH # SNIPER if attackerVehicleType == VEHICLE_TYPE_SOLDIER: if victimVehicleType == VEHICLE_TYPE_SOLDIER: if attackerKitType == KIT_TYPE_SNIPER and victimKitType == KIT_TYPE_SNIPER: worth += VICTIM_SNIPER attackerTeamMsg = attacker.getName() + " has eliminated enemy sniper" # SQUADLEADER if victim.isSquadLeader(): worth += VICTIM_SQUADLEADER attackerTeamMsg = attacker.getName() + " has eliminated a enemy squadleader " + victim.getName() # COMMANDER if victim.isCommander(): worth += VICTIM_COMMANDER attackerTeamMsg = attacker.getName() + " has eliminated enemy commander " + victim.getName() victimTeamMsg = "You commander has been eliminated" if attackerTeamMsg != "": sendMsgTeam(attackerTeamMsg, attacker.getTeam()) if victimTeamMsg != "": sendMsgTeam(victimTeamMsg, victim.getTeam()) return worth # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Calculate a players worth # ------------------------------------------------------------------------ def GetPlayerWorth( player ): worth = -1 vehicle = player.getVehicle() rootVehicle = getRootParent(vehicle) vehicleType = getVehicleType(rootVehicle.templateName) args = WORTHSCHEMA[vehicleType] index = GetPlayerIndexInVehicle( player, rootVehicle ) if index > -1: worth = args[index] return worth # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Get a players index inside a vehicle # ------------------------------------------------------------------------ def GetPlayerIndexInVehicle( player, vehicle ): # This dosn't work on dead player/vehicles ... it allways return 0 playerArgs = vehicle.getOccupyingPlayers() index = -1 found = False while index < len(playerArgs) and not found: index += 1 if playerArgs[index] == player: found = True return index # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Get a players threat rating # ------------------------------------------------------------------------ def GetPlayerThreatRating( player ): score = 0 kills = 0 deaths = 0 playerArgs = bf2.playerManager.getPlayers() for p in playerArgs: score += p.score.score kills += p.score.kills deaths += p.score.deaths avgScore = float(score)/len(playerArgs) avgKills = float(kills)/len(playerArgs) avgDeaths = float(deaths)/len(playerArgs) if player.score.score <= 0: scoreFactor = 1/avgScore else: scoreFactor = float(player.score.score)/avgScore if player.score.kills <= 0: killsFactor = 1/avgKills else: killsFactor = float(player.score.kills)/avgKills if player.score.deaths <= 0: deathsFactor = avgDeaths/1 else: deathsFactor = avgDeaths/float(player.score.deaths) threatRating = round(killsFactor * deathsFactor * scoreFactor,3) return threatRating # ------------------------------------------------------------------------