toontown-just-works/toontown/effects/Fireworks.py
2024-07-07 18:08:39 -05:00

239 lines
9.5 KiB
Python

from direct.interval.IntervalGlobal import *
from direct.particles import ParticleEffect
from direct.particles import Particles
from direct.particles import ForceGroup
from panda3d.core import *
import random
from FireworkGlobals import *
colors = {WHITE: Vec4(1, 1, 1, 1),
RED: Vec4(1, 0.2, 0.2, 1),
BLUE: Vec4(0.2, 0.2, 1, 1),
YELLOW: Vec4(1, 1, 0.2, 1),
GREEN: Vec4(0.2, 1, 0.2, 1),
PINK: Vec4(1, 0.5, 0.5, 1),
PEACH: Vec4(0.9, 0.6, 0.4, 1),
PURPLE: Vec4(1, 0.1, 1, 1),
CYAN: Vec4(0.2, 1, 1, 1)}
textures = {SNOWFLAKE: 'phase_8/models/props/snowflake_treasure',
MUSICNOTE: 'phase_6/models/props/music_treasure',
FLOWER: 'phase_8/models/props/flower_treasure',
ICECREAM: 'phase_4/models/props/icecream',
STARFISH: 'phase_6/models/props/starfish_treasure',
ZZZ: 'phase_8/models/props/zzz_treasure'}
fireworkId = 0
def getNextSequenceName(name):
global fireworkId
fireworkId += 1
return '%s-%s' % (name, fireworkId)
def getColor(colorIndex):
return colors.get(colorIndex)
def getTexture(textureIndex):
return loader.loadModel(textures.get(textureIndex))
def shootFirework(style, x = 0, y = 0, z = 0, colorIndex1 = 0, colorIndex2 = 0, amp = 10):
func = style2shootFunc.get(style)
color1 = getColor(colorIndex1)
if style is CIRCLESPRITE:
color2 = getTexture(colorIndex2)
else:
color2 = getColor(colorIndex2)
if func and color1 and color2:
return func(x, y, z, color1, color2, amp)
def shootFireworkRing(x, y, z, color1, color2, amp):
f = ParticleEffect.ParticleEffect()
p0 = Particles.Particles('particles-1')
p0.setFactory('PointParticleFactory')
p0.setRenderer('SparkleParticleRenderer')
p0.setEmitter('RingEmitter')
p0.setPoolSize(100)
p0.setBirthRate(0.01)
p0.setLitterSize(100)
p0.setLitterSpread(0)
p0.factory.setLifespanBase(1.5)
p0.factory.setLifespanSpread(0.5)
p0.factory.setMassBase(1.0)
p0.factory.setMassSpread(0.0)
p0.factory.setTerminalVelocityBase(20.0)
p0.factory.setTerminalVelocitySpread(2.0)
p0.renderer.setAlphaMode(BaseParticleRenderer.PRALPHAOUT)
p0.renderer.setUserAlpha(1.0)
p0.renderer.setCenterColor(color1)
p0.renderer.setEdgeColor(color2)
p0.renderer.setBirthRadius(0.3)
p0.renderer.setDeathRadius(0.3)
p0.renderer.setLifeScale(SparkleParticleRenderer.SPNOSCALE)
p0.emitter.setEmissionType(BaseParticleEmitter.ETRADIATE)
p0.emitter.setAmplitude(0)
p0.emitter.setAmplitudeSpread(0)
f0 = ForceGroup.ForceGroup('gravity')
force0 = LinearSourceForce(Point3(x, y, z), LinearDistanceForce.FTONEOVERR, 0.1, 1.1 * amp, 1)
force0.setActive(1)
f0.addForce(force0)
force1 = LinearSinkForce(Point3(x, y, z), LinearDistanceForce.FTONEOVERR, 0.5, 2.0 * amp, 1)
force1.setActive(1)
f0.addForce(force1)
f.addForceGroup(f0)
p0.emitter.setRadius(4.0)
f.addParticles(p0)
f.setPos(x, y, z)
f.setHpr(0, random.random() * 180, random.random() * 180)
sfx = loader.loadSfx('phase_4/audio/sfx/firework_distance_03.ogg')
sfx.setVolume(0.7)
t = Sequence(Func(f.start, render, render), Func(sfx.play), Wait(0.5), Func(p0.setBirthRate, 3), Wait(1.5), Func(f.cleanup), name=getNextSequenceName('shootFireworkRing'))
t.start()
def shootFireworkRocket(x, y, z, color1, color2, amp):
f = ParticleEffect.ParticleEffect()
p0 = Particles.Particles('particles-1')
p0.setFactory('PointParticleFactory')
p0.setRenderer('SparkleParticleRenderer')
p0.setEmitter('SphereVolumeEmitter')
p0.setPoolSize(110)
p0.setBirthRate(0.01)
p0.setLitterSize(2)
p0.setLitterSpread(0)
p0.factory.setLifespanBase(0.4)
p0.factory.setLifespanSpread(0.1)
p0.factory.setMassBase(1.0)
p0.factory.setMassSpread(0.0)
p0.factory.setTerminalVelocityBase(400.0)
p0.factory.setTerminalVelocitySpread(0.0)
p0.renderer.setAlphaMode(BaseParticleRenderer.PRALPHAOUT)
p0.renderer.setUserAlpha(1.0)
p0.renderer.setCenterColor(color1)
p0.renderer.setEdgeColor(color2)
p0.renderer.setBirthRadius(0.6)
p0.renderer.setDeathRadius(0.6)
p0.renderer.setLifeScale(SparkleParticleRenderer.SPNOSCALE)
p0.emitter.setEmissionType(BaseParticleEmitter.ETRADIATE)
p0.emitter.setAmplitude(amp)
p0.emitter.setAmplitudeSpread(0.0)
p0.emitter.setRadius(0.3)
f.addParticles(p0)
gravityForceGroup = ForceGroup.ForceGroup('gravity')
force0 = LinearVectorForce(Vec3(0.0, 0.0, -10.0), 1.0, 0)
force0.setActive(1)
gravityForceGroup.addForce(force0)
f.addForceGroup(gravityForceGroup)
f.setPos(x, y, z)
sfxName = random.choice(('phase_4/audio/sfx/firework_whistle_01.ogg', 'phase_4/audio/sfx/firework_whistle_02.ogg'))
sfx = loader.loadSfx(sfxName)
sfx.setVolume(0.4)
t = Sequence(Func(f.start, render, render), Func(sfx.play), LerpPosInterval(f, 2.0, Vec3(x, y, z + 20 * amp), blendType='easeInOut'), Func(p0.setBirthRate, 3), Wait(0.5), Func(f.cleanup), name=getNextSequenceName('shootFirework'))
t.start()
def shootPop(x, y, z, color1, color2, amp):
sfxName = random.choice(('phase_4/audio/sfx/firework_distance_01.ogg', 'phase_4/audio/sfx/firework_distance_02.ogg', 'phase_4/audio/sfx/firework_distance_03.ogg'))
sfx = loader.loadSfx(sfxName)
t = Sequence(Func(sfx.play), Wait(3), name=getNextSequenceName('shootFireworkRocket'))
t.start()
def shootFireworkCircle(x, y, z, color1, color2, amp):
return shootFireworkCircleGeneric(x, y, z, color1, color2, amp, 100)
def shootFireworkCircleLarge(x, y, z, color1, color2, amp):
return shootFireworkCircleGeneric(x, y, z, color1, color2, amp * 1.5, 200)
def shootFireworkCircleSmall(x, y, z, color1, color2, amp):
return shootFireworkCircleGeneric(x, y, z, color1, color2, amp * 0.5, 50)
def shootFireworkCircleGeneric(x, y, z, color1, color2, amp, poolSize):
f = ParticleEffect.ParticleEffect()
p0 = Particles.Particles('particles-1')
p0.setFactory('PointParticleFactory')
p0.setRenderer('SparkleParticleRenderer')
p0.setEmitter('SphereVolumeEmitter')
p0.setPoolSize(poolSize)
p0.setBirthRate(0.01)
p0.setLitterSize(poolSize)
p0.factory.setLifespanBase(2.0)
p0.factory.setLifespanSpread(0.5)
p0.factory.setTerminalVelocityBase(400.0)
p0.factory.setTerminalVelocitySpread(40.0)
p0.renderer.setAlphaMode(BaseParticleRenderer.PRALPHAOUT)
p0.renderer.setUserAlpha(1.0)
p0.renderer.setCenterColor(color1)
p0.renderer.setEdgeColor(color1)
p0.renderer.setBirthRadius(0.4)
p0.renderer.setDeathRadius(0.6)
p0.renderer.setLifeScale(SparkleParticleRenderer.SPSCALE)
p0.emitter.setEmissionType(BaseParticleEmitter.ETRADIATE)
p0.emitter.setAmplitudeSpread(0.1)
p0.emitter.setAmplitude(amp)
p0.emitter.setRadius(0.1)
f.addParticles(p0)
circleForceGroup = ForceGroup.ForceGroup('gravity')
force1 = LinearSinkForce(Point3(x, y, z - 100), LinearDistanceForce.FTONEOVERRSQUARED, 2.0, 0.3 * amp * 0.1, 1)
force1.setActive(1)
circleForceGroup.addForce(force1)
f.addForceGroup(circleForceGroup)
f.setPos(x, y, z)
sfxName = random.choice(('phase_4/audio/sfx/firework_explosion_01.ogg', 'phase_4/audio/sfx/firework_explosion_02.ogg', 'phase_4/audio/sfx/firework_explosion_03.ogg'))
sfx = loader.loadSfx(sfxName)
sfx.setVolume(0.7)
t = Sequence(Func(f.start, render, render), Func(sfx.play), Wait(0.5), Func(p0.setBirthRate, 3), Wait(0.5), Func(p0.renderer.setCenterColor, color2), Func(p0.renderer.setEdgeColor, color2), Wait(1.5), Func(f.cleanup), name=getNextSequenceName('shootFireworkCircle'))
t.start()
def shootFireworkCircleSprite(x, y, z, color, texture, amp):
f = ParticleEffect.ParticleEffect()
p0 = Particles.Particles('particles-1')
p0.setFactory('PointParticleFactory')
p0.setRenderer('SpriteParticleRenderer')
p0.setEmitter('SphereVolumeEmitter')
p0.setPoolSize(100)
p0.setBirthRate(0.01)
p0.setLitterSize(100)
p0.factory.setLifespanBase(2.0)
p0.factory.setLifespanSpread(0.5)
p0.factory.setTerminalVelocityBase(400.0)
p0.factory.setTerminalVelocitySpread(40.0)
p0.renderer.setAlphaMode(BaseParticleRenderer.PRALPHAUSER)
p0.renderer.setUserAlpha(1.0)
p0.renderer.setFromNode(texture)
p0.renderer.setColor(color)
p0.renderer.setXScaleFlag(1)
p0.renderer.setYScaleFlag(1)
p0.renderer.setInitialXScale(0.12)
p0.renderer.setFinalXScale(0.48)
p0.renderer.setInitialYScale(0.12)
p0.renderer.setFinalYScale(0.48)
p0.emitter.setEmissionType(BaseParticleEmitter.ETRADIATE)
p0.emitter.setAmplitudeSpread(0.1)
p0.emitter.setAmplitude(amp)
p0.emitter.setRadius(0.1)
f.addParticles(p0)
circleForceGroup = ForceGroup.ForceGroup('gravity')
force1 = LinearSinkForce(Point3(x, y, z - 100), LinearDistanceForce.FTONEOVERRSQUARED, 2.0, 0.3 * amp * 0.1, 1)
force1.setActive(1)
circleForceGroup.addForce(force1)
f.addForceGroup(circleForceGroup)
f.setPos(x, y, z)
sfxName = random.choice(('phase_4/audio/sfx/firework_explosion_01.ogg', 'phase_4/audio/sfx/firework_explosion_02.ogg', 'phase_4/audio/sfx/firework_explosion_03.ogg'))
sfx = loader.loadSfx(sfxName)
sfx.setVolume(0.7)
t = Sequence(Func(f.start, render, render), Func(sfx.play), Wait(0.5), Func(p0.setBirthRate, 3), Wait(2.0), Func(f.cleanup), name=getNextSequenceName('shootFireworkSprite'))
t.start()
style2shootFunc = {CIRCLE: shootFireworkCircle,
CIRCLELARGE: shootFireworkCircleLarge,
CIRCLESMALL: shootFireworkCircleSmall,
CIRCLESPRITE: shootFireworkCircleSprite,
ROCKET: shootFireworkRocket,
RING: shootFireworkRing,
POP: shootPop}