toontown-just-works/toontown/battle/DistributedBattleBase.py
2024-07-07 18:08:39 -05:00

1537 lines
61 KiB
Python

from panda3d.core import *
from toontown.toonbase.ToonBaseGlobal import *
from direct.interval.IntervalGlobal import *
from BattleBase import *
from direct.distributed.ClockDelta import *
from toontown.toonbase import ToontownBattleGlobals
from direct.distributed import DistributedNode
from direct.fsm import ClassicFSM
from direct.fsm import State
from direct.task.Task import Task
from direct.directnotify import DirectNotifyGlobal
import Movie
import MovieUtil
from toontown.suit import Suit
from direct.actor import Actor
import BattleProps
from direct.particles import ParticleEffect
import BattleParticles
from toontown.hood import ZoneUtil
from toontown.distributed import DelayDelete
from toontown.toon import TTEmote
from otp.avatar import Emote
from otp.nametag.NametagConstants import *
from otp.nametag import NametagGlobals
class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBattleBase')
camPos = ToontownBattleGlobals.BattleCamDefaultPos
camHpr = ToontownBattleGlobals.BattleCamDefaultHpr
camFov = ToontownBattleGlobals.BattleCamDefaultFov
camMenuFov = ToontownBattleGlobals.BattleCamMenuFov
camJoinPos = ToontownBattleGlobals.BattleCamJoinPos
camJoinHpr = ToontownBattleGlobals.BattleCamJoinHpr
id = 0
def __init__(self, cr, townBattle):
DistributedNode.DistributedNode.__init__(self, cr)
NodePath.__init__(self)
self.assign(render.attachNewNode(self.uniqueBattleName('distributed-battle')))
BattleBase.__init__(self)
self.bossBattle = 0
self.townBattle = townBattle
self.__battleCleanedUp = 0
self.activeIntervals = {}
self.localToonJustJoined = 0
self.choseAttackAlready = 0
self.toons = []
self.exitedToons = []
self.suitTraps = ''
self.membersKeep = None
self.faceOffName = self.uniqueBattleName('faceoff')
self.localToonBattleEvent = self.uniqueBattleName('localtoon-battle-event')
self.adjustName = self.uniqueBattleName('adjust')
self.timerCountdownTaskName = self.uniqueBattleName('timer-countdown')
self.movie = Movie.Movie(self)
self.timer = Timer()
self.needAdjustTownBattle = 0
self.streetBattle = 1
self.levelBattle = 0
self.localToonFsm = ClassicFSM.ClassicFSM('LocalToon', [State.State('HasLocalToon', self.enterHasLocalToon, self.exitHasLocalToon, ['NoLocalToon', 'WaitForServer']), State.State('NoLocalToon', self.enterNoLocalToon, self.exitNoLocalToon, ['HasLocalToon', 'WaitForServer']), State.State('WaitForServer', self.enterWaitForServer, self.exitWaitForServer, ['HasLocalToon', 'NoLocalToon'])], 'WaitForServer', 'WaitForServer')
self.localToonFsm.enterInitialState()
self.fsm = ClassicFSM.ClassicFSM('DistributedBattle', [State.State('Off', self.enterOff, self.exitOff, ['FaceOff',
'WaitForInput',
'WaitForJoin',
'MakeMovie',
'PlayMovie',
'Reward',
'Resume']),
State.State('FaceOff', self.enterFaceOff, self.exitFaceOff, ['WaitForInput']),
State.State('WaitForJoin', self.enterWaitForJoin, self.exitWaitForJoin, ['WaitForInput', 'Resume']),
State.State('WaitForInput', self.enterWaitForInput, self.exitWaitForInput, ['WaitForInput', 'PlayMovie', 'Resume']),
State.State('MakeMovie', self.enterMakeMovie, self.exitMakeMovie, ['PlayMovie', 'Resume']),
State.State('PlayMovie', self.enterPlayMovie, self.exitPlayMovie, ['WaitForInput',
'WaitForJoin',
'Reward',
'Resume']),
State.State('Reward', self.enterReward, self.exitReward, ['Resume']),
State.State('Resume', self.enterResume, self.exitResume, [])], 'Off', 'Off')
self.fsm.enterInitialState()
self.adjustFsm = ClassicFSM.ClassicFSM('Adjust', [State.State('Adjusting', self.enterAdjusting, self.exitAdjusting, ['NotAdjusting']), State.State('NotAdjusting', self.enterNotAdjusting, self.exitNotAdjusting, ['Adjusting'])], 'NotAdjusting', 'NotAdjusting')
self.adjustFsm.enterInitialState()
self.interactiveProp = None
self.fireCount = 0
return
def uniqueBattleName(self, name):
DistributedBattleBase.id += 1
return name + '-%d' % DistributedBattleBase.id
def generate(self):
self.notify.debug('generate(%s)' % self.doId)
DistributedNode.DistributedNode.generate(self)
self.__battleCleanedUp = 0
self.reparentTo(render)
self._skippingRewardMovie = False
def storeInterval(self, interval, name):
if name in self.activeIntervals:
ival = self.activeIntervals[name]
if hasattr(ival, 'delayDelete') or hasattr(ival, 'delayDeletes'):
self.clearInterval(name, finish=1)
self.activeIntervals[name] = interval
def __cleanupIntervals(self):
for interval in self.activeIntervals.values():
interval.finish()
DelayDelete.cleanupDelayDeletes(interval)
self.activeIntervals = {}
def clearInterval(self, name, finish = 0):
if name in self.activeIntervals:
ival = self.activeIntervals[name]
if finish:
ival.finish()
else:
ival.pause()
if name in self.activeIntervals:
DelayDelete.cleanupDelayDeletes(ival)
if name in self.activeIntervals:
del self.activeIntervals[name]
else:
self.notify.debug('interval: %s already cleared' % name)
def finishInterval(self, name):
if name in self.activeIntervals:
interval = self.activeIntervals[name]
interval.finish()
def disable(self):
self.notify.debug('disable(%s)' % self.doId)
self.cleanupBattle()
DistributedNode.DistributedNode.disable(self)
def battleCleanedUp(self):
return self.__battleCleanedUp
def cleanupBattle(self):
if self.__battleCleanedUp:
return
self.notify.debug('cleanupBattle(%s)' % self.doId)
self.__battleCleanedUp = 1
self.__cleanupIntervals()
self.fsm.requestFinalState()
if self.hasLocalToon():
self.removeLocalToon()
base.camLens.setMinFov(settings['fov']/(4./3.))
self.localToonFsm.request('WaitForServer')
self.ignoreAll()
for suit in self.suits:
if suit.battleTrap != NO_TRAP:
self.notify.debug('250 calling self.removeTrap, suit=%d' % suit.doId)
self.removeTrap(suit)
suit.battleTrap = NO_TRAP
suit.battleTrapProp = None
self.notify.debug('253 suit.battleTrapProp = None')
suit.battleTrapIsFresh = 0
self.suits = []
self.pendingSuits = []
self.joiningSuits = []
self.activeSuits = []
self.suitTraps = ''
self.toons = []
self.joiningToons = []
self.pendingToons = []
self.activeToons = []
self.runningToons = []
self.__stopTimer()
self.__cleanupIntervals()
self._removeMembersKeep()
return
def delete(self):
self.notify.debug('delete(%s)' % self.doId)
self.__cleanupIntervals()
self._removeMembersKeep()
self.movie.cleanup()
del self.townBattle
self.removeNode()
self.fsm = None
self.localToonFsm = None
self.adjustFsm = None
self.__stopTimer()
self.timer = None
DistributedNode.DistributedNode.delete(self)
return
def loadTrap(self, suit, trapid):
self.notify.debug('loadTrap() trap: %d suit: %d' % (trapid, suit.doId))
trapName = AvProps[TRAP][trapid]
trap = BattleProps.globalPropPool.getProp(trapName)
suit.battleTrap = trapid
suit.battleTrapIsFresh = 0
suit.battleTrapProp = trap
self.notify.debug('suit.battleTrapProp = trap %s' % trap)
if trap.getName() == 'traintrack':
pass
else:
trap.wrtReparentTo(suit)
distance = MovieUtil.SUIT_TRAP_DISTANCE
if trapName == 'rake':
distance = MovieUtil.SUIT_TRAP_RAKE_DISTANCE
distance += MovieUtil.getSuitRakeOffset(suit)
trap.setH(180)
trap.setScale(0.7)
elif trapName == 'trapdoor' or trapName == 'quicksand':
trap.setScale(1.7)
elif trapName == 'marbles':
distance = MovieUtil.SUIT_TRAP_MARBLES_DISTANCE
trap.setH(94)
elif trapName == 'tnt':
trap.setP(90)
tip = trap.find('**/joint_attachEmitter')
sparks = BattleParticles.createParticleEffect(file='tnt')
trap.sparksEffect = sparks
sparks.start(tip)
trap.setPos(0, distance, 0)
if isinstance(trap, Actor.Actor):
frame = trap.getNumFrames(trapName) - 1
trap.pose(trapName, frame)
def removeTrap(self, suit, removeTrainTrack = False):
self.notify.debug('removeTrap() from suit: %d, removeTrainTrack=%s' % (suit.doId, removeTrainTrack))
if suit.battleTrapProp == None:
self.notify.debug('suit.battleTrapProp == None, suit.battleTrap=%s setting to NO_TRAP, returning' % suit.battleTrap)
suit.battleTrap = NO_TRAP
return
if suit.battleTrap == UBER_GAG_LEVEL_INDEX:
if removeTrainTrack:
self.notify.debug('doing removeProp on traintrack')
MovieUtil.removeProp(suit.battleTrapProp)
for otherSuit in self.suits:
if not otherSuit == suit:
otherSuit.battleTrapProp = None
self.notify.debug('351 otherSuit=%d otherSuit.battleTrapProp = None' % otherSuit.doId)
otherSuit.battleTrap = NO_TRAP
otherSuit.battleTrapIsFresh = 0
else:
self.notify.debug('deliberately not doing removeProp on traintrack')
else:
self.notify.debug('suit.battleTrap != UBER_GAG_LEVEL_INDEX')
MovieUtil.removeProp(suit.battleTrapProp)
suit.battleTrapProp = None
self.notify.debug('360 suit.battleTrapProp = None')
suit.battleTrap = NO_TRAP
suit.battleTrapIsFresh = 0
return
def pause(self):
self.timer.stop()
def unpause(self):
self.timer.resume()
def findSuit(self, id):
for s in self.suits:
if s.doId == id:
return s
return None
def findToon(self, id):
toon = self.getToon(id)
if toon == None:
return
for t in self.toons:
if t == toon:
return t
return
def isSuitLured(self, suit):
if self.luredSuits.count(suit) != 0:
return 1
return 0
def unlureSuit(self, suit):
self.notify.debug('movie unluring suit %s' % suit.doId)
if self.luredSuits.count(suit) != 0:
self.luredSuits.remove(suit)
self.needAdjustTownBattle = 1
return None
def lureSuit(self, suit):
self.notify.debug('movie luring suit %s' % suit.doId)
if self.luredSuits.count(suit) == 0:
self.luredSuits.append(suit)
self.needAdjustTownBattle = 1
return None
def getActorPosHpr(self, actor, actorList = []):
if isinstance(actor, Suit.Suit):
if actorList == []:
actorList = self.activeSuits
if actorList.count(actor) != 0:
numSuits = len(actorList) - 1
index = actorList.index(actor)
point = self.suitPoints[numSuits][index]
return (Point3(point[0]), VBase3(point[1], 0.0, 0.0))
else:
self.notify.warning('getActorPosHpr() - suit not active')
else:
if actorList == []:
actorList = self.activeToons
if actorList.count(actor) != 0:
numToons = len(actorList) - 1
index = actorList.index(actor)
point = self.toonPoints[numToons][index]
return (Point3(point[0]), VBase3(point[1], 0.0, 0.0))
else:
self.notify.warning('getActorPosHpr() - toon not active')
def setLevelDoId(self, levelDoId):
pass
def setBattleCellId(self, battleCellId):
pass
def getInteractiveProp(self):
if config.GetBool('want-anim-props', True):
if self.interactiveProp:
return self.interactiveProp
elif base.cr.playGame.hood and hasattr(base.cr.playGame.hood, 'loader'):
loader = base.cr.playGame.hood.loader
if hasattr(loader, 'getInteractiveProp'):
self.interactiveProp = base.cr.playGame.hood.loader.getInteractiveProp(self.zoneId)
return self.interactiveProp
return None
else:
return None
def getInteractivePropTrackBonus(self):
prop = self.getInteractiveProp()
return prop.BattleTrack if prop else -1
def setPosition(self, x, y, z):
self.notify.debug('setPosition() - %d %d %d' % (x, y, z))
pos = Point3(x, y, z)
self.setPos(pos)
def setInitialSuitPos(self, x, y, z):
self.initialSuitPos = Point3(x, y, z)
self.headsUp(self.initialSuitPos)
def setZoneId(self, zoneId):
self.zoneId = zoneId
def setBossBattle(self, value):
self.bossBattle = value
def setState(self, state, timestamp):
if self.__battleCleanedUp:
return
self.notify.debug('setState(%s)' % state)
self.fsm.request(state, [globalClockDelta.localElapsedTime(timestamp)])
def setMembers(self, suits, suitsJoining, suitsPending, suitsActive, suitsLured, suitTraps, toons, toonsJoining, toonsPending, toonsActive, toonsRunning, timestamp):
if self.__battleCleanedUp:
return
self.notify.debug('setMembers() - suits: %s suitsJoining: %s suitsPending: %s suitsActive: %s suitsLured: %s suitTraps: %s toons: %s toonsJoining: %s toonsPending: %s toonsActive: %s toonsRunning: %s' % (suits,
suitsJoining,
suitsPending,
suitsActive,
suitsLured,
suitTraps,
toons,
toonsJoining,
toonsPending,
toonsActive,
toonsRunning))
ts = globalClockDelta.localElapsedTime(timestamp)
oldsuits = self.suits
self.suits = []
suitGone = 0
prop = self.getInteractiveProp()
for s in suits:
if s in self.cr.doId2do:
suit = self.cr.doId2do[s]
suit.setState('Battle')
self.suits.append(suit)
if prop:
suit.interactivePropTrackBonus = prop.BattleTrack
try:
suit.battleTrap
except:
suit.battleTrap = NO_TRAP
suit.battleTrapProp = None
self.notify.debug('496 suit.battleTrapProp = None')
suit.battleTrapIsFresh = 0
else:
self.notify.warning('setMembers() - no suit in repository: %d' % s)
self.suits.append(None)
suitGone = 1
numSuitsThatDied = 0
for s in oldsuits:
if self.suits.count(s) == 0:
self.__removeSuit(s)
numSuitsThatDied += 1
self.notify.debug('suit %d dies, numSuitsThatDied=%d' % (s.doId, numSuitsThatDied))
if numSuitsThatDied == 4:
trainTrap = self.find('**/traintrack')
if not trainTrap.isEmpty():
self.notify.debug('removing old train trap when 4 suits died')
trainTrap.removeNode()
for s in suitsJoining:
suit = self.suits[int(s)]
if suit != None and self.joiningSuits.count(suit) == 0:
self.makeSuitJoin(suit, ts)
for s in suitsPending:
suit = self.suits[int(s)]
if suit != None and self.pendingSuits.count(suit) == 0:
self.__makeSuitPending(suit)
activeSuits = []
for s in suitsActive:
suit = self.suits[int(s)]
if suit != None and self.activeSuits.count(suit) == 0:
activeSuits.append(suit)
oldLuredSuits = self.luredSuits
self.luredSuits = []
for s in suitsLured:
suit = self.suits[int(s)]
if suit != None:
self.luredSuits.append(suit)
if oldLuredSuits.count(suit) == 0:
self.needAdjustTownBattle = 1
if self.needAdjustTownBattle == 0:
for s in oldLuredSuits:
if self.luredSuits.count(s) == 0:
self.needAdjustTownBattle = 1
index = 0
oldSuitTraps = self.suitTraps
self.suitTraps = suitTraps
for s in suitTraps:
trapid = int(s)
if trapid == 9:
trapid = -1
suit = self.suits[index]
index += 1
if suit != None:
if (trapid == NO_TRAP or trapid != suit.battleTrap) and suit.battleTrapProp != None:
self.notify.debug('569 calling self.removeTrap, suit=%d' % suit.doId)
self.removeTrap(suit)
if trapid != NO_TRAP and suit.battleTrapProp == None:
if self.fsm.getCurrentState().getName() != 'PlayMovie':
self.loadTrap(suit, trapid)
if len(oldSuitTraps) != len(self.suitTraps):
self.needAdjustTownBattle = 1
else:
for i in xrange(len(oldSuitTraps)):
if oldSuitTraps[i] == '9' and self.suitTraps[i] != '9' or oldSuitTraps[i] != '9' and self.suitTraps[i] == '9':
self.needAdjustTownBattle = 1
break
if suitGone:
validSuits = []
for s in self.suits:
if s != None:
validSuits.append(s)
self.suits = validSuits
self.needAdjustTownBattle = 1
oldtoons = self.toons
self.toons = []
toonGone = 0
for t in toons:
toon = self.getToon(t)
if toon == None:
self.notify.warning('setMembers() - toon not in cr!')
self.toons.append(None)
toonGone = 1
continue
self.toons.append(toon)
if oldtoons.count(toon) == 0:
self.notify.debug('setMembers() - add toon: %d' % toon.doId)
self.__listenForUnexpectedExit(toon)
toon.stopLookAround()
toon.stopSmooth()
for t in oldtoons:
if self.toons.count(t) == 0:
if self.__removeToon(t) == 1:
self.notify.debug('setMembers() - local toon left battle')
return []
for t in toonsJoining:
if int(t) < len(self.toons):
toon = self.toons[int(t)]
if toon != None and self.joiningToons.count(toon) == 0:
self.__makeToonJoin(toon, toonsPending, ts)
else:
self.notify.warning('setMembers toonsJoining t=%s not in self.toons %s' % (t, self.toons))
for t in toonsPending:
if int(t) < len(self.toons):
toon = self.toons[int(t)]
if toon != None and self.pendingToons.count(toon) == 0:
self.__makeToonPending(toon, ts)
else:
self.notify.warning('setMembers toonsPending t=%s not in self.toons %s' % (t, self.toons))
for t in toonsRunning:
toon = self.toons[int(t)]
if toon != None and self.runningToons.count(toon) == 0:
self.__makeToonRun(toon, ts)
activeToons = []
for t in toonsActive:
toon = self.toons[int(t)]
if toon != None and self.activeToons.count(toon) == 0:
activeToons.append(toon)
if len(activeSuits) > 0 or len(activeToons) > 0:
self.__makeAvsActive(activeSuits, activeToons)
if toonGone == 1:
validToons = []
for toon in self.toons:
if toon != None:
validToons.append(toon)
self.toons = validToons
if len(self.activeToons) > 0:
self.__requestAdjustTownBattle()
currStateName = self.localToonFsm.getCurrentState().getName()
if self.toons.count(base.localAvatar):
if oldtoons.count(base.localAvatar) == 0:
self.notify.debug('setMembers() - local toon just joined')
if self.streetBattle == 1:
base.cr.playGame.getPlace().enterZone(self.zoneId)
self.localToonJustJoined = 1
if currStateName != 'HasLocalToon':
self.localToonFsm.request('HasLocalToon')
else:
if oldtoons.count(base.localAvatar):
self.notify.debug('setMembers() - local toon just ran')
if self.levelBattle:
self.unlockLevelViz()
if currStateName != 'NoLocalToon':
self.localToonFsm.request('NoLocalToon')
for suit in self.luredSuits:
suit.loop('lured')
return oldtoons
def adjust(self, timestamp):
if self.__battleCleanedUp:
return
self.notify.debug('adjust(%f) from server' % globalClockDelta.localElapsedTime(timestamp))
self.adjustFsm.request('Adjusting', [globalClockDelta.localElapsedTime(timestamp)])
def setMovie(self, active, toons, suits, id0, tr0, le0, tg0, hp0, ac0, hpb0, kbb0, died0, revive0, id1, tr1, le1, tg1, hp1, ac1, hpb1, kbb1, died1, revive1, id2, tr2, le2, tg2, hp2, ac2, hpb2, kbb2, died2, revive2, id3, tr3, le3, tg3, hp3, ac3, hpb3, kbb3, died3, revive3, sid0, at0, stg0, dm0, sd0, sb0, st0, sid1, at1, stg1, dm1, sd1, sb1, st1, sid2, at2, stg2, dm2, sd2, sb2, st2, sid3, at3, stg3, dm3, sd3, sb3, st3):
if self.__battleCleanedUp:
return
self.notify.debug('setMovie()')
if int(active) == 1:
self.notify.debug('setMovie() - movie is active')
self.movie.genAttackDicts(toons, suits, id0, tr0, le0, tg0, hp0, ac0, hpb0, kbb0, died0, revive0, id1, tr1, le1, tg1, hp1, ac1, hpb1, kbb1, died1, revive1, id2, tr2, le2, tg2, hp2, ac2, hpb2, kbb2, died2, revive2, id3, tr3, le3, tg3, hp3, ac3, hpb3, kbb3, died3, revive3, sid0, at0, stg0, dm0, sd0, sb0, st0, sid1, at1, stg1, dm1, sd1, sb1, st1, sid2, at2, stg2, dm2, sd2, sb2, st2, sid3, at3, stg3, dm3, sd3, sb3, st3)
def setChosenToonAttacks(self, ids, tracks, levels, targets):
if self.__battleCleanedUp:
return
self.notify.debug('setChosenToonAttacks() - (%s), (%s), (%s), (%s)' % (ids,
tracks,
levels,
targets))
toonIndices = []
targetIndices = []
unAttack = 0
localToonInList = 0
for i in xrange(len(ids)):
track = tracks[i]
level = levels[i]
toon = self.findToon(ids[i])
if toon == None or self.activeToons.count(toon) == 0:
self.notify.warning('setChosenToonAttacks() - toon gone or not in battle: %d!' % ids[i])
toonIndices.append(-1)
tracks.append(-1)
levels.append(-1)
targetIndices.append(-1)
continue
if toon == base.localAvatar:
localToonInList = 1
toonIndices.append(self.activeToons.index(toon))
if track == SOS:
targetIndex = -1
elif track == NPCSOS:
targetIndex = targets[i]
elif track == PETSOS:
targetIndex = -1
elif track == PASS:
targetIndex = -1
tracks[i] = PASS_ATTACK
elif attackAffectsGroup(track, level):
targetIndex = -1
elif track == HEAL:
target = self.findToon(targets[i])
if target != None and self.activeToons.count(target) != 0:
targetIndex = self.activeToons.index(target)
else:
targetIndex = -1
elif track == UN_ATTACK:
targetIndex = -1
tracks[i] = NO_ATTACK
if toon == base.localAvatar:
unAttack = 1
self.choseAttackAlready = 0
elif track == NO_ATTACK:
targetIndex = -1
else:
target = self.findSuit(targets[i])
if target != None and self.activeSuits.count(target) != 0:
targetIndex = self.activeSuits.index(target)
else:
targetIndex = -1
targetIndices.append(targetIndex)
for i in xrange(4 - len(ids)):
toonIndices.append(-1)
tracks.append(-1)
levels.append(-1)
targetIndices.append(-1)
self.townBattleAttacks = (toonIndices,
tracks,
levels,
targetIndices)
if self.localToonActive() and localToonInList == 1:
if unAttack == 1 and self.fsm.getCurrentState().getName() == 'WaitForInput':
if self.townBattle.fsm.getCurrentState().getName() != 'Attack':
self.townBattle.setState('Attack')
self.townBattle.updateChosenAttacks(self.townBattleAttacks[0], self.townBattleAttacks[1], self.townBattleAttacks[2], self.townBattleAttacks[3])
return
def setBattleExperience(self, id0, origExp0, earnedExp0, origQuests0, items0, missedItems0, origMerits0, merits0, parts0, id1, origExp1, earnedExp1, origQuests1, items1, missedItems1, origMerits1, merits1, parts1, id2, origExp2, earnedExp2, origQuests2, items2, missedItems2, origMerits2, merits2, parts2, id3, origExp3, earnedExp3, origQuests3, items3, missedItems3, origMerits3, merits3, parts3, deathList, uberList, helpfulToonsList):
if self.__battleCleanedUp:
return
self.movie.genRewardDicts(id0, origExp0, earnedExp0, origQuests0, items0, missedItems0, origMerits0, merits0, parts0, id1, origExp1, earnedExp1, origQuests1, items1, missedItems1, origMerits1, merits1, parts1, id2, origExp2, earnedExp2, origQuests2, items2, missedItems2, origMerits2, merits2, parts2, id3, origExp3, earnedExp3, origQuests3, items3, missedItems3, origMerits3, merits3, parts3, deathList, uberList, helpfulToonsList)
def __listenForUnexpectedExit(self, toon):
self.accept(toon.uniqueName('disable'), self.__handleUnexpectedExit, extraArgs=[toon])
self.accept(toon.uniqueName('died'), self.__handleDied, extraArgs=[toon])
def __handleUnexpectedExit(self, toon):
self.notify.warning('handleUnexpectedExit() - toon: %d' % toon.doId)
self.__removeToon(toon, unexpected=1)
def __handleDied(self, toon):
self.notify.warning('handleDied() - toon: %d' % toon.doId)
if toon == base.localAvatar:
self.d_toonDied(toon.doId)
self.cleanupBattle()
def delayDeleteMembers(self):
membersKeep = []
for t in self.toons:
membersKeep.append(DelayDelete.DelayDelete(t, 'delayDeleteMembers'))
for s in self.suits:
membersKeep.append(DelayDelete.DelayDelete(s, 'delayDeleteMembers'))
self._removeMembersKeep()
self.membersKeep = membersKeep
def _removeMembersKeep(self):
if self.membersKeep:
for delayDelete in self.membersKeep:
delayDelete.destroy()
self.membersKeep = None
return
def __removeSuit(self, suit):
self.notify.debug('__removeSuit(%d)' % suit.doId)
if self.suits.count(suit) != 0:
self.suits.remove(suit)
if self.joiningSuits.count(suit) != 0:
self.joiningSuits.remove(suit)
if self.pendingSuits.count(suit) != 0:
self.pendingSuits.remove(suit)
if self.activeSuits.count(suit) != 0:
self.activeSuits.remove(suit)
self.suitGone = 1
if suit.battleTrap != NO_TRAP:
self.notify.debug('882 calling self.removeTrap, suit=%d' % suit.doId)
self.removeTrap(suit)
suit.battleTrap = NO_TRAP
suit.battleTrapProp = None
self.notify.debug('883 suit.battleTrapProp = None')
suit.battleTrapIsFresh = 0
return
def __removeToon(self, toon, unexpected = 0):
self.notify.debug('__removeToon(%d)' % toon.doId)
self.exitedToons.append(toon)
if self.toons.count(toon) != 0:
self.toons.remove(toon)
if self.joiningToons.count(toon) != 0:
self.clearInterval(self.taskName('to-pending-toon-%d' % toon.doId))
if toon in self.joiningToons:
self.joiningToons.remove(toon)
if self.pendingToons.count(toon) != 0:
self.pendingToons.remove(toon)
if self.activeToons.count(toon) != 0:
self.activeToons.remove(toon)
if self.runningToons.count(toon) != 0:
self.clearInterval(self.taskName('running-%d' % toon.doId), finish=1)
if toon in self.runningToons:
self.runningToons.remove(toon)
self.ignore(toon.uniqueName('disable'))
self.ignore(toon.uniqueName('died'))
self.toonGone = 1
if toon == base.localAvatar:
self.removeLocalToon()
self.__teleportToSafeZone(toon)
return 1
return 0
def removeLocalToon(self):
if self._skippingRewardMovie:
return
if base.cr.playGame.getPlace() != None:
base.cr.playGame.getPlace().setState('walk')
base.localAvatar.earnedExperience = None
self.localToonFsm.request('NoLocalToon')
return
def removeInactiveLocalToon(self, toon):
self.notify.debug('removeInactiveLocalToon(%d)' % toon.doId)
self.exitedToons.append(toon)
if self.toons.count(toon) != 0:
self.toons.remove(toon)
if self.joiningToons.count(toon) != 0:
self.clearInterval(self.taskName('to-pending-toon-%d' % toon.doId), finish=1)
if toon in self.joiningToons:
self.joiningToons.remove(toon)
if self.pendingToons.count(toon) != 0:
self.pendingToons.remove(toon)
self.ignore(toon.uniqueName('disable'))
self.ignore(toon.uniqueName('died'))
base.cr.playGame.getPlace().setState('walk')
self.localToonFsm.request('WaitForServer')
def __createJoinInterval(self, av, destPos, destHpr, name, ts, callback, toon = 0):
joinTrack = Sequence()
joinTrack.append(Func(Emote.globalEmote.disableAll, av, 'dbattlebase, createJoinInterval'))
avPos = av.getPos(self)
avPos = Point3(avPos[0], avPos[1], 0.0)
av.setShadowHeight(0)
plist = self.buildJoinPointList(avPos, destPos, toon)
if len(plist) == 0:
joinTrack.append(Func(av.headsUp, self, destPos))
if toon == 0:
timeToDest = self.calcSuitMoveTime(avPos, destPos)
joinTrack.append(Func(av.loop, 'walk'))
else:
timeToDest = self.calcToonMoveTime(avPos, destPos)
joinTrack.append(Func(av.loop, 'run'))
if timeToDest > BATTLE_SMALL_VALUE:
joinTrack.append(LerpPosInterval(av, timeToDest, destPos, other=self))
totalTime = timeToDest
else:
totalTime = 0
else:
timeToPerimeter = 0
if toon == 0:
timeToPerimeter = self.calcSuitMoveTime(plist[0], avPos)
timePerSegment = 10.0 / BattleBase.suitSpeed
timeToDest = self.calcSuitMoveTime(BattleBase.posA, destPos)
else:
timeToPerimeter = self.calcToonMoveTime(plist[0], avPos)
timePerSegment = 10.0 / BattleBase.toonSpeed
timeToDest = self.calcToonMoveTime(BattleBase.posE, destPos)
totalTime = timeToPerimeter + (len(plist) - 1) * timePerSegment + timeToDest
if totalTime > MAX_JOIN_T:
self.notify.warning('__createJoinInterval() - time: %f' % totalTime)
joinTrack.append(Func(av.headsUp, self, plist[0]))
if toon == 0:
joinTrack.append(Func(av.loop, 'walk'))
else:
joinTrack.append(Func(av.loop, 'run'))
joinTrack.append(LerpPosInterval(av, timeToPerimeter, plist[0], other=self))
for p in plist[1:]:
joinTrack.append(Func(av.headsUp, self, p))
joinTrack.append(LerpPosInterval(av, timePerSegment, p, other=self))
joinTrack.append(Func(av.headsUp, self, destPos))
joinTrack.append(LerpPosInterval(av, timeToDest, destPos, other=self))
joinTrack.append(Func(av.loop, 'neutral'))
joinTrack.append(Func(av.headsUp, self, Point3(0, 0, 0)))
tval = totalTime - ts
if tval < 0:
tval = totalTime
joinTrack.append(Func(Emote.globalEmote.releaseAll, av, 'dbattlebase, createJoinInterval'))
joinTrack.append(Func(callback, av, tval))
if av == base.localAvatar:
camTrack = Sequence()
def setCamFov(fov):
base.camLens.setMinFov(fov/(4./3.))
camTrack.append(Func(setCamFov, self.camFov))
camTrack.append(Func(camera.wrtReparentTo, self))
camTrack.append(Func(camera.setPos, self.camJoinPos))
camTrack.append(Func(camera.setHpr, self.camJoinHpr))
return Parallel(joinTrack, camTrack, name=name)
else:
return Sequence(joinTrack, name=name)
def makeSuitJoin(self, suit, ts):
self.notify.debug('makeSuitJoin(%d)' % suit.doId)
spotIndex = len(self.pendingSuits) + len(self.joiningSuits)
self.joiningSuits.append(suit)
suit.setState('Battle')
openSpot = self.suitPendingPoints[spotIndex]
pos = openSpot[0]
hpr = VBase3(openSpot[1], 0.0, 0.0)
trackName = self.taskName('to-pending-suit-%d' % suit.doId)
track = self.__createJoinInterval(suit, pos, hpr, trackName, ts, self.__handleSuitJoinDone)
track.start(ts)
track.delayDelete = DelayDelete.DelayDelete(suit, 'makeSuitJoin')
self.storeInterval(track, trackName)
if ToontownBattleGlobals.SkipMovie:
track.finish()
def __handleSuitJoinDone(self, suit, ts):
self.notify.debug('suit: %d is now pending' % suit.doId)
if self.hasLocalToon():
self.d_joinDone(base.localAvatar.doId, suit.doId)
def __makeSuitPending(self, suit):
self.notify.debug('__makeSuitPending(%d)' % suit.doId)
self.clearInterval(self.taskName('to-pending-suit-%d' % suit.doId), finish=1)
if self.joiningSuits.count(suit):
self.joiningSuits.remove(suit)
self.pendingSuits.append(suit)
def __teleportToSafeZone(self, toon):
self.notify.debug('teleportToSafeZone(%d)' % toon.doId)
hoodId = ZoneUtil.getCanonicalHoodId(self.zoneId)
if hoodId in base.localAvatar.hoodsVisited:
target_sz = ZoneUtil.getSafeZoneId(self.zoneId)
else:
target_sz = ZoneUtil.getSafeZoneId(base.localAvatar.defaultZone)
base.cr.playGame.getPlace().fsm.request('teleportOut', [{'loader': ZoneUtil.getLoaderName(target_sz),
'where': ZoneUtil.getWhereName(target_sz, 1),
'how': 'teleportIn',
'hoodId': target_sz,
'zoneId': target_sz,
'shardId': None,
'avId': -1,
'battle': 1}])
return
def __makeToonJoin(self, toon, pendingToons, ts):
self.notify.debug('__makeToonJoin(%d)' % toon.doId)
spotIndex = len(pendingToons) + len(self.joiningToons)
self.joiningToons.append(toon)
openSpot = self.toonPendingPoints[spotIndex]
pos = openSpot[0]
hpr = VBase3(openSpot[1], 0.0, 0.0)
trackName = self.taskName('to-pending-toon-%d' % toon.doId)
track = self.__createJoinInterval(toon, pos, hpr, trackName, ts, self.__handleToonJoinDone, toon=1)
if toon != base.localAvatar:
toon.animFSM.request('off')
track.start(ts)
track.delayDelete = DelayDelete.DelayDelete(toon, '__makeToonJoin')
self.storeInterval(track, trackName)
def __handleToonJoinDone(self, toon, ts):
self.notify.debug('__handleToonJoinDone() - pending: %d' % toon.doId)
if self.hasLocalToon():
self.d_joinDone(base.localAvatar.doId, toon.doId)
def __makeToonPending(self, toon, ts):
self.notify.debug('__makeToonPending(%d)' % toon.doId)
self.clearInterval(self.taskName('to-pending-toon-%d' % toon.doId), finish=1)
if self.joiningToons.count(toon):
self.joiningToons.remove(toon)
spotIndex = len(self.pendingToons)
self.pendingToons.append(toon)
openSpot = self.toonPendingPoints[spotIndex]
pos = openSpot[0]
hpr = VBase3(openSpot[1], 0.0, 0.0)
toon.loop('neutral')
toon.setPosHpr(self, pos, hpr)
if base.localAvatar == toon:
currStateName = self.fsm.getCurrentState().getName()
def __makeAvsActive(self, suits, toons):
self.notify.debug('__makeAvsActive()')
self.__stopAdjusting()
for s in suits:
if self.joiningSuits.count(s):
self.notify.warning('suit: %d was in joining list!' % s.doId)
self.joiningSuits.remove(s)
if self.pendingSuits.count(s):
self.pendingSuits.remove(s)
self.notify.debug('__makeAvsActive() - suit: %d' % s.doId)
self.activeSuits.append(s)
if len(self.activeSuits) >= 1:
for suit in self.activeSuits:
suitPos, suitHpr = self.getActorPosHpr(suit)
if self.isSuitLured(suit) == 0:
suit.setPosHpr(self, suitPos, suitHpr)
else:
spos = Point3(suitPos[0], suitPos[1] - MovieUtil.SUIT_LURE_DISTANCE, suitPos[2])
suit.setPosHpr(self, spos, suitHpr)
suit.loop('neutral')
for toon in toons:
if self.joiningToons.count(toon):
self.notify.warning('toon: %d was in joining list!' % toon.doId)
self.joiningToons.remove(toon)
if self.pendingToons.count(toon):
self.pendingToons.remove(toon)
self.notify.debug('__makeAvsActive() - toon: %d' % toon.doId)
if self.activeToons.count(toon) == 0:
self.activeToons.append(toon)
else:
self.notify.warning('makeAvsActive() - toon: %d is active!' % toon.doId)
if len(self.activeToons) >= 1:
for toon in self.activeToons:
toonPos, toonHpr = self.getActorPosHpr(toon)
toon.setPosHpr(self, toonPos, toonHpr)
toon.loop('neutral')
if self.fsm.getCurrentState().getName() == 'WaitForInput' and self.localToonActive() and self.localToonJustJoined == 1:
self.notify.debug('makeAvsActive() - local toon just joined')
self.__enterLocalToonWaitForInput()
self.localToonJustJoined = 0
self.startTimer()
def __makeToonRun(self, toon, ts):
self.notify.debug('__makeToonRun(%d)' % toon.doId)
if self.activeToons.count(toon):
self.activeToons.remove(toon)
self.runningToons.append(toon)
self.toonGone = 1
self.__stopTimer()
if self.localToonRunning():
self.townBattle.setState('Off')
runMTrack = MovieUtil.getToonTeleportOutInterval(toon)
runName = self.taskName('running-%d' % toon.doId)
self.notify.debug('duration: %f' % runMTrack.getDuration())
runMTrack.start(ts)
runMTrack.delayDelete = DelayDelete.DelayDelete(toon, '__makeToonRun')
self.storeInterval(runMTrack, runName)
def getToon(self, toonId):
if toonId in self.cr.doId2do:
return self.cr.doId2do[toonId]
else:
self.notify.warning('getToon() - toon: %d not in repository!' % toonId)
return None
return None
def d_toonRequestJoin(self, toonId, pos):
self.notify.debug('network:toonRequestJoin()')
self.sendUpdate('toonRequestJoin', [pos[0], pos[1], pos[2]])
def d_toonRequestRun(self, toonId):
self.notify.debug('network:toonRequestRun()')
self.sendUpdate('toonRequestRun', [])
def d_toonDied(self, toonId):
self.notify.debug('network:toonDied()')
self.sendUpdate('toonDied', [])
def d_faceOffDone(self, toonId):
self.notify.debug('network:faceOffDone()')
self.sendUpdate('faceOffDone', [])
def d_adjustDone(self, toonId):
self.notify.debug('network:adjustDone()')
self.sendUpdate('adjustDone', [])
def d_timeout(self, toonId):
self.notify.debug('network:timeout()')
self.sendUpdate('timeout', [])
def d_movieDone(self, toonId):
self.notify.debug('network:movieDone()')
self.sendUpdate('movieDone', [])
def d_rewardDone(self, toonId):
self.notify.debug('network:rewardDone()')
self.sendUpdate('rewardDone', [])
def d_joinDone(self, toonId, avId):
self.notify.debug('network:joinDone(%d)' % avId)
self.sendUpdate('joinDone', [avId])
def d_requestAttack(self, toonId, track, level, av):
self.notify.debug('network:requestAttack(%d, %d, %d)' % (track, level, av))
self.sendUpdate('requestAttack', [track, level, av])
def d_requestPetProxy(self, toonId, av):
self.notify.debug('network:requestPetProxy(%s)' % av)
self.sendUpdate('requestPetProxy', [av])
def enterOff(self, ts = 0):
self.localToonFsm.requestFinalState()
return None
def exitOff(self):
return None
def enterFaceOff(self, ts = 0):
return None
def exitFaceOff(self):
return None
def enterWaitForJoin(self, ts = 0):
self.notify.debug('enterWaitForJoin()')
return None
def exitWaitForJoin(self):
return None
def __enterLocalToonWaitForInput(self):
self.notify.debug('enterLocalToonWaitForInput()')
camera.setPosHpr(self.camPos, self.camHpr)
base.camLens.setMinFov(self.camMenuFov/(4./3.))
NametagGlobals.setMasterArrowsOn(0)
self.townBattle.setState('Attack')
self.accept(self.localToonBattleEvent, self.__handleLocalToonBattleEvent)
def startTimer(self, ts = 0):
self.notify.debug('startTimer()')
if ts >= CLIENT_INPUT_TIMEOUT:
self.notify.warning('startTimer() - ts: %f timeout: %f' % (ts, CLIENT_INPUT_TIMEOUT))
self.__timedOut()
return
self.timer.startCallback(CLIENT_INPUT_TIMEOUT - ts, self.__timedOut)
timeTask = Task.loop(Task(self.__countdown), Task.pause(0.2))
taskMgr.add(timeTask, self.timerCountdownTaskName)
def __stopTimer(self):
self.notify.debug('__stopTimer()')
self.timer.stop()
taskMgr.remove(self.timerCountdownTaskName)
def __countdown(self, task):
if hasattr(self.townBattle, 'timer'):
self.townBattle.updateTimer(int(self.timer.getT()))
else:
self.notify.warning('__countdown has tried to update a timer that has been deleted. Stopping timer')
self.__stopTimer()
return Task.done
def enterWaitForInput(self, ts = 0):
prop = self.getInteractiveProp()
if prop:
prop.gotoBattleCheer()
self.choseAttackAlready = 0
if self.localToonActive():
self.__enterLocalToonWaitForInput()
self.startTimer(ts)
if self.needAdjustTownBattle == 1:
self.__adjustTownBattle()
return None
def exitWaitForInput(self):
self.notify.debug('exitWaitForInput()')
if self.localToonActive():
self.townBattle.setState('Off')
base.camLens.setMinFov(self.camFov/(4./3.))
self.ignore(self.localToonBattleEvent)
self.__stopTimer()
return None
def __handleLocalToonBattleEvent(self, response):
mode = response['mode']
noAttack = 0
if mode == 'Attack':
self.notify.debug('got an attack')
track = response['track']
level = response['level']
target = response['target']
targetId = target
if track == HEAL and not levelAffectsGroup(HEAL, level):
if target >= 0 and target < len(self.activeToons):
targetId = self.activeToons[target].doId
else:
self.notify.warning('invalid toon target: %d' % target)
track = -1
level = -1
targetId = -1
elif track == HEAL and len(self.activeToons) == 1:
self.notify.warning('invalid group target for heal')
track = -1
level = -1
elif not attackAffectsGroup(track, level):
if target >= 0 and target < len(self.activeSuits):
targetId = self.activeSuits[target].doId
else:
target = -1
if len(self.luredSuits) > 0:
if track == TRAP or track == LURE and not levelAffectsGroup(LURE, level):
if target != -1:
suit = self.findSuit(targetId)
if self.luredSuits.count(suit) != 0:
self.notify.warning('Suit: %d was lured!' % targetId)
track = -1
level = -1
targetId = -1
elif track == LURE:
if levelAffectsGroup(LURE, level) and len(self.activeSuits) == len(self.luredSuits):
self.notify.warning('All suits are lured!')
track = -1
level = -1
targetId = -1
if track == TRAP:
if target != -1:
if attackAffectsGroup(track, level):
pass
else:
suit = self.findSuit(targetId)
if suit.battleTrap != NO_TRAP:
self.notify.warning('Suit: %d was already trapped!' % targetId)
track = -1
level = -1
targetId = -1
self.d_requestAttack(base.localAvatar.doId, track, level, targetId)
elif mode == 'Run':
self.notify.debug('got a run')
self.d_toonRequestRun(base.localAvatar.doId)
elif mode == 'SOS':
targetId = response['id']
self.notify.debug('got an SOS for friend: %d' % targetId)
self.d_requestAttack(base.localAvatar.doId, SOS, -1, targetId)
elif mode == 'NPCSOS':
targetId = response['id']
self.notify.debug('got an NPCSOS for friend: %d' % targetId)
self.d_requestAttack(base.localAvatar.doId, NPCSOS, -1, targetId)
elif mode == 'PETSOS':
targetId = response['id']
trickId = response['trickId']
self.notify.debug('got an PETSOS for pet: %d' % targetId)
self.d_requestAttack(base.localAvatar.doId, PETSOS, trickId, targetId)
elif mode == 'PETSOSINFO':
petProxyId = response['id']
self.notify.debug('got a PETSOSINFO for pet: %d' % petProxyId)
if petProxyId in base.cr.doId2do:
self.notify.debug('pet: %d was already in the repository' % petProxyId)
proxyGenerateMessage = 'petProxy-%d-generated' % petProxyId
messenger.send(proxyGenerateMessage)
else:
self.d_requestPetProxy(base.localAvatar.doId, petProxyId)
noAttack = 1
elif mode == 'Pass':
targetId = response['id']
self.notify.debug('got a Pass')
self.d_requestAttack(base.localAvatar.doId, PASS, -1, -1)
elif mode == 'UnAttack':
self.d_requestAttack(base.localAvatar.doId, UN_ATTACK, -1, -1)
noAttack = 1
elif mode == 'Fire':
target = response['target']
targetId = self.activeSuits[target].doId
self.d_requestAttack(base.localAvatar.doId, FIRE, -1, targetId)
else:
self.notify.warning('unknown battle response')
return
if noAttack == 1:
self.choseAttackAlready = 0
else:
self.choseAttackAlready = 1
def __timedOut(self):
if self.choseAttackAlready == 1:
return
self.notify.debug('WaitForInput timed out')
if self.localToonActive():
self.notify.debug('battle timed out')
self.d_timeout(base.localAvatar.doId)
def enterMakeMovie(self, ts = 0):
self.notify.debug('enterMakeMovie()')
return None
def exitMakeMovie(self):
return None
def enterPlayMovie(self, ts):
self.notify.debug('enterPlayMovie()')
self.delayDeleteMembers()
if self.hasLocalToon():
NametagGlobals.setMasterArrowsOn(0)
if ToontownBattleGlobals.SkipMovie:
self.movie.play(ts, self.__handleMovieDone)
self.movie.finish()
else:
self.movie.play(ts, self.__handleMovieDone)
return None
def __handleMovieDone(self):
self.notify.debug('__handleMovieDone()')
if self.hasLocalToon():
self.d_movieDone(base.localAvatar.doId)
self.movie.reset()
def exitPlayMovie(self):
self.notify.debug('exitPlayMovie()')
self.movie.reset(finish=1)
self._removeMembersKeep()
self.townBattleAttacks = ([-1,
-1,
-1,
-1],
[-1,
-1,
-1,
-1],
[-1,
-1,
-1,
-1],
[0,
0,
0,
0])
return None
def hasLocalToon(self):
return self.toons.count(base.localAvatar) > 0
def localToonPendingOrActive(self):
return self.pendingToons.count(base.localAvatar) > 0 or self.activeToons.count(base.localAvatar) > 0
def localToonActive(self):
return self.activeToons.count(base.localAvatar) > 0
def localToonActiveOrRunning(self):
return self.activeToons.count(base.localAvatar) > 0 or self.runningToons.count(base.localAvatar) > 0
def localToonRunning(self):
return self.runningToons.count(base.localAvatar) > 0
def enterHasLocalToon(self):
self.notify.debug('enterHasLocalToon()')
if base.cr.playGame.getPlace() != None:
base.cr.playGame.getPlace().setState('battle', self.localToonBattleEvent)
if localAvatar and hasattr(localAvatar, 'inventory') and localAvatar.inventory:
prop = self.getInteractiveProp()
if prop:
localAvatar.inventory.setInteractivePropTrackBonus(prop.BattleTrack)
camera.wrtReparentTo(self)
base.camLens.setMinFov(self.camFov/(4./3.))
return
def exitHasLocalToon(self):
self.ignore(self.localToonBattleEvent)
self.__stopTimer()
if localAvatar and hasattr(localAvatar, 'inventory') and localAvatar.inventory:
localAvatar.inventory.setInteractivePropTrackBonus(-1)
stateName = None
place = base.cr.playGame.getPlace()
if place:
stateName = place.fsm.getCurrentState().getName()
if stateName == 'died':
self.movie.reset()
camera.reparentTo(render)
camera.setPosHpr(localAvatar, 5.2, 5.45, localAvatar.getHeight() * 0.66, 131.5, 3.6, 0)
else:
camera.wrtReparentTo(base.localAvatar)
messenger.send('localToonLeftBattle')
base.camLens.setMinFov(settings['fov']/(4./3.))
return
def enterNoLocalToon(self):
self.notify.debug('enterNoLocalToon()')
return None
def exitNoLocalToon(self):
return None
def setSkippingRewardMovie(self):
self._skippingRewardMovie = True
def enterWaitForServer(self):
self.notify.debug('enterWaitForServer()')
return None
def exitWaitForServer(self):
return None
def createAdjustInterval(self, av, destPos, destHpr, toon = 0, run = 0):
if run == 1:
adjustTime = self.calcToonMoveTime(destPos, av.getPos(self))
else:
adjustTime = self.calcSuitMoveTime(destPos, av.getPos(self))
self.notify.debug('creating adjust interval for: %d' % av.doId)
adjustTrack = Sequence()
if run == 1:
adjustTrack.append(Func(av.loop, 'run'))
else:
adjustTrack.append(Func(av.loop, 'walk'))
adjustTrack.append(Func(av.headsUp, self, destPos))
adjustTrack.append(LerpPosInterval(av, adjustTime, destPos, other=self))
adjustTrack.append(Func(av.setHpr, self, destHpr))
adjustTrack.append(Func(av.loop, 'neutral'))
return adjustTrack
def __adjust(self, ts, callback):
self.notify.debug('__adjust(%f)' % ts)
adjustTrack = Parallel()
if len(self.pendingSuits) > 0 or self.suitGone == 1:
self.suitGone = 0
numSuits = len(self.pendingSuits) + len(self.activeSuits) - 1
index = 0
for suit in self.activeSuits:
point = self.suitPoints[numSuits][index]
pos = suit.getPos(self)
destPos = point[0]
if self.isSuitLured(suit) == 1:
destPos = Point3(destPos[0], destPos[1] - MovieUtil.SUIT_LURE_DISTANCE, destPos[2])
if pos != destPos:
destHpr = VBase3(point[1], 0.0, 0.0)
adjustTrack.append(self.createAdjustInterval(suit, destPos, destHpr))
index += 1
for suit in self.pendingSuits:
point = self.suitPoints[numSuits][index]
destPos = point[0]
destHpr = VBase3(point[1], 0.0, 0.0)
adjustTrack.append(self.createAdjustInterval(suit, destPos, destHpr))
index += 1
if len(self.pendingToons) > 0 or self.toonGone == 1:
self.toonGone = 0
numToons = len(self.pendingToons) + len(self.activeToons) - 1
index = 0
for toon in self.activeToons:
point = self.toonPoints[numToons][index]
pos = toon.getPos(self)
destPos = point[0]
if pos != destPos:
destHpr = VBase3(point[1], 0.0, 0.0)
adjustTrack.append(self.createAdjustInterval(toon, destPos, destHpr))
index += 1
for toon in self.pendingToons:
point = self.toonPoints[numToons][index]
destPos = point[0]
destHpr = VBase3(point[1], 0.0, 0.0)
adjustTrack.append(self.createAdjustInterval(toon, destPos, destHpr))
index += 1
if len(adjustTrack) > 0:
self.notify.debug('creating adjust multitrack')
e = Func(self.__handleAdjustDone)
track = Sequence(adjustTrack, e, name=self.adjustName)
self.storeInterval(track, self.adjustName)
track.start(ts)
if ToontownBattleGlobals.SkipMovie:
track.finish()
else:
self.notify.warning('adjust() - nobody needed adjusting')
self.__adjustDone()
def __handleAdjustDone(self):
self.notify.debug('__handleAdjustDone() - client adjust finished')
self.clearInterval(self.adjustName)
self.__adjustDone()
def __stopAdjusting(self):
self.notify.debug('__stopAdjusting()')
self.clearInterval(self.adjustName)
if self.adjustFsm.getCurrentState().getName() == 'Adjusting':
self.adjustFsm.request('NotAdjusting')
def __requestAdjustTownBattle(self):
self.notify.debug('__requestAdjustTownBattle() curstate = %s' % self.fsm.getCurrentState().getName())
if self.fsm.getCurrentState().getName() == 'WaitForInput':
self.__adjustTownBattle()
else:
self.needAdjustTownBattle = 1
def __adjustTownBattle(self):
self.notify.debug('__adjustTownBattle()')
if self.localToonActive() and len(self.activeSuits) > 0:
self.notify.debug('__adjustTownBattle() - adjusting town battle')
luredSuits = []
for suit in self.luredSuits:
if suit not in self.activeSuits:
self.notify.error('lured suit not in self.activeSuits')
luredSuits.append(self.activeSuits.index(suit))
trappedSuits = []
for suit in self.activeSuits:
if suit.battleTrap != NO_TRAP:
trappedSuits.append(self.activeSuits.index(suit))
self.townBattle.adjustCogsAndToons(self.activeSuits, luredSuits, trappedSuits, self.activeToons)
if hasattr(self, 'townBattleAttacks'):
self.townBattle.updateChosenAttacks(self.townBattleAttacks[0], self.townBattleAttacks[1], self.townBattleAttacks[2], self.townBattleAttacks[3])
self.needAdjustTownBattle = 0
def __adjustDone(self):
self.notify.debug('__adjustDone()')
if self.hasLocalToon():
self.d_adjustDone(base.localAvatar.doId)
self.adjustFsm.request('NotAdjusting')
def enterAdjusting(self, ts):
self.notify.debug('enterAdjusting()')
if self.localToonActive():
self.__stopTimer()
self.delayDeleteMembers()
self.__adjust(ts, self.__handleAdjustDone)
return None
def exitAdjusting(self):
self.notify.debug('exitAdjusting()')
self.finishInterval(self.adjustName)
self._removeMembersKeep()
currStateName = self.fsm.getCurrentState().getName()
if currStateName == 'WaitForInput' and self.localToonActive():
self.startTimer()
return None
def enterNotAdjusting(self):
self.notify.debug('enterNotAdjusting()')
return None
def exitNotAdjusting(self):
return None
def visualize(self):
try:
self.isVisualized
except:
self.isVisualized = 0
if self.isVisualized:
self.vis.removeNode()
del self.vis
self.detachNode()
self.isVisualized = 0
else:
lsegs = LineSegs()
lsegs.setColor(0.5, 0.5, 1, 1)
lsegs.moveTo(0, 0, 0)
for p in BattleBase.allPoints:
lsegs.drawTo(p[0], p[1], p[2])
p = BattleBase.allPoints[0]
lsegs.drawTo(p[0], p[1], p[2])
self.vis = self.attachNewNode(lsegs.create())
self.reparentTo(render)
self.isVisualized = 1
def setupCollisions(self, name):
self.lockout = CollisionTube(0, 0, 0, 0, 0, 9, 9)
lockoutNode = CollisionNode(name)
lockoutNode.addSolid(self.lockout)
lockoutNode.setCollideMask(ToontownGlobals.WallBitmask)
self.lockoutNodePath = self.attachNewNode(lockoutNode)
self.lockoutNodePath.detachNode()
def removeCollisionData(self):
del self.lockout
self.lockoutNodePath.removeNode()
del self.lockoutNodePath
def enableCollision(self):
self.lockoutNodePath.reparentTo(self)
if len(self.toons) < 4:
self.accept(self.getCollisionName(), self.__handleLocalToonCollision)
def __handleLocalToonCollision(self, collEntry):
self.notify.debug('localToonCollision')
if self.fsm.getCurrentState().getName() == 'Off':
self.notify.debug('ignoring collision in Off state')
return
if not base.localAvatar.wantBattles:
return
if self._skippingRewardMovie:
return
base.cr.playGame.getPlace().setState('WaitForBattle')
toon = base.localAvatar
self.d_toonRequestJoin(toon.doId, toon.getPos(self))
base.localAvatar.preBattleHpr = base.localAvatar.getHpr(render)
self.localToonFsm.request('WaitForServer')
self.onWaitingForJoin()
def onWaitingForJoin(self):
pass
def denyLocalToonJoin(self):
self.notify.debug('denyLocalToonJoin()')
place = self.cr.playGame.getPlace()
if place.fsm.getCurrentState().getName() == 'WaitForBattle':
place.setState('walk')
self.localToonFsm.request('NoLocalToon')
def disableCollision(self):
self.ignore(self.getCollisionName())
self.lockoutNodePath.detachNode()
def openBattleCollision(self):
if not self.hasLocalToon():
self.enableCollision()
def closeBattleCollision(self):
self.ignore(self.getCollisionName())
def getCollisionName(self):
return 'enter' + self.lockoutNodePath.getName()
def setFireCount(self, amount):
self.fireCount = amount
def getFireCount(self):
return self.fireCount