Poodletooth-iLand/toontown/minigame/TwoDEnemy.py
2015-11-14 14:28:53 -05:00

279 lines
13 KiB
Python

from panda3d.core import *
from direct.directnotify import DirectNotifyGlobal
from direct.showbase.DirectObject import DirectObject
from direct.showbase import PythonUtil
from direct.interval.IntervalGlobal import *
from toontown.minigame import ToonBlitzGlobals
from toontown.toonbase import ToontownGlobals
from toontown.suit import Suit
from toontown.suit import SuitDNA
from toontown.battle.BattleProps import *
from toontown.battle import MovieUtil
from toontown.battle import BattleParticles, BattleProps
from direct.particles import ParticleEffect
import math, random
COLOR_RED = VBase4(1, 0, 0, 0.3)
class TwoDEnemy(DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory('TwoDEnemy')
def __init__(self, enemyMgr, index, suitAttribs):
self.enemyMgr = enemyMgr
self.game = self.enemyMgr.section.sectionMgr.game
self.index = index
self.moveIval = None
self.propTrack = None
self.animTrack = None
self.shotTrack = None
self.deathTrack = None
self.deathSuit = None
self.suitSound = None
self.deleteMeCallback = None
self.isMovingUpDown = False
self.isMovingLeftRight = False
self.showCollSpheres = False
self.isDestroyed = False
self.isGoingUp = False
self.setupEnemy(suitAttribs)
BattleParticles.loadParticles()
return
def destroy(self):
if self.isDestroyed:
return
self.isDestroyed = True
if hasattr(self.suit, 'prop') and self.suit.prop:
self.suit.prop.stash()
if self.propTrack:
self.propTrack.finish()
self.propTrack = None
if self.suitSound:
self.suitSound.stop()
del self.suitSound
if self.animTrack:
self.animTrack.finish()
self.animTrack = None
if self.shotTrack != None:
self.shotTrack.finish()
self.shotTrack = None
if self.deathTrack != None:
self.deathTrack.finish()
self.deathTrack = None
if self.deathSuit:
self.deathSuit.detachNode()
self.suit.cleanupLoseActor()
self.deathSuit = None
if self.moveIval:
self.moveIval.pause()
del self.moveIval
if self.suit:
self.suit.delete()
self.suit = None
BattleParticles.unloadParticles()
self.ignore(self.game.uniqueName('enter' + self.suitName))
self.game = None
self.enemyMgr = None
return
def setupEnemy(self, suitAttribs):
suitType = suitAttribs[0]
self.suit = Suit.Suit()
suitDNA = SuitDNA.SuitDNA()
suitDNA.newSuit(suitType)
self.suit.setDNA(suitDNA)
self.suit.pose('walk', 0)
self.suitName = 'Enemy-%s' % self.index
self.suit.setName(self.suitName)
self.suit.nametag3d.stash()
self.suit.nametag.destroy()
suitPosAttribs = suitAttribs[1]
initX, initY, initZ = suitPosAttribs[0]
initPos = Point3(initX, initY, initZ)
if len(suitPosAttribs) == 3:
finalX, finalY, finalZ = suitPosAttribs[1]
finalPos = Point3(finalX, finalY, finalZ)
posIvalDuration = suitPosAttribs[2]
self.clearMoveIval()
def getForwardIval(blendTypeStr, self = self):
forwardIval = LerpPosInterval(self.suit, posIvalDuration, pos=finalPos, startPos=initPos, name='%s-moveFront' % self.suitName, blendType=blendTypeStr, fluid=1)
return forwardIval
def getBackwardIval(blendTypeStr, self = self):
backwardIval = LerpPosInterval(self.suit, posIvalDuration, pos=initPos, startPos=finalPos, name='%s-moveBack' % self.suitName, blendType=blendTypeStr, fluid=1)
return backwardIval
if abs(finalZ - initZ) > 0.0:
def setIsGoingUp(value):
self.isGoingUp = value
self.isMovingUpDown = True
self.suit.setH(90)
self.suit.prop = None
if self.suit.prop == None:
self.suit.prop = BattleProps.globalPropPool.getProp('propeller')
self.suit.prop.setScale(1.1)
self.suit.prop.setColor(1, 1, 0.6, 1)
head = self.suit.find('**/joint_head')
self.suit.prop.reparentTo(head)
self.propTrack = Sequence(ActorInterval(self.suit.prop, 'propeller', startFrame=8, endFrame=25, playRate=2.0))
self.animTrack = Sequence(ActorInterval(self.suit, 'landing', startFrame=8, endFrame=28, playRate=0.5), ActorInterval(self.suit, 'landing', startFrame=8, endFrame=28, playRate=-0.5))
self.moveIval = Sequence(Func(setIsGoingUp, True), getForwardIval('easeInOut'), Func(setIsGoingUp, False), getBackwardIval('easeInOut'))
self.suitSound = base.loadSfx('phase_4/audio/sfx/TB_propeller.ogg')
else:
self.isMovingLeftRight = True
self.moveIval = Sequence(Func(self.setHeading, finalPos, initPos), getForwardIval('noBlend'), Func(self.setHeading, initPos, finalPos), getBackwardIval('noBlend'))
self.suit.setPos(initX, initY, initZ)
self.suit.dropShadow.hide()
self.setupCollision()
return
def setupCollision(self):
collSphere = CollisionSphere(0, 0, 2, 2)
collSphere.setTangible(1)
collNode = CollisionNode(self.game.uniqueName(self.suitName))
collNode.setIntoCollideMask(ToontownGlobals.WallBitmask)
collNode.addSolid(collSphere)
self.collNodePath = self.suit.attachNewNode(collNode)
self.collNodePath.hide()
if self.showCollSpheres:
self.collNodePath.show()
self.accept(self.game.uniqueName('enter' + self.suitName), self.handleEnemyCollision)
def clearMoveIval(self):
if self.moveIval:
self.moveIval.pause()
del self.moveIval
self.moveIval = None
return
def start(self, elapsedTime):
if self.moveIval:
self.moveIval.loop()
self.moveIval.setT(elapsedTime)
if self.isMovingLeftRight:
self.suit.loop('walk')
elif self.isMovingUpDown:
self.propTrack.loop()
self.animTrack.loop()
base.playSfx(self.suitSound, node=self.suit, looping=1)
def enterPause(self):
if hasattr(self, 'moveIval') and self.moveIval:
self.moveIval.pause()
self.suit.loop('neutral')
if self.suitSound:
self.suitSound.stop()
def exitPause(self):
if hasattr(self, 'moveIval') and self.moveIval:
self.moveIval.resume()
if self.isMovingLeftRight:
self.suit.loop('walk')
elif self.isMovingUpDown:
self.propTrack.loop()
self.animTrack.loop()
base.playSfx(self.suitSound, node=self.suit, looping=1, volume=0.1)
def handleEnemyCollision(self, cevent):
messenger.send('enemyHit')
def setHeading(self, finalPos, initPos):
diffX = finalPos.getX() - initPos.getX()
angle = -90 * diffX / math.fabs(diffX)
startAngle = self.suit.getH()
startAngle = PythonUtil.fitSrcAngle2Dest(startAngle, angle)
dur = 0.1 * abs(startAngle - angle) / 90
self.suitTurnIval = LerpHprInterval(self.suit, dur, Point3(angle, 0, 0), startHpr=Point3(startAngle, 0, 0), name='SuitLerpHpr')
self.suitTurnIval.start()
def blinkColor(self, color, duration):
blink = Sequence(LerpColorScaleInterval(self.suit, 0.5, color, startColorScale=VBase4(1, 1, 1, 1)), LerpColorScaleInterval(self.suit, 0.5, VBase4(1, 1, 1, 1), startColorScale=color))
track = Sequence(Func(blink.loop), Wait(duration), Func(blink.finish))
return track
def doShotTrack(self):
blinkRed = self.blinkColor(COLOR_RED, 2)
point = Point3(self.suit.getX(render), self.suit.getY(render), self.suit.getZ(render) + self.suit.height / 2.0)
scale = 0.3
splashHold = 0.1
def prepSplash(splash, point):
if callable(point):
point = point()
splash.reparentTo(render)
splash.setPos(point)
scale = splash.getScale()
splash.setBillboardPointWorld()
splash.setScale(scale)
splash = globalPropPool.getProp('splash-from-splat')
splash.setScale(scale)
splashTrack = Sequence(Func(prepSplash, splash, point), ActorInterval(splash, 'splash-from-splat'), Wait(splashHold), Func(MovieUtil.removeProp, splash))
self.shotTrack = Parallel(Func(self.game.assetMgr.playSplashSound), blinkRed, splashTrack)
self.shotTrack.start()
def doDeathTrack(self):
def removeDeathSuit(suit, deathSuit):
if not deathSuit.isEmpty():
deathSuit.detachNode()
suit.cleanupLoseActor()
if self.suitSound:
self.suitSound.stop()
self.deathSuit = self.suit.getLoseActor()
self.deathSuit.reparentTo(self.enemyMgr.enemiesNP)
self.deathSuit.setPos(render, self.suit.getPos(render))
self.deathSuit.setHpr(render, self.suit.getHpr(render))
self.suit.hide()
self.collNodePath.reparentTo(self.deathSuit)
treasureSpawnPoint = Point3(self.suit.getX(), self.suit.getY(), self.suit.getZ() + self.suit.height / 2.0)
gearPoint = Point3(0, 0, self.suit.height / 2.0 + 2.0)
spinningSound = base.loadSfx('phase_3.5/audio/sfx/Cog_Death.ogg')
deathSound = base.loadSfx('phase_3.5/audio/sfx/ENC_cogfall_apart_%s.ogg' % random.randint(1, 6))
smallGears = BattleParticles.createParticleEffect(file='gearExplosionSmall')
singleGear = BattleParticles.createParticleEffect('GearExplosion', numParticles=1)
smallGearExplosion = BattleParticles.createParticleEffect('GearExplosion', numParticles=10)
bigGearExplosion = BattleParticles.createParticleEffect('BigGearExplosion', numParticles=30)
smallGears.setPos(gearPoint)
singleGear.setPos(gearPoint)
smallGearExplosion.setPos(gearPoint)
bigGearExplosion.setPos(gearPoint)
smallGears.setDepthWrite(False)
singleGear.setDepthWrite(False)
smallGearExplosion.setDepthWrite(False)
bigGearExplosion.setDepthWrite(False)
if self.isMovingLeftRight:
self.enterPause()
suitTrack = Sequence(Func(self.collNodePath.stash), ActorInterval(self.deathSuit, 'lose', startFrame=80, endFrame=140), Func(removeDeathSuit, self.suit, self.deathSuit, name='remove-death-suit'))
explosionTrack = Sequence(Wait(1.5), MovieUtil.createKapowExplosionTrack(self.deathSuit, explosionPoint=gearPoint))
soundTrack = Sequence(SoundInterval(spinningSound, duration=1.6, startTime=0.6, volume=0.8, node=self.deathSuit), SoundInterval(deathSound, volume=0.32, node=self.deathSuit))
gears1Track = Sequence(ParticleInterval(smallGears, self.deathSuit, worldRelative=0, duration=4.3, cleanup=True), name='gears1Track')
gears2MTrack = Track((0.0, explosionTrack), (0.7, ParticleInterval(singleGear, self.deathSuit, worldRelative=0, duration=5.7, cleanup=True)), (5.2, ParticleInterval(smallGearExplosion, self.deathSuit, worldRelative=0, duration=1.2, cleanup=True)), (5.4, ParticleInterval(bigGearExplosion, self.deathSuit, worldRelative=0, duration=1.0, cleanup=True)), name='gears2MTrack')
elif self.isMovingUpDown:
def getFinalPos():
if self.isGoingUp:
direction = 1.0
else:
direction = -1.0
pos = Point3(self.deathSuit.getX(), self.deathSuit.getY(), self.deathSuit.getZ() + 2.0 * direction)
return pos
deathMoveIval = LerpPosInterval(self.deathSuit, 1.5, pos=getFinalPos(), name='%s-deathSuitMove' % self.suitName, blendType='easeInOut', fluid=1)
suitTrack = Sequence(Func(self.collNodePath.stash), Parallel(ActorInterval(self.deathSuit, 'lose', startFrame=80, endFrame=140), deathMoveIval), Func(removeDeathSuit, self.suit, self.deathSuit, name='remove-death-suit'))
explosionTrack = Sequence(Wait(1.5), MovieUtil.createKapowExplosionTrack(self.deathSuit, explosionPoint=gearPoint))
soundTrack = Sequence(SoundInterval(spinningSound, duration=1.6, startTime=0.6, volume=0.8, node=self.deathSuit), SoundInterval(deathSound, volume=0.32, node=self.deathSuit))
gears1Track = Sequence(ParticleInterval(smallGears, self.deathSuit, worldRelative=0, duration=4.3, cleanup=True), name='gears1Track')
gears2MTrack = Track((0.0, explosionTrack), (0.0, ParticleInterval(singleGear, self.deathSuit, worldRelative=0, duration=5.7, cleanup=True)), (2.7, ParticleInterval(smallGearExplosion, self.deathSuit, worldRelative=0, duration=1.2, cleanup=True)), (2.9, ParticleInterval(bigGearExplosion, self.deathSuit, worldRelative=0, duration=1.0, cleanup=True)), name='gears2MTrack')
def removeParticle(particle):
if particle and hasattr(particle, 'renderParent'):
particle.cleanup()
del particle
removeParticles = Parallel(Func(removeParticle, smallGears), Func(removeParticle, singleGear), Func(removeParticle, smallGearExplosion), Func(removeParticle, bigGearExplosion))
self.deathTrack = Sequence(Parallel(suitTrack, gears2MTrack, gears1Track, soundTrack), removeParticles, Func(self.destroy))
self.deathTrack.start()