Scripts:AntiBaseRapeMM
From BF2 Technical Information Wiki
Contents |
What It Is
BF2CC/ModManager port of AntiBaseRape Script by SHAnders
Installation
- Copy and paste into mm_baserape.py to admin/modules in your Battlefield 2 server install.
- if necessary, edit the file and change the settings
- change your modmanager.con and include the following line:
modmanager.loadModule "mm_baserape"
- restart BF2 server from BF2CC
Code
Readable
# ------------------------------------------------------------------------ # Module: AntiBaseRape.py # Author: SHAnders # Port to bf2cc/mm: graag42 # # Version 1.11 # # Changes: # v1.1 -> 1.11 # Fixed the timer to only be started once # v1.0 -> 1.1 # Implemted a baseRapeWarning attribute on players to count safe base kills # Implemted allowed amount of safe base kills (3) # up to this amount player only loses kill points + 1 score pr baseRapeWarning # over this amount player is allso killed # Implemtes a timer for removing 1 baseRapeWarning every 2 minutes # # Description: # Server side only admin script # # This script will punish players who kill enemy within the area of a safe base # # Requirements: # None. # # Installation as Admin script: # 1: Save this script as 'AntiBaseRape.py' in your <bf2>/admin/standard_admin directory. # 2: Add the lines 'import AntiBaseRape' and 'AntiBaseRape.init()' to the file # '<bf2>/admin/standard_admin/__init__.py'. # # TODO: # Since not all maps are alike, the requirements for base rape protiction # should be able to be altered individualy for each control point. # # Thanks to: # Battlefield.no for inspiration from their pingkick.py script # # ------------------------------------------------------------------------ import host import bf2 import math import mm_utils from bf2.stats.constants import * from bf2 import g_debug # Set the version of your module here __version__ = 1.11 # Set the required module versions here __required_modules__ = { 'modmanager': 1.0 } # Does this module support reload ( are all its reference closed on shutdown? ) __supports_reload__ = True # Set the description of your module here __description__ = "AntiBaseRape v%s" % __version__ # ------------------------------------------------------------------------ # Constants # ------------------------------------------------------------------------ DEFAULT_SAFEBASE_RADIUS = 50 # Default safe area radius (normal commandpoint radius = 10) ALLOWED_SAFEBASEKILLS = 3 SAFEBASEKILL_TIMER_INTERVAL = 120 # Intervals between removing a point from players.baseRapeWarning # ------------------------------------------------------------------------ # Variables # ------------------------------------------------------------------------ WarnReduceTimer = None # Timer that reduces the warnings at intervals # ------------------------------------------------------------------------ # Init # ------------------------------------------------------------------------ class BaseRape( object ) : def __init__( self, modManager ): # ModManager reference self.mm = modManager # Internal shutdown state self.__state = 0 def init( self ): if g_debug: print "AntiBaseRape init" if 0 == self.__state: host.registerHandler('PlayerConnect', self.onPlayerConnect, 1) host.registerHandler('PlayerKilled', self.onPlayerKilled) # Update to the running state self.__state = 1 # Start the timer that reduces warnings on the SAFEBASEKILL_TIMER_INTERVAL WarnReduceTimer = bf2.Timer(self.onSafeBaseKillTimer, SAFEBASEKILL_TIMER_INTERVAL, 1) WarnReduceTimer.setRecurring(SAFEBASEKILL_TIMER_INTERVAL) # Connect already connected players if reinitializing for p in bf2.playerManager.getPlayers(): self.onPlayerConnect(p) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # onPlayerConnect # ------------------------------------------------------------------------ def onPlayerConnect(self, player): self.resetPlayer(player) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # onPlayerKilled # ------------------------------------------------------------------------ def onPlayerKilled(self, victim, attacker, weapon, assists, object): # killed by self if attacker == victim: pass # killed by enemy elif attacker != None and attacker.getTeam() != victim.getTeam(): self.checkForSafeBase(attacker, victim) # ------------------------------------------------------------------------ def shutdown( self ): """Shutdown and stop processing.""" # Unregister game handlers and do any other # other actions to ensure your module no longer affects # the game in anyway if WarnReduceTimer: WarnReduceTimer.destroy() WarnReduceTimer = None # Flag as shutdown as there is currently way to: # host.unregisterHandler self.__state = 2 # ------------------------------------------------------------------------ # Reset the number of warnings # ------------------------------------------------------------------------ def resetPlayer(self, player): player.baseRapeWarning = 0 # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Check if victim was killed within safebase area # ------------------------------------------------------------------------ def checkForSafeBase(self, attacker, victim): victimVehicle = victim.getVehicle() controlPoints = bf2.objectManager.getObjectsOfType('dice.hfe.world.ObjectTemplate.ControlPoint') for cp in controlPoints: if cp.cp_getParam('unableToChangeTeam') != 0 and cp.cp_getParam('team') != attacker.getTeam(): distanceTo = self.getVectorDistance(victimVehicle.getPosition(), cp.getPosition()) if DEFAULT_SAFEBASE_RADIUS > float(distanceTo): self.justify(attacker, victim, cp, distanceTo) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Punish attacker, give victim life back and inform all # ------------------------------------------------------------------------ def justify(self, attacker, victim, controlPoint, distanceTo): victim.score.deaths += -1 attacker.score.kills += -1 attacker.score.score += -2 - attacker.baseRapeWarning attacker.baseRapeWarning += 1 self.sendWarning(attacker, controlPoint, distanceTo) if attacker.baseRapeWarning > ALLOWED_SAFEBASEKILLS: attacker.score.TKs += 1 if attacker.isAlive(): vehicle = attacker.getVehicle() rootVehicle = getRootParent(vehicle) if getVehicleType(rootVehicle.templateName) == VEHICLE_TYPE_SOLDIER: rootVehicle.setDamage(0) # This should kill them ! else: rootVehicle.setDamage(1) # a vehicle will likely explode within 1 sec killing entire crew, # not so sure about base defenses though # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Send Warning # ------------------------------------------------------------------------ def sendWarning(self, player, controlPoint, distanceTo): mapName = bf2.gameLogic.getMapName() if player.baseRapeWarning > ALLOWED_SAFEBASEKILLS: mm_utils.msg_server(player.getName() + " is punished for repeated violating of the no kill rules within safe base area") else: mm_utils.msg_server(player.getName() + " has violated the no kill rules within safe base area " + str(player.baseRapeWarning) + " times now") # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # remove baseRapeWarnings over time # ------------------------------------------------------------------------ def onSafeBaseKillTimer(self, data): for p in bf2.playerManager.getPlayers(): if p.baseRapeWarning <= 0: p.baseRapeWarning = 0 else: p.baseRapeWarning += -1 # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # get distance between two positions # ------------------------------------------------------------------------ def getVectorDistance(self, pos1, pos2): diffVec = [0.0, 0.0, 0.0] diffVec[0] = math.fabs(pos1[0] - pos2[0]) diffVec[1] = math.fabs(pos1[1] - pos2[1]) diffVec[2] = math.fabs(pos1[2] - pos2[2]) return math.sqrt(diffVec[0] * diffVec[0] + diffVec[1] * diffVec[1] + diffVec[2] * diffVec[2]) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ModManager Init # ------------------------------------------------------------------------ def mm_load( modManager ): """Creates and returns your object.""" return BaseRape( modManager )