toontown-just-works/toontown/coghq/DistributedCashbotBossObject.py

323 lines
11 KiB
Python
Raw Normal View History

2024-07-07 18:08:39 -05:00
from panda3d.core import *
from direct.interval.IntervalGlobal import *
from direct.directnotify import DirectNotifyGlobal
from direct.distributed import DistributedSmoothNode
from toontown.toonbase import ToontownGlobals
from otp.otpbase import OTPGlobals
from direct.fsm import FSM
from direct.task import Task
smileyDoId = 1
class DistributedCashbotBossObject(DistributedSmoothNode.DistributedSmoothNode, FSM.FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCashbotBossObject')
wantsWatchDrift = 1
def __init__(self, cr):
DistributedSmoothNode.DistributedSmoothNode.__init__(self, cr)
FSM.FSM.__init__(self, 'DistributedCashbotBossObject')
self.boss = None
self.avId = 0
self.craneId = 0
self.cleanedUp = 0
self.collisionNode = CollisionNode('object')
self.collisionNode.setIntoCollideMask(ToontownGlobals.PieBitmask | OTPGlobals.WallBitmask | ToontownGlobals.CashbotBossObjectBitmask | OTPGlobals.CameraBitmask)
self.collisionNode.setFromCollideMask(ToontownGlobals.PieBitmask | OTPGlobals.FloorBitmask)
self.collisionNodePath = NodePath(self.collisionNode)
self.physicsActivated = 0
self.toMagnetSoundInterval = Sequence()
self.hitFloorSoundInterval = Sequence()
self.hitBossSfx = loader.loadSfx('phase_5/audio/sfx/AA_drop_safe_miss.ogg')
self.hitBossSoundInterval = SoundInterval(self.hitBossSfx)
self.touchedBossSfx = loader.loadSfx('phase_5/audio/sfx/AA_drop_sandbag.ogg')
self.touchedBossSoundInterval = SoundInterval(self.touchedBossSfx, duration=0.8)
self.lerpInterval = None
return
def disable(self):
self.cleanup()
self.stopSmooth()
DistributedSmoothNode.DistributedSmoothNode.disable(self)
def cleanup(self):
if self.cleanedUp:
return
else:
self.cleanedUp = 1
self.demand('Off')
self.detachNode()
self.toMagnetSoundInterval.finish()
self.hitFloorSoundInterval.finish()
self.hitBossSoundInterval.finish()
self.touchedBossSoundInterval.finish()
del self.toMagnetSoundInterval
del self.hitFloorSoundInterval
del self.hitBossSoundInterval
del self.touchedBossSoundInterval
self.boss = None
return
def setupPhysics(self, name):
an = ActorNode('%s-%s' % (name, self.doId))
anp = NodePath(an)
if not self.isEmpty():
self.reparentTo(anp)
NodePath.assign(self, anp)
self.physicsObject = an.getPhysicsObject()
self.setTag('object', str(self.doId))
self.collisionNodePath.reparentTo(self)
self.handler = PhysicsCollisionHandler()
self.handler.addCollider(self.collisionNodePath, self)
self.collideName = self.uniqueName('collide')
self.handler.addInPattern(self.collideName + '-%in')
self.handler.addAgainPattern(self.collideName + '-%in')
self.watchDriftName = self.uniqueName('watchDrift')
def activatePhysics(self):
if not self.physicsActivated:
self.boss.physicsMgr.attachPhysicalNode(self.node())
base.cTrav.addCollider(self.collisionNodePath, self.handler)
self.physicsActivated = 1
self.accept(self.collideName + '-floor', self.__hitFloor)
self.accept(self.collideName + '-goon', self.__hitGoon)
self.acceptOnce(self.collideName + '-headTarget', self.__hitBoss)
self.accept(self.collideName + '-dropPlane', self.__hitDropPlane)
def deactivatePhysics(self):
if self.physicsActivated:
self.boss.physicsMgr.removePhysicalNode(self.node())
base.cTrav.removeCollider(self.collisionNodePath)
self.physicsActivated = 0
self.ignore(self.collideName + '-floor')
self.ignore(self.collideName + '-goon')
self.ignore(self.collideName + '-headTarget')
self.ignore(self.collideName + '-dropPlane')
def hideShadows(self):
pass
def showShadows(self):
pass
def stashCollisions(self):
self.collisionNodePath.stash()
def unstashCollisions(self):
self.collisionNodePath.unstash()
def __hitFloor(self, entry):
if self.state == 'Dropped' or self.state == 'LocalDropped':
self.d_hitFloor()
self.demand('SlidingFloor', localAvatar.doId)
def __hitGoon(self, entry):
if self.state == 'Dropped' or self.state == 'LocalDropped':
goonId = int(entry.getIntoNodePath().getNetTag('doId'))
goon = self.cr.doId2do.get(goonId)
if goon:
self.doHitGoon(goon)
def doHitGoon(self, goon):
pass
def __hitBoss(self, entry):
if (self.state == 'Dropped' or self.state == 'LocalDropped') and self.craneId != self.boss.doId:
vel = self.physicsObject.getVelocity()
vel = self.crane.root.getRelativeVector(render, vel)
vel.normalize()
impact = vel[1]
if impact >= self.getMinImpact():
print 'hit! %s' % impact
self.hitBossSoundInterval.start()
self.doHitBoss(impact)
else:
self.touchedBossSoundInterval.start()
print '--not hard enough: %s' % impact
def doHitBoss(self, impact):
self.d_hitBoss(impact)
def __hitDropPlane(self, entry):
self.notify.info('%s fell out of the world.' % self.doId)
self.fellOut()
def fellOut(self):
raise StandardError, 'fellOut unimplented'
def getMinImpact(self):
return 0
def __watchDrift(self, task):
v = self.physicsObject.getVelocity()
if abs(v[0]) < 0.0001 and abs(v[1]) < 0.0001:
self.d_requestFree()
self.demand('Free')
return Task.cont
def prepareGrab(self):
pass
def prepareRelease(self):
pass
def setBossCogId(self, bossCogId):
self.bossCogId = bossCogId
self.boss = base.cr.doId2do[bossCogId]
def setObjectState(self, state, avId, craneId):
if state == 'G':
self.demand('Grabbed', avId, craneId)
elif state == 'D':
if self.state != 'Dropped':
self.demand('Dropped', avId, craneId)
elif state == 's':
if self.state != 'SlidingFloor':
self.demand('SlidingFloor', avId)
elif state == 'F':
self.demand('Free')
else:
self.notify.error('Invalid state from AI: %s' % state)
def d_requestGrab(self):
self.sendUpdate('requestGrab')
def rejectGrab(self):
if self.state == 'LocalGrabbed':
self.demand('LocalDropped', self.avId, self.craneId)
def d_requestDrop(self):
self.sendUpdate('requestDrop')
def d_hitFloor(self):
self.sendUpdate('hitFloor')
def d_requestFree(self):
self.sendUpdate('requestFree', [self.getX(),
self.getY(),
self.getZ(),
self.getH()])
def d_hitBoss(self, impact):
self.sendUpdate('hitBoss', [impact])
def defaultFilter(self, request, args):
if self.boss == None:
raise FSM.RequestDenied, request
return FSM.FSM.defaultFilter(self, request, args)
def enterOff(self):
self.detachNode()
if self.lerpInterval:
self.lerpInterval.finish()
self.lerpInterval = None
return
def exitOff(self):
self.reparentTo(render)
def enterLocalGrabbed(self, avId, craneId):
self.avId = avId
self.craneId = craneId
self.crane = self.cr.doId2do.get(craneId)
self.hideShadows()
self.prepareGrab()
self.crane.grabObject(self)
def exitLocalGrabbed(self):
if self.newState != 'Grabbed':
self.crane.dropObject(self)
self.prepareRelease()
del self.crane
self.showShadows()
def enterGrabbed(self, avId, craneId):
if self.oldState == 'LocalGrabbed':
if craneId == self.craneId:
return
else:
self.crane.dropObject(self)
self.prepareRelease()
self.avId = avId
self.craneId = craneId
self.crane = self.cr.doId2do.get(craneId)
self.hideShadows()
self.prepareGrab()
self.crane.grabObject(self)
def exitGrabbed(self):
self.crane.dropObject(self)
self.prepareRelease()
self.showShadows()
del self.crane
def enterLocalDropped(self, avId, craneId):
self.avId = avId
self.craneId = craneId
self.crane = self.cr.doId2do.get(craneId)
self.activatePhysics()
self.startPosHprBroadcast()
self.hideShadows()
self.handler.setStaticFrictionCoef(0)
self.handler.setDynamicFrictionCoef(0)
def exitLocalDropped(self):
if self.newState != 'SlidingFloor' and self.newState != 'Dropped':
self.deactivatePhysics()
self.stopPosHprBroadcast()
del self.crane
self.showShadows()
def enterDropped(self, avId, craneId):
self.avId = avId
self.craneId = craneId
self.crane = self.cr.doId2do.get(craneId)
if self.avId == base.localAvatar.doId:
self.activatePhysics()
self.startPosHprBroadcast()
self.handler.setStaticFrictionCoef(0)
self.handler.setDynamicFrictionCoef(0)
else:
self.startSmooth()
self.hideShadows()
def exitDropped(self):
if self.avId == base.localAvatar.doId:
if self.newState != 'SlidingFloor':
self.deactivatePhysics()
self.stopPosHprBroadcast()
else:
self.stopSmooth()
del self.crane
self.showShadows()
def enterSlidingFloor(self, avId):
self.avId = avId
if self.lerpInterval:
self.lerpInterval.finish()
self.lerpInterval = None
if self.avId == base.localAvatar.doId:
self.activatePhysics()
self.startPosHprBroadcast()
self.handler.setStaticFrictionCoef(0.9)
self.handler.setDynamicFrictionCoef(0.5)
if self.wantsWatchDrift:
taskMgr.add(self.__watchDrift, self.watchDriftName)
else:
self.startSmooth()
self.hitFloorSoundInterval.start()
return
def exitSlidingFloor(self):
if self.avId == base.localAvatar.doId:
taskMgr.remove(self.watchDriftName)
self.deactivatePhysics()
self.stopPosHprBroadcast()
else:
self.stopSmooth()
def enterFree(self):
self.avId = 0
self.craneId = 0
def exitFree(self):
pass