from lib.toontown.globals import CIGlobals
from lib.toontown.online.OnlineGlobals import *
from direct.distributed.MsgTypesCMU import MsgName2Id
from pandac.PandaModules import *
from panda3d.core import *
from direct.actor.Actor import *
from lib.toontown.gui.Dialog import *
from direct.task import Task
from direct.showbase.Transitions import *
from direct.directnotify.DirectNotify import *
from direct.showbase import Audio3DManager
import sys
import os
import random

connectionNotify = DirectNotify().newCategory("ToontownConnectionManager")

it = loader.loadFont("phase_3/models/fonts/ImpressBT.ttf")
dialog_box = loader.loadModel("phase_3/models/gui/dialog_box_gui.bam")
dialog_btns = loader.loadModel("phase_3/models/gui/dialog_box_buttons_gui.bam")
fade = loader.loadModel("phase_3/models/misc/fade.bam")

host = base.config.GetString('server-address')
port = base.config.GetString('server-port')
url = URLSpec("http://%s:%s" % (host, port))


class ToontownConnectionManager:
    def __init__(self, cr):
        self.cr = cr
from pandac.PandaModules import *
from panda3d.core import *
from panda3d.core import loadPrcFileData
from direct.actor.Actor import *
from direct.gui.DirectGui import *
from direct.task import Task
from direct.showbase.Transitions import *
from direct.directnotify.DirectNotify import *
from direct.distributed.PyDatagram import PyDatagram
from direct.distributed.PyDatagramIterator import PyDatagramIterator
import sys
import os
import random

globalnotify = DirectNotify().newCategory("ServerGlobals")
globalnotify.info("Imported all server global modules")
示例#3
0
from panda3d.core import *
from pandac.PandaModules import *
from direct.showbase import Audio3DManager
from direct.fsm.ClassicFSM import ClassicFSM
from direct.fsm.State import State
from direct.actor.Actor import Actor
from direct.showbase.ShadowPlacer import ShadowPlacer
from direct.interval.ProjectileInterval import ProjectileInterval
from lib.coginvasion.toon import ParticleLoader
from direct.task.Task import Task
from direct.interval.IntervalGlobal import *
import random

audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], camera)
audio3d.setDistanceFactor(25)
notify = DirectNotify().newCategory("Suit")

class Suit(Avatar.Avatar):
	healthColors = (Vec4(0, 1, 0, 1),
		Vec4(1, 1, 0, 1),
		Vec4(1, 0.5, 0, 1),
		Vec4(1, 0, 0, 1),
		Vec4(0.3, 0.3, 0.3, 1))
	healthGlowColors = (Vec4(0.25, 1, 0.25, 0.5),
		Vec4(1, 1, 0.25, 0.5),
		Vec4(1, 0.5, 0.25, 0.5),
		Vec4(1, 0.25, 0.25, 0.5),
		Vec4(0.3, 0.3, 0.3, 0))
	medallionColors = {'c': Vec4(0.863, 0.776, 0.769, 1.0),
		's': Vec4(0.843, 0.745, 0.745, 1.0),
		'l': Vec4(0.749, 0.776, 0.824, 1.0),
class AIRepository:
    eventLoggerNotify = DirectNotify().newCategory("EventLogger")

    def __init__(self):
        base.cr = ClientRepository(
            dcFileNames=['phase_3/etc/direct.dc', 'phase_3/etc/toon.dc'],
            dcSuffix='AI')
        base.cr.connect([url],
                        successCallback=self.connectSuccess,
                        failureCallback=self.connectFailure)
        base.cTrav = CollisionTraverser()
        self.skeleton = 0
        if base.config.GetBool('want-suits', True):
            base.accept("SpawnSuit", self.createSuit)
        self.activeInvasion = False
        self.invasionSize = 0
        self.difficulty = ""
        self.title = DirectLabel(text="Server Menu",
                                 pos=(-0.05, -0.1, -0.1),
                                 scale=0.1,
                                 relief=None,
                                 text_fg=(1, 1, 1, 1),
                                 parent=base.a2dTopRight,
                                 text_align=TextNode.ARight)
        self.Suits = []
        base.pathNodes = []
        self.SuitCount = 0
        self.automaticSuits = 0
        self.hoodUtil = HoodUtil(base.cr)
        self.tournament = SuitTournament()
        self.lastChoice = None
        self.zoneAllocator = UniqueIdAllocator(50, 500)

    def allocateZone(self):
        return self.zoneAllocator.allocate()

    def freeZone(self, zone):
        self.zoneAllocator.free(zone)

    def logServerEvent(self, type, msg):
        self.eventLoggerNotify.info("%s: %s" % (type.upper(), msg))

    def killAllSuits(self):
        for suit in self.Suits:
            if not suit.distSuit.isDead() and suit.head != "vp":
                suit.distSuit.b_setHealth(0)

    def enableAutoSuits(self):
        self.automaticSuits = 1
        random_wait = random.uniform(5, 60)
        taskMgr.doMethodLater(random_wait, self.autoSuiter, "autoSuitSpawn")
        base.accept("control", self.disableAutoSuits)
        print "AutoSuit: Auto suits enabled."

    def disableAutoSuits(self):
        self.automaticSuits = 0
        taskMgr.remove("autoSuitSpawn")
        base.accept("control", self.enableAutoSuits)
        print "AutoSuit: Auto suits disabled."

    def isBossActive(self):
        for suit in self.Suits:
            if suit.head == "vp":
                return True
        return False

    def autoSuiter(self, task):
        random_choice = random.randint(0, 7)
        if self.lastChoice == 0 or self.lastChoice == 1 or self.lastChoice == 2 and self.SuitCount > 0:
            random_choice = random.randint(2, 6)
        elif self.lastChoice == 7:
            random_choice = random.randint(1, 6)

        if random_choice == 0 or random_choice == 1 or random_choice == 2:
            random_delay = random.randint(40, 80)
            choice = "invasion"
        elif random_choice == 3 or random_choice == 4 or random_choice == 5 or random_choice == 6:
            random_delay = random.randint(5, 20)
            choice = "suit"
        elif random_choice == 7:
            choice = "tournament"
            random_delay = random.randint(360, 700)
        self.lastChoice = random_choice
        if self.lastChoice == 7 and self.activeInvasion or self.SuitCount > 0:
            self.lastChoice = 1
            random_delay = random.randint(5, 80)
        if self.toonsAreInZone(20):
            self.createAutoSuit(choice)
            print "AutoSuit: Creating auto suit."
        else:
            random_delay = random.randint(20, 80)
            print "AutoSuit: Can't create an auto suit with no toons playing. Changing delay time."
        print "AutoSuit: Delay is %s seconds." % random_delay
        task.delayTime = random_delay
        return task.again

    def toonsArePlaying(self):
        for key in base.cr.doId2do.keys():
            obj = base.cr.doId2do[key]
            if obj.__class__.__name__ == "DistributedToon":
                return True
        return False

    def toonsAreInZone(self, zone):
        for key in base.cr.doId2do.keys():
            obj = base.cr.doId2do[key]
            if obj.__class__.__name__ == "DistributedToon":
                if obj.zoneId == zone:
                    return True
        return False

    def createAutoSuit(self, choice):
        if choice == "invasion":
            if self.SuitCount < 20 and not self.tournament.inTournament and not self.activeInvasion:
                # Spawn invasion
                random_diff = random.randint(0, 2)
                if random_diff == 0:
                    self.difficulty = "easy"
                elif random_diff == 1:
                    self.diffiuclty = "normal"
                elif random_diff == 2:
                    self.difficulty = "hard"
                random_size = random.randint(0, 2)
                if random_size == 0:
                    self.size = "small"
                elif random_size == 1:
                    self.size = "medium"
                elif random_size == 2:
                    self.size = "large"
                self.suit = "ABC"
                taskMgr.add(self.startInvasion,
                            "startInvasion",
                            extraArgs=[0],
                            appendTask=True)
        elif choice == "suit":
            if self.SuitCount < 25 and not self.tournament.inTournament:
                # Spawn suit
                random_type = random.randint(0, 2)
                if random_type == 0:
                    type = "A"
                elif random_type == 1:
                    type = "B"
                elif random_type == 2:
                    type = "C"
                self.createSuit(type)
        elif choice == "tournament":
            if self.SuitCount == 0 and not self.tournament.inTournament and not self.activeInvasion:
                # Spawn tournament
                self.tournament.initiateTournament()
            else:
                self.lastChoice = 1

        return None

    def callBackup(self, difficulty):
        self.difficulty = difficulty
        self.suit = "ABC"
        self.size = "medium"
        self.killAllSuits()
        taskMgr.doMethodLater(8,
                              self.startInvasion,
                              "startBackupInvasion",
                              extraArgs=[1],
                              appendTask=True)

    def sendSysMessage(self, textEntered):
        pkg = PyDatagram()
        pkg.addUint16(SYS_MSG)
        pkg.addString("SYSTEM: " + textEntered)
        base.sr.sendDatagram(pkg)

    def connectFailure(self):
        notify.warning(
            "failure connecting to gameserver, AI server will not initiate.")

    def connectSuccess(self):
        base.acceptOnce('createReady', self.createReady)

    def startInvasion(self, skeleton, task):
        if not self.activeInvasion and not self.tournament.inTournament:
            self.sendSysMessage("A " + ToontownGlobals.Suit +
                                " Invasion has begun in Toontown Central!!!")
        self.activeInvasion = True
        if self.isFullInvasion():
            return Task.done

        suitsNow = random.randint(0, 7)
        for suit in range(suitsNow):
            if self.isFullInvasion():
                break
            if self.suit == "ABC":
                random_suitType = random.randint(0, 2)
                if random_suitType == 0:
                    self.createSuit("A", skeleton=skeleton)
                elif random_suitType == 1:
                    self.createSuit("B", skeleton=skeleton)
                elif random_suitType == 2:
                    self.createSuit("C", skeleton=skeleton)
            else:
                self.createSuit(self.suit, skeleton=skeleton)

        task.delayTime = 4
        return Task.again

    def isFullInvasion(self):
        if self.size == "large":
            if self.SuitCount >= 20:
                return True
            else:
                return False
        elif self.size == "medium":
            if self.SuitCount >= 13:
                return True
            else:
                return False
        elif self.size == "small":
            if self.SuitCount >= 5:
                return True
            else:
                return False

    def createReady(self):
        self.hoodUtil.load("TT", AI=1)
        base.cr.setInterestZones([10, 20, 30])
        self.timeMgr = base.cr.createDistributedObject(
            className="TimeManagerAI", zoneId=10)
        self.createCChars()
        self.createMinigames()

    def createCChars(self):
        if base.config.GetBool('want-classic-chars', True):
            if base.config.GetBool('want-mickey', True):
                MickeyNPCBase(base.cr)
            if base.config.GetBool('want-goofy', True):
                GoofyNPCBase(base.cr)

    def createMinigames(self):
        if base.config.GetBool('want-minigames', True):
            if base.config.GetBool('want-race-game', True):
                mg1 = base.cr.createDistributedObject(
                    className="DistributedMinigameStationAI", zoneId=30)
                mg1.b_setStation(ToontownGlobals.RaceGame)
                mg1.b_setLocationPoint(0)
            if base.config.GetBool('want-uno-game', True):
                mg2 = base.cr.createDistributedObject(
                    className="DistributedMinigameStationAI", zoneId=30)
                mg2.b_setStation(ToontownGlobals.UnoGame)
                mg2.b_setLocationPoint(1)
            if base.config.GetBool('want-sneaky-game', True):
                mg3 = base.cr.createDistributedObject(
                    className="DistributedMinigameStationAI", zoneId=30)
                mg3.b_setStation(ToontownGlobals.SneakyGame)
                mg3.b_setLocationPoint(2)

    def createSuit(self, type, head=None, team=None, anySuit=1, skeleton=0):
        if self.SuitCount == 0 and not self.activeInvasion and not self.tournament.inTournament:
            self.sendSysMessage("A " + ToontownGlobals.Suit +
                                " is flying down in Toontown Central!")
        self.SuitCount += 1
        if not self.activeInvasion:
            self.invasionSize = 0
        if self.SuitCount == 1:
            if self.tournament.inTournament:
                if self.tournament.getRound() == 1:
                    self.hoodUtil.enableSuitEffect(0)
                    pkg = PyDatagram()
                    pkg.addUint16(SUITS_ACTIVE)
                    pkg.addUint32(self.invasionSize)
                    base.sr.sendDatagram(pkg)
            else:
                self.hoodUtil.enableSuitEffect(0)
                pkg = PyDatagram()
                pkg.addUint16(SUITS_ACTIVE)
                pkg.addUint32(self.invasionSize)
                base.sr.sendDatagram(pkg)
        if anySuit:
            if self.difficulty == "hard":
                if type == "B":
                    self.random_head = random.randint(7, 8)
                elif type == "C":
                    self.random_head = random.randint(7, 8)
                elif type == "A":
                    self.random_head = random.randint(8, 13)
            elif self.difficulty == "normal":
                if type == "B":
                    self.random_head = random.randint(3, 6)
                elif type == "C":
                    self.random_head = random.randint(4, 6)
                elif type == "A":
                    self.random_head = random.randint(4, 7)
            elif self.difficulty == "easy":
                if type == "B":
                    self.random_head = random.randint(0, 2)
                elif type == "C":
                    self.random_head = random.randint(0, 3)
                elif type == "A":
                    self.random_head = random.randint(0, 3)
            elif self.difficulty == "all" or self.difficulty == "":
                if type == "B" or type == "C":
                    self.random_head = random.randint(0, 8)
                elif type == "A":
                    self.random_head = random.randint(0, 13)
            if type == "C":
                if self.random_head == 0:
                    head = 'coldcaller'
                    team = 's'
                elif self.random_head == 1:
                    head = 'shortchange'
                    team = 'm'
                elif self.random_head == 2:
                    head = 'bottomfeeder'
                    team = 'l'
                elif self.random_head == 3:
                    head = 'flunky'
                    team = 'c'
                elif self.random_head == 4:
                    head = 'tightwad'
                    team = 'm'
                elif self.random_head == 5:
                    head = 'micromanager'
                    team = 'c'
                elif self.random_head == 6:
                    head = 'gladhander'
                    team = 's'
                elif self.random_head == 7:
                    head = 'moneybags'
                    team = 'm'
                elif self.random_head == 8:
                    head = 'corporateraider'
                    team = 'c'
            if type == "B":
                if self.random_head == 0:
                    head = 'pencilpusher'
                    team = 'c'
                elif self.random_head == 1:
                    head = 'bloodsucker'
                    team = 'l'
                elif self.random_head == 2:
                    head = 'telemarketer'
                    team = 's'
                elif self.random_head == 3:
                    head = 'ambulancechaser'
                    team = 'l'
                elif self.random_head == 4:
                    head = 'beancounter'
                    team = 'm'
                elif self.random_head == 5:
                    head = 'downsizer'
                    team = 'c'
                elif self.random_head == 6:
                    head = 'movershaker'
                    team = 's'
                elif self.random_head == 7:
                    head = 'spindoctor'
                    team = 'l'
                elif self.random_head == 8:
                    head = 'loanshark'
                    team = 'm'
            if type == "A":
                if self.random_head == 0:
                    head = 'pennypincher'
                    team = 'm'
                elif self.random_head == 1:
                    head = 'yesman'
                    team = 'c'
                elif self.random_head == 2:
                    head = 'doubletalker'
                    team = 'l'
                elif self.random_head == 3:
                    head = 'namedropper'
                    team = 's'
                elif self.random_head == 4:
                    head = 'backstabber'
                    team = 'l'
                elif self.random_head == 5:
                    head = 'numbercruncher'
                    team = 'm'
                elif self.random_head == 6:
                    head = 'headhunter'
                    team = 'c'
                elif self.random_head == 7:
                    head = 'twoface'
                    team = 's'
                elif self.random_head == 8:
                    head = 'legaleagle'
                    team = 'l'
                elif self.random_head == 9:
                    head = 'mingler'
                    team = 's'
                elif self.random_head == 10:
                    head = 'bigcheese'
                    team = 'c'
                elif self.random_head == 11:
                    head = 'bigwig'
                    team = 'l'
                elif self.random_head == 12:
                    head = 'robberbaron'
                    team = 'm'
                elif self.random_head == 13:
                    head = 'mrhollywood'
                    team = 's'
        if head == "vp":
            self.handleBossSpawned()
        SuitBase(base.cr, type, head, team, skeleton)

    def handleBossSpawned(self):
        bosses = 0
        for suit in self.Suits:
            if suit.head == "vp":
                bosses += 1
        if bosses == 0:
            self.sendBossSpawned()

    def sendBossSpawned(self):
        pkg = PyDatagram()
        pkg.addUint16(BOSS_SPAWNED)
        base.sr.sendDatagram(pkg)

    def deadSuit(self):
        self.SuitCount -= 1
        if self.SuitCount < 0:
            self.SuitCount = 0
        if self.tournament.inTournament:
            self.tournament.handleDeadSuit()
            return
        if self.SuitCount == 0:
            if self.activeInvasion:
                self.activeInvasion = False
            self.hoodUtil.disableSuitEffect()
            pkg = PyDatagram()
            pkg.addUint16(SUITS_INACTIVE)
            base.sr.sendDatagram(pkg)
import os
import random
from direct.distributed.PyDatagram import PyDatagram
import os
from lib.toontown.suit.SuitTournament import SuitTournament
from lib.toontown.hood.HoodUtil import HoodUtil
from lib.toontown.minigame.MinigameStationBase import MinigameStationBase
from pandac.PandaModules import UniqueIdAllocator

SUITS_ACTIVE = 25001
SUITS_INACTIVE = 25002
SYS_MSG = 50000
BOSS_SPAWNED = 25007
BOSS_ACTIVE = 25008

notify = DirectNotify().newCategory("AIRepository")

#render2d.hide()

host = base.config.GetString('server-address')
port = base.config.GetString('server-port')
url = URLSpec("http://%s:%s" % (host, port))

render.setAntialias(AntialiasAttrib.MMultisample)


class AIRepository:
    eventLoggerNotify = DirectNotify().newCategory("EventLogger")

    def __init__(self):
        base.cr = ClientRepository(
class Pies:
    notify = DirectNotify().newCategory("Pies")

    def __init__(self):
        self.models = {
            1: "phase_3.5/models/props/tart.bam",
            0: "phase_5/models/props/birthday-cake-mod.bam",
            2: "phase_5/models/props/cream-pie-slice.bam"
        }
        self.hitsounds = {
            1: "phase_4/audio/sfx/AA_wholepie_only.ogg",
            0: "phase_4/audio/sfx/AA_wholepie_only.ogg",
            2: "phase_3.5/audio/sfx/AA_tart_only.ogg"
        }
        self.splatcolors = {
            1: VBase4(1, 1, 0, 1),
            0: VBase4(1, 0, 1, 1),
            2: VBase4(1, 1, 0, 1)
        }
        self.playrates = {1: 1.0, 0: 1.0, 2: 1.0}
        self.damage = {1: 36, 0: 75, 2: 17}
        self.max_ammo = {1: 7, 0: 3, 2: 15}
        self.current_ammo = {1: 7, 0: 3, 2: 15}
        self.avatar = None
        self.splat = None
        self.pie = None
        self.woosh = None
        self.pie_type = 1  # Default pie is the wholecream pie.
        self.pie_state = "start"
        return

    def delete(self):
        self.avatar = None
        if self.splat is not None:
            self.splat.cleanup()
            self.splat = None
        if self.pie is not None:
            self.deletePie()
        self.pie_type = None
        self.pie_state = None
        self.current_ammo = None
        self.max_ammo = None
        self.damage = None
        self.playrates = None
        self.splatcolors = None
        self.hitsounds = None
        self.models = None
        return

    def setAvatar(self, avatar):
        self.avatar = avatar

    def getAvatar(self):
        return self.avatar

    def setPieType(self, pietype):
        self.pie_type = pietype

    def getPieType(self):
        return self.pie_type

    def setAmmo(self, ammo, pietype=None):
        if pietype is None:
            pietype = self.getPieType()
        self.current_ammo[pietype] = ammo

    def getAmmo(self, pietype=None):
        if pietype is None:
            pietype = self.getPieType()
        return self.current_ammo[pietype]

    def getDamage(self):
        return self.damage[self.pie_type]

    def deletePie(self):
        try:
            self.trajectory.pause()
        except:
            pass
        if self.pie:
            self.pie.removeNode()
            self.pie = None

    def pieStart(self):
        self.pie = Pie(self, self.avatar, self.pie_type)
        self.pie.load()

        self.avatar.setPlayRate(self.playrates[self.pie_type], "pie")
        self.avatar.play("pie", fromFrame=0, toFrame=45)

    def pieThrow(self):
        self.avatar.play("pie", fromFrame=45, toFrame=90)

    def pieRelease(self):
        if self.pie is None:
            return
        self.pie.throw()
        self.setAmmo(self.getAmmo() - 1)

    def handlePieSplat(self):
        if self.splat:
            self.splat.cleanup()
            self.splat = None

        self.splat = Actor("phase_3.5/models/props/splat-mod.bam",
                           {"chan": "phase_3.5/models/props/splat-chan.bam"})
        self.splat_sfx = audio3d.loadSfx(self.hitsounds[self.pie_type])
        audio3d.attachSoundToObject(self.splat_sfx, self.splat)
        self.splat_sfx.play()
        self.splat.reparentTo(render)
        self.splat.setBillboardPointEye()
        self.splat.setColor(self.splatcolors[self.pie_type])
        if self.pie and self.splat:
            self.splat.setPos(self.pie.getPos(render))
            self.splat.play("chan")

        if self.woosh:
            self.woosh.stop()
            self.woosh = None
        try:
            self.trajectory.pause()
        except:
            pass
        if self.pie:
            self.pie.removeNode()
            self.pie = None
        taskMgr.doMethodLater(0.5, self.delSplat, "delSplat")

    def delSplat(self, task):
        if self.splat:
            self.splat.cleanup()
            self.splat = None
        return task.done
示例#7
0
# uncompyle6 version 3.2.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)]
# Embedded file name: lib.coginvasion.base.InitialLoad
from lib.coginvasion.globals import CIGlobals
from lib.coginvasion.suit import CogTournamentMusicManager
from direct.gui.DirectGui import *
from panda3d.core import TextNode
from direct.directnotify.DirectNotify import *
import FileUtility
from LoadUtility import LoadUtility
import glob

loadernotify = DirectNotify().newCategory('InitialLoad')


class InitialLoad(LoadUtility):
    def __init__(self, callback):
        LoadUtility.__init__(self, callback)
        phasesToScan = ['models', 'phase_3/models']
        self.models = FileUtility.findAllModelFilesInVFS(phasesToScan)
        self.version_lbl = None
        self.clouds = None
        return

    def createGui(self):
        self.version_lbl = OnscreenText(text='ver-' + game.version,
                                        scale=0.06,
                                        pos=(-1.32, -0.97, -0.97),
                                        align=TextNode.ALeft,
                                        fg=(0.343, 0.343, 0.343, 1))
示例#8
0
class Pies:
    notify = DirectNotify().newCategory("Pies")

    def __init__(self):
        self.models = {
            1: "phase_3.5/models/props/tart.bam",
            0: "phase_5/models/props/birthday-cake-mod.bam",
            2: "phase_5/models/props/cream-pie-slice.bam"
        }
        self.hitsounds = {
            1: "phase_4/audio/sfx/AA_wholepie_only.mp3",
            0: "phase_4/audio/sfx/AA_wholepie_only.mp3",
            2: "phase_3.5/audio/sfx/AA_tart_only.mp3"
        }
        self.splatcolors = {
            1: VBase4(1, 1, 0, 1),
            0: VBase4(1, 0, 1, 1),
            2: VBase4(1, 1, 0, 1)
        }
        self.playrates = {1: 1.0, 0: 1.0, 2: 1.0, 3: 1.0}
        self.damage = {1: 36, 0: 75, 2: 17, 3: 180}
        self.health = {1: 5, 0: 10, 2: 2}
        self.max_ammo = {1: 7, 0: 3, 2: 15, 3: 2}
        self.current_ammo = {1: 7, 0: 3, 2: 15, 3: 0}
        self.weapon_id_2_weapon = {0: "cake", 1: "tart", 2: "slice", 3: "tnt"}
        self.avatar = None
        self.splat = None
        self.pie = None
        self.tnt = None
        self.tntSparks = None
        self.tntTrajectory = None
        self.tntExplosion = None
        self.woosh = None
        self.dynamiteSfx = None
        self.pie_type = 1  # Default pie is the wholecream pie.
        self.pie_state = "start"
        self.tnt_state = "ready"
        return

    def getPieTypeName(self):
        return self.weapon_id_2_weapon.get(self.pie_type, None)

    def attachTNT(self):
        self.detachTNT()
        self.tnt = Actor("phase_5/models/props/tnt-mod.bam",
                         {"chan": "phase_5/models/props/tnt-chan.bam"})
        self.tnt.reparentTo(self.avatar.find('**/def_joint_right_hold'))
        self.tntSparks = ParticleEffect()
        self.tntSparks.loadConfig("phase_5/etc/tnt.ptf")
        #self.tntSparks.start(parent = self.tnt.find('**/joint_attachEmitter'),
        #	renderParent = self.tnt.find('**/joint_attachEmitter'))

    def detachTNT(self):
        if self.tntTrajectory:
            self.tntTrajectory.pause()
            self.tntTrajectory = None
        if self.tnt is not None:
            self.tnt.cleanup()
            self.tnt = None
        if self.tntSparks is not None:
            self.tntSparks.cleanup()
            self.tntSparks = None

    def delete(self):
        self.avatar = None
        if self.splat is not None:
            self.splat.cleanup()
            self.splat = None
        self.detachTNT()
        self.tnt = None
        self.tnt_state = None
        self.tntSparks = None
        if self.tntExplosion:
            self.tntExplosion.cleanup()
            self.tntExplosion = None
        if self.dynamiteSfx:
            self.dynamiteSfx.stop()
            self.dynamiteSfx = None
        if self.pie is not None:
            self.deletePie()
        self.pie_type = None
        self.pie_state = None
        self.current_ammo = None
        self.max_ammo = None
        self.damage = None
        self.playrates = None
        self.splatcolors = None
        self.hitsounds = None
        self.models = None
        return

    def setAvatar(self, avatar):
        self.avatar = avatar

    def getAvatar(self):
        return self.avatar

    def setPieType(self, pietype):
        self.pie_type = pietype
        weaponType = None
        if pietype in [0, 1, 2]:
            weaponType = "pie"
        elif pietype == 3:
            weaponType = "tnt"
        if hasattr(self.avatar, 'setWeaponType'):
            self.avatar.setWeaponType(weaponType)

    def getPieType(self):
        return self.pie_type

    def setAmmo(self, ammo, pietype=None):
        if pietype is None:
            pietype = self.getPieType()
        self.current_ammo[pietype] = ammo

    def getAmmo(self, pietype=None):
        if pietype is None:
            pietype = self.getPieType()
        return self.current_ammo[pietype]

    def getDamage(self, weapon_id=None):
        if weapon_id is None:
            return self.damage[self.pie_type]
        else:
            return self.damage[weapon_id]

    def getHealth(self, weapon_id=None):
        if weapon_id is None:
            return self.health[self.pie_type]
        else:
            return self.health[weapon_id]

    def deletePie(self):
        try:
            self.trajectory.pause()
        except:
            pass
        if self.pie:
            self.pie.removeNode()
            self.pie = None

    def pieStart(self):
        try:
            audio3d.detachSound(self.woosh)
            self.trajectory.pause()
            self.pie.remove()
            self.pie = None
        except:
            pass
        self.pie_state = 'start'
        self.pie = loader.loadModel(self.models[self.pie_type])
        self.pie.reparentTo(
            self.avatar.getPart('torso').find('**/def_joint_right_hold'))

        self.avatar.setPlayRate(self.playrates[self.pie_type], "pie")
        self.avatar.play("pie", fromFrame=0, toFrame=45)

    def tntStart(self):
        self.avatar.play("toss", fromFrame=22)
        self.tnt_state = "start"

    def tntRelease(self):
        if self.tnt is None:
            return

        tntNp = self.avatar.attachNewNode('tntNp')
        tntNp.setScale(render, 1.0)
        tntNp.setPos(0, 160, -120)
        tntNp.setHpr(0, 90, 0)

        self.tntTrajectory = ProjectileInterval(
            self.tnt,
            startPos=(self.avatar.getPart('torso').find(
                '**/def_joint_right_hold').getPos(render)),
            endPos=tntNp.getPos(render),
            gravityMult=0.9,
            duration=3)
        self.tnt.setHpr(tntNp.getHpr(render))
        self.tntTrajectory.start()
        self.tnt.reparentTo(render)
        self.tnt_state = "released"
        self.setAmmo(self.getAmmo() - 1)

    def handleTntHitGround(self):
        if not self.tnt:
            return

        self.tntSparks.start(
            parent=self.tnt.find('**/joint_attachEmitter'),
            renderParent=self.tnt.find('**/joint_attachEmitter'))

        self.dynamiteSfx = audio3d.loadSfx("phase_5/audio/sfx/TL_dynamite.mp3")
        audio3d.attachSoundToObject(self.dynamiteSfx, self.tnt)
        self.dynamiteSfx.play()

        self.tnt.play("chan")

        if self.tntTrajectory:
            self.tntTrajectory.pause()
            self.tntTrajectory = None

    def tntExplode(self):
        if not self.tnt:
            return

        self.tntExplosion = Actor(
            "phase_5/models/props/kapow-mod.bam",
            {"chan": "phase_5/models/props/kapow-chan.bam"})
        self.tntExplosion.reparentTo(render)
        self.tntExplosion.setBillboardPointEye()
        self.tntExplosion.setPos(self.tnt.getPos(render) + (0, 0, 4))
        self.tntExplosion.setScale(0.5)
        self.tntExplosion.play("chan")
        if self.dynamiteSfx:
            self.dynamiteSfx.stop()
            self.dynamiteSfx = None
        explosionSfx = audio3d.loadSfx(
            "phase_3.5/audio/sfx/ENC_cogfall_apart.mp3")
        audio3d.attachSoundToObject(explosionSfx, self.tntExplosion)
        SoundInterval(explosionSfx).start()
        if self.tntSparks:
            self.tntSparks.cleanup()
            self.tntSparks = None
        if self.tnt:
            self.tnt.cleanup()
            self.tnt = None
        self.tnt_state = "ready"
        if self.getAmmo(3) > 0 and self.getPieType() == 3:
            self.attachTNT()
            if hasattr(self.avatar, "enablePieKeys"):
                # This must be the local avatar
                self.avatar.enablePieKeys()
        taskMgr.doMethodLater(0.5, self.delTntExplosion, "delTntExplosion")

    def delTntExplosion(self, task):
        if self.tntExplosion:
            self.tntExplosion.cleanup()
            self.tntExplosion = None
        return task.done

    def tntCollisions(self):
        if not self.tnt:
            return
        tss = CollisionSphere(0, 0, 0, 1)
        tsNode = CollisionNode('tntSensor')
        tsNode.add_solid(tss)
        self.tsNp = self.tnt.attach_new_node(tsNode)
        self.tsNp.set_scale(0.75, 0.8, 0.75)
        self.tsNp.set_pos(0.0, 0.1, 0.5)
        self.tsNp.set_collide_mask(BitMask32(0))
        self.tsNp.node().set_from_collide_mask(CIGlobals.FloorBitmask)

        event = CollisionHandlerEvent()
        event.set_in_pattern("%fn-into")
        event.set_out_pattern("%fn-out")
        base.cTrav.add_collider(self.tsNp, event)

    def setTntPos(self, pos):
        if self.tnt:
            self.tnt.setPos(pos)

    def pieCollisions(self):
        pss = CollisionSphere(0, 0, 0, 1)
        psnode = CollisionNode('pieSensor')
        psnode.add_solid(pss)
        self.psnp = self.pie.attach_new_node(psnode)
        self.psnp.set_collide_mask(BitMask32(0))
        self.psnp.node().set_from_collide_mask(CIGlobals.WallBitmask
                                               | CIGlobals.FloorBitmask)

        event = CollisionHandlerEvent()
        event.set_in_pattern("%fn-into")
        event.set_out_pattern("%fn-out")
        base.cTrav.add_collider(self.psnp, event)

    def pieThrow(self):
        self.avatar.play("pie", fromFrame=45, toFrame=90)

    def pieRelease(self):
        if self.pie is None:
            return

        self.woosh = audio3d.loadSfx(
            "phase_3.5/audio/sfx/AA_pie_throw_only.mp3")
        audio3d.attachSoundToObject(self.woosh, self.pie)
        self.woosh.play()

        self.pieNp = NodePath("PieNp")
        self.pieNp.reparentTo(self.avatar)
        self.pieNp.setScale(render, 1.0)
        self.pieNp.setPos(0, 160, -90)
        self.pieNp.setHpr(90, -90, 90)

        self.pie.setScale(self.pie.getScale(render))
        self.pie.reparentTo(render)
        self.pie.setHpr(self.pieNp.getHpr(render))

        self.trajectory = ProjectileInterval(
            self.pie,
            startPos=(self.avatar.getPart('torso').find(
                '**/def_joint_right_hold').getPos(render)),
            endPos=self.pieNp.getPos(render),
            gravityMult=0.9,
            duration=3)
        self.trajectory.start()
        self.pie_state = 'released'
        self.setAmmo(self.getAmmo() - 1)

    def handlePieSplat(self):
        if self.splat:
            self.splat.cleanup()
            self.splat = None

        if self.pie_type == 3:
            # Not sure why I get a KeyError: 3 crash, but just for now
            # return if the pie type is tnt (3).
            return

        self.splat = Actor("phase_3.5/models/props/splat-mod.bam",
                           {"chan": "phase_3.5/models/props/splat-chan.bam"})
        self.splat_sfx = audio3d.loadSfx(self.hitsounds[self.pie_type])
        audio3d.attachSoundToObject(self.splat_sfx, self.splat)
        self.splat_sfx.play()
        pietype2splatscale = {0: 0.6, 1: 0.5, 2: 0.35}
        self.splat.setScale(pietype2splatscale[self.pie_type])
        self.splat.reparentTo(render)
        self.splat.setBillboardPointEye()
        self.splat.setColor(self.splatcolors[self.pie_type])
        if self.pie and self.splat:
            self.splat.setPos(self.pie.getPos(render))
            self.splat.play("chan")

        if self.woosh:
            self.woosh.stop()
            self.woosh = None
        try:
            self.trajectory.pause()
        except:
            pass
        if self.pie:
            self.pie.removeNode()
            self.pie = None
        taskMgr.doMethodLater(0.5, self.delSplat, "delSplat")
        del pietype2splatscale

    def delSplat(self, task):
        if self.splat:
            self.splat.cleanup()
            self.splat = None
        return task.done