toontown-just-works/toontown/suit/DistributedLawbotBossSuit.py

385 lines
17 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.fsm import ClassicFSM, State
from direct.fsm import State
from direct.directnotify import DirectNotifyGlobal
import DistributedSuitBase
from toontown.toonbase import ToontownGlobals
from toontown.battle import MovieUtil
class DistributedLawbotBossSuit(DistributedSuitBase.DistributedSuitBase):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedLawbotBossSuit')
timeToShow = 1.0
timeToRelease = 3.15
throwPaperEndTime = 4.33
def __init__(self, cr):
self.flyingEvidenceTrack = None
try:
self.DistributedSuit_initialized
except:
self.DistributedSuit_initialized = 1
DistributedSuitBase.DistributedSuitBase.__init__(self, cr)
self.activeIntervals = {}
self.boss = None
self.fsm = ClassicFSM.ClassicFSM('DistributedLawbotBossSuit', [
State.State('Off',
self.enterOff,
self.exitOff, [
'Walk',
'Battle',
'neutral']),
State.State('Walk',
self.enterWalk,
self.exitWalk, [
'WaitForBattle',
'Battle']),
State.State('Battle',
self.enterBattle,
self.exitBattle, []),
State.State('neutral',
self.enterNeutral,
self.exitNeutral, [
'PreThrowProsecute',
'PreThrowAttack',
'Stunned']),
State.State('PreThrowProsecute',
self.enterPreThrowProsecute,
self.exitPreThrowProsecute,
['PostThrowProsecute',
'neutral',
'Stunned']),
State.State('PostThrowProsecute',
self.enterPostThrowProsecute,
self.exitPostThrowProsecute, [
'neutral',
'Stunned']),
State.State('PreThrowAttack',
self.enterPreThrowAttack,
self.exitPreThrowAttack, [
'PostThrowAttack',
'neutral',
'Stunned']),
State.State('PostThrowAttack',
self.enterPostThrowAttack,
self.exitPostThrowAttack, [
'neutral',
'Stunned']),
State.State('Stunned',
self.enterStunned,
self.exitStunned, [
'neutral']),
State.State('WaitForBattle',
self.enterWaitForBattle,
self.exitWaitForBattle, [
'Battle'])],
'Off', 'Off')
self.fsm.enterInitialState()
return
def generate(self):
self.notify.debug('DLBS.generate:')
DistributedSuitBase.DistributedSuitBase.generate(self)
def announceGenerate(self):
DistributedSuitBase.DistributedSuitBase.announceGenerate(self)
self.notify.debug('DLBS.announceGenerate')
colNode = self.find('**/distAvatarCollNode*')
colNode.setTag('pieCode', str(ToontownGlobals.PieCodeLawyer))
self.attackEvidenceA = self.getEvidence(True)
self.attackEvidenceB = self.getEvidence(True)
self.attackEvidence = self.attackEvidenceA
self.prosecuteEvidence = self.getEvidence(False)
self.hideName()
self.setPickable(False)
def disable(self):
self.notify.debug('DistributedSuit %d: disabling' % self.getDoId())
self.setState('Off')
DistributedSuitBase.DistributedSuitBase.disable(self)
self.cleanupIntervals()
self.boss = None
return
def delete(self):
try:
self.DistributedSuit_deleted
except:
self.DistributedSuit_deleted = 1
self.notify.debug('DistributedSuit %d: deleting' % self.getDoId())
del self.fsm
DistributedSuitBase.DistributedSuitBase.delete(self)
def d_requestBattle(self, pos, hpr):
self.cr.playGame.getPlace().setState('WaitForBattle')
self.sendUpdate('requestBattle', [pos[0],
pos[1],
pos[2],
hpr[0],
hpr[1],
hpr[2]])
return None
def __handleToonCollision(self, collEntry):
toonId = base.localAvatar.getDoId()
self.notify.debug('Distributed suit: requesting a Battle with ' + 'toon: %d' % toonId)
self.d_requestBattle(self.getPos(), self.getHpr())
self.setState('WaitForBattle')
return None
def enterWalk(self):
self.notify.debug('enterWalk')
self.enableBattleDetect('walk', self.__handleToonCollision)
self.loop('walk', 0)
pathPoints = [Vec3(50, 15, 0),
Vec3(50, 25, 0),
Vec3(20, 25, 0),
Vec3(20, 15, 0),
Vec3(50, 15, 0)]
self.tutWalkTrack = self.makePathTrack(self, pathPoints, 4.5, 'tutFlunkyWalk')
self.tutWalkTrack.loop()
def exitWalk(self):
self.notify.debug('exitWalk')
self.disableBattleDetect()
self.tutWalkTrack.pause()
self.tutWalkTrack = None
return
def enterNeutral(self):
self.notify.debug('enterNeutral')
self.notify.debug('DistributedLawbotBossSuit: Neutral')
self.loop('neutral', 0)
def exitNeutral(self):
self.notify.debug('exitNeutral')
def doAttack(self, x1, y1, z1, x2, y2, z2):
self.notify.debug('x1=%.2f y1=%.2f z2=%.2f x2=%.2f y2=%.2f z2=%.2f' % (x1,
y1,
z1,
x2,
y2,
z2))
self.curTargetPt = Point3(x2, y2, z2)
self.fsm.request('PreThrowAttack')
return
attackEvidence = self.getEvidence(True)
nodePath = render
node = nodePath.attachNewNode('attackEvidence-%s' % self.doId)
node.setPos(x1, y1, z1)
duration = 3.0
throwName = self.uniqueName('lawyerAttack')
throwingSeq = self.makeAttackThrowingTrack(attackEvidence, duration, Point3(x2, y2, z2))
fullSequence = Sequence(throwingSeq, name=throwName)
self.activeIntervals[throwName] = fullSequence
fullSequence.start()
def doProsecute(self):
self.notify.debug('doProsecute')
bounds = self.boss.prosecutionColNodePath.getBounds()
panCenter = bounds.getCenter()
localPos = panCenter
prosecutionPanPos = render.getRelativePoint(self.boss.prosecutionColNodePath, localPos)
self.curTargetPt = prosecutionPanPos
self.fsm.request('PreThrowProsecute')
return
attackEvidence = self.getEvidence(False)
nodePath = render
node = nodePath.attachNewNode('prosecuteEvidence-%s' % self.doId)
node.setPos(self.getPos())
duration = ToontownGlobals.LawbotBossLawyerToPanTime
throwName = self.uniqueName('lawyerProsecute')
throwingSeq = self.makeProsecuteThrowingTrack(attackEvidence, duration, prosecutionPanPos)
fullSequence = Sequence(throwingSeq, Func(self.boss.flashGreen), Func(self.clearInterval, throwName), name=throwName)
self.activeIntervals[throwName] = fullSequence
fullSequence.start()
def makeDummySequence(self):
retval = Sequence(Wait(10))
return retval
def makeProsecuteThrowingTrack(self, evidence, inFlightDuration, hitPos):
suitTrack = Sequence()
suitTrack.append(ActorInterval(self, 'throw-paper'))
throwPaperDuration = suitTrack.getDuration()
inFlight = Parallel(evidence.posInterval(inFlightDuration, hitPos, fluid=1))
origHpr = self.getHpr()
self.headsUp(hitPos)
newHpr = self.getHpr()
self.setHpr(origHpr)
rotateTrack = Sequence(self.hprInterval(self.timeToShow, newHpr, fluid=1))
propTrack = Sequence(Func(evidence.hide), Func(evidence.setPos, 0, 0.5, -0.3), Func(evidence.reparentTo, self.getRightHand()), Wait(self.timeToShow), Func(evidence.show), Wait(self.timeToRelease - self.timeToShow), Func(evidence.wrtReparentTo, render), Func(self.makeDummySequence), inFlight, Func(evidence.detachNode))
throwingTrack = Parallel(suitTrack, propTrack, rotateTrack)
return throwingTrack
def makeAttackThrowingTrack(self, evidence, inFlightDuration, hitPos):
suitTrack = Sequence()
suitTrack.append(ActorInterval(self, 'throw-paper'))
throwPaperDuration = suitTrack.getDuration()
origHpr = self.getHpr()
self.headsUp(hitPos)
newHpr = self.getHpr()
self.setHpr(origHpr)
rotateTrack = Sequence(self.hprInterval(self.timeToShow, newHpr, fluid=1))
propTrack = Sequence(Func(evidence.hide), Func(evidence.setPos, 0, 0.5, -0.3), Func(evidence.reparentTo, self.getRightHand()), Wait(self.timeToShow), Func(evidence.show), Wait(self.timeToRelease - self.timeToShow), Func(evidence.wrtReparentTo, render), Func(evidence.setZ, 1.3), evidence.posInterval(inFlightDuration, hitPos, fluid=1), Func(evidence.detachNode))
throwingTrack = Parallel(suitTrack, propTrack, rotateTrack)
return throwingTrack
def makePreThrowAttackTrack(self, evidence, inFlightDuration, hitPos):
suitTrack = Sequence()
suitTrack.append(ActorInterval(self, 'throw-paper', endTime=self.timeToRelease))
throwPaperDuration = suitTrack.getDuration()
origHpr = self.getHpr()
self.headsUp(hitPos)
newHpr = self.getHpr()
self.setHpr(origHpr)
rotateTrack = Sequence(self.hprInterval(self.timeToShow, newHpr, fluid=1))
propTrack = Sequence(Func(evidence.hide), Func(evidence.setPos, 0, 0.5, -0.3), Func(evidence.setScale, 1), Func(evidence.setHpr, 0, 0, 0), Func(evidence.reparentTo, self.getRightHand()), Wait(self.timeToShow), Func(evidence.show), Wait(self.timeToRelease - self.timeToShow))
throwingTrack = Parallel(suitTrack, propTrack, rotateTrack)
return throwingTrack
def makePostThrowAttackTrack(self, evidence, inFlightDuration, hitPos):
suitTrack = Sequence()
suitTrack.append(ActorInterval(self, 'throw-paper', startTime=self.timeToRelease))
propTrack = Sequence(Func(evidence.wrtReparentTo, render), Func(evidence.setScale, 1), Func(evidence.show), Func(evidence.setZ, 1.3), evidence.posInterval(inFlightDuration, hitPos, fluid=1), Func(evidence.hide))
return (suitTrack, propTrack)
def makePreThrowProsecuteTrack(self, evidence, inFlightDuration, hitPos):
return self.makePreThrowAttackTrack(evidence, inFlightDuration, hitPos)
def makePostThrowProsecuteTrack(self, evidence, inFlightDuration, hitPos):
suitTrack = Sequence()
suitTrack.append(ActorInterval(self, 'throw-paper', startTime=self.timeToRelease))
propTrack = Sequence(Func(evidence.wrtReparentTo, render), Func(evidence.setScale, 1), Func(evidence.show), evidence.posInterval(inFlightDuration, hitPos, fluid=1), Func(evidence.hide))
return (suitTrack, propTrack)
def getEvidence(self, usedForAttack = False):
model = loader.loadModel('phase_5/models/props/lawbook')
if usedForAttack:
bounds = model.getBounds()
center = bounds.getCenter()
radius = bounds.getRadius()
sphere = CollisionSphere(center.getX(), center.getY(), center.getZ(), radius)
colNode = CollisionNode('BossZap')
colNode.setTag('attackCode', str(ToontownGlobals.BossCogLawyerAttack))
colNode.addSolid(sphere)
model.attachNewNode(colNode)
model.setTransparency(1)
model.setAlphaScale(0.5)
return model
def cleanupIntervals(self):
for interval in self.activeIntervals.values():
interval.finish()
self.activeIntervals = {}
def clearInterval(self, name, finish = 1):
if name in self.activeIntervals:
ival = self.activeIntervals[name]
if finish:
ival.finish()
else:
ival.pause()
if name in self.activeIntervals:
del self.activeIntervals[name]
else:
self.notify.debug('interval: %s already cleared' % name)
def setBossCogId(self, bossCogId):
self.bossCogId = bossCogId
self.boss = base.cr.doId2do[bossCogId]
def doStun(self):
self.notify.debug('doStun')
self.fsm.request('Stunned')
def enterPreThrowProsecute(self):
duration = ToontownGlobals.LawbotBossLawyerToPanTime
throwName = self.uniqueName('preThrowProsecute')
preThrowTrack = self.makePreThrowProsecuteTrack(self.prosecuteEvidence, duration, self.curTargetPt)
fullSequence = Sequence(preThrowTrack, Func(self.requestStateIfNotInFlux, 'PostThrowProsecute'), name=throwName)
self.activeIntervals[throwName] = fullSequence
fullSequence.start()
def exitPreThrowProsecute(self):
throwName = self.uniqueName('preThrowProsecute')
if throwName in self.activeIntervals:
self.activeIntervals[throwName].pause()
del self.activeIntervals[throwName]
def enterPostThrowProsecute(self):
duration = ToontownGlobals.LawbotBossLawyerToPanTime
throwName = self.uniqueName('postThrowProsecute')
postThrowTrack, self.flyingEvidenceTrack = self.makePostThrowProsecuteTrack(self.prosecuteEvidence, duration, self.curTargetPt)
fullSequence = Sequence(postThrowTrack, Func(self.requestStateIfNotInFlux, 'neutral'), name=throwName)
self.activeIntervals[throwName] = fullSequence
fullSequence.start()
flyName = self.uniqueName('flyingEvidence')
self.activeIntervals[flyName] = self.flyingEvidenceTrack
self.flyingEvidenceTrack.append(Func(self.finishedWithFlying, 'prosecute'))
self.flyingEvidenceTrack.start()
def exitPostThrowProsecute(self):
throwName = self.uniqueName('postThrowProsecute')
if throwName in self.activeIntervals:
self.activeIntervals[throwName].finish()
del self.activeIntervals[throwName]
def requestStateIfNotInFlux(self, state):
if not self.fsm._ClassicFSM__internalStateInFlux:
self.fsm.request(state)
def enterPreThrowAttack(self):
if self.attackEvidence == self.attackEvidenceA:
self.attackEvidence = self.attackEvidenceB
else:
self.attackEvidence = self.attackEvidenceA
duration = 3.0
throwName = self.uniqueName('preThrowAttack')
preThrowTrack = self.makePreThrowAttackTrack(self.attackEvidence, duration, self.curTargetPt)
fullSequence = Sequence(preThrowTrack, Func(self.requestStateIfNotInFlux, 'PostThrowAttack'), name=throwName)
self.activeIntervals[throwName] = fullSequence
fullSequence.start()
def exitPreThrowAttack(self):
throwName = self.uniqueName('preThrowAttack')
if throwName in self.activeIntervals:
self.activeIntervals[throwName].pause()
del self.activeIntervals[throwName]
def enterPostThrowAttack(self):
duration = 3.0
throwName = self.uniqueName('postThrowAttack')
postThrowTrack, self.flyingEvidenceTrack = self.makePostThrowAttackTrack(self.attackEvidence, duration, self.curTargetPt)
fullSequence = Sequence(postThrowTrack, Func(self.requestStateIfNotInFlux, 'neutral'), name=throwName)
self.notify.debug('duration of postThrowAttack = %f' % fullSequence.getDuration())
self.activeIntervals[throwName] = fullSequence
fullSequence.start()
flyName = self.uniqueName('flyingEvidence')
self.activeIntervals[flyName] = self.flyingEvidenceTrack
self.flyingEvidenceTrack.append(Func(self.finishedWithFlying, 'attack'))
self.flyingEvidenceTrack.start()
def finishedWithFlying(self, str):
self.notify.debug('finished flyingEvidenceTrack %s' % str)
def exitPostThrowAttack(self):
throwName = self.uniqueName('postThrowAttack')
if throwName in self.activeIntervals:
self.activeIntervals[throwName].finish()
del self.activeIntervals[throwName]
def enterStunned(self):
stunSequence = MovieUtil.createSuitStunInterval(self, 0, ToontownGlobals.LawbotBossLawyerStunTime)
seqName = stunSequence.getName()
stunSequence.append(Func(self.fsm.request, 'neutral'))
self.activeIntervals[seqName] = stunSequence
stunSequence.start()
def exitStunned(self):
self.prosecuteEvidence.hide()
self.attackEvidence.hide()