Scripts:ClanTkProtection

From BF2 Technical Information Wiki
Jump to navigation Jump to search

This script is a modified version of the default tkpunish script.

Clanmembers is a list of current members that will be protected This is the only code changed besides the declare of the list.

def onPlayerKilled(victim, attacker, weapon, assists, object):
      
        string1 = attacker.getName()
        #Is the attacker protected against punishments? If so, dont handle the event and return
        for ncount in clanmembers:
            if string1 == ncount: return
# tk punish system


import bf2
import host
from bf2 import g_debug

TK_PUNISH_TIME = 20

TK_PUNISH_COMMANDID = 100
TK_FORGIVE_COMMANDID = 101

hasPendingTks = {}
updateTimer = None

clanmembers = ["|TAG|Bill","|TAG|John","|TAG|Blue"]#clan members to protect

class TkData:
    def __init__(self):
        self.punished = 0
        self.pending = []
        self.lastTKedBy = None


def init():
    if g_debug: print "initializing tk-punish script"

    host.registerHandler('PlayerConnect', onPlayerConnect, 1)
    host.registerHandler('PlayerKilled', onPlayerKilled)
    host.registerHandler('ClientCommand', onClientCommand)

    # Connect already connected players if reinitializing
    for p in bf2.playerManager.getPlayers():
        onPlayerConnect(p)
   
    checkEnable()


def checkEnable():
    global updateTimer
   
    if not bf2.serverSettings.getTKPunishEnabled():
        if updateTimer:
            updateTimer.destroy()
            updateTimer = None
        return False
    else:
        if not updateTimer:
            #if g_debug: print "Started timer"
            updateTimer = bf2.Timer(onUpdate, 10, 1)
            updateTimer.setRecurring(10)
           
        return True
   

def onUpdate(data):
    if not checkEnable(): return
    global hasPendingTks

    #if len(hasPendingTks) > 0:
    #    if g_debug: print "update: Has pending tks!"
    #else:
    #    if g_debug: print "update:No pending tks."
       

    currentTime = host.timer_getWallTime()

    newPending = {}
    for attacker in hasPendingTks.iterkeys():
        newList = []
        #if g_debug: print "attacker pending list:", len(attacker.tkData.pending)
        for tk in attacker.tkData.pending:
            tkDate = tk[0]
            tkVictim = tk[1]
            #if g_debug: print "check %d %s" % (tkDate, tkVictim.getName())

            # if there is a pending TK with time expired
            if tkDate + TK_PUNISH_TIME < currentTime:
                if bf2.serverSettings.getTKPunishByDefault():
                    attacker.tkData.punished += 1
                    checkPunishLimit(attacker)
                #    if g_debug: print "Default punished ", attacker.getName()
                else:
                #    if g_debug: print "Timeouted pending tk for ", attacker.getName()
                    pass

                # remove player from global list, if it was the last tk
                if len(attacker.tkData.pending) == 1:
                    pass
                else:
                    newPending[attacker] = 1
           
            else:
                newList += [tk]
                newPending[attacker] = 1
       
        attacker.tkData.pending = newList

    hasPendingTks = newPending
   
                       
def checkPunishLimit(player):
    #if g_debug: print "player %s has %d punishes" % (player.getName(), player.tkData.punished)

    if player.tkData.punished >= bf2.serverSettings.getTKNumPunishToKick():
        if g_debug: print "%s reached punish limit" % player.getName()
        if g_debug: print "Banning player!"
       
        result = host.rcon_invoke("admin.banPlayer " + str(player.index) + " Round")
       
   


# event actions   

def onPlayerConnect(player):
    player.tkData = TkData()

def onClientCommand(command, issuer, args):
    if not checkEnable(): return
   
    #if g_debug: print "received client command"
    if command == TK_PUNISH_COMMANDID:
        executePunishAction(issuer, True)
    elif command == TK_FORGIVE_COMMANDID:
        executePunishAction(issuer, False)
       

def onPlayerKilled(victim, attacker, weapon, assists, object):
      
        string1 = attacker.getName()
        #Is the attacker protected against punishments? If so, dont handle the event and return
        for ncount in clanmembers:
            if string1 == ncount: return
       
    if not checkEnable(): return

    if not victim or not attacker or victim == attacker or victim.getTeam() != attacker.getTeam(): return
   
    # ok, we have a teamkill
   
    currentTime = host.timer_getWallTime()
    attacker.tkData.pending += [(currentTime, victim)]
    hasPendingTks[attacker] = 1
       
    victim.tkData.lastTKedBy = attacker # can only punish / forgive the last TK'er
   
    bf2.gameLogic.sendClientCommand(victim.index, 100, (2, victim.index, attacker.index, TK_PUNISH_TIME))


def executePunishAction(victim, punish):
    if not checkEnable() or not victim or not victim.isValid(): return
    attacker = victim.tkData.lastTKedBy
    if attacker == None or not attacker.isValid(): return

    global hasPendingTks

    if punish:
        if g_debug: print "%s tkPunished %s" % (victim.getName(), attacker.getName())
    else:
        if g_debug: print "%s tkForgive %s" % (victim.getName(), attacker.getName())

    currentTime = host.timer_getWallTime()
   
    newList = []
    for tk in attacker.tkData.pending:
        tkDate = tk[0]
        tkVictim = tk[1]
       
        # if the attacker had a pending tk, and time has not run out
        if tkVictim == victim and tkDate + TK_PUNISH_TIME > currentTime:
            if punish:
                attacker.tkData.punished += 1
                bf2.gameLogic.sendClientCommand(-1, 100, (0, victim.index, attacker.index)) # 100 = tkpunish event, 0 = punish
                if g_debug: print "%s punished %s, now has %d punishes" % (victim.getName(), attacker.getName(), attacker.tkData.punished)
            else:
                bf2.gameLogic.sendClientCommand(-1, 100, (1, victim.index, attacker.index)) # 100 = tkpunish event, 1 = forgive
                if g_debug: print "%s forgave %s" % (victim.getName(), attacker.getName())
        else:
            newList += [tk]
           
    attacker.tkData.pending = newList
   
    if len(attacker.tkData.pending) == 0:
        del hasPendingTks[attacker]
   
    checkPunishLimit(attacker)