oldschool-toontown/toontown/estate/DistributedCannon.py

1590 lines
61 KiB
Python
Raw Normal View History

from panda3d.core import *
2019-11-02 17:27:54 -05:00
from toontown.toonbase.ToonBaseGlobal import *
from toontown.toonbase import ToontownGlobals
from direct.distributed.ClockDelta import *
from direct.interval.IntervalGlobal import *
from direct.fsm import ClassicFSM, State
from direct.fsm import State
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import ToontownTimer
from direct.task.Task import Task
from toontown.minigame import Trajectory
import math
from toontown.toon import ToonHead
from toontown.effects import Splash
from toontown.effects import DustCloud
from toontown.minigame import CannonGameGlobals
from . import CannonGlobals
2019-11-02 17:27:54 -05:00
from direct.gui.DirectGui import *
from panda3d.core import *
2019-11-02 17:27:54 -05:00
from toontown.toonbase import TTLocalizer
from direct.distributed import DistributedObject
from toontown.effects import Wake
from direct.controls.ControlManager import CollisionHandlerRayStart
LAND_TIME = 2
WORLD_SCALE = 2.0
GROUND_SCALE = 1.4 * WORLD_SCALE
CANNON_SCALE = 1.0
FAR_PLANE_DIST = 600 * WORLD_SCALE
GROUND_PLANE_MIN = -15
CANNON_Y = -int(CannonGameGlobals.TowerYRange / 2 * 1.3)
CANNON_X_SPACING = 12
CANNON_Z = 20
CANNON_ROTATION_MIN = -55
CANNON_ROTATION_MAX = 50
CANNON_ROTATION_VEL = 15.0
CANNON_ANGLE_MIN = 15
CANNON_ANGLE_MAX = 85
CANNON_ANGLE_VEL = 15.0
CANNON_MOVE_UPDATE_FREQ = 0.5
CAMERA_PULLBACK_MIN = 20
CAMERA_PULLBACK_MAX = 40
MAX_LOOKAT_OFFSET = 80
TOON_TOWER_THRESHOLD = 150
SHADOW_Z_OFFSET = 0.5
TOWER_HEIGHT = 43.85
TOWER_RADIUS = 10.5
BUCKET_HEIGHT = 36
TOWER_Y_RANGE = CannonGameGlobals.TowerYRange
TOWER_X_RANGE = int(TOWER_Y_RANGE / 2.0)
INITIAL_VELOCITY = 80.0
WHISTLE_SPEED = INITIAL_VELOCITY * 0.35
class DistributedCannon(DistributedObject.DistributedObject):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCannon')
font = ToontownGlobals.getToonFont()
LOCAL_CANNON_MOVE_TASK = 'localCannonMoveTask'
REWARD_COUNTDOWN_TASK = 'cannonGameRewardCountdown'
HIT_GROUND = 0
HIT_TOWER = 1
HIT_WATER = 2
FIRE_KEY = 'control'
UP_KEY = 'arrow_up'
DOWN_KEY = 'arrow_down'
LEFT_KEY = 'arrow_left'
RIGHT_KEY = 'arrow_right'
BUMPER_KEY = 'delete'
BUMPER_KEY2 = 'insert'
INTRO_TASK_NAME = 'CannonGameIntro'
INTRO_TASK_NAME_CAMERA_LERP = 'CannonGameIntroCamera'
def __init__(self, cr):
DistributedObject.DistributedObject.__init__(self, cr)
self.avId = 0
self.av = None
self.localToonShooting = 0
self.nodePath = None
self.collSphere = None
self.collNode = None
self.collNodePath = None
self.madeGui = 0
self.gui = None
self.cannonLocation = None
self.cannonPosition = None
self.cannon = None
self.toonModel = None
self.shadowNode = None
self.toonHead = None
self.toonScale = None
self.estateId = None
self.targetId = None
self.splash = None
self.dustCloud = None
self.model_Created = 0
self.lastWakeTime = 0
self.leftPressed = 0
self.rightPressed = 0
self.upPressed = 0
self.downPressed = 0
self.hitBumper = 0
self.hitTarget = 0
self.lastPos = Vec3(0, 0, 0)
self.lastVel = Vec3(0, 0, 0)
self.vel = Vec3(0, 0, 0)
self.landingPos = Vec3(0, 0, 0)
self.t = 0
self.lastT = 0
self.deltaT = 0
self.hitTrack = None
self.cTrav = None
self.cRay = None
self.cRayNode = None
self.cRayNodePath = None
self.lifter = None
self.flyColNode = None
self.flyColNodePath = None
self.bumperCol = None
self.cannonMoving = 0
self.inWater = 0
self.localAvId = base.localAvatar.doId
self.nextState = None
self.nextKey = None
self.cannonsActive = 0
self.codeFSM = ClassicFSM.ClassicFSM('CannonCode', [State.State('init', self.enterInit, self.exitInit, ['u1', 'init']),
State.State('u1', self.enteru1, self.exitu1, ['u2', 'init']),
State.State('u2', self.enteru2, self.exitu2, ['d3', 'init']),
State.State('d3', self.enterd3, self.exitd3, ['d4', 'init']),
State.State('d4', self.enterd4, self.exitd4, ['l5', 'init']),
State.State('l5', self.enterl5, self.exitl5, ['r6', 'init']),
State.State('r6', self.enterr6, self.exitr6, ['l7', 'init']),
State.State('l7', self.enterl7, self.exitl7, ['r8', 'init']),
State.State('r8', self.enterr8, self.exitr8, ['acceptCode', 'init']),
State.State('acceptCode', self.enterAcceptCode, self.exitAcceptCode, ['init', 'final']),
State.State('final', self.enterFinal, self.exitFinal, [])], 'init', 'final')
self.codeFSM.enterInitialState()
self.curPinballScore = 0
self.curPinballMultiplier = 1
return
def disable(self):
self.__unmakeGui()
taskMgr.remove(self.taskNameFireCannon)
taskMgr.remove(self.taskNameShoot)
taskMgr.remove(self.taskNameFly)
taskMgr.remove(self.taskNameSmoke)
self.ignoreAll()
self.setMovie(CannonGlobals.CANNON_MOVIE_CLEAR, 0)
self.nodePath.detachNode()
if self.hitTrack:
self.hitTrack.finish()
del self.hitTrack
self.hitTrack = None
DistributedObject.DistributedObject.disable(self)
return
def __unmakeGui(self):
if not self.madeGui:
return
self.aimPad.destroy()
del self.aimPad
del self.fireButton
del self.upButton
del self.downButton
del self.leftButton
del self.rightButton
self.madeGui = 0
def generateInit(self):
DistributedObject.DistributedObject.generateInit(self)
self.taskNameFireCannon = self.taskName('fireCannon')
self.taskNameShoot = self.taskName('shootTask')
self.taskNameSmoke = self.taskName('smokeTask')
self.taskNameFly = self.taskName('flyTask')
self.nodePath = NodePath(self.uniqueName('Cannon'))
self.load()
self.activateCannons()
self.listenForCode()
def listenForCode(self):
self.accept(self.UP_KEY + '-up', self.__upKeyCode)
self.accept(self.DOWN_KEY + '-up', self.__downKeyCode)
self.accept(self.LEFT_KEY + '-up', self.__leftKeyCode)
self.accept(self.RIGHT_KEY + '-up', self.__rightKeyCode)
def ignoreCode(self):
self.ignore(self.UP_KEY + '-up')
self.ignore(self.DOWN_KEY + '-up')
self.ignore(self.LEFT_KEY + '-up')
self.ignore(self.RIGHT_KEY + '-up')
def activateCannons(self):
if not self.cannonsActive:
self.cannonsActive = 1
self.onstage()
self.nodePath.reparentTo(self.getParentNodePath())
self.accept(self.uniqueName('enterCannonSphere'), self.__handleEnterSphere)
def deActivateCannons(self):
if self.cannonsActive:
self.cannonsActive = 0
self.offstage()
self.nodePath.reparentTo(hidden)
self.ignore(self.uniqueName('enterCannonSphere'))
def delete(self):
self.offstage()
self.unload()
DistributedObject.DistributedObject.delete(self)
def __handleEnterSphere(self, collEntry):
self.notify.debug('collEntry: %s' % collEntry)
base.cr.playGame.getPlace().setState('fishing')
self.d_requestEnter()
def d_requestEnter(self):
self.sendUpdate('requestEnter', [])
def requestExit(self):
self.notify.debug('requestExit')
base.localAvatar.reparentTo(render)
base.cr.playGame.getPlace().setState('walk')
def getSphereRadius(self):
return 1.5
def getParentNodePath(self):
return base.cr.playGame.hood.loader.geom
def setEstateId(self, estateId):
self.estateId = estateId
def setTargetId(self, targetId):
self.notify.debug('setTargetId %d' % targetId)
self.targetId = targetId
def setPosHpr(self, x, y, z, h, p, r):
self.nodePath.setPosHpr(x, y, z, h, p, r)
def setMovie(self, mode, avId):
wasLocalToon = self.localToonShooting
self.avId = avId
if mode == CannonGlobals.CANNON_MOVIE_CLEAR:
self.listenForCode()
self.setLanded()
elif mode == CannonGlobals.CANNON_MOVIE_LANDED:
self.setLanded()
elif mode == CannonGlobals.CANNON_MOVIE_FORCE_EXIT:
self.exitCannon(self.avId)
self.setLanded()
elif mode == CannonGlobals.CANNON_MOVIE_LOAD:
self.ignoreCode()
if self.avId == base.localAvatar.doId:
base.localAvatar.pose('lose', 110)
base.localAvatar.pose('slip-forward', 25)
base.cr.playGame.getPlace().setState('fishing')
base.localAvatar.setTeleportAvailable(0)
base.localAvatar.collisionsOff()
base.setCellsAvailable([base.bottomCells[3], base.bottomCells[4]], 0)
base.setCellsAvailable([base.rightCells[1]], 0)
self.localToonShooting = 1
self.__makeGui()
camera.reparentTo(self.barrel)
camera.setPos(0.5, -2, 2.5)
self.curPinballScore = 0
self.curPinballMultiplier = 1
self.incrementPinballInfo(0, 0)
if self.avId in self.cr.doId2do:
2019-11-02 17:27:54 -05:00
self.av = self.cr.doId2do[self.avId]
self.acceptOnce(self.av.uniqueName('disable'), self.__avatarGone)
self.av.stopSmooth()
self.__createToonModels()
else:
self.notify.warning('Unknown avatar %d in cannon %d' % (self.avId, self.doId))
if wasLocalToon and not self.localToonShooting:
base.setCellsAvailable([base.bottomCells[3], base.bottomCells[4]], 1)
base.setCellsAvailable([base.rightCells[1]], 1)
def __avatarGone(self):
self.setMovie(CannonGlobals.CANNON_MOVIE_CLEAR, 0)
def load(self):
self.cannon = loader.loadModel('phase_4/models/minigames/toon_cannon')
self.shadow = loader.loadModel('phase_3/models/props/drop_shadow')
self.shadowNode = hidden.attachNewNode('dropShadow')
self.shadow.copyTo(self.shadowNode)
self.smoke = loader.loadModel('phase_4/models/props/test_clouds')
self.smoke.setBillboardPointEye()
self.cannon.setScale(CANNON_SCALE)
self.shadowNode.setColor(0, 0, 0, 0.5)
self.shadowNode.setBin('fixed', 0, 1)
self.splash = Splash.Splash(render)
self.dustCloud = DustCloud.DustCloud(render)
self.dustCloud.setBillboardPointEye()
2020-01-14 13:28:52 -06:00
self.sndCannonMove = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_adjust.ogg')
self.sndCannonFire = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.ogg')
self.sndHitGround = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg')
self.sndHitTower = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_hit_tower.ogg')
self.sndHitWater = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_splash.ogg')
self.sndWhizz = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_whizz.ogg')
self.sndWin = base.loader.loadSfx('phase_4/audio/sfx/MG_win.ogg')
self.sndHitHouse = base.loader.loadSfx('phase_5/audio/sfx/AA_drop_sandbag.ogg')
2019-11-02 17:27:54 -05:00
self.collSphere = CollisionSphere(0, 0, 0, self.getSphereRadius())
self.collSphere.setTangible(1)
self.collNode = CollisionNode(self.uniqueName('CannonSphere'))
self.collNode.setCollideMask(ToontownGlobals.WallBitmask)
self.collNode.addSolid(self.collSphere)
self.collNodePath = self.nodePath.attachNewNode(self.collNode)
self.loadCannonBumper()
def setupMovingShadow(self):
self.cTrav = base.cTrav
self.cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0)
self.cRayNode = CollisionNode('cRayNode')
self.cRayNode.addSolid(self.cRay)
self.cRayNodePath = self.shadowNode.attachNewNode(self.cRayNode)
self.cRayNodePath.hide()
self.cRayBitMask = ToontownGlobals.FloorBitmask
self.cRayNode.setFromCollideMask(self.cRayBitMask)
self.cRayNode.setIntoCollideMask(BitMask32.allOff())
self.lifter = CollisionHandlerFloor()
self.lifter.setOffset(ToontownGlobals.FloorOffset)
self.lifter.setReach(20.0)
self.enableRaycast(1)
def enableRaycast(self, enable = 1):
if not self.cTrav or not hasattr(self, 'cRayNode') or not self.cRayNode:
return
self.notify.debug('-------enabling raycast--------')
self.cTrav.removeCollider(self.cRayNodePath)
if enable:
self.cTrav.addCollider(self.cRayNodePath, self.lifter)
def __makeGui(self):
if self.madeGui:
return
guiModel = 'phase_4/models/gui/cannon_game_gui'
cannonGui = loader.loadModel(guiModel)
self.aimPad = DirectFrame(image=cannonGui.find('**/CannonFire_PAD'), relief=None, pos=(0.7, 0, -0.553333), scale=0.8)
cannonGui.removeNode()
self.fireButton = DirectButton(parent=self.aimPad, image=((guiModel, '**/Fire_Btn_UP'), (guiModel, '**/Fire_Btn_DN'), (guiModel, '**/Fire_Btn_RLVR')), relief=None, pos=(0.0115741, 0, 0.00505051), scale=1.0, command=self.__firePressed)
self.upButton = DirectButton(parent=self.aimPad, image=((guiModel, '**/Cannon_Arrow_UP'), (guiModel, '**/Cannon_Arrow_DN'), (guiModel, '**/Cannon_Arrow_RLVR')), relief=None, pos=(0.0115741, 0, 0.221717))
self.downButton = DirectButton(parent=self.aimPad, image=((guiModel, '**/Cannon_Arrow_UP'), (guiModel, '**/Cannon_Arrow_DN'), (guiModel, '**/Cannon_Arrow_RLVR')), relief=None, pos=(0.0136112, 0, -0.210101), image_hpr=(0, 0, 180))
self.leftButton = DirectButton(parent=self.aimPad, image=((guiModel, '**/Cannon_Arrow_UP'), (guiModel, '**/Cannon_Arrow_DN'), (guiModel, '**/Cannon_Arrow_RLVR')), relief=None, pos=(-0.199352, 0, -0.000505269), image_hpr=(0, 0, -90))
self.rightButton = DirectButton(parent=self.aimPad, image=((guiModel, '**/Cannon_Arrow_UP'), (guiModel, '**/Cannon_Arrow_DN'), (guiModel, '**/Cannon_Arrow_RLVR')), relief=None, pos=(0.219167, 0, -0.00101024), image_hpr=(0, 0, 90))
self.aimPad.setColor(1, 1, 1, 0.9)
def bindButton(button, upHandler, downHandler):
button.bind(DGG.B1PRESS, lambda x, handler = upHandler: handler())
button.bind(DGG.B1RELEASE, lambda x, handler = downHandler: handler())
bindButton(self.upButton, self.__upPressed, self.__upReleased)
bindButton(self.downButton, self.__downPressed, self.__downReleased)
bindButton(self.leftButton, self.__leftPressed, self.__leftReleased)
bindButton(self.rightButton, self.__rightPressed, self.__rightReleased)
self.__enableAimInterface()
self.madeGui = 1
return
def __unmakeGui(self):
self.notify.debug('__unmakeGui')
if not self.madeGui:
return
self.__disableAimInterface()
self.upButton.unbind(DGG.B1PRESS)
self.upButton.unbind(DGG.B1RELEASE)
self.downButton.unbind(DGG.B1PRESS)
self.downButton.unbind(DGG.B1RELEASE)
self.leftButton.unbind(DGG.B1PRESS)
self.leftButton.unbind(DGG.B1RELEASE)
self.rightButton.unbind(DGG.B1PRESS)
self.rightButton.unbind(DGG.B1RELEASE)
self.aimPad.destroy()
del self.aimPad
del self.fireButton
del self.upButton
del self.downButton
del self.leftButton
del self.rightButton
self.madeGui = 0
def unload(self):
self.ignoreCode()
del self.codeFSM
if self.cannon:
self.cannon.removeNode()
self.cannon = None
if self.shadowNode != None:
self.shadowNode.removeNode()
del self.shadowNode
if self.splash != None:
self.splash.destroy()
del self.splash
if self.dustCloud != None:
self.dustCloud.destroy()
del self.dustCloud
del self.sndCannonMove
del self.sndCannonFire
del self.sndHitHouse
del self.sndHitGround
del self.sndHitTower
del self.sndHitWater
del self.sndWhizz
del self.sndWin
self.bumperCol = None
taskMgr.remove(self.uniqueName('BumperON'))
if self.av:
self.__resetToon(self.av)
self.av.loop('neutral')
self.av.setPlayRate(1.0, 'run')
if hasattr(self.av, 'nametag'):
self.av.nametag.removeNametag(self.toonHead.tag)
if self.toonHead != None:
self.toonHead.stopBlink()
self.toonHead.stopLookAroundNow()
self.toonHead.delete()
self.toonHead = None
if self.toonModel != None:
self.toonModel.removeNode()
self.toonModel = None
del self.toonScale
del self.cannonLocation
del self.cRay
del self.cRayNode
if self.cRayNodePath:
self.cRayNodePath.removeNode()
del self.cRayNodePath
del self.lifter
self.enableRaycast(0)
return
def onstage(self):
self.__createCannon()
self.cannon.reparentTo(self.nodePath)
self.splash.reparentTo(render)
self.dustCloud.reparentTo(render)
def offstage(self):
if self.cannon:
self.cannon.reparentTo(hidden)
if self.splash:
self.splash.reparentTo(hidden)
self.splash.stop()
if self.dustCloud:
self.dustCloud.reparentTo(hidden)
self.dustCloud.stop()
def __createCannon(self):
self.barrel = self.cannon.find('**/cannon')
self.cannonLocation = Point3(0, 0, 0.025)
self.cannonPosition = [0, CANNON_ANGLE_MIN]
self.cannon.setPos(self.cannonLocation)
self.__updateCannonPosition(self.avId)
def __createToonModels(self):
self.model_Created = 1
toon = self.av
self.toonScale = toon.getScale()
toon.useLOD(1000)
toonParent = render.attachNewNode('toonOriginChange')
toon.wrtReparentTo(toonParent)
toon.setPosHpr(0, 0, -(toon.getHeight() / 2.0), 0, -90, 0)
self.toonModel = toonParent
self.toonHead = ToonHead.ToonHead()
self.toonHead.setupHead(self.av.style)
self.toonHead.reparentTo(hidden)
tag = NametagFloat3d()
tag.setContents(Nametag.CSpeech | Nametag.CThought)
tag.setBillboardOffset(0)
tag.setAvatar(self.toonHead)
toon.nametag.addNametag(tag)
tagPath = self.toonHead.attachNewNode(tag.upcastToPandaNode())
tagPath.setPos(0, 0, 1)
self.toonHead.tag = tag
self.__loadToonInCannon()
self.av.dropShadow.hide()
self.dropShadow = self.shadowNode.copyTo(hidden)
def __destroyToonModels(self):
if self.av != None:
self.av.dropShadow.show()
if self.dropShadow != None:
self.dropShadow.removeNode()
self.dropShadow = None
self.hitBumper = 0
self.hitTarget = 0
self.angularVel = 0
self.vel = Vec3(0, 0, 0)
self.lastVel = Vec3(0, 0, 0)
self.lastPos = Vec3(0, 0, 0)
self.landingPos = Vec3(0, 0, 0)
self.t = 0
self.lastT = 0
self.deltaT = 0
self.av = None
self.lastWakeTime = 0
self.localToonShooting = 0
if self.toonHead != None:
self.toonHead.reparentTo(hidden)
self.toonHead.stopBlink()
self.toonHead.stopLookAroundNow()
self.toonHead.delete()
self.toonHead = None
if self.toonModel != None:
self.toonModel.removeNode()
self.toonModel = None
self.model_Created = 0
return
def updateCannonPosition(self, avId, zRot, angle):
if avId != self.localAvId:
self.cannonPosition = [zRot, angle]
self.__updateCannonPosition(avId)
def setCannonWillFire(self, avId, fireTime, zRot, angle, timestamp):
self.notify.debug('setCannonWillFire: ' + str(avId) + ': zRot=' + str(zRot) + ', angle=' + str(angle) + ', time=' + str(fireTime))
if not self.model_Created:
self.notify.warning("We walked into the zone mid-flight, so we won't see it")
return
self.cannonPosition[0] = zRot
self.cannonPosition[1] = angle
self.__updateCannonPosition(avId)
task = Task(self.__fireCannonTask)
task.avId = avId
ts = globalClockDelta.localElapsedTime(timestamp)
task.fireTime = fireTime - ts
if task.fireTime < 0.0:
task.fireTime = 0.0
taskMgr.add(task, self.taskNameFireCannon)
def exitCannon(self, avId):
self.__unmakeGui()
if self.avId == avId:
if self.av:
self.__resetToonToCannon(self.av)
def __enableAimInterface(self):
self.aimPad.show()
self.accept(self.FIRE_KEY, self.__fireKeyPressed)
self.accept(self.UP_KEY, self.__upKeyPressed)
self.accept(self.DOWN_KEY, self.__downKeyPressed)
self.accept(self.LEFT_KEY, self.__leftKeyPressed)
self.accept(self.RIGHT_KEY, self.__rightKeyPressed)
self.accept(self.BUMPER_KEY, self.__bumperKeyPressed)
self.accept(self.BUMPER_KEY2, self.__bumperKeyPressed)
self.__spawnLocalCannonMoveTask()
def __disableAimInterface(self):
self.aimPad.hide()
self.ignore(self.FIRE_KEY)
self.ignore(self.UP_KEY)
self.ignore(self.DOWN_KEY)
self.ignore(self.LEFT_KEY)
self.ignore(self.RIGHT_KEY)
self.ignore(self.FIRE_KEY + '-up')
self.ignore(self.UP_KEY + '-up')
self.ignore(self.DOWN_KEY + '-up')
self.ignore(self.LEFT_KEY + '-up')
self.ignore(self.RIGHT_KEY + '-up')
self.__killLocalCannonMoveTask()
def __fireKeyPressed(self):
self.ignore(self.FIRE_KEY)
self.accept(self.FIRE_KEY + '-up', self.__fireKeyReleased)
self.__firePressed()
def __upKeyPressed(self):
self.ignore(self.UP_KEY)
self.accept(self.UP_KEY + '-up', self.__upKeyReleased)
self.__upPressed()
def __downKeyPressed(self):
self.ignore(self.DOWN_KEY)
self.accept(self.DOWN_KEY + '-up', self.__downKeyReleased)
self.__downPressed()
def __leftKeyPressed(self):
self.ignore(self.LEFT_KEY)
self.accept(self.LEFT_KEY + '-up', self.__leftKeyReleased)
self.__leftPressed()
def __rightKeyPressed(self):
self.ignore(self.RIGHT_KEY)
self.accept(self.RIGHT_KEY + '-up', self.__rightKeyReleased)
self.__rightPressed()
def __fireKeyReleased(self):
self.ignore(self.FIRE_KEY + '-up')
self.accept(self.FIRE_KEY, self.__fireKeyPressed)
self.__fireReleased()
def __leftKeyReleased(self):
self.ignore(self.LEFT_KEY + '-up')
self.accept(self.LEFT_KEY, self.__leftKeyPressed)
self.handleCodeKey('left')
self.__leftReleased()
def __rightKeyReleased(self):
self.ignore(self.RIGHT_KEY + '-up')
self.accept(self.RIGHT_KEY, self.__rightKeyPressed)
self.handleCodeKey('right')
self.__rightReleased()
def __upKeyReleased(self):
self.ignore(self.UP_KEY + '-up')
self.accept(self.UP_KEY, self.__upKeyPressed)
self.__upReleased()
def __downKeyReleased(self):
self.ignore(self.DOWN_KEY + '-up')
self.accept(self.DOWN_KEY, self.__downKeyPressed)
self.handleCodeKey('down')
self.__downReleased()
def __upKeyCode(self):
self.handleCodeKey('up')
def __downKeyCode(self):
self.handleCodeKey('down')
def __rightKeyCode(self):
self.handleCodeKey('right')
def __leftKeyCode(self):
self.handleCodeKey('left')
def __firePressed(self):
self.notify.debug('fire pressed')
self.__broadcastLocalCannonPosition()
self.__unmakeGui()
self.sendUpdate('setCannonLit', [self.cannonPosition[0], self.cannonPosition[1]])
def __upPressed(self):
self.notify.debug('up pressed')
self.upPressed = self.__enterControlActive(self.upPressed)
def __downPressed(self):
self.notify.debug('down pressed')
self.downPressed = self.__enterControlActive(self.downPressed)
def __leftPressed(self):
self.notify.debug('left pressed')
self.leftPressed = self.__enterControlActive(self.leftPressed)
def __rightPressed(self):
self.notify.debug('right pressed')
self.rightPressed = self.__enterControlActive(self.rightPressed)
def __upReleased(self):
self.notify.debug('up released')
self.upPressed = self.__exitControlActive(self.upPressed)
def __downReleased(self):
self.notify.debug('down released')
self.downPressed = self.__exitControlActive(self.downPressed)
def __leftReleased(self):
self.notify.debug('left released')
self.leftPressed = self.__exitControlActive(self.leftPressed)
def __rightReleased(self):
self.notify.debug('right released')
self.rightPressed = self.__exitControlActive(self.rightPressed)
def __enterControlActive(self, control):
return control + 1
def __exitControlActive(self, control):
return max(0, control - 1)
def __spawnLocalCannonMoveTask(self):
self.leftPressed = 0
self.rightPressed = 0
self.upPressed = 0
self.downPressed = 0
self.cannonMoving = 0
task = Task(self.__localCannonMoveTask)
task.lastPositionBroadcastTime = 0.0
taskMgr.add(task, self.LOCAL_CANNON_MOVE_TASK)
def __killLocalCannonMoveTask(self):
taskMgr.remove(self.LOCAL_CANNON_MOVE_TASK)
if self.cannonMoving:
self.sndCannonMove.stop()
def __localCannonMoveTask(self, task):
pos = self.cannonPosition
oldRot = pos[0]
oldAng = pos[1]
rotVel = 0
if self.leftPressed:
rotVel += CANNON_ROTATION_VEL
if self.rightPressed:
rotVel -= CANNON_ROTATION_VEL
pos[0] += rotVel * globalClock.getDt()
if pos[0] < CANNON_ROTATION_MIN:
pos[0] = CANNON_ROTATION_MIN
elif pos[0] > CANNON_ROTATION_MAX:
pos[0] = CANNON_ROTATION_MAX
angVel = 0
if self.upPressed:
angVel += CANNON_ANGLE_VEL
if self.downPressed:
angVel -= CANNON_ANGLE_VEL
pos[1] += angVel * globalClock.getDt()
if pos[1] < CANNON_ANGLE_MIN:
pos[1] = CANNON_ANGLE_MIN
elif pos[1] > CANNON_ANGLE_MAX:
pos[1] = CANNON_ANGLE_MAX
if oldRot != pos[0] or oldAng != pos[1]:
if self.cannonMoving == 0:
self.cannonMoving = 1
base.playSfx(self.sndCannonMove, looping=1)
self.__updateCannonPosition(self.localAvId)
if task.time - task.lastPositionBroadcastTime > CANNON_MOVE_UPDATE_FREQ:
task.lastPositionBroadcastTime = task.time
self.__broadcastLocalCannonPosition()
elif self.cannonMoving:
self.cannonMoving = 0
self.sndCannonMove.stop()
self.__broadcastLocalCannonPosition()
print('Cannon Rot:%s Angle:%s' % (pos[0], pos[1]))
2019-11-02 17:27:54 -05:00
return Task.cont
def __broadcastLocalCannonPosition(self):
self.sendUpdate('setCannonPosition', [self.cannonPosition[0], self.cannonPosition[1]])
def __updateCannonPosition(self, avId):
self.cannon.setHpr(self.cannonPosition[0], 0.0, 0.0)
self.barrel.setHpr(0.0, self.cannonPosition[1], 0.0)
maxP = 90
newP = self.barrel.getP()
yScale = 1 - 0.5 * float(newP) / maxP
shadow = self.cannon.find('**/square_drop_shadow')
shadow.setScale(1, yScale, 1)
def __getCameraPositionBehindCannon(self):
return Point3(self.cannonLocationDict[self.localAvId][0], CANNON_Y - 5.0, CANNON_Z + 7)
def __putCameraBehindCannon(self):
camera.setPos(self.__getCameraPositionBehindCannon())
camera.setHpr(0, 0, 0)
def __loadToonInCannon(self):
self.toonModel.reparentTo(hidden)
self.toonHead.startBlink()
self.toonHead.startLookAround()
self.toonHead.reparentTo(self.barrel)
self.toonHead.setPosHpr(0, 6, 0, 0, -45, 0)
sc = self.toonScale
self.toonHead.setScale(render, sc[0], sc[1], sc[2])
self.toonModel.setPos(self.toonHead.getPos(render))
def __toRadians(self, angle):
return angle * 2.0 * math.pi / 360.0
def __toDegrees(self, angle):
return angle * 360.0 / (2.0 * math.pi)
def __calcFlightResults(self, avId, launchTime):
head = self.toonHead
startPos = head.getPos(render)
startHpr = head.getHpr(render)
hpr = self.barrel.getHpr(render)
rotation = self.__toRadians(hpr[0])
angle = self.__toRadians(hpr[1])
horizVel = INITIAL_VELOCITY * math.cos(angle)
xVel = horizVel * -math.sin(rotation)
yVel = horizVel * math.cos(rotation)
zVel = INITIAL_VELOCITY * math.sin(angle)
startVel = Vec3(xVel, yVel, zVel)
trajectory = Trajectory.Trajectory(launchTime, startPos, startVel)
self.trajectory = trajectory
hitTreasures = self.__calcHitTreasures(trajectory)
timeOfImpact, hitWhat = self.__calcToonImpact(trajectory)
return {'startPos': startPos,
'startHpr': startHpr,
'startVel': startVel,
'trajectory': trajectory,
'timeOfImpact': 3 * timeOfImpact,
'hitWhat': hitWhat}
def __fireCannonTask(self, task):
launchTime = task.fireTime
avId = task.avId
self.inWater = 0
if not self.toonHead:
return Task.done
flightResults = self.__calcFlightResults(avId, launchTime)
if not __debug__ or __execWarnings__:
print('EXECWARNING DistributedCannon: %s' % flightResults)
2019-11-02 17:27:54 -05:00
printStack()
for key in flightResults:
exec("%s = flightResults['%s']" % (key, key))
2019-11-02 17:27:54 -05:00
self.notify.debug('start position: ' + str(startPos))
self.notify.debug('start velocity: ' + str(startVel))
self.notify.debug('time of launch: ' + str(launchTime))
self.notify.debug('time of impact: ' + str(timeOfImpact))
self.notify.debug('location of impact: ' + str(trajectory.getPos(timeOfImpact)))
if hitWhat == self.HIT_WATER:
self.notify.debug('toon will land in the water')
elif hitWhat == self.HIT_TOWER:
self.notify.debug('toon will hit the tower')
else:
self.notify.debug('toon will hit the ground')
head = self.toonHead
head.stopBlink()
head.stopLookAroundNow()
head.reparentTo(hidden)
av = self.toonModel
av.reparentTo(render)
print('start Pos%s Hpr%s' % (startPos, startHpr))
2019-11-02 17:27:54 -05:00
av.setPos(startPos)
barrelHpr = self.barrel.getHpr(render)
place = base.cr.playGame.getPlace()
if self.av == base.localAvatar:
place.fsm.request('stopped')
av.setHpr(startHpr)
avatar = self.av
avatar.loop('swim')
avatar.setPosHpr(0, 0, -(avatar.getHeight() / 2.0), 0, 0, 0)
info = {}
info['avId'] = avId
info['trajectory'] = trajectory
info['launchTime'] = launchTime
info['timeOfImpact'] = timeOfImpact
info['hitWhat'] = hitWhat
info['toon'] = self.toonModel
info['hRot'] = self.cannonPosition[0]
info['haveWhistled'] = 0
info['maxCamPullback'] = CAMERA_PULLBACK_MIN
if self.localToonShooting:
camera.reparentTo(self.av)
camera.setP(45.0)
camera.setZ(-10.0)
self.flyColSphere = CollisionSphere(0, 0, self.av.getHeight() / 2.0, 1.0)
self.flyColNode = CollisionNode(self.uniqueName('flySphere'))
self.flyColNode.setCollideMask(ToontownGlobals.WallBitmask | ToontownGlobals.FloorBitmask)
self.flyColNode.addSolid(self.flyColSphere)
self.flyColNodePath = self.av.attachNewNode(self.flyColNode)
self.flyColNodePath.setColor(1, 0, 0, 1)
self.handler = CollisionHandlerEvent()
self.handler.setInPattern(self.uniqueName('cannonHit'))
base.cTrav.addCollider(self.flyColNodePath, self.handler)
self.accept(self.uniqueName('cannonHit'), self.__handleCannonHit)
shootTask = Task(self.__shootTask, self.taskNameShoot)
smokeTask = Task(self.__smokeTask, self.taskNameSmoke)
flyTask = Task(self.__flyTask, self.taskNameFly)
shootTask.info = info
flyTask.info = info
seqTask = Task.sequence(shootTask, smokeTask, flyTask)
if self.av == base.localAvatar:
print('disable controls')
2019-11-02 17:27:54 -05:00
base.localAvatar.disableAvatarControls()
taskMgr.add(seqTask, self.taskName('flyingToon') + '-' + str(avId))
self.acceptOnce(self.uniqueName('stopFlyTask'), self.__stopFlyTask)
return Task.done
def __stopFlyTask(self, avId):
taskMgr.remove(self.taskName('flyingToon') + '-' + str(avId))
def b_setLanded(self):
self.d_setLanded()
def d_setLanded(self):
self.notify.debug('localTOonshooting = %s' % self.localToonShooting)
if self.localToonShooting:
self.sendUpdate('setLanded', [])
def setLanded(self):
self.removeAvFromCannon()
def removeAvFromCannon(self):
place = base.cr.playGame.getPlace()
print('removeAvFromCannon')
2019-11-02 17:27:54 -05:00
self.notify.debug('self.inWater = %s' % self.inWater)
if place:
if not hasattr(place, 'fsm'):
return
placeState = place.fsm.getCurrentState().getName()
print(placeState)
2019-11-02 17:27:54 -05:00
if (self.inWater or place.toonSubmerged) and placeState != 'fishing':
if self.av != None:
self.av.startSmooth()
self.__destroyToonModels()
return
self.inWater = 0
if self.av != None:
self.__stopCollisionHandler(self.av)
self.av.resetLOD()
if self.av == base.localAvatar:
if place and not self.inWater:
place.fsm.request('walk')
self.av.setPlayRate(1.0, 'run')
self.av.nametag.removeNametag(self.toonHead.tag)
if self.av.getParent().getName() == 'toonOriginChange':
self.av.wrtReparentTo(render)
self.__setToonUpright(self.av)
if self.av == base.localAvatar:
self.av.startPosHprBroadcast()
self.av.startSmooth()
self.av.setScale(1, 1, 1)
if self.av == base.localAvatar:
print('enable controls')
2019-11-02 17:27:54 -05:00
base.localAvatar.enableAvatarControls()
self.ignore(self.av.uniqueName('disable'))
self.__destroyToonModels()
return
def __stopCollisionHandler(self, avatar):
if avatar:
avatar.loop('neutral')
if self.flyColNode:
self.flyColNode = None
if avatar == base.localAvatar:
avatar.collisionsOn()
self.flyColSphere = None
if self.flyColNodePath:
base.cTrav.removeCollider(self.flyColNodePath)
self.flyColNodePath.removeNode()
self.flyColNodePath = None
self.handler = None
return
def __handleCannonHit(self, collisionEntry):
if self.av == None or self.flyColNode == None:
return
hitNode = collisionEntry.getIntoNode().getName()
self.notify.debug('hitNode = %s' % hitNode)
self.notify.debug('hitNodePath.getParent = %s' % collisionEntry.getIntoNodePath().getParent())
self.vel = self.trajectory.getVel(self.t)
vel = self.trajectory.getVel(self.t)
vel.normalize()
if self.hitBumper:
vel = self.lastVel * 1
vel.normalize()
self.notify.debug('normalized vel=%s' % vel)
solid = collisionEntry.getInto()
intoNormal = collisionEntry.getSurfaceNormal(collisionEntry.getIntoNodePath())
self.notify.debug('old intoNormal = %s' % intoNormal)
intoNormal = collisionEntry.getSurfaceNormal(render)
self.notify.debug('new intoNormal = %s' % intoNormal)
hitPylonAboveWater = False
hitPylonBelowWater = False
if hitNode in ['pier_pylon_collisions_1', 'pier_pylon_collisions_3']:
if collisionEntry.getSurfacePoint(render)[2] > 0:
hitPylonAboveWater = True
self.notify.debug('hitPylonAboveWater = True')
else:
hitPylonBelowWater = True
self.notify.debug('hitPylonBelowWater = True')
hitNormal = intoNormal
if ( hitNode.find('cSphere') == 0 or
hitNode.find('treasureSphere') == 0 or
hitNode.find('prop') == 0 or
hitNode.find('distAvatarCollNode') == 0 or
hitNode.find('CannonSphere') == 0 or
hitNode.find('plotSphere') == 0 or
hitNode.find('flySphere') == 0 or
hitNode.find('mailboxSphere') == 0 or
hitNode.find('FishingSpotSphere') == 0 or
hitNode == 'gagtree_collision' or
hitNode == 'sign_collision' or
hitNode == 'FlowerSellBox' or
hitPylonBelowWater):
self.notify.debug('--------------hit and ignoring %s' % hitNode)
return
if vel.dot(hitNormal) > 0 and not hitNode == 'collision_roof' and not hitNode == 'collision_fence':
self.notify.debug('--------------hit and ignoring backfacing %s, dot=%s' % (hitNode, vel.dot(hitNormal)))
return
intoNode = collisionEntry.getIntoNodePath()
bumperNodes = ['collision_house',
'collision_fence',
'targetSphere',
'collision_roof',
'collision_cannon_bumper',
'statuaryCol']
cloudBumpers = ['cloudSphere-0']
bumperNodes += cloudBumpers
if hitNode not in bumperNodes:
self.__stopCollisionHandler(self.av)
self.__stopFlyTask(self.avId)
self.notify.debug('stopping flying since we hit %s' % hitNode)
if self.hitTarget == 0:
messenger.send('missedTarget')
else:
if hitNode == 'collision_house':
self.__hitHouse(self.av, collisionEntry)
elif hitNode == 'collision_fence':
self.__hitFence(self.av, collisionEntry)
elif hitNode == 'collision_roof':
self.__hitRoof(self.av, collisionEntry)
elif hitNode == 'targetSphere':
self.__hitTarget(self.av, collisionEntry, [vel])
elif hitNode in cloudBumpers:
self.__hitCloudPlatform(self.av, collisionEntry)
elif hitNode == 'collision_cannon_bumper':
self.__hitCannonBumper(self.av, collisionEntry)
elif hitNode == 'statuaryCol':
self.__hitStatuary(self.av, collisionEntry)
else:
self.notify.debug('*************** hit something else ************')
return
if self.localToonShooting:
camera.wrtReparentTo(render)
if self.dropShadow:
self.dropShadow.reparentTo(hidden)
pos = collisionEntry.getSurfacePoint(render)
hpr = self.av.getHpr()
hitPos = collisionEntry.getSurfacePoint(render)
pos = hitPos
self.landingPos = pos
self.notify.debug('hitNode,Normal = %s,%s' % (hitNode, intoNormal))
track = Sequence()
track.append(Func(self.av.wrtReparentTo, render))
if self.localToonShooting:
track.append(Func(self.av.collisionsOff))
if hitPylonAboveWater or hitNode in ['matCollisions',
'collision1',
'floor',
'sand_collision',
'dirt_collision',
'soil1',
'collision2',
'floor_collision']:
track.append(Func(self.__hitGround, self.av, pos))
track.append(Wait(1.0))
track.append(Func(self.__setToonUpright, self.av, self.landingPos))
elif hitNode == 'collision_house':
track.append(Func(self.__hitHouse, self.av, collisionEntry))
elif hitNode == 'collision_fence' or hitNode == 'collision4':
track.append(Func(self.__hitFence, self.av, collisionEntry))
elif hitNode == 'targetSphere':
track.append(Func(self.__hitHouse, self.av, collisionEntry))
elif hitNode == 'collision3':
track.append(Func(self.__hitWater, self.av, pos, collisionEntry))
track.append(Wait(2.0))
track.append(Func(self.__setToonUpright, self.av, self.landingPos))
elif hitNode == 'roofOutside' or hitNode == 'collision_roof' or hitNode == 'roofclision':
track.append(Func(self.__hitRoof, self.av, collisionEntry))
track.append(Wait(2.0))
track.append(Func(self.__setToonUpright, self.av, self.landingPos))
elif hitNode.find('MovingPlatform') == 0 or hitNode.find('cloudSphere') == 0:
track.append(Func(self.__hitCloudPlatform, self.av, collisionEntry))
else:
self.notify.warning('************* unhandled hitNode=%s parent =%s' % (hitNode, collisionEntry.getIntoNodePath().getParent()))
track.append(Func(self.b_setLanded))
if self.localToonShooting:
track.append(Func(self.av.collisionsOn))
if 1:
if self.hitTrack:
self.hitTrack.finish()
self.hitTrack = track
self.hitTrack.start()
def __hitGround(self, avatar, pos, extraArgs = []):
hitP = avatar.getPos(render)
self.notify.debug('hitGround pos = %s, hitP = %s' % (pos, hitP))
self.notify.debug('avatar hpr = %s' % avatar.getHpr())
h = self.barrel.getH(render)
avatar.setPos(pos[0], pos[1], pos[2] + avatar.getHeight() / 3.0)
avatar.setHpr(h, -135, 0)
self.notify.debug('parent = %s' % avatar.getParent())
self.notify.debug('pos = %s, hpr = %s' % (avatar.getPos(render), avatar.getHpr(render)))
self.dustCloud.setPos(render, pos[0], pos[1], pos[2] + avatar.getHeight() / 3.0)
self.dustCloud.setScale(0.35)
self.dustCloud.play()
base.playSfx(self.sndHitGround)
avatar.setPlayRate(2.0, 'run')
avatar.loop('run')
def __hitHouse(self, avatar, collisionEntry, extraArgs = []):
self.__hitBumper(avatar, collisionEntry, self.sndHitHouse, kr=0.2, angVel=3)
pinballScore = ToontownGlobals.PinballScoring[ToontownGlobals.PinballHouse]
self.incrementPinballInfo(pinballScore[0], pinballScore[1])
def __hitFence(self, avatar, collisionEntry, extraArgs = []):
self.__hitBumper(avatar, collisionEntry, self.sndHitHouse, kr=0.2, angVel=3)
pinballScore = ToontownGlobals.PinballScoring[ToontownGlobals.PinballFence]
self.incrementPinballInfo(pinballScore[0], pinballScore[1])
def __hitTarget(self, avatar, collisionEntry, extraArgs = []):
self.__hitBumper(avatar, collisionEntry, self.sndHitHouse, kr=0.1, angVel=2)
pinballScore = ToontownGlobals.PinballScoring[ToontownGlobals.PinballTarget]
self.incrementPinballInfo(pinballScore[0], pinballScore[1])
if self.localToonShooting:
self.hitTarget = 1
messenger.send('hitTarget', [self.avId, self.lastVel])
def __hitBumper(self, avatar, collisionEntry, sound, kr = 0.6, angVel = 1):
self.hitBumper = 1
base.playSfx(self.sndHitHouse)
hitP = avatar.getPos(render)
self.lastPos = hitP
house = collisionEntry.getIntoNodePath()
normal = collisionEntry.getSurfaceNormal(house)
normal.normalize()
normal = collisionEntry.getSurfaceNormal(render)
self.notify.debug('normal = %s' % normal)
vel = self.vel * 1
speed = vel.length()
vel.normalize()
self.notify.debug('old vel = %s' % vel)
newVel = (normal * 2.0 + vel) * (kr * speed)
self.lastVel = newVel
self.notify.debug('new vel = %s' % newVel)
self.angularVel = angVel * 360
t = Sequence(Func(avatar.pose, 'lose', 110))
t.start()
def __hitRoof(self, avatar, collisionEntry, extraArgs = []):
if True:
self.__hitBumper(avatar, collisionEntry, self.sndHitHouse, kr=0.3, angVel=3)
pinballScore = ToontownGlobals.PinballScoring[ToontownGlobals.PinballRoof]
self.incrementPinballInfo(pinballScore[0], pinballScore[1])
return
np = collisionEntry.getIntoNodePath()
roof = np.getParent()
normal = collisionEntry.getSurfaceNormal(np)
normal.normalize()
vel = self.trajectory.getVel(self.t)
vel.normalize()
dot = normal.dot(vel)
self.notify.debug('--------------dot product = %s---------------' % dot)
temp = render.attachNewNode('temp')
temp.setPosHpr(0, 0, 0, 0, 0, 0)
2019-11-02 17:27:54 -05:00
temp.lookAt(Point3(normal))
temp.reparentTo(roof)
self.notify.debug('avatar pos = %s, landingPos = %s' % (avatar.getPos(), self.landingPos))
temp.setPos(render, self.landingPos)
avatar.reparentTo(temp)
avatar.setPosHpr(0, 0.25, 0.5, 0, 270, 180)
avatar.pose('slip-forward', 25)
base.playSfx(self.sndHitHouse)
avatar.setPlayRate(1.0, 'jump')
h = self.barrel.getH(render)
t = Sequence(LerpPosInterval(avatar, 0.5, Point3(0, 0, -.5), blendType='easeInOut'), Func(avatar.clearColorScale), Func(avatar.wrtReparentTo, render), Wait(0.3), Parallel(Func(avatar.setP, 0), Func(avatar.play, 'jump', None, 19, 39), LerpHprInterval(avatar, 0.3, Vec3(h, 0, 0), blendType='easeOut')), Func(avatar.play, 'neutral'))
t.start()
hitP = avatar.getPos(render)
return
def __hitBridge(self, avatar, collisionEntry, extraArgs = []):
self.notify.debug('hit bridge')
hitP = avatar.getPos(render)
self.dustCloud.setPos(render, hitP[0], hitP[1], hitP[2] - 0.5)
self.dustCloud.setScale(0.35)
self.dustCloud.play()
base.playSfx(self.sndHitGround)
def __hitWater(self, avatar, pos, collisionEntry, extraArgs = []):
hitP = avatar.getPos(render)
if hitP[2] > ToontownGlobals.EstateWakeWaterHeight:
self.notify.debug('we hit the ground before we hit water')
self.__hitGround(avatar, pos, extraArgs)
print('but not really')
2019-11-02 17:27:54 -05:00
return
self.inWater = 1
self.notify.debug('hit water')
hitP = avatar.getPos(render)
avatar.loop('neutral')
self.splash.setPos(hitP)
self.splash.setZ(ToontownGlobals.EstateWakeWaterHeight)
self.splash.setScale(2)
self.splash.play()
base.playSfx(self.sndHitWater)
place = base.cr.playGame.getPlace()
self.notify.debug('hitWater: submerged = %s' % place.toonSubmerged)
def __hitCannonBumper(self, avatar, collisionEntry, extraArgs = []):
self.__hitBumper(avatar, collisionEntry, self.sndHitHouse, kr=0.4, angVel=5)
score, multiplier = ToontownGlobals.PinballScoring[ToontownGlobals.PinballCannonBumper]
self.incrementPinballInfo(score, multiplier)
def __hitStatuary(self, avatar, collisionEntry, extraArgs = []):
self.__hitBumper(avatar, collisionEntry, self.sndHitHouse, kr=0.4, angVel=5)
score, multiplier = ToontownGlobals.PinballScoring[ToontownGlobals.PinballStatuary]
intoNodePath = collisionEntry.getIntoNodePath()
name = intoNodePath.getParent().getName()
splitParts = name.split('-')
if len(splitParts) >= 3:
score = int(splitParts[1])
multiplier = int(splitParts[2])
self.incrementPinballInfo(score, multiplier)
def __hitCloudPlatform(self, avatar, collisionEntry, extraArgs = []):
if True:
self.__hitBumper(avatar, collisionEntry, self.sndHitHouse, kr=0.4, angVel=5)
score, multiplier = ToontownGlobals.PinballScoring[ToontownGlobals.PinballCloudBumperLow]
intoNodePath = collisionEntry.getIntoNodePath()
name = intoNodePath.getParent().getName()
splitParts = name.split('-')
if len(splitParts) >= 3:
score = int(splitParts[1])
multiplier = int(splitParts[2])
self.incrementPinballInfo(score, multiplier)
return
avatar.reparentTo(collisionEntry.getIntoNodePath())
h = self.barrel.getH(render)
avatar.setPosHpr(0, 0, 0, h, 0, 0)
messenger.send('hitCloud')
def __setToonUpright(self, avatar, pos = None):
if avatar:
if self.inWater:
avatar.setP(0)
avatar.setR(0)
return
if not pos:
pos = avatar.getPos(render)
avatar.setPos(render, pos)
avatar.loop('neutral')
place = base.cr.playGame.getPlace()
h = self.barrel.getH(render)
p = Point3(self.vel[0], self.vel[1], self.vel[2])
self.notify.debug('lookat = %s' % p)
if hasattr(self, 'cannon') and self.cannon:
avatar.lookAt(self.cannon)
avatar.setP(0)
avatar.setR(0)
avatar.setScale(1, 1, 1)
def __calcToonImpact(self, trajectory):
t_groundImpact = trajectory.checkCollisionWithGround(GROUND_PLANE_MIN)
if t_groundImpact >= trajectory.getStartTime():
return (t_groundImpact, self.HIT_GROUND)
else:
self.notify.error('__calcToonImpact: toon never impacts ground?')
return (0.0, self.HIT_GROUND)
def __calcHitTreasures(self, trajectory):
estate = self.cr.doId2do.get(self.estateId)
self.hitTreasures = []
if estate:
doIds = estate.flyingTreasureId
for id in doIds:
t = self.cr.doId2do.get(id)
if t:
pos = t.pos
rad = 10.5
height = 10.0
t_impact = trajectory.checkCollisionWithCylinderSides(pos, rad, height)
if t_impact > 0:
self.hitTreasures.append([t_impact, t])
del estate
return None
def __shootTask(self, task):
base.playSfx(self.sndCannonFire)
self.dropShadow.reparentTo(render)
return Task.done
def __smokeTask(self, task):
self.smoke.reparentTo(self.barrel)
self.smoke.setPos(0, 6, -3)
self.smoke.setScale(0.5)
self.smoke.wrtReparentTo(render)
track = Sequence(Parallel(LerpScaleInterval(self.smoke, 0.5, 3), LerpColorScaleInterval(self.smoke, 0.5, Vec4(2, 2, 2, 0))), Func(self.smoke.reparentTo, hidden), Func(self.smoke.clearColorScale))
track.start()
return Task.done
def __flyTask(self, task):
toon = task.info['toon']
if toon.isEmpty():
self.__resetToonToCannon(self.av)
return Task.done
curTime = task.time + task.info['launchTime']
t = curTime
self.lastT = self.t
self.t = t
deltaT = self.t - self.lastT
self.deltaT = deltaT
if self.hitBumper:
pos = self.lastPos + self.lastVel * deltaT
vel = self.lastVel
self.lastVel += Vec3(0, 0, -32.0) * deltaT
self.lastPos = pos
toon.setFluidPos(pos)
lastH = toon.getH()
toon.setH(lastH + deltaT * self.angularVel)
view = 0
else:
pos = task.info['trajectory'].getPos(t)
toon.setFluidPos(pos)
shadowPos = Point3(pos)
shadowPos.setZ(SHADOW_Z_OFFSET)
self.dropShadow.setPos(shadowPos)
vel = task.info['trajectory'].getVel(t)
run = math.sqrt(vel[0] * vel[0] + vel[1] * vel[1])
rise = vel[2]
theta = self.__toDegrees(math.atan(rise / run))
toon.setHpr(self.cannon.getH(render), -90 + theta, 0)
view = 2
if pos.getZ() < -20 or pos.getZ() > 1000:
self.notify.debug('stopping fly task toon.getZ()=%.2f' % pos.getZ())
self.__resetToonToCannon(self.av)
return Task.done
lookAt = task.info['toon'].getPos(render)
hpr = task.info['toon'].getHpr(render)
if self.localToonShooting:
if view == 0:
camera.wrtReparentTo(render)
camera.lookAt(lookAt)
elif view == 1:
camera.reparentTo(render)
camera.setPos(render, 100, 100, 35.25)
camera.lookAt(render, lookAt)
elif view == 2:
if hpr[1] > -90:
camera.setPos(0, 0, -30)
if camera.getZ() < lookAt[2]:
camera.setZ(render, lookAt[2] + 10)
camera.lookAt(Point3(0, 0, 0))
self.__pickupTreasures(t)
return Task.cont
def __pickupTreasures(self, t):
updatedList = []
for tList in self.hitTreasures:
if t > tList[0]:
messenger.send(tList[1].uniqueName('entertreasureSphere'))
self.notify.debug('hit something!')
else:
updatedList.append(tList)
self.hitTreasures = updatedList
def __resetToonToCannon(self, avatar):
pos = None
if not avatar:
if self.avId:
avatar = base.cr.doId2do.get(self.avId, None)
if avatar:
if self.cannon:
avatar.reparentTo(self.cannon)
avatar.setPos(2, -4, 0)
avatar.wrtReparentTo(render)
self.__resetToon(avatar)
return
def __resetToon(self, avatar, pos = None):
self.notify.debug('__resetToon')
if avatar:
self.__stopCollisionHandler(avatar)
self.__setToonUpright(avatar, pos)
if self.localToonShooting:
self.notify.debug('toon setting position to %s' % pos)
if pos:
base.localAvatar.setPos(pos)
camera.reparentTo(avatar)
self.b_setLanded()
def setActiveState(self, active):
self.notify.debug('got setActiveState(%s)' % active)
if active and not self.cannonsActive:
self.activateCannons()
elif not active and self.cannonsActive:
self.deActivateCannons()
def enterInit(self):
self.nextKey = 'up'
self.nextState = 'u1'
def exitInit(self):
pass
def enteru1(self):
self.nextKey = 'up'
self.nextState = 'u2'
def exitu1(self):
pass
def enteru2(self):
self.nextKey = 'down'
self.nextState = 'd3'
def exitu2(self):
pass
def enterd3(self):
self.nextKey = 'down'
self.nextState = 'd4'
def exitd3(self):
pass
def enterd4(self):
self.nextKey = 'left'
self.nextState = 'l5'
def exitd4(self):
pass
def enterl5(self):
self.nextKey = 'right'
self.nextState = 'r6'
def exitl5(self):
pass
def enterr6(self):
self.nextKey = 'left'
self.nextState = 'l7'
def exitr6(self):
pass
def enterl7(self):
self.nextKey = 'right'
self.nextState = 'r8'
def exitl7(self):
pass
def enterr8(self):
self.nextKey = None
self.nextState = ''
self.codeFSM.request('acceptCode')
return
def exitr8(self):
pass
def enterAcceptCode(self):
if not self.cannonsActive:
self.activateCannons()
self.sendUpdate('setActive', [1])
else:
self.deActivateCannons()
self.sendUpdate('setActive', [0])
self.codeFSM.request('init')
def exitAcceptCode(self):
pass
def enterFinal(self):
pass
def exitFinal(self):
pass
def handleCodeKey(self, key):
if self.nextKey and self.nextState:
if key == self.nextKey:
self.codeFSM.request(self.nextState)
else:
self.codeFSM.request('init')
def incrementPinballInfo(self, score, multiplier):
if base.localAvatar.doId == self.avId:
self.curPinballScore += score
self.curPinballMultiplier += multiplier
self.notify.debug('score =%d multiplier=%d curscore=%d curMult=%d' % (score,
multiplier,
self.curPinballScore,
self.curPinballMultiplier))
self.d_setPinballInfo()
def d_setPinballInfo(self):
self.notify.debug('d_setPinballInfo %d %d' % (self.curPinballScore, self.curPinballMultiplier))
target = base.cr.doId2do[self.targetId]
target.b_setCurPinballScore(self.avId, self.curPinballScore, self.curPinballMultiplier)
def createBlock(self, collisionName = None):
gFormat = GeomVertexFormat.getV3c4()
myVertexData = GeomVertexData('Cannon bumper vertices', gFormat, Geom.UHDynamic)
vertexWriter = GeomVertexWriter(myVertexData, 'vertex')
colorWriter = GeomVertexWriter(myVertexData, 'color')
vertices = [(-1, 1, 1),
(1, 1, 1),
(1, -1, 1),
(-1, -1, 1),
(-1, 1, -1),
(1, 1, -1),
(1, -1, -1),
(-1, -1, -1)]
colors = [(0, 0, 0, 1),
(0, 0, 1, 1),
(0, 1, 0, 1),
(0, 1, 1, 1),
(1, 0, 0, 1),
(1, 0, 1, 1),
(1, 1, 0, 1),
(1, 1, 1, 1)]
faces = [(0, 2, 1),
(0, 3, 2),
(7, 4, 5),
(6, 7, 5),
(2, 3, 7),
(2, 7, 6),
(4, 0, 1),
(5, 4, 1),
(0, 4, 3),
(3, 4, 7),
(1, 2, 6),
(1, 6, 5)]
quads = [(3, 2, 1, 0),
(4, 5, 6, 7),
(3, 7, 6, 2),
(0, 1, 5, 4),
(0, 4, 7, 3),
(1, 2, 6, 5)]
for i in range(len(vertices)):
vertex = vertices[i]
vertexWriter.addData3f(vertex[0], vertex[1], vertex[2])
colorWriter.addData4f(*colors[i])
cubeGeom = Geom(myVertexData)
tris = GeomTriangles(Geom.UHDynamic)
tris.makeIndexed()
for face in faces:
for vertex in face:
tris.addVertex(vertex)
tris.closePrimitive()
cubeGeom.addPrimitive(tris)
cubeGN = GeomNode('cubeGeom')
cubeGN.addGeom(cubeGeom)
if collisionName:
colNode = CollisionNode(collisionName)
else:
colNode = CollisionNode('cubeCollision')
for quad in quads:
colQuad = CollisionPolygon(Point3(*vertices[quad[0]]), Point3(*vertices[quad[1]]), Point3(*vertices[quad[2]]), Point3(*vertices[quad[3]]))
colQuad.setTangible(0)
colNode.addSolid(colQuad)
block = NodePath('cubeNodePath')
block.attachNewNode(cubeGN)
block.attachNewNode(colNode)
return block
def loadCannonBumper(self):
self.cannonBumper = loader.loadModel('phase_5.5/models/estate/bumper_cloud')
self.cannonBumper.reparentTo(self.nodePath)
self.cannonBumper.setScale(4.0)
self.cannonBumper.setColor(0.52, 0.8, 0.98, 1)
colCube = self.cannonBumper.find('**/collision')
colCube.setName('cloudSphere-0')
self.bumperCol = colCube
self.notify.debug('------------self.cannonBumper.setPos %.2f %.2f %.2f' % (ToontownGlobals.PinballCannonBumperInitialPos[0], ToontownGlobals.PinballCannonBumperInitialPos[1], ToontownGlobals.PinballCannonBumperInitialPos[2]))
self.cannonBumper.setPos(*ToontownGlobals.PinballCannonBumperInitialPos)
def __bumperKeyPressed(self):
self.notify.debug('__bumperKeyPressed')
self.__bumperPressed()
def __bumperPressed(self):
renderPos = base.localAvatar.getPos(render)
if renderPos[2] > 15.0:
if not self.localToonShooting:
return
self.ignore(self.BUMPER_KEY)
self.ignore(self.BUMPER_KEY2)
self.notify.debug('renderPos %s' % renderPos)
cannonPos = base.localAvatar.getPos(self.nodePath)
self.notify.debug('cannonPos %s' % cannonPos)
self.setCannonBumperPos(cannonPos[0], cannonPos[1], cannonPos[2])
self.requestBumperMove(cannonPos[0], cannonPos[1], cannonPos[2])
def requestBumperMove(self, x, y, z):
self.sendUpdate('requestBumperMove', [x, y, z])
def setCannonBumperPos(self, x, y, z):
self.notify.debug('------------setCannonBumperPos %f %f %f' % (x, y, z))
self.cannonBumper.setPos(x, y, z)
self.bumperCol.setCollideMask(BitMask32.allOff())
taskMgr.doMethodLater(0.25, self.turnOnBumperCollision, self.uniqueName('BumperON'))
def turnOnBumperCollision(self, whatever = 0):
if self.bumperCol:
self.bumperCol.setCollideMask(ToontownGlobals.WallBitmask)