2022-12-16 18:40:57 -06:00
|
|
|
from panda3d.core import *
|
2019-11-02 17:27:54 -05:00
|
|
|
from toontown.toonbase.ToonBaseGlobal import *
|
|
|
|
from direct.interval.IntervalGlobal import *
|
2019-12-30 00:07:56 -06:00
|
|
|
from .DistributedMinigame import *
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.distributed.ClockDelta import *
|
|
|
|
from direct.fsm import ClassicFSM, State
|
|
|
|
from direct.fsm import State
|
|
|
|
from direct.task import Task
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import ArrowKeys
|
|
|
|
from . import TargetGameGlobals
|
2019-11-02 17:27:54 -05:00
|
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
from toontown.toonbase import TTLocalizer
|
|
|
|
import math
|
|
|
|
from math import *
|
|
|
|
import random
|
|
|
|
import random
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import RubberBand
|
|
|
|
from . import FogOverlay
|
2019-11-02 17:27:54 -05:00
|
|
|
|
|
|
|
def circleX(angle, radius, centerX, centerY):
|
|
|
|
x = radius * cos(angle) + centerX
|
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
|
|
def circleY(angle, radius, centerX, centerY):
|
|
|
|
y = radius * sin(angle) + centerY
|
|
|
|
return y
|
|
|
|
|
|
|
|
|
|
|
|
def getCirclePoints(segCount, centerX, centerY, radius, wideX = 1.0, wideY = 1.0):
|
|
|
|
returnShape = []
|
|
|
|
for seg in range(0, segCount):
|
|
|
|
coordX = wideX * circleX(pi * 2.0 * float(float(seg) / float(segCount)), radius, centerX, centerY)
|
|
|
|
coordY = wideY * circleY(pi * 2.0 * float(float(seg) / float(segCount)), radius, centerX, centerY)
|
|
|
|
returnShape.append((coordX, coordY, 1))
|
|
|
|
|
|
|
|
coordX = wideX * circleX(pi * 2.0 * float(0 / segCount), radius, centerX, centerY)
|
|
|
|
coordY = wideY * circleY(pi * 2.0 * float(0 / segCount), radius, centerX, centerY)
|
|
|
|
returnShape.append((coordX, coordY, 1))
|
|
|
|
return returnShape
|
|
|
|
|
|
|
|
|
|
|
|
def getRingPoints(segCount, centerX, centerY, radius, thickness = 2.0, wideX = 1.0, wideY = 1.0):
|
|
|
|
returnShape = []
|
|
|
|
for seg in range(0, segCount):
|
|
|
|
coordX = wideX * circleX(pi * 2.0 * float(float(seg) / float(segCount)), radius - thickness, centerX, centerY)
|
|
|
|
coordY = wideY * circleY(pi * 2.0 * float(float(seg) / float(segCount)), radius - thickness, centerX, centerY)
|
|
|
|
returnShape.append((coordX, coordY, 1))
|
|
|
|
coordX = wideX * circleX(pi * 2.0 * float(float(seg) / float(segCount)), radius, centerX, centerY)
|
|
|
|
coordY = wideY * circleY(pi * 2.0 * float(float(seg) / float(segCount)), radius, centerX, centerY)
|
|
|
|
returnShape.append((coordX, coordY, 1))
|
|
|
|
|
|
|
|
return returnShape
|
|
|
|
|
|
|
|
|
|
|
|
def addRing(attachNode, color, vertexCount, radius, layer = 0, thickness = 1.0):
|
|
|
|
targetGN = GeomNode('target Circle')
|
|
|
|
zFloat = 0.025
|
2019-12-31 00:11:28 -06:00
|
|
|
targetCircleShape = getRingPoints(5 + int(vertexCount), 0.0, 0.0, radius, thickness)
|
2019-11-02 17:27:54 -05:00
|
|
|
gFormat = GeomVertexFormat.getV3cp()
|
|
|
|
targetCircleVertexData = GeomVertexData('holds my vertices', gFormat, Geom.UHDynamic)
|
|
|
|
targetCircleVertexWriter = GeomVertexWriter(targetCircleVertexData, 'vertex')
|
|
|
|
targetCircleColorWriter = GeomVertexWriter(targetCircleVertexData, 'color')
|
|
|
|
for vertex in targetCircleShape:
|
|
|
|
targetCircleVertexWriter.addData3f(0.0 + vertex[0], 0.0 + vertex[1], zFloat)
|
|
|
|
targetCircleColorWriter.addData4f(1.0, 1.0, 1.0, 1.0)
|
|
|
|
|
|
|
|
targetTris = GeomTristrips(Geom.UHStatic)
|
|
|
|
sizeTarget = len(targetCircleShape)
|
|
|
|
for countVertex in range(0, sizeTarget):
|
|
|
|
targetTris.addVertex(countVertex)
|
|
|
|
|
|
|
|
targetTris.addVertex(0)
|
|
|
|
targetTris.addVertex(1)
|
|
|
|
targetTris.closePrimitive()
|
|
|
|
targetGeom = Geom(targetCircleVertexData)
|
|
|
|
targetGeom.addPrimitive(targetTris)
|
|
|
|
attachNode.addGeom(targetGeom)
|
|
|
|
return targetGeom
|
|
|
|
|
|
|
|
|
|
|
|
def addCircle(attachNode, color, vertexCount, radius, layer = 0):
|
|
|
|
targetGN = GeomNode('target Circle')
|
|
|
|
zFloat = 0.025
|
2019-12-31 00:11:28 -06:00
|
|
|
targetCircleShape = getCirclePoints(5 + int(vertexCount), 0.0, 0.0, radius)
|
2019-11-02 17:27:54 -05:00
|
|
|
gFormat = GeomVertexFormat.getV3cp()
|
|
|
|
targetCircleVertexData = GeomVertexData('holds my vertices', gFormat, Geom.UHDynamic)
|
|
|
|
targetCircleVertexWriter = GeomVertexWriter(targetCircleVertexData, 'vertex')
|
|
|
|
targetCircleColorWriter = GeomVertexWriter(targetCircleVertexData, 'color')
|
|
|
|
targetCircleVertexWriter.addData3f(0.0, 0.0, zFloat)
|
|
|
|
targetCircleColorWriter.addData4f(1.0, 1.0, 1.0, 1.0)
|
|
|
|
for vertex in targetCircleShape:
|
|
|
|
targetCircleVertexWriter.addData3f(0.0 + vertex[0], 0.0 + vertex[1], zFloat)
|
|
|
|
targetCircleColorWriter.addData4f(1.0, 1.0, 1.0, 1.0)
|
|
|
|
|
|
|
|
targetTris = GeomTrifans(Geom.UHStatic)
|
|
|
|
sizeTarget = len(targetCircleShape)
|
|
|
|
targetTris.addVertex(0)
|
|
|
|
for countVertex in range(1, sizeTarget + 1):
|
|
|
|
targetTris.addVertex(countVertex)
|
|
|
|
|
|
|
|
targetTris.addVertex(1)
|
|
|
|
targetTris.closePrimitive()
|
|
|
|
targetGeom = Geom(targetCircleVertexData)
|
|
|
|
targetGeom.addPrimitive(targetTris)
|
|
|
|
attachNode.addGeom(targetGeom)
|
|
|
|
return targetGeom
|
|
|
|
|
|
|
|
|
|
|
|
def checkPlace(placeX, placeY, fillSize, placeList):
|
|
|
|
goodPlacement = 1
|
|
|
|
for place in placeList:
|
|
|
|
distance = math.sqrt((place[0] - placeX) * (place[0] - placeX) + (place[1] - placeY) * (place[1] - placeY))
|
|
|
|
distance = distance - (fillSize + place[2])
|
|
|
|
if distance <= 0.0:
|
|
|
|
goodPlacement = 0
|
|
|
|
break
|
|
|
|
|
|
|
|
return goodPlacement
|
|
|
|
|
|
|
|
|
|
|
|
class DistributedTargetGame(DistributedMinigame):
|
|
|
|
UPDATE_ENVIRON_TASK = 'TargetGameUpdateEnvironTask'
|
|
|
|
UPDATE_LOCALTOON_TASK = 'TargetGameUpdateLocalToonTask'
|
|
|
|
UPDATE_SHADOWS_TASK = 'TargetGameUpdateShadowsTask'
|
|
|
|
COLLISION_DETECTION_TASK = 'TargetGameCollisionDetectionTask'
|
|
|
|
END_GAME_WAIT_TASK = 'TargetGameCollisionDetectionTask'
|
|
|
|
UPDATE_POWERBAR_TASK = 'TargetGameUpdatePowerBarTask'
|
|
|
|
GAME_DONE_TASK = 'gameDoneTask'
|
|
|
|
UPDATE_COUNTDOWN_TASK = 'countdown task'
|
|
|
|
FLY2FALL_CAM_TASK = 'fly2FallCameraTask'
|
|
|
|
PRELAUNCH_CAM_TASK = 'prelaunchCameraTask'
|
|
|
|
SCORE_CAM_TASK = 'scoreCameraTask'
|
|
|
|
TOONSTRETCHTASK = 'tooncamtask'
|
|
|
|
UPDATE_LOCAL_TOON_PRIORITY = 0
|
|
|
|
UPDATE_POWER_BAR_PRIORITY = 1
|
|
|
|
UPDATE_RUBBER_BAND_PRIORITY = 2
|
|
|
|
COLLISION_DETECTION_PRIORITY = 5
|
|
|
|
UPDATE_SHADOWS_PRIORITY = 47
|
|
|
|
UMBRELLA_TEXTURE_LIST = ['phase_4/maps/mg_slingshot_umbrella_blue.jpg',
|
|
|
|
'phase_4/maps/mg_slingshot_umbrella_purple.jpg',
|
|
|
|
'phase_4/maps/mg_slingshot_umbrella_red.jpg',
|
|
|
|
'phase_4/maps/mg_slingshot_umbrella_yellow.jpg']
|
|
|
|
RT_UNKNOWN = 0
|
|
|
|
RT_SUCCESS = 1
|
|
|
|
RT_GROUPSUCCESS = 2
|
|
|
|
RT_FAILURE = 3
|
|
|
|
|
|
|
|
def __init__(self, cr):
|
|
|
|
DistributedMinigame.__init__(self, cr)
|
|
|
|
self.gameFSM = ClassicFSM.ClassicFSM('DistributedTargetGame', [State.State('off', self.enterOff, self.exitOff, ['prelaunch']),
|
|
|
|
State.State('prelaunch', self.enterPrelaunch, self.exitPrelaunch, ['launch']),
|
|
|
|
State.State('launch', self.enterLaunch, self.exitLaunch, ['fly']),
|
|
|
|
State.State('fly', self.enterFly, self.exitFly, ['fall', 'bouncing', 'score']),
|
|
|
|
State.State('fall', self.enterFall, self.exitFall, ['bouncing', 'score']),
|
|
|
|
State.State('bouncing', self.enterBouncing, self.exitBouncing, ['score']),
|
|
|
|
State.State('score', self.enterScore, self.exitScore, ['cleanup', 'prelaunch']),
|
|
|
|
State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
|
|
|
|
self.addChildGameFSM(self.gameFSM)
|
|
|
|
self.targets = None
|
|
|
|
self.round = 1
|
|
|
|
self.signalLaunch = 0
|
|
|
|
self.stretchX = 0
|
|
|
|
self.stretchY = 0
|
|
|
|
self.targetsPlaced = []
|
|
|
|
self.pattern = None
|
|
|
|
self.maxDist = 50
|
|
|
|
self.targetMarker = None
|
|
|
|
self.umbrellaColorSelect = [1,
|
|
|
|
1,
|
|
|
|
1,
|
|
|
|
1]
|
|
|
|
self.localTrack = None
|
|
|
|
self.hitInfo = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def getTitle(self):
|
|
|
|
return TTLocalizer.TargetGameTitle
|
|
|
|
|
|
|
|
def getInstructions(self):
|
|
|
|
p = self.avIdList.index(self.localAvId)
|
|
|
|
if self.isSinglePlayer():
|
|
|
|
text = TTLocalizer.TargetGameInstructionsSinglePlayer
|
|
|
|
else:
|
|
|
|
text = TTLocalizer.TargetGameInstructionsMultiPlayer
|
|
|
|
return text
|
|
|
|
|
|
|
|
def getMaxDuration(self):
|
|
|
|
return 60
|
|
|
|
|
|
|
|
def defineConstants(self):
|
|
|
|
self.CAMERA_Y = -25
|
|
|
|
self.TOON_Y = 0
|
|
|
|
self.FAR_PLANE_DIST = 370
|
|
|
|
tScreenCenterToEdge = 1.0
|
|
|
|
self.TOONXZ_SPEED = TargetGameGlobals.MAX_TOONXZ / tScreenCenterToEdge
|
|
|
|
self.WATER_DEPTH = 75.0
|
|
|
|
self.ENVIRON_LENGTH = TargetGameGlobals.ENVIRON_LENGTH
|
|
|
|
self.ENVIRON_WIDTH = TargetGameGlobals.ENVIRON_WIDTH
|
|
|
|
self.ENVIRON_START_OFFSET = 20.0
|
|
|
|
self.TOON_INITIAL_SPACING = 14.0
|
|
|
|
waterZOffset = 28.0
|
|
|
|
self.SEA_FLOOR_Z = -self.WATER_DEPTH / 2.0 + waterZOffset
|
|
|
|
self.FOGDISTGROUND = 600
|
|
|
|
self.FOGDISTCLOUD = 200
|
|
|
|
farPlaneDist = self.CAMERA_Y + self.FAR_PLANE_DIST - self.TOON_Y
|
|
|
|
self.ringGroupArrivalPeriod = 3.0
|
|
|
|
self.AMB_COLOR = Vec4(0.75, 0.8, 1.0, 1.0)
|
|
|
|
self.CLOUD_COLOR = Vec4(1.0, 1.0, 1.0, 1.0)
|
|
|
|
self.SHADOW_Z_OFFSET = 0.1
|
|
|
|
self.Y_VIS_MAX = self.FAR_PLANE_DIST
|
|
|
|
self.Y_VIS_MIN = self.CAMERA_Y
|
|
|
|
targetRadius = TargetGameGlobals.TARGET_RADIUS * 1.025
|
|
|
|
self.GAME_END_DELAY = 1.0
|
|
|
|
self.TOON_LOD = 1000
|
|
|
|
self.speedLaunch = 60
|
|
|
|
self.speedStall = 30
|
|
|
|
self.speedForward = 0
|
|
|
|
self.airResistance = 0.1
|
|
|
|
self.umbrellaResistance = 0.11
|
|
|
|
self.distance = 0
|
|
|
|
self.zVel = 0
|
|
|
|
self.lastPressed = None
|
|
|
|
self.lastPressTime = None
|
|
|
|
self.driftX = 0
|
|
|
|
self.driftY = 0
|
|
|
|
self.launchLaterial = 0
|
|
|
|
self.laterial = 0
|
|
|
|
self.gravity = 12.5
|
|
|
|
self.inList = []
|
|
|
|
self.placeShift = 10
|
|
|
|
self.startPower = 10
|
|
|
|
self.canPressRight = 1
|
|
|
|
self.canPressLeft = 1
|
|
|
|
self.jumpCount = 0
|
|
|
|
self.trampZ = 3.6
|
|
|
|
self.trampBounceCount = 0
|
|
|
|
self.cameraState = 'Low'
|
|
|
|
self.updateTick = 0
|
|
|
|
self.hitInfo = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
self.notify.debug('load')
|
|
|
|
DistributedMinigame.load(self)
|
|
|
|
self.defineConstants()
|
|
|
|
self.help = DirectLabel(parent=aspect2d, relief=None, pos=(-0.0, 0, -0.8), text=TTLocalizer.TargetGameCountdown, text_scale=0.08, text_fg=(1, 1, 1, 1))
|
|
|
|
self.help.hide()
|
|
|
|
self.fogOver = FogOverlay.FogOverlay(Point3(self.CLOUD_COLOR[0], self.CLOUD_COLOR[1], self.CLOUD_COLOR[2]))
|
|
|
|
self.scoreboard = DirectFrame(parent=aspect2d, relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(1.75, 1, 0.75), pos=(0, 0, 0.587))
|
|
|
|
self.roundLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(0, 0, 0.28), text=TTLocalizer.TargetGameBoard % self.round, text_scale=0.08)
|
|
|
|
av1Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.8, 0, 0.14), text_align=TextNode.ALeft, text=' ', text_scale=0.08)
|
|
|
|
av2Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.8, 0, 0.02), text_align=TextNode.ALeft, text=' ', text_scale=0.08)
|
|
|
|
av3Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.8, 0, -0.1), text_align=TextNode.ALeft, text=' ', text_scale=0.08)
|
|
|
|
av4Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.8, 0, -0.22), text_align=TextNode.ALeft, text=' ', text_scale=0.08)
|
|
|
|
score1Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(0.8, 0, 0.14), text_align=TextNode.ARight, text=' ', text_scale=0.08)
|
|
|
|
score2Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(0.8, 0, 0.02), text_align=TextNode.ARight, text=' ', text_scale=0.08)
|
|
|
|
score3Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(0.8, 0, -0.1), text_align=TextNode.ARight, text=' ', text_scale=0.08)
|
|
|
|
score4Label = DirectLabel(parent=self.scoreboard, relief=None, pos=(0.8, 0, -0.22), text_align=TextNode.ARight, text=' ', text_scale=0.08)
|
|
|
|
self.avLabels = [av1Label,
|
|
|
|
av2Label,
|
|
|
|
av3Label,
|
|
|
|
av4Label]
|
|
|
|
self.scoreLabels = [score1Label,
|
|
|
|
score2Label,
|
|
|
|
score3Label,
|
|
|
|
score4Label]
|
|
|
|
self.scoreboard.hide()
|
2020-01-14 13:28:52 -06:00
|
|
|
self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_Diving.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.sndAmbience = None
|
|
|
|
self.skyListLow = []
|
|
|
|
self.skyListMid = []
|
|
|
|
loadBase = 'phase_4/models/minigames/'
|
|
|
|
self.modelName = 'slingshot_game_desert4.bam'
|
|
|
|
self.trampoline = loader.loadModel('phase_4/models/minigames/slingshot_game_tramp.bam')
|
|
|
|
self.trampoline.setBin('ground', 100)
|
|
|
|
self.trampoline.find('**/tramp_shadow').hide()
|
|
|
|
self.cacti = loader.loadModel('phase_4/models/minigames/slingshot_game_cacti.bam')
|
|
|
|
self.cactusA = self.cacti.find('**/cactus_a')
|
|
|
|
self.cactusB = self.cacti.find('**/cactus_b')
|
|
|
|
self.findGround = '**/sand_layer1'
|
|
|
|
self.findSky = '**/blue_sky_layer1'
|
|
|
|
self.findCloudExtra = '**/cloud_layer1'
|
|
|
|
self.findCloud = '**/cloud_layer_alpha'
|
|
|
|
self.findLeftMount = '**/mountain_set_b'
|
|
|
|
self.findRightMount = '**/mountain_c'
|
|
|
|
self.findBack = '**/backdrop_layer1'
|
|
|
|
self.environModel = loader.loadModel(loadBase + self.modelName)
|
|
|
|
self.skyGN = GeomNode('sky Geometry')
|
|
|
|
self.skyNode1 = self.environModel.attachNewNode(self.skyGN)
|
|
|
|
leftMountModel = self.environModel.find(self.findLeftMount)
|
|
|
|
rightMountModel = self.environModel.find(self.findRightMount)
|
|
|
|
wrongCloud = self.environModel.find(self.findCloudExtra)
|
|
|
|
wrongCloud.hide()
|
|
|
|
backModel = self.environModel.find(self.findBack)
|
|
|
|
backModel.hide()
|
|
|
|
leftMountModel.hide()
|
|
|
|
rightMountModel.hide()
|
|
|
|
groundModel = self.environModel.find(self.findGround)
|
|
|
|
groundModel.setBin('ground', 0)
|
|
|
|
groundModel.setZ(-0.05)
|
|
|
|
skyModel = self.environModel.find(self.findSky)
|
|
|
|
skyModel2 = self.environModel.find(self.findCloud)
|
|
|
|
skyModel3 = self.environModel.attachNewNode('skyLow')
|
|
|
|
skyModel2.copyTo(skyModel3)
|
|
|
|
skyModel.setZ(76.0)
|
|
|
|
skyModel.setColorScale(1.0, 1.0, 1.0, 1.0)
|
|
|
|
skyModel.setBin('ground', 2)
|
|
|
|
skyModel2.setZ(63.0)
|
|
|
|
skyModel2.setDepthWrite(0)
|
|
|
|
skyModel2.setTransparency(1)
|
|
|
|
skyModel2.setColorScale(1.0, 1.0, 1.0, 1.0)
|
|
|
|
skyModel2.setTwoSided(True)
|
|
|
|
skyModel2.setBin('fixed', 3)
|
|
|
|
skyModel2.setR(180)
|
|
|
|
skyModel3.setZ(50.0)
|
|
|
|
skyModel3.setDepthWrite(0)
|
|
|
|
skyModel3.setTransparency(1)
|
|
|
|
skyModel3.setColorScale(1.0, 1.0, 1.0, 1.0)
|
|
|
|
skyModel3.setTwoSided(True)
|
|
|
|
skyModel3.setBin('fixed', 4)
|
|
|
|
self.skyListLow.append(skyModel3)
|
|
|
|
self.lowSky = skyModel3
|
|
|
|
self.environModel.setPos(0, -5.0, 0)
|
|
|
|
self.environModel.flattenMedium()
|
|
|
|
self.environModel.setScale(15.0, 15.0, 2.0)
|
|
|
|
self.dropShadowModel = loader.loadModel('phase_3/models/props/drop_shadow')
|
|
|
|
self.dropShadowModel.setColor(0, 0, 0, 0.5)
|
|
|
|
self.dropShadowModel.flattenMedium()
|
|
|
|
self.toonDropShadows = []
|
|
|
|
self.__textGen = TextNode('targetGame')
|
|
|
|
self.__textGen.setFont(ToontownGlobals.getSignFont())
|
|
|
|
self.__textGen.setAlign(TextNode.ACenter)
|
|
|
|
self.powerBar = DirectWaitBar(guiId='launch power bar', pos=(0.0, 0, -0.65), relief=DGG.SUNKEN, frameSize=(-2.0,
|
|
|
|
2.0,
|
|
|
|
-0.2,
|
|
|
|
0.2), borderWidth=(0.02, 0.02), scale=0.25, range=100, sortOrder=50, frameColor=(0.5, 0.5, 0.5, 0.5), barColor=(1.0, 0.0, 0.0, 1.0), text='0%', text_scale=0.26, text_fg=(1, 1, 1, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05))
|
|
|
|
self.power = self.startPower
|
|
|
|
self.powerBar['value'] = self.power
|
|
|
|
self.powerBar.hide()
|
|
|
|
self.rubberBands = []
|
|
|
|
self.umbrella = loader.loadModel('phase_4/models/minigames/slingshot_game_umbrellas.bam')
|
|
|
|
pick = random.randint(0, 3)
|
|
|
|
self.umbrellaColorSelect[pick] = 0
|
|
|
|
tex = loader.loadTexture(DistributedTargetGame.UMBRELLA_TEXTURE_LIST[pick])
|
|
|
|
tex.setMinfilter(Texture.FTLinearMipmapLinear)
|
|
|
|
tex.setMagfilter(Texture.FTLinear)
|
|
|
|
self.umbrella.setTexture(tex, 1)
|
|
|
|
open = self.umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
open.setPos(0.1, 0.2, -0.1)
|
|
|
|
open.setHpr(-90.0, 0.0, 15.0)
|
|
|
|
closed = self.umbrella.find('**/closed_umbrella')
|
|
|
|
closed.show()
|
|
|
|
hands = localAvatar.getRightHands()
|
|
|
|
ce = CompassEffect.make(NodePath(), CompassEffect.PRot)
|
|
|
|
closed.node().setEffect(ce)
|
|
|
|
closed.setHpr(0.0, 100.0, 35.0)
|
|
|
|
for hand in hands:
|
|
|
|
self.umbrella.instanceTo(hand)
|
|
|
|
|
|
|
|
self.remoteUmbrellas = {}
|
2020-01-14 13:28:52 -06:00
|
|
|
self.addSound('wind1', 'target_cloud.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.addSound('trampoline', 'target_trampoline_2.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.addSound('launch', 'target_launch.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.addSound('miss', 'target_Lose.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.addSound('score', 'target_happydance.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.addSound('impact', 'target_impact_grunt1.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.addSound('umbrella', 'target_chute.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.addSound('bounce', 'target_impact_only.ogg', 'phase_4/audio/sfx/')
|
|
|
|
self.flySound = loader.loadSfx('phase_4/audio/sfx/target_wind_fly_loop.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.flySound.setVolume(0.0)
|
|
|
|
self.flySound.setPlayRate(1.0)
|
|
|
|
self.flySound.setLoop(True)
|
|
|
|
self.flySound.play()
|
2020-01-14 13:28:52 -06:00
|
|
|
self.rubberSound = loader.loadSfx('phase_4/audio/sfx/target_stretching_aim_loop.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.rubberSound.setVolume(0.0)
|
|
|
|
self.rubberSound.setPlayRate(1.0)
|
|
|
|
self.rubberSound.setLoop(True)
|
|
|
|
self.rubberSound.play()
|
2020-01-14 13:28:52 -06:00
|
|
|
self.flutterSound = loader.loadSfx('phase_4/audio/sfx/target_wind_float_clothloop.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.flutterSound.setVolume(1.0)
|
|
|
|
self.flutterSound.setPlayRate(1.0)
|
|
|
|
self.flutterSound.setLoop(True)
|
|
|
|
return
|
|
|
|
|
|
|
|
def addSound(self, name, soundName, path = None):
|
|
|
|
if not hasattr(self, 'soundTable'):
|
|
|
|
self.soundTable = {}
|
|
|
|
if path:
|
|
|
|
self.soundPath = path
|
|
|
|
soundSource = '%s%s' % (self.soundPath, soundName)
|
|
|
|
self.soundTable[name] = loader.loadSfx(soundSource)
|
|
|
|
|
|
|
|
def playSound(self, name, volume = 1.0):
|
|
|
|
if hasattr(self, 'soundTable'):
|
|
|
|
self.soundTable[name].setVolume(volume)
|
|
|
|
self.soundTable[name].play()
|
|
|
|
|
|
|
|
def addSkys(self, instance):
|
|
|
|
low = instance.find('**/skyLow')
|
|
|
|
mid = instance.find(self.findCloud)
|
|
|
|
self.skyListLow.append(low)
|
|
|
|
self.skyListMid.append(mid)
|
|
|
|
|
|
|
|
def setTargetSeed(self, targetSeed, extra = None):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
random.seed(targetSeed)
|
|
|
|
self.pattern = TargetGameGlobals.difficultyPatterns[self.getSafezoneId()]
|
2019-12-30 00:07:56 -06:00
|
|
|
print('seed %s' % targetSeed)
|
2019-11-02 17:27:54 -05:00
|
|
|
self.setupTargets()
|
|
|
|
|
|
|
|
def setupTargets(self):
|
|
|
|
fieldWidth = self.ENVIRON_WIDTH * 3
|
|
|
|
fieldLength = self.ENVIRON_LENGTH * 3.7
|
|
|
|
self.targetSubParts = [2,
|
|
|
|
2,
|
|
|
|
2,
|
|
|
|
1]
|
|
|
|
self.targetList = self.pattern[0]
|
|
|
|
self.targetValue = self.pattern[1]
|
|
|
|
self.targetSize = self.pattern[2]
|
|
|
|
self.targetColors = self.pattern[3]
|
|
|
|
self.targetSubParts = self.pattern[4]
|
|
|
|
highestValue = 0
|
|
|
|
for value in self.targetValue:
|
|
|
|
if value > highestValue:
|
|
|
|
highestValue = value
|
|
|
|
|
|
|
|
placeList = []
|
|
|
|
self.jumpColor = TargetGameGlobals.colorBlack
|
|
|
|
self.placeValue = highestValue * 0.5
|
|
|
|
self.jumpSize = self.pattern[5]
|
|
|
|
self.jumpNum = self.pattern[6]
|
|
|
|
self.accept('enterJump', self.jumpIn)
|
|
|
|
self.accept('exitJump', self.jumpOut)
|
|
|
|
self.targets = render.attachNewNode('targetGameTargets')
|
|
|
|
for typeIndex in range(len(self.targetList)):
|
|
|
|
for targetIndex in range(self.targetList[typeIndex]):
|
|
|
|
goodPlacement = 0
|
|
|
|
while not goodPlacement:
|
|
|
|
placeX = random.random() * (fieldWidth * 0.6) - fieldWidth * 0.6 * 0.5
|
|
|
|
placeY = (random.random() * 0.6 + (0.0 + 0.4 * (self.placeValue * 1.0 / (highestValue * 1.0)))) * fieldLength
|
|
|
|
fillSize = self.targetSize[typeIndex]
|
|
|
|
goodPlacement = checkPlace(placeX, placeY, fillSize, placeList)
|
|
|
|
|
|
|
|
placeList.append((placeX, placeY, fillSize))
|
|
|
|
subIndex = self.targetSubParts[typeIndex]
|
|
|
|
first = 1
|
|
|
|
while subIndex:
|
|
|
|
combinedIndex = typeIndex + subIndex - 1
|
|
|
|
targetGN = GeomNode('target Circle')
|
|
|
|
targetNodePathGeom = self.targets.attachNewNode(targetGN)
|
|
|
|
targetNodePathGeom.setPos(placeX, placeY, 0)
|
|
|
|
points = self.targetSize[combinedIndex] / 2 + 20
|
|
|
|
order = len(self.targetList) - combinedIndex + 10
|
|
|
|
if first:
|
|
|
|
first = 0
|
|
|
|
geo = addCircle(targetGN, self.targetColors[combinedIndex], points, self.targetSize[combinedIndex], order)
|
|
|
|
else:
|
|
|
|
thickness = abs(self.targetSize[combinedIndex] - self.targetSize[combinedIndex + 1]) - 0.0
|
|
|
|
geo = addRing(targetGN, self.targetColors[combinedIndex], points, self.targetSize[combinedIndex], order, thickness)
|
|
|
|
targetNodePathGeom.setBin('ground', combinedIndex * 2 + 1)
|
|
|
|
targetNodePathGeom.setColorScale(self.targetColors[combinedIndex]['Red'], self.targetColors[combinedIndex]['Green'], self.targetColors[combinedIndex]['Blue'], self.targetColors[combinedIndex]['Alpha'])
|
|
|
|
targetNodePathGeom.setDepthWrite(False)
|
|
|
|
targetNodePathGeom.setDepthTest(False)
|
|
|
|
targetNodePathGeom.setTransparency(TransparencyAttrib.MAlpha)
|
|
|
|
self.targetsPlaced.append((placeX,
|
|
|
|
placeY,
|
|
|
|
combinedIndex,
|
|
|
|
geo))
|
|
|
|
subIndex -= 1
|
|
|
|
|
|
|
|
for jump in range(self.jumpNum):
|
|
|
|
normJumpSize = 6.8
|
|
|
|
goodPlacement = 0
|
|
|
|
while not goodPlacement:
|
|
|
|
placeX = random.random() * (fieldWidth * 0.6) - fieldWidth * 0.6 * 0.5
|
|
|
|
placeY = (random.random() * 0.6 + (0.0 + 0.4 * (self.placeValue * 1.0 / (highestValue * 1.0)))) * fieldLength
|
|
|
|
fillSize = self.jumpSize
|
|
|
|
goodPlacement = checkPlace(placeX, placeY, fillSize, placeList)
|
|
|
|
|
|
|
|
placeList.append((placeX, placeY, fillSize))
|
|
|
|
target = CollisionSphere(0, 0, 0, self.jumpSize)
|
|
|
|
target.setTangible(0)
|
|
|
|
targetNode = CollisionNode('Jump')
|
|
|
|
targetNode.addSolid(target)
|
|
|
|
targetGN = GeomNode('target jump Circle')
|
|
|
|
targetNodePathGeom = self.targets.attachNewNode(targetGN)
|
|
|
|
trampI = self.trampoline.copyTo(self.targets)
|
|
|
|
trampI.setPos(placeX, placeY, 0.05)
|
|
|
|
latScale = self.jumpSize / normJumpSize
|
|
|
|
trampI.setScale(latScale, latScale, 1.0)
|
|
|
|
targetNodePath = self.targets.attachNewNode(targetNode)
|
|
|
|
targetNodePath.setPos(placeX, placeY, 0.0)
|
|
|
|
targetNodePathGeom.setPos(placeX, placeY, 0.05)
|
|
|
|
points = self.jumpSize / 2 + 20
|
|
|
|
order = 0
|
|
|
|
addCircle(targetGN, self.jumpColor, points, self.jumpSize + 0.5, order)
|
|
|
|
targetNodePathGeom.setColorScale(self.jumpColor['Red'], self.jumpColor['Green'], self.jumpColor['Blue'], 0.25)
|
|
|
|
targetNodePathGeom.setBin('ground', 20)
|
|
|
|
targetNodePathGeom.setDepthWrite(True)
|
|
|
|
targetNodePathGeom.setTransparency(TransparencyAttrib.MAlpha)
|
|
|
|
|
|
|
|
cactusCount = 30
|
|
|
|
for cactus in range(cactusCount):
|
|
|
|
placeX = random.random() * (fieldWidth * 0.75) - fieldWidth * 0.75 * 0.5
|
|
|
|
placeY = 5.0 + random.random() * (fieldLength - 5.0)
|
|
|
|
targetGN = GeomNode('cactus')
|
|
|
|
cactus = random.choice([self.cactusA, self.cactusB])
|
|
|
|
targetNodePathGeom = self.targets.attachNewNode(targetGN)
|
|
|
|
targetNodePathGeom = self.targets.attachNewNode(targetGN)
|
|
|
|
cactusI = cactus.copyTo(self.targets)
|
|
|
|
cactusI.setPos(placeX, placeY, 0)
|
|
|
|
cactusI.setHpr(random.random() * 360, 0, 0)
|
|
|
|
cactusI.setScale(0.5 + random.random())
|
|
|
|
|
|
|
|
def unload(self):
|
|
|
|
self.notify.debug('unload')
|
|
|
|
DistributedMinigame.unload(self)
|
|
|
|
del self.__textGen
|
|
|
|
del self.toonDropShadows
|
|
|
|
self.dropShadowModel.removeNode()
|
|
|
|
del self.dropShadowModel
|
|
|
|
self.environModel.removeNode()
|
|
|
|
del self.environModel
|
|
|
|
self.fogOver.delete()
|
|
|
|
self.umbrella.removeNode()
|
|
|
|
del self.umbrella
|
|
|
|
for umbrella in self.remoteUmbrellas:
|
|
|
|
self.remoteUmbrellas[umbrella].removeNode()
|
|
|
|
|
|
|
|
self.remoteUmbrellas.clear()
|
|
|
|
del self.remoteUmbrellas
|
|
|
|
self.flySound.stop()
|
|
|
|
del self.flySound
|
|
|
|
self.rubberSound.stop()
|
|
|
|
del self.rubberSound
|
|
|
|
self.flutterSound.stop()
|
|
|
|
del self.flutterSound
|
|
|
|
del self.music
|
|
|
|
del self.sndAmbience
|
|
|
|
self.removeChildGameFSM(self.gameFSM)
|
|
|
|
del self.gameFSM
|
|
|
|
if self.targets:
|
2019-11-23 16:51:14 -06:00
|
|
|
self.targets.removeNode()
|
2019-11-02 17:27:54 -05:00
|
|
|
del self.targets
|
|
|
|
self.scoreboard.destroy()
|
|
|
|
del self.scoreboard
|
|
|
|
self.powerBar.destroy()
|
|
|
|
del self.powerBar
|
|
|
|
self.help.destroy()
|
|
|
|
del self.help
|
|
|
|
if self.localTrack:
|
|
|
|
self.localTrack.finish()
|
|
|
|
del self.localTrack
|
|
|
|
|
|
|
|
def onstage(self):
|
|
|
|
self.notify.debug('onstage')
|
|
|
|
DistributedMinigame.onstage(self)
|
|
|
|
self.arrowKeys = ArrowKeys.ArrowKeys()
|
|
|
|
toon = base.localAvatar
|
|
|
|
toon.reparentTo(render)
|
|
|
|
toon.setAnimState('SitStart', 1.0)
|
|
|
|
toon.useLOD(self.TOON_LOD)
|
|
|
|
self.__placeToon(self.localAvId)
|
|
|
|
self.localStartPos = toon.getPos()
|
|
|
|
localBand = RubberBand.RubberBand(toon, Point3(0, -1.75, 0), taskPriority=self.UPDATE_RUBBER_BAND_PRIORITY)
|
|
|
|
tP = self.getToonPlace(self.localAvId)
|
|
|
|
pos = Point3(tP[0], tP[1] + 10, tP[2])
|
|
|
|
localBand.setPos(pos)
|
|
|
|
self.rubberBands.append(localBand)
|
|
|
|
toon.dropShadow.hide()
|
|
|
|
toonPos = base.localAvatar.getPos()
|
|
|
|
camera.reparentTo(render)
|
|
|
|
toonPos = self.getAvatar(self.localAvId).getPos()
|
|
|
|
camera.setPosHpr(toonPos[0], toonPos[1] - 18, toonPos[2] + 10, 0, -15, 0)
|
|
|
|
base.camLens.setFov(80)
|
|
|
|
base.camLens.setFar(self.FOGDISTGROUND)
|
|
|
|
base.setBackgroundColor(self.AMB_COLOR)
|
|
|
|
self.__fog = Fog('ringGameFog')
|
|
|
|
if base.wantFog:
|
|
|
|
self.__fog.setColor(self.AMB_COLOR)
|
|
|
|
self.__fog.setLinearRange(0.1, self.FOGDISTGROUND)
|
|
|
|
render.setFog(self.__fog)
|
|
|
|
self.environNode = render.attachNewNode('environNode')
|
|
|
|
self.environBlocks = []
|
|
|
|
maxI = 4
|
|
|
|
self.maxDist = (maxI - 1) * self.ENVIRON_LENGTH
|
|
|
|
for i in range(-1, maxI + 1):
|
|
|
|
instance = self.environModel.copyTo(self.environNode)
|
|
|
|
y = self.ENVIRON_LENGTH * i
|
|
|
|
instance.setY(y)
|
|
|
|
self.addSkys(instance)
|
|
|
|
self.environBlocks.append(instance)
|
|
|
|
jRange = 3
|
|
|
|
for j in range(0, jRange):
|
|
|
|
instance = self.environModel.copyTo(self.environNode)
|
|
|
|
x = self.ENVIRON_WIDTH * (j + 1)
|
|
|
|
instance.setY(y)
|
|
|
|
instance.setX(-x)
|
|
|
|
height = random.random() * 5.0 + 5.0
|
|
|
|
heading = random.random() * 15.0 - 7.5
|
|
|
|
self.addSkys(instance)
|
|
|
|
self.environBlocks.append(instance)
|
|
|
|
if j == jRange - 2:
|
|
|
|
mount = instance.find(self.findLeftMount)
|
|
|
|
mount.setScale(1.0, 1.1, height)
|
|
|
|
mount.setBin('ground', 1)
|
|
|
|
mount.show()
|
|
|
|
sand = mount.find('**/sand_b')
|
|
|
|
sand.hide()
|
|
|
|
mount.setPos(mount.getX() + 8.5, 0, 0.0)
|
|
|
|
if i >= maxI - 1:
|
|
|
|
mount.setHpr(310, 0, 0)
|
|
|
|
mount.setScale(1.0, 1.5, height * 1.2)
|
|
|
|
mount.setPos(mount.getX() - 2.0, 0, 0.0)
|
|
|
|
if i == maxI:
|
|
|
|
mount.hide()
|
|
|
|
if i == -1:
|
|
|
|
mount.setHpr(50, 0, 0)
|
|
|
|
mount.setScale(1.0, 1.5, height * 1.2)
|
|
|
|
mount.setPos(mount.getX() + 5.0, 3.0, 0.0)
|
|
|
|
if j == jRange - 1:
|
|
|
|
sand = instance.find(self.findGround)
|
|
|
|
sand.hide()
|
|
|
|
|
|
|
|
for j in range(0, jRange):
|
|
|
|
instance = self.environModel.copyTo(self.environNode)
|
|
|
|
x = self.ENVIRON_WIDTH * (j + 1)
|
|
|
|
instance.setY(y)
|
|
|
|
instance.setX(x)
|
|
|
|
height = random.random() * 5.0 + 5.0
|
|
|
|
heading = random.random() * 15.0 - 7.5
|
|
|
|
self.addSkys(instance)
|
|
|
|
self.environBlocks.append(instance)
|
|
|
|
if j == jRange - 2:
|
|
|
|
mount = instance.find(self.findRightMount)
|
|
|
|
mount.setScale(1.0, 1.1, height)
|
|
|
|
mount.setBin('ground', 1)
|
|
|
|
mount.show()
|
|
|
|
sand = mount.find('**/sand_c')
|
|
|
|
sand.hide()
|
|
|
|
mount.setPos(mount.getX() - 8.5, 0, 0.0)
|
|
|
|
if i >= maxI - 1:
|
|
|
|
mount.setHpr(50, 0, 0)
|
|
|
|
mount.setScale(1.0, 1.5, height * 1.2)
|
|
|
|
mount.setPos(mount.getX() + 2.0, 0, 0.0)
|
|
|
|
if i == maxI:
|
|
|
|
mount.hide()
|
|
|
|
if i == -1:
|
|
|
|
mount.setHpr(310, 0, 0)
|
|
|
|
mount.setScale(1.0, 1.5, height * 1.2)
|
|
|
|
mount.setPos(mount.getX() - 5.0, 3.0, 0.0)
|
|
|
|
if j == jRange - 1:
|
|
|
|
sand = instance.find(self.findGround)
|
|
|
|
sand.hide()
|
|
|
|
|
|
|
|
self.__addToonDropShadow(self.getAvatar(self.localAvId))
|
|
|
|
self.__spawnUpdateEnvironTask()
|
|
|
|
self.__spawnUpdateShadowsTask()
|
|
|
|
self.__spawnUpdateLocalToonTask()
|
|
|
|
if self.music:
|
|
|
|
base.playMusic(self.music, looping=1, volume=0.8)
|
|
|
|
if None != self.sndAmbience:
|
|
|
|
base.playSfx(self.sndAmbience, looping=1, volume=0.8)
|
|
|
|
return
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
toon = base.localAvatar
|
|
|
|
toon.setAnimState('SitStart', 1.0)
|
|
|
|
toon.useLOD(self.TOON_LOD)
|
|
|
|
self.__placeToon(self.localAvId)
|
|
|
|
toon.dropShadow.hide()
|
|
|
|
self.__spawnUpdateLocalToonTask()
|
|
|
|
toonPos = base.localAvatar.getPos()
|
|
|
|
camera.setPosHpr(toonPos[0], toonPos[1] - 26, toonPos[2] + 10, 0, -15, 0)
|
|
|
|
base.camLens.setFov(80)
|
|
|
|
self.resetNums()
|
|
|
|
|
|
|
|
def resetNums(self):
|
|
|
|
self.stretchX = 0
|
|
|
|
self.stretchY = 0
|
|
|
|
self.driftX = 0
|
|
|
|
self.driftY = 0
|
|
|
|
self.driftY = 0
|
|
|
|
self.jumpCount = 0
|
|
|
|
self.trampBounceCount = 0
|
|
|
|
self.cameraState = 'Low'
|
|
|
|
|
|
|
|
def offstage(self):
|
|
|
|
self.notify.debug('offstage')
|
|
|
|
DistributedMinigame.offstage(self)
|
|
|
|
if self.music:
|
|
|
|
self.music.stop()
|
|
|
|
if None != self.sndAmbience:
|
|
|
|
self.sndAmbience.stop()
|
|
|
|
self.__killUpdateLocalToonTask()
|
|
|
|
self.__killUpdateShadowsTask()
|
|
|
|
self.__killUpdateEnvironTask()
|
|
|
|
self.__killCountDownTask()
|
|
|
|
del self.soundTable
|
|
|
|
self.__removeAllToonDropShadows()
|
|
|
|
render.clearFog()
|
|
|
|
base.camLens.setFar(ToontownGlobals.DefaultCameraFar)
|
|
|
|
base.camLens.setFov(ToontownGlobals.DefaultCameraFov)
|
|
|
|
camera.setHpr(0, 90, 0)
|
|
|
|
base.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor)
|
|
|
|
self.arrowKeys.destroy()
|
|
|
|
del self.arrowKeys
|
|
|
|
for block in self.environBlocks:
|
|
|
|
del block
|
|
|
|
|
|
|
|
self.environNode.removeNode()
|
|
|
|
del self.environNode
|
|
|
|
for avId in self.avIdList:
|
|
|
|
av = self.getAvatar(avId)
|
|
|
|
if av:
|
|
|
|
av.dropShadow.show()
|
|
|
|
av.resetLOD()
|
|
|
|
|
|
|
|
for band in self.rubberBands:
|
|
|
|
band.delete()
|
|
|
|
|
|
|
|
rubberBands = []
|
|
|
|
self.targetsPlaced = []
|
|
|
|
return
|
|
|
|
|
|
|
|
def handleDisabledAvatar(self, avId):
|
|
|
|
self.notify.debug('handleDisabledAvatar')
|
|
|
|
self.notify.debug('avatar ' + str(avId) + ' disabled')
|
|
|
|
self.__removeToonDropShadow(self.remoteToons[avId])
|
|
|
|
DistributedMinigame.handleDisabledAvatar(self, avId)
|
|
|
|
|
|
|
|
def __genText(self, text):
|
|
|
|
self.__textGen.setText(text)
|
|
|
|
return self.__textGen.generate()
|
|
|
|
|
|
|
|
def __placeToon(self, avId):
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
i = self.avIdList.index(avId)
|
|
|
|
numToons = float(self.numPlayers)
|
|
|
|
x = i * self.TOON_INITIAL_SPACING
|
|
|
|
x -= self.TOON_INITIAL_SPACING * (numToons - 1) / 2.0
|
|
|
|
pos = self.getToonPlace(avId)
|
|
|
|
toon.setPosHpr(pos[0], pos[1], pos[2], 0, 0, 0)
|
|
|
|
|
|
|
|
def getToonPlace(self, avId):
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
i = self.avIdList.index(avId)
|
|
|
|
numToons = float(self.numPlayers)
|
|
|
|
x = i * self.TOON_INITIAL_SPACING
|
|
|
|
x -= self.TOON_INITIAL_SPACING * (numToons - 1) / 2.0
|
|
|
|
pos = Point3(x + self.placeShift, self.TOON_Y, 1.0)
|
|
|
|
return pos
|
|
|
|
|
|
|
|
def setGameReady(self):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameReady')
|
|
|
|
if DistributedMinigame.setGameReady(self):
|
|
|
|
return
|
|
|
|
if not self.isSinglePlayer():
|
|
|
|
base.localAvatar.collisionsOff()
|
|
|
|
cSphere = CollisionSphere(0.0, 0.0, 0.0, TargetGameGlobals.CollisionRadius)
|
|
|
|
cSphereNode = CollisionNode('RingGameSphere-%s' % self.localAvId)
|
|
|
|
cSphereNode.addSolid(cSphere)
|
|
|
|
cSphereNode.setFromCollideMask(TargetGameGlobals.CollideMask)
|
|
|
|
cSphereNode.setIntoCollideMask(BitMask32.allOff())
|
|
|
|
self.cSphereNodePath = base.localAvatar.attachNewNode(cSphereNode)
|
|
|
|
self.pusher = CollisionHandlerPusher()
|
|
|
|
self.pusher.addCollider(self.cSphereNodePath, base.localAvatar)
|
|
|
|
self.pusher.setHorizontal(0)
|
|
|
|
self.cTrav = CollisionTraverser('DistributedRingGame')
|
|
|
|
self.cTrav.addCollider(self.cSphereNodePath, self.pusher)
|
|
|
|
self.remoteToonCollNPs = {}
|
|
|
|
for avId in self.remoteAvIdList:
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
if toon:
|
|
|
|
cSphere = CollisionSphere(0.0, 0.0, 0.0, TargetGameGlobals.CollisionRadius)
|
|
|
|
cSphereNode = CollisionNode('RingGameSphere-%s' % avId)
|
|
|
|
cSphereNode.addSolid(cSphere)
|
|
|
|
cSphereNode.setCollideMask(TargetGameGlobals.CollideMask)
|
|
|
|
cSphereNP = toon.attachNewNode(cSphereNode)
|
|
|
|
self.remoteToonCollNPs[avId] = cSphereNP
|
|
|
|
|
|
|
|
for avId in self.remoteAvIdList:
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
if toon:
|
|
|
|
toon.reparentTo(render)
|
|
|
|
self.__placeToon(avId)
|
|
|
|
toon.setAnimState('SitStart', 1.0)
|
|
|
|
toon.useLOD(self.TOON_LOD)
|
|
|
|
toon.dropShadow.hide()
|
|
|
|
self.__addToonDropShadow(toon)
|
|
|
|
band = RubberBand.RubberBand(toon, Point3(0, -1.75, 0), taskPriority=self.UPDATE_RUBBER_BAND_PRIORITY)
|
|
|
|
tP = self.getToonPlace(avId)
|
|
|
|
pos = Point3(tP[0], tP[1] + 10, tP[2])
|
|
|
|
band.setPos(pos)
|
|
|
|
self.rubberBands.append(band)
|
|
|
|
umbrella = self.umbrella.copyTo(render)
|
|
|
|
self.remoteUmbrellas[avId] = umbrella
|
|
|
|
test = 0
|
|
|
|
kill = 16
|
|
|
|
while test == 0 and kill > 0:
|
|
|
|
kill -= 1
|
|
|
|
pick = random.randint(0, 3)
|
|
|
|
if self.umbrellaColorSelect[pick]:
|
|
|
|
self.umbrellaColorSelect[pick] = 0
|
|
|
|
test = 1
|
|
|
|
|
|
|
|
tex = loader.loadTexture(DistributedTargetGame.UMBRELLA_TEXTURE_LIST[pick])
|
|
|
|
tex.setMinfilter(Texture.FTLinearMipmapLinear)
|
|
|
|
tex.setMagfilter(Texture.FTLinear)
|
|
|
|
umbrella.setTexture(tex, 1)
|
|
|
|
open = umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
open.setPos(0.1, 0.2, -0.1)
|
|
|
|
open.setHpr(-90.0, 180.0, 0.0)
|
|
|
|
open.setScale(1.5)
|
|
|
|
closed = umbrella.find('**/closed_umbrella')
|
|
|
|
closed.show()
|
2020-01-07 15:44:33 -06:00
|
|
|
hand = toon.getRightHands()[0]
|
2019-11-02 17:27:54 -05:00
|
|
|
ce = CompassEffect.make(NodePath(), CompassEffect.PRot)
|
|
|
|
closed.node().setEffect(ce)
|
|
|
|
closed.setHpr(0.0, 90.0, 35.0)
|
|
|
|
umbrella.reparentTo(hand)
|
|
|
|
toon.startSmooth()
|
|
|
|
|
|
|
|
self.remoteToons = {}
|
|
|
|
for avId in self.remoteAvIdList:
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
self.remoteToons[avId] = toon
|
|
|
|
|
|
|
|
labelIndex = 0
|
|
|
|
for avId in self.avIdList:
|
|
|
|
av = self.getAvatar(avId)
|
|
|
|
self.avLabels[labelIndex]['text'] = av.getName()
|
|
|
|
labelIndex += 1
|
|
|
|
|
|
|
|
def setGameStart(self, timestamp):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameStart')
|
|
|
|
DistributedMinigame.setGameStart(self, timestamp)
|
|
|
|
self.gameFSM.request('prelaunch')
|
|
|
|
|
|
|
|
def enterOff(self):
|
|
|
|
self.notify.debug('enterOff')
|
|
|
|
|
|
|
|
def exitOff(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterPrelaunch(self):
|
|
|
|
self.defineConstants()
|
|
|
|
self.resetNums()
|
|
|
|
self.gameFSM.request('launch')
|
|
|
|
self.powerBar.show()
|
|
|
|
self.powerBar['value'] = self.startPower
|
|
|
|
camera.reparentTo(render)
|
|
|
|
self.__placeToon(self.localAvId)
|
|
|
|
toonPos = self.getAvatar(self.localAvId).getPos()
|
|
|
|
newPos = Point3(toonPos[0], toonPos[1] - 25, toonPos[2] + 7)
|
|
|
|
newHpr = Point3(0, -15, 0)
|
|
|
|
self.cameraWork = camera.posHprInterval(2.5, newPos, newHpr, blendType='easeInOut')
|
|
|
|
self.cameraWork.start()
|
|
|
|
base.camLens.setFov(80)
|
|
|
|
self.stretchY = self.startPower
|
|
|
|
self.power = self.startPower
|
|
|
|
self.scoreboard.hide()
|
|
|
|
open = self.umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
closed = self.umbrella.find('**/closed_umbrella')
|
|
|
|
closed.show()
|
|
|
|
self.umbrella.setScale(1.0)
|
|
|
|
if self.targetMarker:
|
|
|
|
self.targetMarker.removeNode()
|
|
|
|
|
|
|
|
def exitPrelaunch(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterLaunch(self):
|
|
|
|
self.__spawnUpdatePowerBarTask()
|
|
|
|
self.__spawnCountDownTask()
|
|
|
|
self.help.show()
|
|
|
|
self.help['text'] = TTLocalizer.TargetGameCountHelp
|
|
|
|
|
|
|
|
def exitLaunch(self):
|
|
|
|
self.cameraWork.finish()
|
|
|
|
self.__killUpdatePowerBarTask()
|
|
|
|
self.speedLaunch = self.power
|
|
|
|
self.powerBar.hide()
|
|
|
|
self.playSound('launch')
|
|
|
|
|
|
|
|
def enterFly(self):
|
|
|
|
self.notify.debug('enterFly')
|
|
|
|
self.__spawnCollisionDetectionTask()
|
|
|
|
self.__placeToon(self.localAvId)
|
|
|
|
self.speedForward = self.speedLaunch
|
|
|
|
self.laterial = -self.launchLaterial * 7
|
|
|
|
self.zVel = self.speedForward * 0.5
|
|
|
|
toon = base.localAvatar
|
|
|
|
toon.b_setAnimState('swim', 1.0)
|
|
|
|
toon.stopBobSwimTask()
|
|
|
|
toon.dropShadow.hide()
|
|
|
|
camera.reparentTo(base.localAvatar)
|
|
|
|
camera.setPosHpr(0, self.CAMERA_Y + self.TOON_Y + 12, 5, 0, -15, 0)
|
|
|
|
base.camLens.setFov(80)
|
|
|
|
self.help.show()
|
|
|
|
self.help['text'] = TTLocalizer.TargetGameFlyHelp
|
|
|
|
self.rubberSound.setVolume(0.0)
|
|
|
|
self.rubberSound.setPlayRate(1.0)
|
|
|
|
self.rubberSound.stop()
|
|
|
|
|
|
|
|
def exitFly(self):
|
|
|
|
taskMgr.remove(self.END_GAME_WAIT_TASK)
|
|
|
|
self.__killCollisionDetectionTask()
|
|
|
|
self.help.hide()
|
|
|
|
|
|
|
|
def enterFall(self):
|
|
|
|
self.notify.debug('enterLaunch')
|
|
|
|
toon = base.localAvatar
|
|
|
|
toon.b_setAnimState('jumpAirborne', 1.0)
|
|
|
|
toon.dropShadow.hide()
|
|
|
|
self.speedForward = self.speedForward * 0.5
|
|
|
|
self.gravity = 4
|
|
|
|
newHpr = Point3(0, -68, 0)
|
|
|
|
newPos = Point3(0, self.CAMERA_Y + self.TOON_Y + 15, 15)
|
2020-01-01 18:21:43 -06:00
|
|
|
camera.posHprInterval(2.5, newPos, newHpr, blendType='easeInOut', name=self.FLY2FALL_CAM_TASK).start()
|
2019-11-02 17:27:54 -05:00
|
|
|
open = self.umbrella.find('**/open_umbrella')
|
|
|
|
open.show()
|
|
|
|
closed = self.umbrella.find('**/closed_umbrella')
|
|
|
|
closed.hide()
|
|
|
|
self.umbrella.setHpr(0, 180.0, -25.0)
|
|
|
|
self.umbrella.setScale(1.5)
|
|
|
|
self.help.show()
|
|
|
|
self.help['text'] = TTLocalizer.TargetGameFallHelp
|
|
|
|
self.playSound('umbrella')
|
|
|
|
self.flutterSound.play()
|
|
|
|
|
|
|
|
def exitFall(self):
|
|
|
|
self.flutterSound.stop()
|
|
|
|
|
|
|
|
def enterBouncing(self):
|
|
|
|
self.notify.debug('enterLaunch')
|
|
|
|
self.gravity = 12.5
|
|
|
|
open = self.umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
closed = self.umbrella.find('**/closed_umbrella')
|
|
|
|
closed.hide()
|
|
|
|
self.umbrella.setHpr(0, 0, 0)
|
|
|
|
self.umbrella.setScale(1.0)
|
|
|
|
toon = base.localAvatar
|
|
|
|
toon.b_setAnimState('neutral', 1.0)
|
|
|
|
toon.dropShadow.hide()
|
|
|
|
self.help.show()
|
|
|
|
self.help['text'] = TTLocalizer.TargetGameBounceHelp
|
|
|
|
|
|
|
|
def exitBouncing(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterScore(self):
|
|
|
|
|
|
|
|
def count(value, list):
|
|
|
|
count = 0
|
|
|
|
for item in list:
|
|
|
|
if value == item:
|
|
|
|
count += 1
|
|
|
|
|
|
|
|
return count
|
|
|
|
|
|
|
|
self.notify.debug('enterScore')
|
|
|
|
self.__killUpdateLocalToonTask()
|
|
|
|
self.__spawnGameDoneTask()
|
|
|
|
self.scoreboard.show()
|
|
|
|
score = 1
|
|
|
|
self.sendUpdate('setScore', [base.localAvatar.getX(), base.localAvatar.getY()])
|
|
|
|
topValue = 0
|
|
|
|
hitTarget = None
|
|
|
|
for target in self.targetsPlaced:
|
|
|
|
radius = self.targetSize[target[2]]
|
|
|
|
value = self.targetValue[target[2]]
|
|
|
|
posX = target[0]
|
|
|
|
posY = target[1]
|
|
|
|
dx = posX - base.localAvatar.getX()
|
|
|
|
dy = posY - base.localAvatar.getY()
|
|
|
|
distance = math.sqrt(dx * dx + dy * dy)
|
|
|
|
if distance < radius and topValue < value:
|
|
|
|
topValue = value
|
|
|
|
hitTarget = target
|
|
|
|
hitX = posX
|
|
|
|
hitY = posY
|
|
|
|
|
|
|
|
if hitTarget:
|
|
|
|
targetGN = GeomNode('target Circle')
|
|
|
|
targetNodePathGeom = self.targets.attachNewNode(targetGN)
|
|
|
|
targetNodePathGeom.setPos(hitX, hitY, 0)
|
|
|
|
addRing(targetGN, TargetGameGlobals.colorBlack, 100, self.targetSize[hitTarget[2]] + 0.5, 0)
|
|
|
|
targetNodePathGeom.setColorScale(TargetGameGlobals.colorWhite['Red'], TargetGameGlobals.colorWhite['Green'], TargetGameGlobals.colorWhite['Blue'], TargetGameGlobals.colorWhite['Alpha'])
|
|
|
|
targetNodePathGeom.setBin('ground', hitTarget[2] * 2 + 100)
|
|
|
|
targetNodePathGeom.setDepthWrite(False)
|
|
|
|
targetNodePathGeom.setDepthTest(False)
|
|
|
|
targetNodePathGeom.setTransparency(TransparencyAttrib.MAlpha)
|
|
|
|
self.targetMarker = targetNodePathGeom
|
|
|
|
score = topValue
|
|
|
|
self.localTrack = Sequence()
|
|
|
|
if self.hitInfo == 'OnButt':
|
|
|
|
self.localTrack.append(ActorInterval(base.localAvatar, 'slip-forward', startFrame=25, endFrame=55))
|
|
|
|
self.hitInfo = 'GettingUp'
|
|
|
|
else:
|
|
|
|
self.localTrack.append(ActorInterval(base.localAvatar, 'slip-forward', startFrame=50, endFrame=55))
|
|
|
|
self.localTrack.append(Wait(0.5))
|
|
|
|
if score <= 1:
|
|
|
|
self.localTrack.append(Parallel(Func(base.localAvatar.b_setAnimState, 'Sad', 1.0), Func(self.playSound, 'miss')))
|
|
|
|
else:
|
|
|
|
self.localTrack.append(Parallel(Func(base.localAvatar.b_setAnimState, 'victory', 1.0), Func(self.playSound, 'score')))
|
|
|
|
newHpr = Point3(180, 10, 0)
|
|
|
|
newPos = Point3(0, -(self.CAMERA_Y + self.TOON_Y + 12), 1)
|
2020-01-01 18:21:43 -06:00
|
|
|
camera.posHprInterval(5.0, newPos, newHpr, blendType='easeInOut', name=self.SCORE_CAM_TASK).start()
|
2019-11-02 17:27:54 -05:00
|
|
|
self.help.hide()
|
|
|
|
self.localTrack.start()
|
|
|
|
return
|
|
|
|
|
|
|
|
def exitScore(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterCleanup(self):
|
|
|
|
self.notify.debug('enterCleanup')
|
|
|
|
if not self.isSinglePlayer():
|
2019-12-30 00:07:56 -06:00
|
|
|
for np in list(self.remoteToonCollNPs.values()):
|
2019-11-02 17:27:54 -05:00
|
|
|
np.removeNode()
|
|
|
|
|
|
|
|
del self.remoteToonCollNPs
|
|
|
|
self.cSphereNodePath.removeNode()
|
|
|
|
del self.cSphereNodePath
|
|
|
|
del self.pusher
|
|
|
|
del self.cTrav
|
|
|
|
base.localAvatar.collisionsOn()
|
|
|
|
|
|
|
|
def exitCleanup(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def signalDone(self):
|
|
|
|
self.sendUpdate('setPlayerDone', [])
|
|
|
|
|
|
|
|
def __spawnUpdatePowerBarTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_POWERBAR_TASK)
|
|
|
|
taskMgr.add(self.__updatePowerBarTask, self.UPDATE_POWERBAR_TASK, priority=self.UPDATE_POWER_BAR_PRIORITY)
|
|
|
|
self.rubberSound.play()
|
|
|
|
self.bandVolume = 0.0
|
|
|
|
|
|
|
|
def __killUpdatePowerBarTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_POWERBAR_TASK)
|
|
|
|
taskMgr.remove(self.TOONSTRETCHTASK)
|
|
|
|
|
|
|
|
def __spawnCountDownTask(self):
|
|
|
|
self.countDown = 10
|
|
|
|
self.signalLaunch = 0
|
|
|
|
taskMgr.remove(self.UPDATE_COUNTDOWN_TASK)
|
|
|
|
self.doCountDown()
|
|
|
|
|
|
|
|
def __killCountDownTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_COUNTDOWN_TASK)
|
|
|
|
|
|
|
|
def __spawnGameDoneTask(self):
|
|
|
|
taskMgr.remove(self.GAME_DONE_TASK)
|
|
|
|
taskMgr.doMethodLater(5.0, self.__gameDone, self.GAME_DONE_TASK)
|
|
|
|
|
|
|
|
def __killUpdateGameDoneTask(self):
|
|
|
|
taskMgr.remove(self.GAME_DONE_TASK)
|
|
|
|
|
|
|
|
def __spawnUpdateLocalToonTask(self):
|
|
|
|
self.__initPosBroadcast()
|
|
|
|
taskMgr.remove(self.UPDATE_LOCALTOON_TASK)
|
|
|
|
taskMgr.add(self.__updateLocalToonTask, self.UPDATE_LOCALTOON_TASK, priority=self.UPDATE_LOCAL_TOON_PRIORITY)
|
|
|
|
|
|
|
|
def __killUpdateLocalToonTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_LOCALTOON_TASK)
|
|
|
|
|
|
|
|
def doCountDown(self, task = None):
|
|
|
|
if self.countDown < 0:
|
|
|
|
self.signalLaunch = 1
|
|
|
|
else:
|
|
|
|
self.powerBar['text'] = TTLocalizer.TargetGameCountdown % self.countDown
|
|
|
|
self.countDown -= 1
|
|
|
|
taskMgr.doMethodLater(1.0, self.doCountDown, self.UPDATE_COUNTDOWN_TASK)
|
|
|
|
|
|
|
|
def __initPosBroadcast(self):
|
|
|
|
self.__posBroadcastPeriod = 0.2
|
|
|
|
self.__timeSinceLastPosBroadcast = 0.0
|
|
|
|
self.__lastPosBroadcast = self.getAvatar(self.localAvId).getPos()
|
|
|
|
self.__storeStop = 0
|
|
|
|
lt = self.getAvatar(self.localAvId)
|
|
|
|
lt.d_clearSmoothing()
|
|
|
|
lt.sendCurrentPosition()
|
|
|
|
|
|
|
|
def __posBroadcast(self, dt):
|
|
|
|
self.__timeSinceLastPosBroadcast += dt
|
|
|
|
if self.__timeSinceLastPosBroadcast > self.__posBroadcastPeriod:
|
|
|
|
self.__timeSinceLastPosBroadcast -= self.__posBroadcastPeriod
|
|
|
|
self.getAvatar(self.localAvId).cnode.broadcastPosHprFull()
|
|
|
|
|
|
|
|
def __spawnUpdateEnvironTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_ENVIRON_TASK)
|
|
|
|
taskMgr.add(self.__updateEnvironTask, self.UPDATE_ENVIRON_TASK)
|
|
|
|
|
|
|
|
def __killUpdateEnvironTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_ENVIRON_TASK)
|
|
|
|
|
|
|
|
def __updateEnvironTask(self, task):
|
|
|
|
return
|
|
|
|
dt = globalClock.getDt()
|
|
|
|
self.speedForward = self.speedForward - self.speedForward * self.airResistance * dt
|
|
|
|
t = globalClock.getFrameTime() - self.__timeBase
|
|
|
|
self.distance = self.distance + dt * self.speedForward
|
|
|
|
distance = self.distance
|
|
|
|
distance %= self.ENVIRON_LENGTH
|
|
|
|
self.environNode.setY(-distance)
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def __updatePowerBarTask(self, task):
|
|
|
|
powerUp = 0
|
|
|
|
timeDiff = None
|
|
|
|
if not self.arrowKeys.rightPressed():
|
|
|
|
self.canPressRight = 1
|
|
|
|
elif self.arrowKeys.rightPressed() and self.canPressRight:
|
|
|
|
powerUp = 1
|
|
|
|
self.canPressRight = 0
|
|
|
|
if not self.arrowKeys.leftPressed():
|
|
|
|
self.canPressLeft = 1
|
|
|
|
elif self.arrowKeys.leftPressed() and self.canPressLeft:
|
|
|
|
powerUp = 1
|
|
|
|
self.canPressLeft = 0
|
|
|
|
if self.lastPressTime:
|
|
|
|
timeDiff = globalClock.getFrameTime() - self.lastPressTime
|
|
|
|
if powerUp and not self.lastPressTime:
|
|
|
|
self.lastPressTime = globalClock.getFrameTime()
|
|
|
|
self.ticker = 0.0
|
|
|
|
elif powerUp:
|
|
|
|
splitTime = abs(timeDiff)
|
|
|
|
if splitTime < 0.15:
|
|
|
|
splitTime = 0.15
|
|
|
|
self.power += 0.6 / abs(timeDiff) + 5.0
|
|
|
|
self.lastPressTime = globalClock.getFrameTime()
|
|
|
|
self.powerBar['value'] = self.power
|
|
|
|
if self.signalLaunch:
|
|
|
|
self.lastPressTime = 1
|
|
|
|
self.ticker = 1
|
|
|
|
timeDiff = 100000
|
|
|
|
if self.lastPressTime:
|
|
|
|
self.ticker += globalClock.getDt()
|
|
|
|
if self.ticker >= 0.1:
|
|
|
|
self.ticker = 0.0
|
|
|
|
powerDiv = 0.05
|
|
|
|
self.power -= 1.0 + 0.2 * (self.power * powerDiv * (self.power * powerDiv))
|
2019-12-31 00:11:28 -06:00
|
|
|
if timeDiff is not None and timeDiff > 0.5:
|
2019-11-02 17:27:54 -05:00
|
|
|
self.power = self.powerBar['value']
|
|
|
|
self.signalLaunch = 0
|
|
|
|
if self.power > 120:
|
|
|
|
self.power = 120
|
|
|
|
if self.power < 40:
|
|
|
|
self.power = 40
|
|
|
|
self.gameFSM.request('fly')
|
|
|
|
self.stretchY = 0.9 * self.stretchY + 0.1 * self.power
|
|
|
|
self.stretchX = 0.9 * self.stretchX + 0.1 * self.launchLaterial
|
|
|
|
base.localAvatar.setY(self.localStartPos[1] - self.stretchY * 0.12)
|
|
|
|
base.localAvatar.setX(self.localStartPos[0] + self.stretchX)
|
|
|
|
dt = globalClock.getDt()
|
|
|
|
self.__posBroadcast(dt)
|
|
|
|
stretchDiff = abs(self.stretchY - self.power) * 0.2
|
|
|
|
self.bandVolume += stretchDiff
|
|
|
|
self.bandVolume -= globalClock.getDt()
|
|
|
|
self.rubberSound.setVolume(self.bandVolume)
|
|
|
|
self.rubberSound.setPlayRate(1.0 + self.stretchY / 120.0)
|
|
|
|
return task.cont
|
|
|
|
|
|
|
|
def __updateLocalToonTask(self, task):
|
|
|
|
stateName = None
|
|
|
|
if self.gameFSM.getCurrentState():
|
|
|
|
stateName = self.gameFSM.getCurrentState().getName()
|
|
|
|
toonPos = self.getAvatar(self.localAvId).getPos()
|
|
|
|
dt = globalClock.getDt()
|
|
|
|
if stateName == 'fall':
|
|
|
|
self.speedForward = self.speedForward - self.speedForward * self.umbrellaResistance * dt
|
|
|
|
self.laterial = self.laterial - self.laterial * self.umbrellaResistance * dt
|
|
|
|
if toonPos[2] > 350.0:
|
|
|
|
diff = toonPos[2] - 350.0
|
|
|
|
self.speedForward += -diff * dt * 0.05
|
|
|
|
else:
|
|
|
|
self.speedForward = self.speedForward - self.speedForward * self.airResistance * dt
|
|
|
|
self.laterial = self.laterial - self.laterial * self.airResistance * dt
|
|
|
|
t = globalClock.getFrameTime() - self.__timeBase
|
|
|
|
self.distance = self.distance + dt * self.speedForward
|
|
|
|
if self.distance > self.maxDist:
|
|
|
|
self.distance = self.maxDist
|
|
|
|
if stateName in ['fall', 'bouncing']:
|
|
|
|
if self.distance < 15.0:
|
|
|
|
self.distance = 15.0
|
|
|
|
pos = [toonPos[0], self.distance, toonPos[2]]
|
|
|
|
if stateName in ['fly', 'fall']:
|
|
|
|
pos[0] += dt * self.laterial
|
|
|
|
liftMult = 0
|
|
|
|
if stateName == 'fly':
|
|
|
|
if self.arrowKeys.upPressed():
|
|
|
|
pass
|
|
|
|
if self.arrowKeys.downPressed():
|
|
|
|
self.gameFSM.request('fall')
|
|
|
|
elif stateName == 'fall':
|
|
|
|
if self.driftX > self.TOONXZ_SPEED:
|
|
|
|
self.driftX = self.TOONXZ_SPEED
|
|
|
|
if self.driftX < -self.TOONXZ_SPEED:
|
|
|
|
self.driftX = -self.TOONXZ_SPEED
|
|
|
|
if self.driftY > self.TOONXZ_SPEED:
|
|
|
|
self.driftY = self.TOONXZ_SPEED
|
|
|
|
if self.driftY < -self.TOONXZ_SPEED:
|
|
|
|
self.driftY = -self.TOONXZ_SPEED
|
|
|
|
if self.arrowKeys.rightPressed():
|
|
|
|
self.driftX += self.TOONXZ_SPEED * dt
|
|
|
|
if self.arrowKeys.leftPressed():
|
|
|
|
self.driftX -= self.TOONXZ_SPEED * dt
|
|
|
|
if self.arrowKeys.upPressed():
|
|
|
|
self.driftY += self.TOONXZ_SPEED * dt
|
|
|
|
if self.arrowKeys.downPressed():
|
|
|
|
self.driftY -= self.TOONXZ_SPEED * dt
|
|
|
|
pos[0] += self.driftX * dt
|
|
|
|
pos[1] += self.driftY * dt
|
|
|
|
self.distance = pos[1]
|
|
|
|
liftMult = 1
|
|
|
|
elif stateName == 'bouncing':
|
|
|
|
pos[0] += self.driftX * dt
|
|
|
|
pos[1] += self.driftY * dt
|
|
|
|
self.distance = pos[1]
|
|
|
|
else:
|
|
|
|
xVel = 0.0
|
|
|
|
if self.arrowKeys.leftPressed():
|
|
|
|
xVel -= self.TOONXZ_SPEED
|
|
|
|
if self.arrowKeys.rightPressed():
|
|
|
|
xVel += self.TOONXZ_SPEED
|
|
|
|
self.launchLaterial += xVel * dt
|
|
|
|
if self.launchLaterial < -TargetGameGlobals.MAX_LAT:
|
|
|
|
self.launchLaterial = -TargetGameGlobals.MAX_LAT
|
|
|
|
if self.launchLaterial > TargetGameGlobals.MAX_LAT:
|
|
|
|
self.launchLaterial = TargetGameGlobals.MAX_LAT
|
|
|
|
pos[0] = self.getToonPlace(self.localAvId)[0] - self.launchLaterial
|
|
|
|
lift = (self.speedForward - self.speedStall) / self.speedStall * liftMult
|
|
|
|
onScreenDebug.removeAllWithPrefix(self.getDisplayPrefix())
|
|
|
|
onScreenDebug.add('%s Vel' % self.getDisplayPrefix(), self.zVel)
|
|
|
|
onScreenDebug.add('%s Lift' % self.getDisplayPrefix(), lift)
|
|
|
|
onScreenDebug.add('%s Gravity' % self.getDisplayPrefix(), self.gravity)
|
|
|
|
onScreenDebug.add('%s Pos' % self.getDisplayPrefix(), pos[2])
|
|
|
|
onScreenDebug.add('%s Drifty' % self.getDisplayPrefix(), self.driftY)
|
|
|
|
if lift < 0:
|
|
|
|
lift = 0
|
|
|
|
upforce = lift * 10.0 - self.gravity
|
|
|
|
self.zVel += (lift - self.gravity) * dt
|
|
|
|
pos[2] += self.zVel * dt
|
|
|
|
if pos[2] < self.trampZ:
|
|
|
|
if self.jumpCount:
|
|
|
|
self.playSound('trampoline')
|
|
|
|
rebound = 0.75
|
|
|
|
if self.trampBounceCount >= 1:
|
|
|
|
rebound = 0.5
|
|
|
|
self.gameFSM.request('bouncing')
|
|
|
|
pos[2] = self.trampZ
|
|
|
|
if self.zVel != 0:
|
|
|
|
signZ = self.zVel / abs(self.zVel)
|
|
|
|
else:
|
|
|
|
signZ = 1
|
|
|
|
self.zVel = -(self.zVel * rebound - signZ * 1.0)
|
|
|
|
self.trampBounceCount += 1
|
|
|
|
if abs(self.zVel) < 1.0:
|
|
|
|
self.zVel = 0
|
|
|
|
toon = base.localAvatar
|
|
|
|
if stateName in ['fly', 'fall', 'bouncing']:
|
|
|
|
toon.b_setAnimState('neutral', 1.0)
|
|
|
|
toon.dropShadow.hide()
|
|
|
|
self.gameFSM.request('score')
|
|
|
|
elif pos[2] < 0.1:
|
|
|
|
toon = base.localAvatar
|
|
|
|
if stateName == 'fall' or stateName == 'fly':
|
|
|
|
self.gameFSM.request('bouncing')
|
|
|
|
if stateName == 'fly':
|
|
|
|
ivolume = math.sqrt(abs(self.zVel) / 40.0)
|
|
|
|
self.hitInfo = 'OnButt'
|
|
|
|
self.localTrack = ActorInterval(toon, 'slip-forward', startFrame=12, endFrame=24)
|
|
|
|
self.localTrack.start()
|
|
|
|
self.playSound('impact', ivolume)
|
|
|
|
self.playSound('bounce', ivolume)
|
|
|
|
elif stateName == 'fall' or stateName == 'bouncing':
|
|
|
|
ivolume = math.sqrt(abs(self.zVel) / 40.0)
|
|
|
|
if ivolume > 0.4:
|
|
|
|
if self.hitInfo == 'OnButt':
|
|
|
|
self.localTrack = ActorInterval(toon, 'slip-forward', startFrame=13, endFrame=24)
|
|
|
|
self.localTrack.start()
|
|
|
|
else:
|
|
|
|
self.localTrack = ActorInterval(toon, 'jump-land', startFrame=6, endFrame=21)
|
|
|
|
self.localTrack.start()
|
|
|
|
self.playSound('bounce', ivolume)
|
|
|
|
pos[2] = 0.1
|
|
|
|
rebound = 0.5
|
|
|
|
self.speedForward = self.speedForward * rebound
|
|
|
|
self.driftX = self.driftX * rebound
|
|
|
|
self.driftY = self.driftY * rebound
|
|
|
|
toon = base.localAvatar
|
|
|
|
if self.zVel != 0:
|
|
|
|
signZ = self.zVel / abs(self.zVel)
|
|
|
|
else:
|
|
|
|
signZ = 1
|
|
|
|
self.zVel = -(self.zVel * rebound - signZ * 1.0)
|
|
|
|
if abs(self.zVel) < 1.0:
|
|
|
|
self.zVel = 0
|
|
|
|
if stateName == 'fly' or stateName == 'bouncing':
|
|
|
|
self.gameFSM.request('score')
|
|
|
|
if pos[0] > TargetGameGlobals.MAX_FIELD_SPAN:
|
|
|
|
pos[0] = TargetGameGlobals.MAX_FIELD_SPAN
|
|
|
|
self.laterial = 0
|
|
|
|
if pos[0] < -TargetGameGlobals.MAX_FIELD_SPAN:
|
|
|
|
pos[0] = -TargetGameGlobals.MAX_FIELD_SPAN
|
|
|
|
self.laterial = 0
|
|
|
|
self.getAvatar(self.localAvId).setPos(pos[0], pos[1], pos[2])
|
|
|
|
if hasattr(self, 'cTrav'):
|
|
|
|
self.cTrav.traverse(render)
|
|
|
|
if stateName in ['fly', 'fall', 'bouncing']:
|
|
|
|
self.__posBroadcast(dt)
|
|
|
|
visZ = camera.getZ(render)
|
|
|
|
lowHeight = 100
|
|
|
|
lowRange = 20
|
|
|
|
opacityLow = 1
|
|
|
|
baseOpLow = 0.6
|
|
|
|
baseTransLow = 1.0 - baseOpLow
|
|
|
|
if visZ < lowHeight - lowRange or visZ > lowHeight + lowRange:
|
|
|
|
transLow = 1.0
|
|
|
|
else:
|
|
|
|
dif = abs(visZ - lowHeight)
|
|
|
|
transLow = dif / lowRange
|
|
|
|
for item in self.skyListLow:
|
|
|
|
item.setColorScale(1.0, 1.0, 1.0, transLow * baseOpLow)
|
|
|
|
|
|
|
|
midHeight = 126
|
|
|
|
midRange = 20
|
|
|
|
opacityMid = 1
|
|
|
|
baseOpMid = 1.0
|
|
|
|
baseTransMid = 1.0 - baseOpMid
|
|
|
|
if visZ < midHeight - midRange or visZ > midHeight + midRange:
|
|
|
|
transMid = 1.0
|
|
|
|
else:
|
|
|
|
dif = abs(visZ - midHeight)
|
|
|
|
transMid = dif / midRange
|
|
|
|
for item in self.skyListMid:
|
|
|
|
item.setColorScale(1.0, 1.0, 1.0, transMid * baseOpMid)
|
|
|
|
|
|
|
|
minTrans = min(1.0, transMid, transLow)
|
|
|
|
fogVis = 1.0 - minTrans
|
|
|
|
fogColor = self.AMB_COLOR * minTrans + self.CLOUD_COLOR * fogVis
|
|
|
|
fogRange = minTrans * self.FOGDISTGROUND + fogVis * self.FOGDISTCLOUD
|
|
|
|
newCamState = 'Low'
|
|
|
|
if visZ > midHeight:
|
|
|
|
newCamState = 'High'
|
|
|
|
if self.cameraState != newCamState:
|
|
|
|
self.cameraState = newCamState
|
|
|
|
self.cloudRendering('High')
|
|
|
|
elif visZ > lowHeight:
|
|
|
|
newCamState = 'Mid'
|
|
|
|
if self.cameraState != newCamState:
|
|
|
|
if self.cameraState == 'Low':
|
|
|
|
self.playSound('wind1')
|
|
|
|
self.cameraState = newCamState
|
|
|
|
self.cloudRendering('Mid')
|
|
|
|
else:
|
|
|
|
newCamState = 'Low'
|
|
|
|
if self.cameraState != newCamState:
|
|
|
|
self.cameraState = newCamState
|
|
|
|
self.cloudRendering('Low')
|
|
|
|
overlayOp = 0.5
|
|
|
|
self.fogOver.setOpacity(fogVis * overlayOp)
|
|
|
|
vol = (self.speedForward + abs(self.zVel)) / 120.0
|
|
|
|
self.flySound.setVolume(vol)
|
|
|
|
self.flySound.setPlayRate(1.0 + abs(self.zVel) * 0.005)
|
|
|
|
if self.updateTick % 5 == 0:
|
|
|
|
for avId in self.remoteAvIdList:
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
if toon:
|
|
|
|
state = toon.animFSM.getCurrentState().getName()
|
|
|
|
umbrella = self.remoteUmbrellas.get(avId)
|
|
|
|
if umbrella:
|
|
|
|
if state == 'Sit':
|
|
|
|
open = umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
closed = umbrella.find('**/closed_umbrella')
|
|
|
|
closed.show()
|
|
|
|
elif state == 'swim':
|
|
|
|
open = umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
closed = umbrella.find('**/closed_umbrella')
|
|
|
|
closed.show()
|
|
|
|
elif state == 'jumpAirborne':
|
|
|
|
open = umbrella.find('**/open_umbrella')
|
|
|
|
open.show()
|
|
|
|
closed = umbrella.find('**/closed_umbrella')
|
|
|
|
closed.hide()
|
|
|
|
elif state == 'neutral':
|
|
|
|
open = umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
closed = umbrella.find('**/closed_umbrella')
|
|
|
|
closed.hide()
|
|
|
|
else:
|
|
|
|
open = umbrella.find('**/open_umbrella')
|
|
|
|
open.hide()
|
|
|
|
closed = umbrella.find('**/closed_umbrella')
|
|
|
|
closed.hide()
|
|
|
|
|
|
|
|
self.updateTick += 1
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def cloudRendering(self, layer):
|
|
|
|
if layer == 'Low':
|
|
|
|
for item in self.skyListMid:
|
|
|
|
item.setBin('fixed', 3)
|
|
|
|
|
|
|
|
for item in self.skyListLow:
|
|
|
|
item.setBin('fixed', 4)
|
|
|
|
|
|
|
|
elif layer == 'Mid':
|
|
|
|
for item in self.skyListMid:
|
|
|
|
item.setBin('fixed', 3)
|
|
|
|
|
|
|
|
for item in self.skyListLow:
|
|
|
|
item.setBin('fixed', 3)
|
|
|
|
|
|
|
|
elif layer == 'High':
|
|
|
|
for item in self.skyListMid:
|
|
|
|
item.setBin('fixed', 4)
|
|
|
|
|
|
|
|
for item in self.skyListLow:
|
|
|
|
item.setBin('fixed', 3)
|
|
|
|
|
|
|
|
def __addDropShadow_INTERNAL(self, object, scale_x, scale_y, scale_z, list):
|
|
|
|
shadow = self.dropShadowModel.copyTo(render)
|
|
|
|
shadow.setPos(0, self.CAMERA_Y, -100)
|
|
|
|
shadow.setBin('shadow', 100)
|
|
|
|
shadow.setDepthWrite(False)
|
|
|
|
shadow.setDepthTest(True)
|
|
|
|
shadow.setScale(scale_x, scale_y, scale_z)
|
|
|
|
list.append([shadow, object])
|
|
|
|
|
|
|
|
def __removeDropShadow_INTERNAL(self, object, list):
|
|
|
|
for i in range(len(list)):
|
|
|
|
entry = list[i]
|
|
|
|
if entry[1] == object:
|
|
|
|
entry[0].removeNode()
|
|
|
|
list.pop(i)
|
|
|
|
return
|
|
|
|
|
|
|
|
self.notify.warning('parent object ' + str(object) + ' not found in drop shadow list!')
|
|
|
|
|
|
|
|
def __addToonDropShadow(self, object):
|
|
|
|
self.__addDropShadow_INTERNAL(object, 0.5, 0.5, 0.5, self.toonDropShadows)
|
|
|
|
|
|
|
|
def __removeToonDropShadow(self, object):
|
|
|
|
self.__removeDropShadow_INTERNAL(object, self.toonDropShadows)
|
|
|
|
|
|
|
|
def __removeAllToonDropShadows(self):
|
|
|
|
for entry in self.toonDropShadows:
|
|
|
|
entry[0].removeNode()
|
|
|
|
|
|
|
|
self.toonDropShadows = []
|
|
|
|
|
|
|
|
def __spawnUpdateShadowsTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_SHADOWS_TASK)
|
|
|
|
taskMgr.add(self.__updateShadowsTask, self.UPDATE_SHADOWS_TASK, priority=self.UPDATE_SHADOWS_PRIORITY)
|
|
|
|
|
|
|
|
def __killUpdateShadowsTask(self):
|
|
|
|
taskMgr.remove(self.UPDATE_SHADOWS_TASK)
|
|
|
|
|
|
|
|
def __updateShadowsTask(self, task):
|
|
|
|
list = self.toonDropShadows
|
|
|
|
for entry in list:
|
|
|
|
object = entry[1]
|
|
|
|
y = object.getY(render)
|
|
|
|
x = object.getX(render)
|
|
|
|
if self.jumpCount and object == base.localAvatar:
|
|
|
|
z = self.trampZ + self.SHADOW_Z_OFFSET
|
|
|
|
else:
|
|
|
|
z = 0.0 + self.SHADOW_Z_OFFSET
|
|
|
|
shadow = entry[0]
|
|
|
|
shadow.setPos(x, y, z)
|
|
|
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def __spawnCollisionDetectionTask(self):
|
|
|
|
self.__ringGroupsPassed = 0
|
|
|
|
taskMgr.remove(self.COLLISION_DETECTION_TASK)
|
|
|
|
taskMgr.add(self.__collisionDetectionTask, self.COLLISION_DETECTION_TASK, priority=self.COLLISION_DETECTION_PRIORITY)
|
|
|
|
|
|
|
|
def __killCollisionDetectionTask(self):
|
|
|
|
taskMgr.remove(self.COLLISION_DETECTION_TASK)
|
|
|
|
|
|
|
|
def __collisionDetectionTask(self, task):
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def __endGameDolater(self, task):
|
|
|
|
self.gameOver()
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
def setTimeBase(self, timestamp):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.__timeBase = globalClockDelta.networkToLocalTime(timestamp)
|
|
|
|
|
|
|
|
def setColorIndices(self, a, b, c, d):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.colorIndices = [a,
|
|
|
|
b,
|
|
|
|
c,
|
|
|
|
d]
|
|
|
|
|
|
|
|
def getDisplayPrefix(self):
|
|
|
|
return 'TargetGame'
|
|
|
|
|
|
|
|
def __gameDone(self, task = None):
|
|
|
|
self.signalDone()
|
|
|
|
return task.done
|
|
|
|
|
|
|
|
def setGameDone(self, extra = None):
|
|
|
|
self.gameOver()
|
|
|
|
|
|
|
|
def setRoundDone(self):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.round += 1
|
|
|
|
self.roundLabel['text'] = TTLocalizer.TargetGameBoard % self.round
|
|
|
|
self.reset()
|
|
|
|
self.gameFSM.request('prelaunch')
|
|
|
|
|
|
|
|
def setSingleScore(self, score, avId):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
for existIndex in range(len(self.avIdList)):
|
|
|
|
if self.avIdList[existIndex] == avId:
|
|
|
|
self.scoreLabels[existIndex]['text'] = '%s' % score
|
|
|
|
|
|
|
|
def jumpIn(self, colEntry):
|
|
|
|
self.jumpCount += 1
|
|
|
|
|
|
|
|
def jumpOut(self, colEntry):
|
|
|
|
self.jumpCount -= 1
|
|
|
|
if self.jumpCount < 0:
|
|
|
|
self.jumpCount = 0
|