class FountainPenAttack(Attack): notify = directNotify.newCategory('FountainPenAttack') attack = 'fountainpen' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.pen = None self.spray = None self.splat = None self.spraySfx = None self.sprayParticle = None self.sprayScaleIval = None self.wsnp = None return def loadAttack(self): self.pen = loader.loadModel('phase_5/models/props/pen.bam') self.pen.reparentTo(self.suit.find('**/joint_Rhold')) self.sprayParticle = ParticleLoader.loadParticleEffect('phase_5/etc/penSpill.ptf') self.spray = loader.loadModel('phase_3.5/models/props/spray.bam') self.spray.setColor(VBase4(0, 0, 0, 1)) self.splat = Actor('phase_3.5/models/props/splat-mod.bam', {'chan': 'phase_3.5/models/props/splat-chan.bam'}) self.splat.setColor(VBase4(0, 0, 0, 1)) self.sprayScaleIval = LerpScaleInterval(self.spray, duration=0.3, scale=(1, 20, 1), startScale=(1, 1, 1)) sphere = CollisionSphere(0, 0, 0, 0.5) sphere.setTangible(0) if hasattr(self.suit, 'uniqueName'): collName = self.suit.uniqueName('fountainPenCollNode') else: collName = 'fountainPenCollNode' collNode = CollisionNode(collName) collNode.addSolid(sphere) collNode.setCollideMask(CIGlobals.WallBitmask) self.wsnp = self.spray.attachNewNode(collNode) self.wsnp.setY(1) def doAttack(self, ts = 0): self.loadAttack() if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doFountainPenAttack') else: name = 'doFountainPenAttack' self.suitTrack = Parallel(name=name) self.suitTrack.append(ActorInterval(self.suit, 'fountainpen')) self.suitTrack.append(Sequence(Wait(1.2), Func(self.acceptOnce, 'enter' + self.wsnp.node().getName(), self.handleSprayCollision), Func(self.playWeaponSound), Func(self.attachSpray), Func(self.sprayParticle.start, self.pen.find('**/joint_toSpray'), self.pen.find('**/joint_toSpray')), self.sprayScaleIval, Wait(0.5), Func(self.sprayParticle.cleanup), Func(self.spray.setScale, 1), Func(self.spray.reparentTo, hidden), Func(self.ignore, 'enter' + self.wsnp.node().getName()))) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def attachSpray(self): self.spray.reparentTo(self.pen.find('**/joint_toSpray')) pos = self.spray.getPos(render) hpr = self.spray.getHpr(render) self.spray.reparentTo(render) self.spray.setPos(pos) self.spray.setHpr(hpr) self.spray.setP(0) if self.suit.type == 'C': self.spray.setH(self.spray.getH() + 7.5) self.spray.setTwoSided(True) def handleSprayCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) self.sprayScaleIval.pause() def playWeaponSound(self): self.spraySfx = base.audio3d.loadSfx('phase_5/audio/sfx/SA_fountain_pen.mp3') base.audio3d.attachSoundToObject(self.spraySfx, self.pen) self.spraySfx.play() def cleanup(self): Attack.cleanup(self) if self.wsnp: self.wsnp.node().clearSolids() self.wsnp.removeNode() self.wsnp = None if self.pen: self.pen.removeNode() self.pen = None if self.sprayParticle: self.sprayParticle.cleanup() self.sprayParticle = None if self.spray: self.spray.removeNode() self.spray = None if self.splat: self.splat.cleanup() self.splat = None if self.sprayScaleIval: self.sprayScaleIval.pause() self.sprayScaleIval = None self.spraySfx = None return
class Highlightable: """A mixin class that receives notifications from zcanvas when the mouse pointer enters or leaves its nodepath. These events can be used to highlight a nodepath as the mouse cursor moves over it. The default implementation scales the nodepath to 120% of its original size over a 0.2 second interval when the mouse enters the nodepath, and scales it back over the same amount of time when the mouse leaves.""" def __init__(self): pass def highlight(self): """The mouse pointer has entered the bounds of this nodepath. Subclasses should override this method to implement custom mouse-over behaviour. """ # If we are already scaling up, do nothing. if hasattr(self,'scaleUpInterval') and self.scaleUpInterval.isPlaying(): return # If we are in the process of scaling down, finish it off immediately. if hasattr(self,'scaleDownInterval') and self.scaleDownInterval.isPlaying(): self.scaleDownInterval.finish() from direct.interval.IntervalGlobal import LerpScaleInterval self.prevScale = self.getScale() self.scaleUpInterval = LerpScaleInterval(self.np, duration=0.2, scale=self.getScale()*1.2, startScale=self.getScale()) self.scaleUpInterval.start() def unhighlight(self): """The mouse pointer has left the bounds of this nodepath. Subclasses should override this method to implement custom mouse-over behaviour. """ # If we are already scaling down, do nothing. if hasattr(self,'scaleDownInterval') and self.scaleDownInterval.isPlaying(): return # If we are in the process of scaling up, stop. if hasattr(self,'scaleUpInterval') and self.scaleUpInterval.isPlaying(): self.scaleUpInterval.pause() from direct.interval.IntervalGlobal import LerpScaleInterval self.scaleDownInterval = LerpScaleInterval(self.np, duration=0.2, scale=self.prevScale, startScale=self.getScale()) self.scaleDownInterval.start() def set_highlightable(self,boolean): """Enable or disable mouse-over highlighting of this nodepath. (When disabled, the highlight and unhighlight methods will not be called.) """ # Finish any intervals that are playing. if hasattr(self,'scaleDownInterval') and self.scaleDownInterval.isPlaying(): self.scaleDownInterval.finish() elif hasattr(self,'scaleUpInterval') and self.scaleUpInterval.isPlaying(): self.scaleUpInterval.finish() # Reset the scale. if hasattr(self,'prevScale'): self.setScale(self.prevScale) if boolean: self.np.setPythonTag("highlightable",self) else: self.np.clearPythonTag("highlightable")
class Droppable: """An object that can be dropped onto. (Part of the Drag & Drop protocol.) Initially droppable is disabled, users must call set_droppable(True) to enable it. """ def __init__(self): pass def drop(self,event): """A draggable has been dropped onto this droppable. Subclasses should extend this if they want to do something.""" # Finish any intervals that are playing. # FIXME: this tightly couples Droppable to Highlightable. Move this code # into highlightable. if hasattr(self,'scaleDownInterval') and self.scaleDownInterval.isPlaying(): self.scaleDownInterval.finish() elif hasattr(self,'scaleUpInterval') and self.scaleUpInterval.isPlaying(): self.scaleUpInterval.finish() # Reset the scale. if hasattr(self,'prevScale'): self.setScale(self.prevScale) def set_droppable(self,b): """Enable or disable dropping onto the NodePath.""" # FIXME: move this into Highlightable. # Finish any intervals that are playing. if hasattr(self,'scaleDownInterval') and self.scaleDownInterval.isPlaying(): self.scaleDownInterval.finish() elif hasattr(self,'scaleUpInterval') and self.scaleUpInterval.isPlaying(): self.scaleUpInterval.finish() # Reset the scale. if hasattr(self,'prevScale'): self.setScale(self.prevScale) if b is True: self.np.setPythonTag('droppable',self) else: self.np.clearPythonTag('droppable') def highlight(self): """Subclasses should override this method to implement custom drag-over behaviour.""" # If we are already scaling up, do nothing. if hasattr(self,'scaleUpInterval') and self.scaleUpInterval.isPlaying(): return # If we are in the process of scaling down, finish it off immediately. if hasattr(self,'scaleDownInterval') and self.scaleDownInterval.isPlaying(): self.scaleDownInterval.finish() from direct.interval.IntervalGlobal import LerpScaleInterval self.prevScale = self.getScale() self.scaleUpInterval = LerpScaleInterval(self.np, duration=0.2, scale=self.getScale()*1.2, startScale=self.getScale()) self.scaleUpInterval.start() def unhighlight(self): """Subclasses should override this method to implement custom drag-over behaviour.""" # If we are already scaling down, do nothing. if hasattr(self,'scaleDownInterval') and self.scaleDownInterval.isPlaying(): return # If we are in the process of scaling up, stop. if hasattr(self,'scaleUpInterval') and self.scaleUpInterval.isPlaying(): self.scaleUpInterval.pause() from direct.interval.IntervalGlobal import LerpScaleInterval self.scaleDownInterval = LerpScaleInterval(self.np, duration=0.2, scale=self.prevScale, startScale=self.getScale()) self.scaleDownInterval.start()
class FountainPenAttack(Attack): notify = directNotify.newCategory('FountainPenAttack') attack = 'fountainpen' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.pen = None self.spray = None self.splat = None self.spraySfx = None self.sprayParticle = None self.sprayScaleIval = None self.wsnp = None return def loadAttack(self): self.pen = loader.loadModel('phase_5/models/props/pen.bam') self.pen.reparentTo(self.suit.find('**/joint_Rhold')) self.sprayParticle = ParticleLoader.loadParticleEffect('phase_5/etc/penSpill.ptf') self.spray = loader.loadModel('phase_3.5/models/props/spray.bam') self.spray.setColor(VBase4(0, 0, 0, 1)) self.splat = Actor('phase_3.5/models/props/splat-mod.bam', {'chan': 'phase_3.5/models/props/splat-chan.bam'}) self.splat.setColor(VBase4(0, 0, 0, 1)) self.sprayScaleIval = LerpScaleInterval(self.spray, duration=0.3, scale=(1, 20, 1), startScale=(1, 1, 1)) sphere = CollisionSphere(0, 0, 0, 0.5) sphere.setTangible(0) if hasattr(self.suit, 'uniqueName'): collName = self.suit.uniqueName('fountainPenCollNode') else: collName = 'fountainPenCollNode' collNode = CollisionNode(collName) collNode.addSolid(sphere) collNode.setCollideMask(CIGlobals.WallBitmask) self.wsnp = self.spray.attachNewNode(collNode) self.wsnp.setY(1) def doAttack(self, ts=0): self.loadAttack() if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doFountainPenAttack') else: name = 'doFountainPenAttack' self.suitTrack = Parallel(name=name) self.suitTrack.append(ActorInterval(self.suit, 'fountainpen')) self.suitTrack.append(Sequence(Wait(1.2), Func(self.acceptOnce, 'enter' + self.wsnp.node().getName(), self.handleSprayCollision), Func(self.playWeaponSound), Func(self.attachSpray), Func(self.sprayParticle.start, self.pen.find('**/joint_toSpray'), self.pen.find('**/joint_toSpray')), self.sprayScaleIval, Wait(0.5), Func(self.sprayParticle.cleanup), Func(self.spray.setScale, 1), Func(self.spray.reparentTo, hidden), Func(self.ignore, 'enter' + self.wsnp.node().getName()))) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def attachSpray(self): self.spray.reparentTo(self.pen.find('**/joint_toSpray')) pos = self.spray.getPos(render) hpr = self.spray.getHpr(render) self.spray.reparentTo(render) self.spray.setPos(pos) self.spray.setHpr(hpr) self.spray.setP(0) if self.suit.type == 'C': self.spray.setH(self.spray.getH() + 7.5) self.spray.setTwoSided(True) def handleSprayCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) self.sprayScaleIval.pause() def playWeaponSound(self): self.spraySfx = base.audio3d.loadSfx('phase_5/audio/sfx/SA_fountain_pen.ogg') base.audio3d.attachSoundToObject(self.spraySfx, self.pen) self.spraySfx.play() def cleanup(self): Attack.cleanup(self) if self.wsnp: self.wsnp.node().clearSolids() self.wsnp.removeNode() self.wsnp = None if self.pen: self.pen.removeNode() self.pen = None if self.sprayParticle: self.sprayParticle.cleanup() self.sprayParticle = None if self.spray: self.spray.removeNode() self.spray = None if self.splat: self.splat.cleanup() self.splat = None if self.sprayScaleIval: self.sprayScaleIval.pause() self.sprayScaleIval = None self.spraySfx = None return