Poodletooth-iLand/toontown/estate/DistributedCannon.py

1582 lines
61 KiB
Python
Raw Normal View History

from panda3d.core import *
from toontown.toonbase.ToonBaseGlobal import *
from toontown.toonbase import ToontownGlobals
2015-03-03 16:10:12 -06:00
from direct.distributed.ClockDelta import *
from direct.interval.IntervalGlobal import *
2015-03-03 16:10:12 -06:00
from direct.fsm import ClassicFSM, State
from direct.fsm import State
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import ToontownTimer
2015-03-03 16:10:12 -06:00
from direct.task.Task import Task
from toontown.minigame import Trajectory
2015-03-03 16:10:12 -06:00
import math
from toontown.toon import ToonHead
2015-03-23 15:28:42 -05:00
from toontown.effects import Splash
from toontown.effects import DustCloud
2015-03-03 16:10:12 -06:00
from toontown.minigame import CannonGameGlobals
import CannonGlobals
from direct.gui.DirectGui import *
2015-03-03 16:10:12 -06:00
from toontown.toonbase import TTLocalizer
from direct.distributed import DistributedObject
from toontown.effects import Wake
from direct.controls.ControlManager import CollisionHandlerRayStart
2015-03-03 16:10:12 -06:00
2015-06-25 21:59:13 -05:00
from otp.nametag.NametagFloat3d import NametagFloat3d
from otp.nametag.Nametag import Nametag
2015-03-03 16:10:12 -06:00
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)
2015-03-03 16:10:12 -06:00
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)
2015-07-05 20:53:42 -05:00
if self.avId in self.cr.doId2do:
2015-03-03 16:10:12 -06: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)
2015-03-03 16:10:12 -06:00
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()
self.sndCannonMove = base.loadSfx('phase_4/audio/sfx/MG_cannon_adjust.ogg')
self.sndCannonFire = base.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.ogg')
self.sndHitGround = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg')
self.sndHitTower = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_tower.ogg')
self.sndHitWater = base.loadSfx('phase_4/audio/sfx/MG_cannon_splash.ogg')
self.sndWhizz = base.loadSfx('phase_4/audio/sfx/MG_cannon_whizz.ogg')
self.sndWin = base.loadSfx('phase_4/audio/sfx/MG_win.ogg')
self.sndHitHouse = base.loadSfx('phase_5/audio/sfx/AA_drop_sandbag.ogg')
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)
2015-03-03 16:10:12 -06:00
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)
2015-03-03 16:10:12 -06:00
tag.setBillboardOffset(0)
tag.setAvatar(self.toonHead)
toon.nametag.addNametag(tag)
tagPath = self.toonHead.attachNewNode(tag)
2015-03-03 16:10:12 -06:00
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])
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, startHpr, startVel, trajectory, 3 * timeOfImpact, hitWhat
def __fireCannonTask(self, task):
launchTime = task.fireTime
avId = task.avId
self.inWater = 0
if not self.toonHead:
return Task.done
startPos, startHpr, startVel, trajectory, timeOfImpact, hitWhat = self.__calcFlightResults(avId, launchTime)
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)
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'
2015-03-03 16:10:12 -06: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()
self.notify.debug('self.inWater = %s' % self.inWater)
if place:
if not hasattr(place, 'fsm'):
return
placeState = place.fsm.getCurrentState().getName()
print placeState
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)
2015-03-03 16:10:12 -06:00
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'
2015-03-03 16:10:12 -06: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.iPosHpr()
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'
2015-03-03 16:10:12 -06: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 = []
2015-06-25 21:59:13 -05:00
'''if estate:
2015-03-03 16:10:12 -06:00
doIds = estate.flyingTreasureId
for id in doIds:
t = self.cr.doId2do.get(id)
if t:
2015-06-25 21:59:13 -05:00
pos = t.pos
2015-03-03 16:10:12 -06:00
rad = 10.5
height = 10.0
t_impact = trajectory.checkCollisionWithCylinderSides(pos, rad, height)
if t_impact > 0:
self.hitTreasures.append([t_impact, t])
2015-06-25 21:59:13 -05:00
del estate'''
2015-03-03 16:10:12 -06:00
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)]
2015-07-05 20:02:35 -05:00
for i in xrange(len(vertices)):
2015-03-03 16:10:12 -06:00
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:
2015-06-25 22:33:15 -05:00
self.bumperCol.setCollideMask(ToontownGlobals.WallBitmask)