toontown-just-works/toontown/suit/DistributedCashbotBossGoon.py
2024-07-07 18:08:39 -05:00

254 lines
9.1 KiB
Python

from panda3d.core import *
from direct.interval.IntervalGlobal import *
from direct.task.TaskManagerGlobal import *
from direct.distributed.ClockDelta import *
from direct.directnotify import DirectNotifyGlobal
import GoonGlobals
from direct.task.Task import Task
from toontown.toonbase import ToontownGlobals
from otp.otpbase import OTPGlobals
from toontown.coghq import DistributedCashbotBossObject
from direct.showbase import PythonUtil
import DistributedGoon
class DistributedCashbotBossGoon(DistributedGoon.DistributedGoon, DistributedCashbotBossObject.DistributedCashbotBossObject):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCashbotBossGoon')
walkGrabZ = -3.6
stunGrabZ = -2.2
wiggleFreeTime = 2
craneFrictionCoef = 0.15
craneSlideSpeed = 10
craneRotateSpeed = 20
def __init__(self, cr):
DistributedCashbotBossObject.DistributedCashbotBossObject.__init__(self, cr)
DistributedGoon.DistributedGoon.__init__(self, cr)
self.target = None
self.arrivalTime = None
self.flyToMagnetSfx = loader.loadSfx('phase_5/audio/sfx/TL_rake_throw_only.ogg')
self.hitMagnetSfx = loader.loadSfx('phase_4/audio/sfx/AA_drop_anvil_miss.ogg')
self.toMagnetSoundInterval = Sequence(SoundInterval(self.flyToMagnetSfx, duration=ToontownGlobals.CashbotBossToMagnetTime, node=self), SoundInterval(self.hitMagnetSfx, node=self))
self.hitFloorSfx = loader.loadSfx('phase_5/audio/sfx/AA_drop_flowerpot.ogg')
self.hitFloorSoundInterval = SoundInterval(self.hitFloorSfx, duration=1.0, node=self)
self.wiggleSfx = loader.loadSfx('phase_5/audio/sfx/SA_finger_wag.ogg')
return
def generate(self):
DistributedCashbotBossObject.DistributedCashbotBossObject.generate(self)
DistributedGoon.DistributedGoon.generate(self)
def announceGenerate(self):
DistributedCashbotBossObject.DistributedCashbotBossObject.announceGenerate(self)
self.setupPhysics('goon')
DistributedGoon.DistributedGoon.announceGenerate(self)
self.name = 'goon-%s' % self.doId
self.setName(self.name)
self.setTag('doId', str(self.doId))
self.collisionNode.setName('goon')
cs = CollisionSphere(0, 0, 4, 4)
self.collisionNode.addSolid(cs)
self.collisionNode.setIntoCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CashbotBossObjectBitmask)
self.wiggleTaskName = self.uniqueName('wiggleTask')
self.wiggleFreeName = self.uniqueName('wiggleFree')
self.boss.goons.append(self)
self.reparentTo(render)
def disable(self):
i = self.boss.goons.index(self)
del self.boss.goons[i]
DistributedGoon.DistributedGoon.disable(self)
DistributedCashbotBossObject.DistributedCashbotBossObject.disable(self)
def delete(self):
DistributedGoon.DistributedGoon.delete(self)
DistributedCashbotBossObject.DistributedCashbotBossObject.delete(self)
def hideShadows(self):
self.dropShadow.hide()
def showShadows(self):
self.dropShadow.show()
def getMinImpact(self):
return ToontownGlobals.CashbotBossGoonImpact
def doHitBoss(self, impact):
self.d_hitBoss(impact)
self.b_destroyGoon()
def __startWalk(self):
self.__stopWalk()
if self.target:
now = globalClock.getFrameTime()
availableTime = self.arrivalTime - now
if availableTime > 0:
origH = self.getH()
h = PythonUtil.fitDestAngle2Src(origH, self.targetH)
delta = abs(h - origH)
turnTime = delta / (self.velocity * 5)
dist = Vec3(self.target - self.getPos()).length()
walkTime = dist / self.velocity
denom = turnTime + walkTime
if denom != 0:
timeCompress = availableTime / denom
self.walkTrack = Sequence(self.hprInterval(turnTime * timeCompress, VBase3(h, 0, 0)), self.posInterval(walkTime * timeCompress, self.target))
self.walkTrack.start()
else:
self.setPos(self.target)
self.setH(self.targetH)
def __stopWalk(self):
if self.walkTrack:
self.walkTrack.pause()
self.walkTrack = None
return
def __wiggleTask(self, task):
elapsed = globalClock.getFrameTime() - self.wiggleStart
h = math.sin(elapsed * 17) * 5
p = math.sin(elapsed * 29) * 10
self.crane.wiggleMagnet.setHpr(h, p, 0)
return Task.cont
def __wiggleFree(self, task):
self.crane.releaseObject()
self.stashCollisions()
return Task.done
def fellOut(self):
self.b_destroyGoon()
def handleToonDetect(self, collEntry = None):
if self.boss.localToonIsSafe:
return
DistributedGoon.DistributedGoon.handleToonDetect(self, collEntry)
def prepareGrab(self):
DistributedCashbotBossObject.DistributedCashbotBossObject.prepareGrab(self)
if self.isStunned or self.boss.localToonIsSafe:
self.pose('collapse', 48)
self.grabPos = (0, 0, self.stunGrabZ * self.scale)
else:
self.setPlayRate(4, 'walk')
self.loop('walk')
self.grabPos = (0, 0, self.walkGrabZ * self.scale)
self.wiggleStart = globalClock.getFrameTime()
taskMgr.add(self.__wiggleTask, self.wiggleTaskName)
base.sfxPlayer.playSfx(self.wiggleSfx, node=self)
if self.avId == localAvatar.doId:
taskMgr.doMethodLater(self.wiggleFreeTime, self.__wiggleFree, self.wiggleFreeName)
self.radar.hide()
def prepareRelease(self):
DistributedCashbotBossObject.DistributedCashbotBossObject.prepareRelease(self)
self.crane.wiggleMagnet.setHpr(0, 0, 0)
taskMgr.remove(self.wiggleTaskName)
taskMgr.remove(self.wiggleFreeName)
self.setPlayRate(self.animMultiplier, 'walk')
def setObjectState(self, state, avId, craneId):
if state == 'W':
self.demand('Walk')
elif state == 'B':
if self.state != 'Battle':
self.demand('Battle')
elif state == 'S':
if self.state != 'Stunned':
self.demand('Stunned')
elif state == 'R':
if self.state != 'Recovery':
self.demand('Recovery')
elif state == 'a':
self.demand('EmergeA')
elif state == 'b':
self.demand('EmergeB')
else:
DistributedCashbotBossObject.DistributedCashbotBossObject.setObjectState(self, state, avId, craneId)
def setTarget(self, x, y, h, arrivalTime):
self.target = Point3(x, y, 0)
self.targetH = h
now = globalClock.getFrameTime()
self.arrivalTime = globalClockDelta.networkToLocalTime(arrivalTime, now)
if self.state == 'Walk':
self.__startWalk()
def d_destroyGoon(self):
self.sendUpdate('destroyGoon')
def b_destroyGoon(self):
if not self.isDead:
self.d_destroyGoon()
self.destroyGoon()
def destroyGoon(self):
if not self.isDead:
self.playCrushMovie(None, None)
self.demand('Off')
return
def enterOff(self):
DistributedGoon.DistributedGoon.enterOff(self)
DistributedCashbotBossObject.DistributedCashbotBossObject.enterOff(self)
def exitOff(self):
DistributedCashbotBossObject.DistributedCashbotBossObject.exitOff(self)
DistributedGoon.DistributedGoon.exitOff(self)
def enterWalk(self, avId = None, ts = 0):
self.startToonDetect()
self.isStunned = 0
self.__startWalk()
self.loop('walk', 0)
self.unstashCollisions()
def exitWalk(self):
self.__stopWalk()
self.stopToonDetect()
self.stop()
def enterEmergeA(self):
self.undead()
self.reparentTo(render)
self.stopToonDetect()
self.boss.doorA.request('open')
self.radar.hide()
self.__startWalk()
self.loop('walk', 0)
def exitEmergeA(self):
if self.boss.doorA:
self.boss.doorA.request('close')
self.radar.show()
self.__stopWalk()
def enterEmergeB(self):
self.undead()
self.reparentTo(render)
self.stopToonDetect()
self.boss.doorB.request('open')
self.radar.hide()
self.__startWalk()
self.loop('walk', 0)
def exitEmergeB(self):
if self.boss.doorB:
self.boss.doorB.request('close')
self.radar.show()
self.__stopWalk()
def enterBattle(self, avId = None, ts = 0):
DistributedGoon.DistributedGoon.enterBattle(self, avId, ts)
avatar = base.cr.doId2do.get(avId)
if avatar:
messenger.send('exitCrane')
avatar.stunToon()
self.unstashCollisions()
def enterStunned(self, ts = 0):
DistributedGoon.DistributedGoon.enterStunned(self, ts)
self.unstashCollisions()
def enterRecovery(self, ts = 0, pauseTime = 0):
DistributedGoon.DistributedGoon.enterRecovery(self, ts, pauseTime)
self.unstashCollisions()