1537 lines
61 KiB
Python
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
|