mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-24 04:02:40 -06:00
Feature: Implemented MML Piano Marry-Go-Round
This commit is contained in:
parent
d252a5cd03
commit
8e070a2231
6 changed files with 140 additions and 58 deletions
|
@ -953,6 +953,7 @@ dclass DistributedButterfly : DistributedObject {
|
||||||
|
|
||||||
dclass DistributedMMPiano : DistributedObject {
|
dclass DistributedMMPiano : DistributedObject {
|
||||||
requestSpeedUp() airecv clsend;
|
requestSpeedUp() airecv clsend;
|
||||||
|
requestSlowDown() airecv clsend;
|
||||||
requestChangeDirection() airecv clsend;
|
requestChangeDirection() airecv clsend;
|
||||||
setSpeed(int16/1000, uint16/100, int16) broadcast ram;
|
setSpeed(int16/1000, uint16/100, int16) broadcast ram;
|
||||||
playSpeedUp(uint32) broadcast;
|
playSpeedUp(uint32) broadcast;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
from pandac.PandaModules import *
|
from pandac.PandaModules import *
|
||||||
|
|
||||||
|
|
||||||
hashVal = 1610389195
|
hashVal = 177192120
|
||||||
|
|
||||||
|
|
||||||
from toontown.coghq import DistributedCashbotBossSafe, DistributedCashbotBossCrane, DistributedBattleFactory, DistributedCashbotBossTreasure, DistributedCogHQDoor, DistributedSellbotHQDoor, DistributedFactoryElevatorExt, DistributedMintElevatorExt, DistributedLawOfficeElevatorExt, DistributedLawOfficeElevatorInt, LobbyManager, DistributedMegaCorp, DistributedFactory, DistributedLawOffice, DistributedLawOfficeFloor, DistributedLift, DistributedDoorEntity, DistributedSwitch, DistributedButton, DistributedTrigger, DistributedCrushableEntity, DistributedCrusherEntity, DistributedStomper, DistributedStomperPair, DistributedLaserField, DistributedGolfGreenGame, DistributedSecurityCamera, DistributedMover, DistributedElevatorMarker, DistributedBarrelBase, DistributedGagBarrel, DistributedBeanBarrel, DistributedHealBarrel, DistributedGrid, ActiveCell, DirectionalCell, CrusherCell, DistributedCrate, DistributedSinkingPlatform, BattleBlocker, DistributedMint, DistributedMintRoom, DistributedMintBattle, DistributedStage, DistributedStageRoom, DistributedStageBattle, DistributedLawbotBossGavel, DistributedLawbotCannon, DistributedLawbotChair, DistributedCogKart, DistributedCountryClub, DistributedCountryClubRoom, DistributedMoleField, DistributedCountryClubBattle, DistributedMaze, DistributedFoodBelt, DistributedBanquetTable, DistributedGolfSpot
|
from toontown.coghq import DistributedCashbotBossSafe, DistributedCashbotBossCrane, DistributedBattleFactory, DistributedCashbotBossTreasure, DistributedCogHQDoor, DistributedSellbotHQDoor, DistributedFactoryElevatorExt, DistributedMintElevatorExt, DistributedLawOfficeElevatorExt, DistributedLawOfficeElevatorInt, LobbyManager, DistributedMegaCorp, DistributedFactory, DistributedLawOffice, DistributedLawOfficeFloor, DistributedLift, DistributedDoorEntity, DistributedSwitch, DistributedButton, DistributedTrigger, DistributedCrushableEntity, DistributedCrusherEntity, DistributedStomper, DistributedStomperPair, DistributedLaserField, DistributedGolfGreenGame, DistributedSecurityCamera, DistributedMover, DistributedElevatorMarker, DistributedBarrelBase, DistributedGagBarrel, DistributedBeanBarrel, DistributedHealBarrel, DistributedGrid, ActiveCell, DirectionalCell, CrusherCell, DistributedCrate, DistributedSinkingPlatform, BattleBlocker, DistributedMint, DistributedMintRoom, DistributedMintBattle, DistributedStage, DistributedStageRoom, DistributedStageBattle, DistributedLawbotBossGavel, DistributedLawbotCannon, DistributedLawbotChair, DistributedCogKart, DistributedCountryClub, DistributedCountryClubRoom, DistributedMoleField, DistributedCountryClubBattle, DistributedMaze, DistributedFoodBelt, DistributedBanquetTable, DistributedGolfSpot
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
from toontown.classicchars import DistributedMinnieAI
|
from toontown.classicchars import DistributedMinnieAI
|
||||||
from toontown.hood import HoodAI
|
from toontown.hood import HoodAI
|
||||||
from toontown.safezone import DistributedTrolleyAI
|
from toontown.safezone import DistributedTrolleyAI
|
||||||
|
from toontown.safezone import DistributedMMPianoAI
|
||||||
from toontown.toonbase import ToontownGlobals
|
from toontown.toonbase import ToontownGlobals
|
||||||
from toontown.ai import DistributedTrickOrTreatTargetAI
|
from toontown.ai import DistributedTrickOrTreatTargetAI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MMHoodAI(HoodAI.HoodAI):
|
class MMHoodAI(HoodAI.HoodAI):
|
||||||
def __init__(self, air):
|
def __init__(self, air):
|
||||||
HoodAI.HoodAI.__init__(self, air,
|
HoodAI.HoodAI.__init__(self, air,
|
||||||
|
@ -12,6 +14,7 @@ class MMHoodAI(HoodAI.HoodAI):
|
||||||
ToontownGlobals.MinniesMelodyland)
|
ToontownGlobals.MinniesMelodyland)
|
||||||
|
|
||||||
self.trolley = None
|
self.trolley = None
|
||||||
|
self.piano = None
|
||||||
self.classicChar = None
|
self.classicChar = None
|
||||||
|
|
||||||
self.startup()
|
self.startup()
|
||||||
|
@ -25,6 +28,9 @@ class MMHoodAI(HoodAI.HoodAI):
|
||||||
if simbase.config.GetBool('want-minnie', True):
|
if simbase.config.GetBool('want-minnie', True):
|
||||||
self.createClassicChar()
|
self.createClassicChar()
|
||||||
|
|
||||||
|
self.piano = DistributedMMPianoAI.DistributedMMPianoAI(self.air)
|
||||||
|
self.piano.generateWithRequired(self.zoneId)
|
||||||
|
|
||||||
if simbase.air.wantHalloween:
|
if simbase.air.wantHalloween:
|
||||||
self.TrickOrTreatTargetManager = DistributedTrickOrTreatTargetAI.DistributedTrickOrTreatTargetAI(self.air)
|
self.TrickOrTreatTargetManager = DistributedTrickOrTreatTargetAI.DistributedTrickOrTreatTargetAI(self.air)
|
||||||
self.TrickOrTreatTargetManager.generateWithRequired(4835)
|
self.TrickOrTreatTargetManager.generateWithRequired(4835)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import random
|
||||||
from pandac.PandaModules import *
|
from pandac.PandaModules import *
|
||||||
from direct.task.Task import Task
|
from direct.task.Task import Task
|
||||||
from direct.distributed.ClockDelta import *
|
from direct.distributed.ClockDelta import *
|
||||||
|
@ -9,6 +10,7 @@ ChangeDirectionDebounce = 1.0
|
||||||
ChangeDirectionTime = 1.0
|
ChangeDirectionTime = 1.0
|
||||||
|
|
||||||
class DistributedMMPiano(DistributedObject.DistributedObject):
|
class DistributedMMPiano(DistributedObject.DistributedObject):
|
||||||
|
whitePartNodeName = 'midkey_floor_1'
|
||||||
|
|
||||||
def __init__(self, cr):
|
def __init__(self, cr):
|
||||||
DistributedObject.DistributedObject.__init__(self, cr)
|
DistributedObject.DistributedObject.__init__(self, cr)
|
||||||
|
@ -16,24 +18,36 @@ class DistributedMMPiano(DistributedObject.DistributedObject):
|
||||||
self.rpm = 0.0
|
self.rpm = 0.0
|
||||||
self.degreesPerSecond = self.rpm / 60.0 * 360.0
|
self.degreesPerSecond = self.rpm / 60.0 * 360.0
|
||||||
self.offset = 0.0
|
self.offset = 0.0
|
||||||
self.oldOffset = 0.0
|
|
||||||
self.lerpStart = 0.0
|
|
||||||
self.lerpFinish = 1.0
|
|
||||||
self.speedUpSound = None
|
self.speedUpSound = None
|
||||||
self.changeDirectionSound = None
|
self.changeDirectionSound = None
|
||||||
self.lastChangeDirection = 0.0
|
self.lastChangeDirection = 0.0
|
||||||
return
|
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
self.piano = base.cr.playGame.hood.loader.piano
|
DistributedObject.DistributedObject.generate(self)
|
||||||
|
taskMgr.doMethodLater(4, self.setupGeom, self.uniqueName('setup-geom'))
|
||||||
|
|
||||||
|
def setupGeom(self, task):
|
||||||
|
geom = self.cr.playGame.getPlace().loader.geom
|
||||||
|
self.piano = geom.find('**/center_icon')
|
||||||
|
if self.piano.isEmpty():
|
||||||
|
loader.notify.error('Piano not found')
|
||||||
|
return
|
||||||
|
|
||||||
|
geom.find('**/center_icon').setPos(0,-20.1,0)
|
||||||
|
geom.find('**/midkey_floor').setPos(0,20.1,0)
|
||||||
|
geom.find('**/pond_floor').setPos(0,20.1,0)
|
||||||
|
geom.find('**/pond_floor').setScale(1.01,1.01,1)
|
||||||
|
geom.find('**/MMsz_water').setPos(0,20.0,0)
|
||||||
|
geom.find('**/midkey_floor').setScale(1.01,1.01,1)
|
||||||
|
geom.find('**/midkey_floor_1').setScale(1.01,1.01,1)
|
||||||
base.cr.parentMgr.registerParent(ToontownGlobals.SPMinniesPiano, self.piano)
|
base.cr.parentMgr.registerParent(ToontownGlobals.SPMinniesPiano, self.piano)
|
||||||
self.accept('enterlarge_round_keyboard_collisions', self.__handleOnFloor)
|
self.accept('enter' + self.whitePartNodeName, self.__handleOnFloor)
|
||||||
self.accept('exitlarge_round_keyboard_collisions', self.__handleOffFloor)
|
self.accept('exit' + self.whitePartNodeName, self.__handleOffFloor)
|
||||||
self.accept('entero7', self.__handleChangeDirectionButton)
|
self.accept('entermid_fishpond', self.__handleChangeDirectionButton)
|
||||||
self.speedUpSound = base.loadSfx('phase_6/audio/sfx/SZ_MM_gliss.ogg')
|
self.speedUpSound = base.loadSfx('phase_6/audio/sfx/SZ_MM_gliss.ogg')
|
||||||
self.changeDirectionSound = base.loadSfx('phase_6/audio/sfx/SZ_MM_cymbal.ogg')
|
self.changeDirectionSound = base.loadSfx('phase_6/audio/sfx/SZ_MM_cymbal.ogg')
|
||||||
self.__setupSpin()
|
self.__setupSpin()
|
||||||
DistributedObject.DistributedObject.generate(self)
|
return task.done
|
||||||
|
|
||||||
def __setupSpin(self):
|
def __setupSpin(self):
|
||||||
taskMgr.add(self.__updateSpin, self.taskName('pianoSpinTask'))
|
taskMgr.add(self.__updateSpin, self.taskName('pianoSpinTask'))
|
||||||
|
@ -42,51 +56,32 @@ class DistributedMMPiano(DistributedObject.DistributedObject):
|
||||||
taskMgr.remove(self.taskName('pianoSpinTask'))
|
taskMgr.remove(self.taskName('pianoSpinTask'))
|
||||||
|
|
||||||
def __updateSpin(self, task):
|
def __updateSpin(self, task):
|
||||||
now = globalClock.getFrameTime()
|
if self.degreesPerSecond == 0:
|
||||||
if now > self.lerpFinish:
|
return Task.cont
|
||||||
offset = self.offset
|
|
||||||
elif now > self.lerpStart:
|
elapsed = globalClock.getRealTime() - self.spinStartTime
|
||||||
t = (now - self.lerpStart) / (self.lerpFinish - self.lerpStart)
|
offset = self.offset
|
||||||
offset = self.oldOffset + t * (self.offset - self.oldOffset)
|
heading = ((self.degreesPerSecond * elapsed) + offset) % 360
|
||||||
else:
|
self.piano.setH(heading)
|
||||||
offset = self.oldOffset
|
|
||||||
heading = self.degreesPerSecond * (now - self.spinStartTime) + offset
|
|
||||||
self.piano.setHprScale(heading % 360.0, 0.0, 0.0, 1.0, 1.0, 1.0)
|
|
||||||
return Task.cont
|
return Task.cont
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
del self.piano
|
if hasattr(self, 'piano'):
|
||||||
base.cr.parentMgr.unregisterParent(ToontownGlobals.SPMinniesPiano)
|
del self.piano
|
||||||
self.ignore('enterlarge_round_keyboard_collisions')
|
base.cr.parentMgr.unregisterParent(ToontownGlobals.SPMinniesPiano)
|
||||||
self.ignore('exitlarge_round_keyboard_collisions')
|
self.ignoreAll()
|
||||||
self.ignore('entero7')
|
|
||||||
self.ignore('entericon_center_collisions')
|
|
||||||
self.speedUpSound = None
|
self.speedUpSound = None
|
||||||
self.changeDirectionSound = None
|
self.changeDirectionSound = None
|
||||||
self.__stopSpin()
|
self.__stopSpin()
|
||||||
DistributedObject.DistributedObject.disable(self)
|
DistributedObject.DistributedObject.disable(self)
|
||||||
return
|
|
||||||
|
|
||||||
def setSpeed(self, rpm, offset, timestamp):
|
def setSpeed(self, rpm, offset, timestamp):
|
||||||
timestamp = globalClockDelta.networkToLocalTime(timestamp)
|
timestamp = globalClockDelta.networkToLocalTime(timestamp)
|
||||||
degreesPerSecond = rpm / 60.0 * 360.0
|
degreesPerSecond = rpm / 60.0 * 360.0
|
||||||
now = globalClock.getFrameTime()
|
|
||||||
oldHeading = self.degreesPerSecond * (now - self.spinStartTime) + self.offset
|
|
||||||
oldHeading = oldHeading % 360.0
|
|
||||||
oldOffset = oldHeading - degreesPerSecond * (now - timestamp)
|
|
||||||
self.rpm = rpm
|
self.rpm = rpm
|
||||||
self.degreesPerSecond = degreesPerSecond
|
self.degreesPerSecond = degreesPerSecond
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.spinStartTime = timestamp
|
self.spinStartTime = timestamp
|
||||||
while oldOffset - offset < -180.0:
|
|
||||||
oldOffset += 360.0
|
|
||||||
|
|
||||||
while oldOffset - offset > 180.0:
|
|
||||||
oldOffset -= 360.0
|
|
||||||
|
|
||||||
self.oldOffset = oldOffset
|
|
||||||
self.lerpStart = now
|
|
||||||
self.lerpFinish = timestamp + ChangeDirectionTime
|
|
||||||
|
|
||||||
def playSpeedUp(self, avId):
|
def playSpeedUp(self, avId):
|
||||||
if avId != base.localAvatar.doId:
|
if avId != base.localAvatar.doId:
|
||||||
|
@ -103,6 +98,7 @@ class DistributedMMPiano(DistributedObject.DistributedObject):
|
||||||
|
|
||||||
def __handleOffFloor(self, collEntry):
|
def __handleOffFloor(self, collEntry):
|
||||||
self.cr.playGame.getPlace().activityFsm.request('off')
|
self.cr.playGame.getPlace().activityFsm.request('off')
|
||||||
|
self.sendUpdate('requestSlowDown', [])
|
||||||
|
|
||||||
def __handleSpeedUpButton(self, collEntry):
|
def __handleSpeedUpButton(self, collEntry):
|
||||||
self.sendUpdate('requestSpeedUp', [])
|
self.sendUpdate('requestSpeedUp', [])
|
||||||
|
@ -111,7 +107,12 @@ class DistributedMMPiano(DistributedObject.DistributedObject):
|
||||||
def __handleChangeDirectionButton(self, collEntry):
|
def __handleChangeDirectionButton(self, collEntry):
|
||||||
now = globalClock.getFrameTime()
|
now = globalClock.getFrameTime()
|
||||||
if now - self.lastChangeDirection < ChangeDirectionDebounce:
|
if now - self.lastChangeDirection < ChangeDirectionDebounce:
|
||||||
|
loader.notify.debug('Rejecting change direction.')
|
||||||
return
|
return
|
||||||
self.lastChangeDirection = now
|
shouldChange = random.randint(1,10)
|
||||||
self.sendUpdate('requestChangeDirection', [])
|
if int(shouldChange) == 10:
|
||||||
base.playSfx(self.changeDirectionSound)
|
self.lastChangeDirection = now
|
||||||
|
self.sendUpdate('requestChangeDirection', [])
|
||||||
|
base.playSfx(self.changeDirectionSound)
|
||||||
|
else:
|
||||||
|
loader.notify.debug('Rejecting change direction.')
|
|
@ -1,21 +1,73 @@
|
||||||
from direct.directnotify import DirectNotifyGlobal
|
from otp.ai.AIBase import *
|
||||||
from direct.distributed.DistributedObjectAI import DistributedObjectAI
|
from toontown.toonbase.ToontownGlobals import *
|
||||||
|
from direct.distributed.ClockDelta import *
|
||||||
|
from direct.distributed import DistributedObjectAI
|
||||||
|
from direct.task import Task
|
||||||
|
PianoSpeeds = [2, 4, 6, 8, 10, 12, 15, 20]
|
||||||
|
PianoMaxSpeed = PianoSpeeds[-1]
|
||||||
|
PianoSlowDownFactor = 0.7
|
||||||
|
PianoSlowDownInterval = 6.0
|
||||||
|
PianoSlowDownMinimum = 0.1
|
||||||
|
|
||||||
class DistributedMMPianoAI(DistributedObjectAI):
|
class DistributedMMPianoAI(DistributedObjectAI.DistributedObjectAI):
|
||||||
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedMMPianoAI")
|
|
||||||
|
def __init__(self, air):
|
||||||
|
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
|
||||||
|
self.spinStartTime = 0.0
|
||||||
|
self.rpm = 0.0
|
||||||
|
self.degreesPerSecond = (self.rpm / 60.0) * 360.0
|
||||||
|
self.offset = 0.0
|
||||||
|
self.direction = 1
|
||||||
|
|
||||||
def requestSpeedUp(self):
|
def requestSpeedUp(self):
|
||||||
pass
|
if self.rpm < PianoMaxSpeed:
|
||||||
|
for speed in PianoSpeeds:
|
||||||
|
if speed > self.rpm:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.updateSpeed(speed, self.direction)
|
||||||
|
|
||||||
|
self.d_playSpeedUp(self.air.getAvatarIdFromSender())
|
||||||
|
self.__slowDownLater()
|
||||||
|
|
||||||
def requestChangeDirection(self):
|
def requestChangeDirection(self):
|
||||||
pass
|
rpm = self.rpm
|
||||||
|
if rpm == 0.0:
|
||||||
|
rpm = PianoSpeeds[0]
|
||||||
|
|
||||||
def setSpeed(self, todo0, todo1, todo2):
|
self.updateSpeed(rpm, -(self.direction))
|
||||||
pass
|
self.__slowDownLater()
|
||||||
|
self.d_playChangeDirection(self.air.getAvatarIdFromSender())
|
||||||
|
|
||||||
def playSpeedUp(self, todo0):
|
def d_setSpeed(self, rpm, offset, startTime):
|
||||||
pass
|
self.sendUpdate('setSpeed', [rpm, offset, globalClockDelta.localToNetworkTime(startTime)])
|
||||||
|
|
||||||
def playChangeDirection(self, todo0):
|
def d_playSpeedUp(self, avId):
|
||||||
pass
|
self.sendUpdate('playSpeedUp', [avId])
|
||||||
|
|
||||||
|
def d_playChangeDirection(self, avId):
|
||||||
|
self.sendUpdate('playChangeDirection', [avId])
|
||||||
|
|
||||||
|
def updateSpeed(self, rpm, direction):
|
||||||
|
now = globalClock.getFrameTime()
|
||||||
|
heading = self.degreesPerSecond * (now - self.spinStartTime) + self.offset
|
||||||
|
self.rpm = rpm
|
||||||
|
self.direction = direction
|
||||||
|
self.degreesPerSecond = (rpm / 60.0) * 360.0 * direction
|
||||||
|
self.offset = heading % 360.0
|
||||||
|
self.spinStartTime = now
|
||||||
|
self.d_setSpeed(self.rpm * self.direction, self.offset, self.spinStartTime)
|
||||||
|
|
||||||
|
def __slowDownLater(self):
|
||||||
|
taskName = self.uniqueName('slowDown')
|
||||||
|
taskMgr.remove(taskName)
|
||||||
|
taskMgr.doMethodLater(PianoSlowDownInterval, self.__slowDown, taskName)
|
||||||
|
|
||||||
|
def __slowDown(self, task):
|
||||||
|
rpm = self.rpm * PianoSlowDownFactor
|
||||||
|
if rpm < PianoSlowDownMinimum:
|
||||||
|
self.updateSpeed(0.0, self.direction)
|
||||||
|
else:
|
||||||
|
self.updateSpeed(rpm, self.direction)
|
||||||
|
self.__slowDownLater()
|
||||||
|
return Task.done
|
||||||
|
|
|
@ -1,8 +1,30 @@
|
||||||
from toontown.classicchars import CCharPaths
|
from toontown.classicchars import CCharPaths
|
||||||
|
from direct.fsm import ClassicFSM, State
|
||||||
|
import random
|
||||||
from toontown.safezone import Playground
|
from toontown.safezone import Playground
|
||||||
from toontown.toonbase import TTLocalizer
|
from toontown.toonbase import TTLocalizer
|
||||||
|
from toontown.toonbase import ToontownGlobals
|
||||||
|
|
||||||
|
|
||||||
class MMPlayground(Playground.Playground):
|
class MMPlayground(Playground.Playground):
|
||||||
|
def __init__(self, loader, parentFSM, doneEvent):
|
||||||
|
Playground.Playground.__init__(self, loader, parentFSM, doneEvent)
|
||||||
|
self.activityFsm = ClassicFSM.ClassicFSM('Activity', [State.State('off', self.enterOff, self.exitOff, ['OnPiano']), State.State('OnPiano', self.enterOnPiano, self.exitOnPiano, ['off'])], 'off', 'off')
|
||||||
|
self.activityFsm.enterInitialState()
|
||||||
|
|
||||||
def showPaths(self):
|
def showPaths(self):
|
||||||
self.showPathPoints(CCharPaths.getPaths(TTLocalizer.Minnie))
|
self.showPathPoints(CCharPaths.getPaths(TTLocalizer.Minnie))
|
||||||
|
|
||||||
|
def enterOff(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def exitOff(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def enterOnPiano(self):
|
||||||
|
base.localAvatar.b_setParent(ToontownGlobals.SPMinniesPiano)
|
||||||
|
|
||||||
|
def exitOnPiano(self):
|
||||||
|
base.localAvatar.b_setParent(ToontownGlobals.SPRender)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue