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")
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
# 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))
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