From ce0064b790a8b118f95117b4487e15c2465ea8ff Mon Sep 17 00:00:00 2001 From: I-Am-The-Great Date: Sun, 1 Sep 2019 10:53:42 +0530 Subject: [PATCH] Added 4 new powerups Added 4 new powerups: i) Headache Bomb ii) 3D flying powerup iii) Motion Tweaker iv) Anti Gravity Bomb --- mods/Portal.py | 98 +++--- mods/newBomb.json | 5 + mods/newBomb.py | 704 +++++++++++++++++++++++++++++++++++++++++ mods/newSpaz.json | 5 + mods/newSpaz.py | 107 +++++++ mods/snowyPowerup.json | 2 +- mods/snowyPowerup.py | 230 +++++++++----- 7 files changed, 1022 insertions(+), 129 deletions(-) create mode 100644 mods/newBomb.json create mode 100644 mods/newBomb.py create mode 100644 mods/newSpaz.json create mode 100644 mods/newSpaz.py diff --git a/mods/Portal.py b/mods/Portal.py index 4ccaf45..2b13cf5 100644 --- a/mods/Portal.py +++ b/mods/Portal.py @@ -7,70 +7,71 @@ # Following are necessary variables for portal maxportals = 3 currentnum = 0 -lastpos = [(0,0,0), (1, 0, 2)] # initial values for test -defi = [(0, 1, 2), (1, 0, 2)] # initial values for test +lastpos = [(0, 0, 0), (1, 0, 2)] # initial values for test +defi = [(0, 1, 2), (1, 0, 2)] # initial values for test + class Portal(bs.Actor): - def __init__(self,position1 = (0,1,0),color = (random.random(),random.random(),random.random()),r = 1.0,activity = None): + def __init__(self, position1=(0, 1, 0), color=(random.random(), random.random(), random.random()), r=1.0, + activity=None): bs.Actor.__init__(self) - + self.radius = r if position1 is None: self.position1 = self.getRandomPosition(activity) - else : + else: self.position1 = position1 self.position2 = self.getRandomPosition(activity) - + self.portal1Material = bs.Material() - self.portal1Material.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('playerMaterial'))),actions=(("modifyPartCollision","collide",True), - ("modifyPartCollision","physical",False), - ("call","atConnect", self.Portal1))) + self.portal1Material.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('playerMaterial'))), + actions=(("modifyPartCollision", "collide", True), + ("modifyPartCollision", "physical", False), + ("call", "atConnect", self.Portal1))) self.portal2Material = bs.Material() - self.portal2Material.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('playerMaterial'))),actions=(("modifyPartCollision","collide",True), - ("modifyPartCollision","physical",False), - ("call","atConnect", self.Portal2))) + self.portal2Material.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('playerMaterial'))), + actions=(("modifyPartCollision", "collide", True), + ("modifyPartCollision", "physical", False), + ("call", "atConnect", self.Portal2))) # uncomment the following lines to teleport objects also # self.portal1Material.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('objectMaterial')),'and',('theyDontHaveMaterial', bs.getSharedObject('playerMaterial'))),actions=(("modifyPartCollision","collide",True), - # ("modifyPartCollision","physical",False), - # ("call","atConnect", self.objPortal1))) + # ("modifyPartCollision","physical",False), + # ("call","atConnect", self.objPortal1))) # self.portal2Material.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('objectMaterial')),'and',('theyDontHaveMaterial', bs.getSharedObject('playerMaterial'))),actions=(("modifyPartCollision","collide",True), - # ("modifyPartCollision","physical",False), - # ("call","atConnect", self.objPortal2))) - - + # ("modifyPartCollision","physical",False), + # ("call","atConnect", self.objPortal2))) + self.node1 = bs.newNode('region', - attrs={'position':(self.position1[0],self.position1[1],self.position1[2]), - 'scale':(self.radius,self.radius,self.radius), - 'type':'sphere', - 'materials':[self.portal1Material]}) - self.visualRadius = bs.newNode('shield',attrs={'position':self.position1,'color':color,'radius':0.1}) - bsUtils.animate(self.visualRadius,"radius",{0:0,500:self.radius*2}) - bsUtils.animateArray(self.node1,"scale",3,{0:(0,0,0),500:(self.radius,self.radius,self.radius)}) - - + attrs={'position': (self.position1[0], self.position1[1], self.position1[2]), + 'scale': (self.radius, self.radius, self.radius), + 'type': 'sphere', + 'materials': [self.portal1Material]}) + self.visualRadius = bs.newNode('shield', attrs={'position': self.position1, 'color': color, 'radius': 0.1}) + bsUtils.animate(self.visualRadius, "radius", {0: 0, 500: self.radius * 2}) + bsUtils.animateArray(self.node1, "scale", 3, {0: (0, 0, 0), 500: (self.radius, self.radius, self.radius)}) + self.node2 = bs.newNode('region', - attrs={'position':(self.position2[0],self.position2[1],self.position2[2]), - 'scale':(self.radius,self.radius,self.radius), - 'type':'sphere', - 'materials':[self.portal2Material]}) - self.visualRadius2 = bs.newNode('shield',attrs={'position':self.position2,'color':color,'radius':0.1}) - bsUtils.animate(self.visualRadius2,"radius",{0:0,500:self.radius*2}) - bsUtils.animateArray(self.node2,"scale",3,{0:(0,0,0),500:(self.radius,self.radius,self.radius)}) - - + attrs={'position': (self.position2[0], self.position2[1], self.position2[2]), + 'scale': (self.radius, self.radius, self.radius), + 'type': 'sphere', + 'materials': [self.portal2Material]}) + self.visualRadius2 = bs.newNode('shield', attrs={'position': self.position2, 'color': color, 'radius': 0.1}) + bsUtils.animate(self.visualRadius2, "radius", {0: 0, 500: self.radius * 2}) + bsUtils.animateArray(self.node2, "scale", 3, {0: (0, 0, 0), 500: (self.radius, self.radius, self.radius)}) + def Portal1(self): node = bs.getCollisionInfo('opposingNode') - node.handleMessage(bs.StandMessage(position = self.node2.position)) - + node.handleMessage(bs.StandMessage(position=self.node2.position)) + def Portal2(self): node = bs.getCollisionInfo('opposingNode') - node.handleMessage(bs.StandMessage(position = self.node1.position)) - + node.handleMessage(bs.StandMessage(position=self.node1.position)) + def objPortal1(self): node = bs.getCollisionInfo('opposingNode') node.position = self.position2 - + def objPortal2(self): node = bs.getCollisionInfo('opposingNode') node.position = self.position1 @@ -85,13 +86,14 @@ def delete(self): lastpos.remove(self.position1) defi.remove(self.node2.position) - def posn(self, s , act): + def posn(self, s, act): ru = random.uniform rc = random.choice - f = rc([(s[0], s[1], s[2]-ru(0.1, 0.6)), (s[0], s[1], s[2]+ru(0.1, 0.6)), (s[0]-ru(0.1, 0.6), s[1], s[2]), (s[0]+ru(0.1, 0.6), s[1], s[2])]) - if f in defi or f in lastpos : + f = rc([(s[0], s[1], s[2] - ru(0.1, 0.6)), (s[0], s[1], s[2] + ru(0.1, 0.6)), (s[0] - ru(0.1, 0.6), s[1], s[2]), + (s[0] + ru(0.1, 0.6), s[1], s[2])]) + if f in defi or f in lastpos: return self.getRandomPosition(act) - else : + else: defi.append(f) return f @@ -110,9 +112,9 @@ def getRandomPosition(self, activity): ru = random.uniform ps = pos t = ru(ps[0][0] - 1.0, ps[0][1] + 1.0), ps[1][1] + ru(0.1, 1.5), ru(ps[2][0] - 1.0, ps[2][1] + 1.0) - s = (t[0],t[1]-ru(1.0,1.3),t[2]) - if s in defi or s in lastpos : + s = (t[0], t[1] - ru(1.0, 1.3), t[2]) + if s in defi or s in lastpos: return self.posn(s, activity) - else : + else: defi.append(s) return s diff --git a/mods/newBomb.json b/mods/newBomb.json new file mode 100644 index 0000000..c394f8b --- /dev/null +++ b/mods/newBomb.json @@ -0,0 +1,5 @@ +{ + "name": "New Bombs", + "author": "The Great", + "category": "libraries" +} diff --git a/mods/newBomb.py b/mods/newBomb.py new file mode 100644 index 0000000..07467e1 --- /dev/null +++ b/mods/newBomb.py @@ -0,0 +1,704 @@ +import bs +import bsSpaz +import bsBomb +import bsUtils +from bsBomb import Bomb, ExplodeMessage, ArmMessage, WarnMessage, Blast, BombFactory, \ + ExplodeHitMessage, ImpactMessage, SplatMessage +import random + + +class AimForOpponent(object): + def __init__(self, bomb, owner): + + self.bomb = bomb + self.owner = owner + self.target = None + + self.aimZoneSpaz = bs.Material() + self.aimZoneSpaz.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('playerMaterial'))), + actions=(("modifyPartCollision", "collide", True), + ("modifyPartCollision", "physical", False), + ("call", "atConnect", self.touchedSpaz))) + + self.lookForSpaz() + + def lookForSpaz(self): + # To slow down the movement of the bomb towards the target and put the bomb over the head of the target. + self.bomb.extraAcceleration = (0, 20, 0) + self.node = bs.newNode('region', + attrs={'position': (self.bomb.position[0], self.bomb.position[1], + self.bomb.position[2]) if self.bomb.exists() else ( + 0, 0, 0), + 'scale': (0.0, 0.0, 0.0), + 'type': 'sphere', + 'materials': [self.aimZoneSpaz]}) + self.s = bsUtils.animateArray(self.node, "scale", 3, {0: (0.0, 0.0, 0.0), 50: (60, 60, 60), 100: (90, 90, 90)}, + True) + + bs.gameTimer(150, self.node.delete) + + def checkTarget(): + if self.target is not None: + self.touchedSpaz() + + bs.gameTimer(151, checkTarget) + + def go(self): + if self.target is not None and self.bomb is not None and self.bomb.exists(): + self.bomb.velocity = ( + self.bomb.velocity[0] + (self.target.position[0] - self.bomb.position[0]), + self.bomb.velocity[1] + (self.target.position[1] - self.bomb.position[1]), + self.bomb.velocity[2] + (self.target.position[2] - self.bomb.position[2])) + bs.gameTimer(1, self.go) + + def touchedSpaz(self): + try: + node = bs.getCollisionInfo('opposingNode') + except AttributeError: + return + if not node == self.owner and node.getDelegate().isAlive() \ + and node.getDelegate().getPlayer().getTeam() != self.owner.getDelegate().getPlayer().getTeam(): + self.target = node + self.s = None + self.node.delete() + self.bomb.extraAcceleration = (0, 200, 0) + self.go() + + +class AntiGravArea(object): + """For making the area to give the spaz upward force.""" + + def __init__(self, position, radius): + self.position = (position[0], position[1] + 1, position[2]) + self.radius = radius + color = (random.random(), random.random(), random.random()) + self.material = bs.Material() + self.material.addActions(conditions=(('theyHaveMaterial', bs.getSharedObject('playerMaterial'))), + actions=(("modifyPartCollision", "collide", True), + ("modifyPartCollision", "physical", False), + ("call", "atConnect", self.touchedSpaz))) + self.node = bs.newNode('region', + attrs={'position': (self.position[0], self.position[1], self.position[2]), + 'scale': (self.radius, self.radius, self.radius), + 'type': 'sphere', + 'materials': [self.material]}) + self.visualRadius = bs.newNode('shield', attrs={'position': self.position, 'color': color, 'radius': 0.1}) + bsUtils.animate(self.visualRadius, "radius", {0: 0, 500: self.radius * 2}) + bsUtils.animateArray(self.node, "scale", 3, {0: (0, 0, 0), 500: (self.radius, self.radius, self.radius)}) + + def delete(self): + if self.node.exists(): + self.node.delete() + if self.visualRadius.exists(): + self.visualRadius.delete() + + def touchedSpaz(self): + node = bs.getCollisionInfo('opposingNode') + + def raiseSpaz(): + if node.getDelegate().isAlive(): + node.handleMessage("impulse", node.position[0], node.position[1] + 0.5, node.position[2], 0, 5, 0, + 3, 10, 0, 0, 0, 5, 0) + bs.gameTimer(50, raiseSpaz) + raiseSpaz() + + +class NewBombFactory(BombFactory): + def __init__(self): + BombFactory.__init__(self) + self.newTex = bs.getTexture("achievementOnslaught") + + self.newImpactBlastMaterial = bs.Material() + self.newImpactBlastMaterial.addActions( + conditions=(('weAreOlderThan', 200), + 'and', ('theyAreOlderThan', 200), + 'and', ('evalColliding',), + 'and', ('theyDontHaveMaterial', bs.getSharedObject('playerMaterial')), + 'and', ('theyHaveMaterial', self.bombMaterial), + 'and', ('theyDontHaveMaterial', self.newImpactBlastMaterial)), + actions=(('message', 'ourNode', 'atConnect', ImpactMessage()))) + + +class NewBlast(Blast): + def __init__(self, position=(0, 1, 0), velocity=(0, 0, 0), blastRadius=2.0, + blastType="normal", sourcePlayer=None, hitType='explosion', + hitSubType='normal'): + bs.Actor.__init__(self) + + factory = Bomb.getFactory() + + self.blastType = blastType + self.sourcePlayer = sourcePlayer + + self.hitType = hitType; + self.hitSubType = hitSubType; + + # blast radius + self.radius = blastRadius + + # set our position a bit lower so we throw more things upward + self.node = bs.newNode('region', delegate=self, attrs={ + 'position': (position[0], position[1] - 0.1, position[2]), + 'scale': (self.radius, self.radius, self.radius), + 'type': 'sphere', + 'materials': (factory.blastMaterial, + bs.getSharedObject('attackMaterial'))}) + + bs.gameTimer(50, self.node.delete) + + # throw in an explosion and flash + explosion = bs.newNode("explosion", attrs={ + 'position': position, + 'velocity': (velocity[0], max(-1.0, velocity[1]), velocity[2]), + 'radius': self.radius, + 'big': (self.blastType == 'tnt')}) + if self.blastType == "ice": + explosion.color = (0, 0.05, 0.4) + + bs.gameTimer(1000, explosion.delete) + + if self.blastType != 'ice': + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(1.0 + random.random() * 4), + emitType='tendrils', tendrilType='thinSmoke') + bs.emitBGDynamics( + position=position, velocity=velocity, + count=int(4.0 + random.random() * 4), emitType='tendrils', + tendrilType='ice' if self.blastType == 'ice' else 'smoke') + bs.emitBGDynamics( + position=position, emitType='distortion', + spread=1.0 if self.blastType == 'tnt' else 2.0) + + # and emit some shrapnel.. + if self.blastType == 'ice': + def _doEmit(): + bs.emitBGDynamics(position=position, velocity=velocity, + count=30, spread=2.0, scale=0.4, + chunkType='ice', emitType='stickers'); + + bs.gameTimer(50, _doEmit) # looks better if we delay a bit + + elif self.blastType == 'sticky': + def _doEmit(): + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(4.0 + random.random() * 8), + spread=0.7, chunkType='slime'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(4.0 + random.random() * 8), scale=0.5, + spread=0.7, chunkType='slime'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=15, scale=0.6, chunkType='slime', + emitType='stickers'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=20, scale=0.7, chunkType='spark', + emitType='stickers'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(6.0 + random.random() * 12), + scale=0.8, spread=1.5, chunkType='spark'); + + bs.gameTimer(50, _doEmit) # looks better if we delay a bit + + elif self.blastType == 'impact': # regular bomb shrapnel + def _doEmit(): + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(4.0 + random.random() * 8), scale=0.8, + chunkType='metal'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(4.0 + random.random() * 8), scale=0.4, + chunkType='metal'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=20, scale=0.7, chunkType='spark', + emitType='stickers'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(8.0 + random.random() * 15), scale=0.8, + spread=1.5, chunkType='spark'); + + bs.gameTimer(50, _doEmit) # looks better if we delay a bit + + elif self.blastType == 'headache': # regular bomb shrapnel + + def _doEmit(): + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(4.0 + random.random() * 8), scale=0.8, + chunkType='metal'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(4.0 + random.random() * 8), scale=0.4, + chunkType='metal'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=20, scale=0.7, chunkType='spark', + emitType='stickers'); + bs.emitBGDynamics(position=position, velocity=velocity, + count=int(8.0 + random.random() * 15), scale=0.8, + spread=1.5, chunkType='spark'); + + bs.gameTimer(50, _doEmit) # looks better if we delay a bit + + + else: # regular or land mine bomb shrapnel + + def _doEmit(): + + if self.blastType != 'tnt': + bs.emitBGDynamics(position=position, velocity=velocity, + + count=int(4.0 + random.random() * 8), + + chunkType='rock'); + + bs.emitBGDynamics(position=position, velocity=velocity, + + count=int(4.0 + random.random() * 8), + + scale=0.5, chunkType='rock'); + + bs.emitBGDynamics(position=position, velocity=velocity, + + count=30, + + scale=1.0 if self.blastType == 'tnt' else 0.7, + + chunkType='spark', emitType='stickers'); + + bs.emitBGDynamics(position=position, velocity=velocity, + + count=int(18.0 + random.random() * 20), + + scale=1.0 if self.blastType == 'tnt' else 0.8, + + spread=1.5, chunkType='spark'); + + # tnt throws splintery chunks + + if self.blastType == 'tnt': + def _emitSplinters(): + bs.emitBGDynamics(position=position, velocity=velocity, + + count=int(20.0 + random.random() * 25), + + scale=0.8, spread=1.0, + + chunkType='splinter'); + + bs.gameTimer(10, _emitSplinters) + + # every now and then do a sparky one + + if self.blastType == 'tnt' or random.random() < 0.1: + def _emitExtraSparks(): + bs.emitBGDynamics(position=position, velocity=velocity, + + count=int(10.0 + random.random() * 20), + + scale=0.8, spread=1.5, + + chunkType='spark'); + + bs.gameTimer(20, _emitExtraSparks) + + bs.gameTimer(50, _doEmit) # looks better if we delay a bit + + light = bs.newNode('light', attrs={ + + 'position': position, + + 'volumeIntensityScale': 10.0, + + 'color': ((0.6, 0.6, 1.0) if self.blastType == 'ice' + + else (1, 0.3, 0.1))}) + + s = random.uniform(0.6, 0.9) + + scorchRadius = lightRadius = self.radius + + if self.blastType == 'tnt': + lightRadius *= 1.4 + + scorchRadius *= 1.15 + + s *= 3.0 + + iScale = 1.6 + + bsUtils.animate(light, "intensity", { + + 0: 2.0 * iScale, int(s * 20): 0.1 * iScale, + + int(s * 25): 0.2 * iScale, int(s * 50): 17.0 * iScale, int(s * 60): 5.0 * iScale, + + int(s * 80): 4.0 * iScale, int(s * 200): 0.6 * iScale, + + int(s * 2000): 0.00 * iScale, int(s * 3000): 0.0}) + + bsUtils.animate(light, "radius", { + + 0: lightRadius * 0.2, int(s * 50): lightRadius * 0.55, + + int(s * 100): lightRadius * 0.3, int(s * 300): lightRadius * 0.15, + + int(s * 1000): lightRadius * 0.05}) + + bs.gameTimer(int(s * 3000), light.delete) + + # make a scorch that fades over time + + scorch = bs.newNode('scorch', attrs={ + + 'position': position, + + 'size': scorchRadius * 0.5, + + 'big': (self.blastType == 'tnt')}) + + scorch.color = (random.random(), random.random(), random.random()) + if self.blastType == 'ice': + scorch.color = (1, 1, 1.5) + + bsUtils.animate(scorch, "presence", {3000: 1, 13000: 0}) + + bs.gameTimer(13000, scorch.delete) + + if self.blastType == 'ice': + bs.playSound(factory.hissSound, position=light.position) + + p = light.position + + bs.playSound(factory.getRandomExplodeSound(), position=p) + + bs.playSound(factory.debrisFallSound, position=p) + + bs.shakeCamera(intensity=5.0 if self.blastType == 'tnt' else 1.0) + + # tnt is more epic.. + + if self.blastType == 'tnt': + bs.playSound(factory.getRandomExplodeSound(), position=p) + + def _extraBoom(): + bs.playSound(factory.getRandomExplodeSound(), position=p) + + bs.gameTimer(250, _extraBoom) + + def _extraDebrisSound(): + bs.playSound(factory.debrisFallSound, position=p) + + bs.playSound(factory.woodDebrisFallSound, position=p) + + bs.gameTimer(400, _extraDebrisSound) + + def handleMessage(self, msg): + self._handleMessageSanityCheck() + + if isinstance(msg, bs.DieMessage): + self.node.delete() + + elif isinstance(msg, ExplodeHitMessage): + node = bs.getCollisionInfo("opposingNode") + if node is not None and node.exists(): + t = self.node.position + + # new + mag = 2000.0 + if self.blastType == 'ice': mag *= 0.5 + elif self.blastType == 'landMine': mag *= 2.5 + elif self.blastType == 'tnt': mag *= 2.0 + elif self.blastType == 'antiGrav': mag *= 0.1 + + node.handleMessage(bs.HitMessage( + pos=t, + velocity=(0,0,0), + magnitude=mag, + hitType=self.hitType, + hitSubType=self.hitSubType, + radius=self.radius, + sourcePlayer=self.sourcePlayer)) + if self.blastType == "ice": + bs.playSound(Bomb.getFactory().freezeSound, 10, position=t) + node.handleMessage(bs.FreezeMessage()) + + else: + bs.Actor.handleMessage(self, msg) + + +class NewBomb(Bomb): + def __init__(self, position=(0, 1, 0), velocity=(0, 0, 0), bombType='normal', + blastRadius=2.0, sourcePlayer=None, owner=None): + bs.Actor.__init__(self) + + factory = self.getFactory() + + if not bombType in ('headache', 'ice', 'impact', 'landMine', 'normal', 'sticky', 'tnt', 'antiGrav'): + raise Exception("invalid bomb type: " + bombType) + self.bombType = bombType + + self._exploded = False + + if self.bombType == 'sticky': self._lastStickySoundTime = 0 + + self.blastRadius = blastRadius + if self.bombType == 'ice': + self.blastRadius *= 1.2 + elif self.bombType == 'impact': + self.blastRadius *= 0.7 + elif self.bombType == 'landMine': + self.blastRadius *= 0.7 + elif self.bombType == 'tnt': + self.blastRadius *= 1.45 + + self._explodeCallbacks = [] + + # the player this came from + self.sourcePlayer = sourcePlayer + + # by default our hit type/subtype is our own, but we pick up types of + # whoever sets us off so we know what caused a chain reaction + self.hitType = 'explosion' + self.hitSubType = self.bombType + + # if no owner was provided, use an unconnected node ref + if owner is None: owner = bs.Node(None) + + # the node this came from + self.owner = owner + + # adding footing-materials to things can screw up jumping and flying + # since players carrying those things + # and thus touching footing objects will think they're on solid ground.. + # perhaps we don't wanna add this even in the tnt case?.. + if self.bombType == 'tnt': + materials = (factory.bombMaterial, + bs.getSharedObject('footingMaterial'), + bs.getSharedObject('objectMaterial')) + else: + materials = (factory.bombMaterial, + bs.getSharedObject('objectMaterial')) + + if self.bombType == 'impact': + materials = materials + (factory.impactBlastMaterial,) + elif self.bombType == 'headache': + materials = materials + (factory.newImpactBlastMaterial,) + elif self.bombType == 'landMine': + materials = materials + (factory.landMineNoExplodeMaterial,) + elif self.bombType == 'antiGrav': + materials = materials + (factory.impactBlastMaterial,) + + if self.bombType == 'sticky': + materials = materials + (factory.stickyMaterial,) + else: + materials = materials + (factory.normalSoundMaterial,) + + if self.bombType == 'landMine': + self.node = bs.newNode('prop', delegate=self, attrs={ + 'position': position, + 'velocity': velocity, + 'model': factory.landMineModel, + 'lightModel': factory.landMineModel, + 'body': 'landMine', + 'shadowSize': 0.44, + 'colorTexture': factory.landMineTex, + 'reflection': 'powerup', + 'reflectionScale': [1.0], + 'materials': materials}) + + elif self.bombType == 'tnt': + self.node = bs.newNode('prop', delegate=self, attrs={ + 'position': position, + 'velocity': velocity, + 'model': factory.tntModel, + 'lightModel': factory.tntModel, + 'body': 'crate', + 'shadowSize': 0.5, + 'colorTexture': factory.tntTex, + 'reflection': 'soft', + 'reflectionScale': [0.23], + 'materials': materials}) + + elif self.bombType == 'impact': + fuseTime = 20000 + self.node = bs.newNode('prop', delegate=self, attrs={ + 'position': position, + 'velocity': velocity, + 'body': 'sphere', + 'model': factory.impactBombModel, + 'shadowSize': 0.3, + 'colorTexture': factory.impactTex, + 'reflection': 'powerup', + 'reflectionScale': [1.5], + 'materials': materials}) + + elif self.bombType == 'antiGrav': + fuseTime = 30000 + self.node = bs.newNode('prop', delegate=self, attrs={ + 'position': position, + 'velocity': velocity, + 'body': 'sphere', + 'model': factory.impactBombModel, + 'shadowSize': 0.3, + 'colorTexture': factory.newTex, + 'reflection': 'powerup', + 'reflectionScale': [1.5], + 'materials': materials}) + + else: + fuseTime = 3000 + if self.bombType == 'sticky': + sticky = True + model = factory.stickyBombModel + rType = 'sharper' + rScale = 1.8 + else: + sticky = False + model = factory.bombModel + rType = 'sharper' + rScale = 1.8 + if self.bombType == 'ice': + tex = factory.iceTex + elif self.bombType == 'sticky': + tex = factory.stickyTex + elif self.bombType == 'headache': + fuseTime = 13000 + tex = factory.newTex + model = factory.impactBombModel + else: + tex = factory.regularTex + self.node = bs.newNode('bomb', delegate=self, attrs={ + 'position': position, + 'velocity': velocity, + 'model': model, + 'shadowSize': 0.3, + 'colorTexture': tex, + 'sticky': sticky, + 'owner': owner, + 'reflection': rType, + 'reflectionScale': [rScale], + 'materials': materials}) + + sound = bs.newNode('sound', owner=self.node, attrs={ + 'sound': factory.fuseSound, + 'volume': 0.25}) + self.node.connectAttr('position', sound, 'position') + bsUtils.animate(self.node, 'fuseLength', {0: 1.0, fuseTime: 0.0}) + + # light the fuse!!! + if self.bombType not in ('landMine', 'tnt'): + bs.gameTimer(fuseTime, + bs.WeakCall(self.handleMessage, ExplodeMessage())) + + bsUtils.animate(self.node, "modelScale", {0: 0, 200: 1.3, 260: 1}) + + def _handleDropped(self, m): + if self.bombType == 'landMine': + self.armTimer = \ + bs.Timer(1250, bs.WeakCall(self.handleMessage, ArmMessage())) + + # once we've thrown a sticky bomb we can stick to it.. + elif self.bombType == 'sticky': + def _safeSetAttr(node, attr, value): + if node.exists(): setattr(node, attr, value) + + bs.gameTimer( + 250, lambda: _safeSetAttr(self.node, 'stickToOwner', True)) + + elif self.bombType == 'headache': + AimForOpponent(self.node, self.owner) + + def _handleHit(self, msg): + if self.bombType == 'headache' and msg.hitType == 'punch': + self.handleMessage(ExplodeMessage()) + isPunch = (msg.srcNode.exists() and msg.srcNode.getNodeType() == 'spaz') + + # normal bombs are triggered by non-punch impacts.. + # impact-bombs by all impacts + + if (not self._exploded and not isPunch + or self.bombType in ['impact', "antiGrav", 'landMine']): + # also lets change the owner of the bomb to whoever is setting + # us off.. (this way points for big chain reactions go to the + # person causing them) + if msg.sourcePlayer not in [None]: + self.sourcePlayer = msg.sourcePlayer + + # also inherit the hit type (if a landmine sets off by a bomb, + # the credit should go to the mine) + # the exception is TNT. TNT always gets credit. + if self.bombType != 'tnt': + self.hitType = msg.hitType + self.hitSubType = msg.hitSubType + + bs.gameTimer(100 + int(random.random() * 100), + bs.WeakCall(self.handleMessage, ExplodeMessage())) + self.node.handleMessage( + "impulse", msg.pos[0], msg.pos[1], msg.pos[2], + msg.velocity[0], msg.velocity[1], msg.velocity[2], + msg.magnitude, msg.velocityMagnitude, msg.radius, 0, + msg.velocity[0], msg.velocity[1], msg.velocity[2]) + + if msg.srcNode.exists(): + pass + + def _handleImpact(self, m): + node, body = bs.getCollisionInfo("opposingNode", "opposingBody") + # if we're an impact bomb or anti-gravity bomb and we came from this node, don't explode... + # alternately if we're hitting another impact-bomb from the same source, + # don't explode... + try: + nodeDelegate = node.getDelegate() + except Exception: + nodeDelegate = None + if node is not None and node.exists(): + if (self.bombType == 'impact' and + (node is self.owner + or (isinstance(nodeDelegate, Bomb) + and nodeDelegate.bombType == 'impact' + and nodeDelegate.owner is self.owner))): + return + elif (self.bombType == 'antiGrav' and + (node is self.owner + or (isinstance(nodeDelegate, Bomb) + and nodeDelegate.bombType == 'antiGrav' + and nodeDelegate.owner is self.owner))): + return + else: + self.handleMessage(ExplodeMessage()) + + def _handleDie(self, msg): + if self.bombType == "antiGrav" and self.node.exists(): + aga = AntiGravArea(position=self.node.position, radius=self.blastRadius) + bs.gameTimer(7000, aga.delete) + self.node.delete() + + def handleMessage(self, msg): + if isinstance(msg, ExplodeMessage): + self.explode() + elif isinstance(msg, ImpactMessage): + self._handleImpact(msg) + elif isinstance(msg, bs.PickedUpMessage): + # change our source to whoever just picked us up *only* if its None + # this way we can get points for killing bots with their own bombs + # hmm would there be a downside to this?... + if self.sourcePlayer is not None: + self.sourcePlayer = msg.node.sourcePlayer + elif isinstance(msg, SplatMessage): + self._handleSplat(msg) + elif isinstance(msg, bs.DroppedMessage): + self._handleDropped(msg) + elif isinstance(msg, bs.HitMessage): + self._handleHit(msg) + elif isinstance(msg, bs.DieMessage): + self._handleDie(msg) + elif isinstance(msg, bs.OutOfBoundsMessage): + self._handleOOB(msg) + elif isinstance(msg, ArmMessage): + self.arm() + elif isinstance(msg, WarnMessage): + self._handleWarn(msg) + else: + bs.Actor.handleMessage(self, msg) + + +bsBomb.Bomb = NewBomb +bs.Bomb = NewBomb +bsBomb.Blast = NewBlast +bs.Blast = NewBlast +bsBomb.BombFactory = NewBombFactory +bs.BombFactory = NewBombFactory diff --git a/mods/newSpaz.json b/mods/newSpaz.json new file mode 100644 index 0000000..e9ddd9b --- /dev/null +++ b/mods/newSpaz.json @@ -0,0 +1,5 @@ +{ + "name": "New Powers of Spaz", + "author": "The Great", + "category": "libraries" +} diff --git a/mods/newSpaz.py b/mods/newSpaz.py new file mode 100644 index 0000000..968cb3a --- /dev/null +++ b/mods/newSpaz.py @@ -0,0 +1,107 @@ +import copy +import bs +import bsSpaz + +default_dropBomb = copy.deepcopy(bsSpaz.Spaz.dropBomb) + + +def onJumpPress(self): + """ + Called to 'press jump' on this spaz; + used by player or AI connections. + """ + if not self.node.exists(): return + t = bs.getGameTime() + if self.jumpTo3DFly or (hasattr(self.getActivity()._map, "fly") and self.getActivity()._map.fly): + if not self.node.exists() or self.node.knockout > 0.0: + return + self.node.handleMessage( + "impulse", self.node.position[0], self.node.position[1], self.node.position[2], + self.node.moveLeftRight * 10, self.node.position[1] + 32, self.node.moveUpDown * -10, + 5, 5, 0, 0, + self.node.moveLeftRight * 10, self.node.position[1] + 32, self.node.moveUpDown * -10) + else: + if t - self.lastJumpTime >= self._jumpCooldown: + self.node.jumpPressed = True + self.lastJumpTime = t + self._turboFilterAddPress('jump') + + +def dropBomb(self): + """ + Tell the spaz to drop one of his bombs, and returns + the resulting bomb object. + If the spaz has no bombs or is otherwise unable to + drop a bomb, returns None. + """ + if (self.headacheCount <= 0 and self.bombCount <= 0) or self.frozen: + return + if (self.antiGravCount <= 0 and self.bombCount <= 0) or self.frozen: + return + p = self.node.positionForward + v = self.node.velocity + + if self.headacheCount > 0: + droppingBomb = False + self.setHeadacheCount(self.headacheCount - 1) + bombType = 'headache' + elif self.antiGravCount > 0: + droppingBomb = False + self.setAntiGravCount(self.antiGravCount - 1) + bombType = 'antiGrav' + else: + return default_dropBomb(self) + + bomb = bs.Bomb(position=(p[0], p[1] - 0.0, p[2]), + velocity=(v[0], v[1], v[2]), + bombType=bombType, + blastRadius=self.blastRadius, + sourcePlayer=self.sourcePlayer, + owner=self.node).autoRetain() + + if droppingBomb: + self.bombCount -= 1 + bomb.node.addDeathAction(bs.WeakCall(self.handleMessage, + bsSpaz._BombDiedMessage())) + self._pickUp(bomb.node) + + for c in self._droppedBombCallbacks: c(self, bomb) + + return bomb + + +def setHeadacheCount(self, count): + """ + Set the number of land-mines this spaz is carrying. + """ + self.headacheCount = count + if self.node.exists(): + if self.headacheCount != 0: + self.node.counterText = 'x' + str(self.headacheCount) + self.node.counterTexture = bs.Powerup.getFactory().texAche + else: + self.node.counterText = '' + + +def setAntiGravCount(self, count): + """ + Set the number of land-mines this spaz is carrying. + """ + self.antiGravCount = count + if self.node.exists(): + if self.antiGravCount != 0: + self.node.counterText = 'x' + str(self.antiGravCount) + self.node.counterTexture = bs.Powerup.getFactory().texAntiGrav + else: + self.node.counterText = '' + + +bsSpaz.Spaz.jumpTo3DFly = False +bsSpaz.Spaz.headacheCount = 0 +bsSpaz.Spaz.antiGravCount = 0 +bsSpaz.Spaz.onJumpPress = onJumpPress +bsSpaz.Spaz.dropBomb = dropBomb +setattr(bsSpaz.Spaz, "setHeadacheCount", setHeadacheCount) +setattr(bsSpaz.Spaz, "setAntiGravCount", setAntiGravCount) + +bs.Spaz = bsSpaz.Spaz diff --git a/mods/snowyPowerup.json b/mods/snowyPowerup.json index f915f0f..9dcbd6e 100644 --- a/mods/snowyPowerup.json +++ b/mods/snowyPowerup.json @@ -2,5 +2,5 @@ "name": "Modified bsPowerup.py", "author": "joshville79", "category": "libraries", - "requires": ["BuddyBunny", "SnoBallz", "Portal"] + "requires": ["BuddyBunny", "SnoBallz", "Portal", "newSpaz", "newBomb"] } \ No newline at end of file diff --git a/mods/snowyPowerup.py b/mods/snowyPowerup.py index 44812d9..22d6793 100644 --- a/mods/snowyPowerup.py +++ b/mods/snowyPowerup.py @@ -1,6 +1,6 @@ import bs import random -#add for bunny buddy: +# add for bunny buddy: import BuddyBunny import SnoBallz import bsPowerup @@ -8,9 +8,9 @@ import Portal from bsPowerup import PowerupMessage, PowerupAcceptMessage, _TouchedMessage, PowerupFactory, Powerup - defaultPowerupInterval = 8000 + class NewPowerupFactory(PowerupFactory): def __init__(self): self._lastPowerupType = None @@ -27,17 +27,22 @@ def __init__(self): self.texHealth = bs.getTexture("powerupHealth") self.texLandMines = bs.getTexture("powerupLandMines") self.texCurse = bs.getTexture("powerupCurse") - #Add for Bunnybot: + # Add for Bunnybot: self.eggModel = bs.getModel('egg') self.texEgg = bs.getTexture('eggTex1') - #Add for snoBalls: - self.texSno = bs.getTexture("bunnyColor") #Bunny is most uniform plain white color. - self.snoModel = bs.getModel("frostyPelvis") #Frosty pelvis is very nice and round... + # Add for snoBalls: + self.texSno = bs.getTexture("bunnyColor") # Bunny is most uniform plain white color. + self.snoModel = bs.getModel("frostyPelvis") # Frosty pelvis is very nice and round... self.healthPowerupSound = bs.getSound("healthPowerup") self.powerupSound = bs.getSound("powerup01") self.powerdownSound = bs.getSound("powerdown01") self.dropSound = bs.getSound("boxDrop") self.texPort = bs.getTexture("ouyaOButton") + self.texFly = bs.getTexture("achievementOnslaught") + self.texAche = bs.getTexture("achievementOnslaught") + self.flyModel = bs.getModel("flash") + self.texMTweaker = bs.getTexture("achievementFlawlessVictory") + self.texAntiGrav = bs.getTexture("achievementFootballShutout") # material for powerups self.powerupMaterial = bs.Material() @@ -47,22 +52,22 @@ def __init__(self): # pass a powerup-touched message to applicable stuff self.powerupMaterial.addActions( - conditions=(("theyHaveMaterial",self.powerupAcceptMaterial)), - actions=(("modifyPartCollision","collide",True), - ("modifyPartCollision","physical",False), - ("message","ourNode","atConnect",_TouchedMessage()))) + conditions=(("theyHaveMaterial", self.powerupAcceptMaterial)), + actions=(("modifyPartCollision", "collide", True), + ("modifyPartCollision", "physical", False), + ("message", "ourNode", "atConnect", _TouchedMessage()))) # we dont wanna be picked up self.powerupMaterial.addActions( - conditions=("theyHaveMaterial",bs.getSharedObject('pickupMaterial')), - actions=( ("modifyPartCollision","collide",False))) + conditions=("theyHaveMaterial", bs.getSharedObject('pickupMaterial')), + actions=(("modifyPartCollision", "collide", False))) self.powerupMaterial.addActions( - conditions=("theyHaveMaterial",bs.getSharedObject('footingMaterial')), - actions=(("impactSound",self.dropSound,0.5,0.1))) + conditions=("theyHaveMaterial", bs.getSharedObject('footingMaterial')), + actions=(("impactSound", self.dropSound, 0.5, 0.1))) self._powerupDist = [] - for p,freq in getDefaultPowerupDistribution(): + for p, freq in getDefaultPowerupDistribution(): for i in range(int(freq)): self._powerupDist.append(p) @@ -78,21 +83,26 @@ def getRandomPowerupType(self, forceType=None, excludeTypes=None): def getDefaultPowerupDistribution(): - return (('tripleBombs',3), - ('iceBombs',3), - ('punch',3), - ('impactBombs',3), - ('landMines',2), - ('stickyBombs',3), - ('shield',2), - ('health',1), - ('bunny',2), - ('portal',2), - ('curse',1), - ('snoball',3)) + return (('tripleBombs', 3), + ('iceBombs', 3), + ('punch', 3), + ('impactBombs', 3), + ('landMines', 2), + ('stickyBombs', 3), + ('shield', 2), + ('health', 1), + ('bunny', 2), + ('portal', 2), + ('headache', 2), + ('curse', 1), + ("fly", 2), + ("motionTweaker", 2), + ("antiGrav", 2), + ('snoball', 3)) + class NewPowerup(Powerup): - def __init__(self,position=(0,1,0),powerupType='tripleBombs',expire=True): + def __init__(self, position=(0, 1, 0), powerupType='tripleBombs', expire=True): """ Create a powerup-box of the requested type at the requested position. @@ -106,115 +116,175 @@ def __init__(self,position=(0,1,0),powerupType='tripleBombs',expire=True): mod = factory.model mScl = 1 - if powerupType == 'tripleBombs': tex = factory.texBomb - elif powerupType == 'punch': tex = factory.texPunch - elif powerupType == 'iceBombs': tex = factory.texIceBombs - elif powerupType == 'impactBombs': tex = factory.texImpactBombs - elif powerupType == 'landMines': tex = factory.texLandMines - elif powerupType == 'stickyBombs': tex = factory.texStickyBombs - elif powerupType == 'shield': tex = factory.texShield - elif powerupType == 'health': tex = factory.texHealth - elif powerupType == 'curse': tex = factory.texCurse - elif powerupType == 'portal': tex = factory.texPort - elif powerupType == 'bunny': + if powerupType == 'tripleBombs': + tex = factory.texBomb + elif powerupType == 'punch': + tex = factory.texPunch + elif powerupType == 'iceBombs': + tex = factory.texIceBombs + elif powerupType == 'impactBombs': + tex = factory.texImpactBombs + elif powerupType == 'landMines': + tex = factory.texLandMines + elif powerupType == 'stickyBombs': + tex = factory.texStickyBombs + elif powerupType == 'shield': + tex = factory.texShield + elif powerupType == 'health': + tex = factory.texHealth + elif powerupType == 'curse': + tex = factory.texCurse + elif powerupType == 'portal': + tex = factory.texPort + elif powerupType == 'bunny': tex = factory.texEgg mod = factory.eggModel mScl = 0.7 - elif powerupType == 'snoball': + elif powerupType == 'snoball': tex = factory.texSno mod = factory.snoModel - else: raise Exception("invalid powerupType: "+str(powerupType)) + elif powerupType == "headache": + tex = factory.texAche + elif powerupType == "fly": + tex = factory.texFly + mod = factory.flyModel + mScl = 0.7 + elif powerupType == "motionTweaker": + tex = factory.texMTweaker + elif powerupType == "antiGrav": + tex = factory.texAntiGrav + else: + raise Exception("invalid powerupType: " + str(powerupType)) if len(position) != 3: raise Exception("expected 3 floats for position") - + self.node = bs.newNode('prop', delegate=self, - attrs={'body':'box', - 'position':position, - 'model':mod, - 'lightModel':factory.modelSimple, - 'shadowSize':0.5, - 'colorTexture':tex, - 'reflection':'powerup', - 'reflectionScale':[1.0], - 'materials':(factory.powerupMaterial,bs.getSharedObject('objectMaterial'))}) + attrs={'body': 'box', + 'position': position, + 'model': mod, + 'lightModel': factory.modelSimple, + 'shadowSize': 0.5, + 'colorTexture': tex, + 'reflection': 'powerup', + 'reflectionScale': [1.0], + 'materials': (factory.powerupMaterial, bs.getSharedObject('objectMaterial'))}) # animate in.. - curve = bs.animate(self.node,"modelScale",{0:0,140:1.6,200:mScl}) - bs.gameTimer(200,curve.delete) + curve = bs.animate(self.node, "modelScale", {0: 0, 140: 1.6, 200: mScl}) + bs.gameTimer(200, curve.delete) if expire: - bs.gameTimer(defaultPowerupInterval-2500,bs.WeakCall(self._startFlashing)) - bs.gameTimer(defaultPowerupInterval-1000,bs.WeakCall(self.handleMessage,bs.DieMessage())) + bs.gameTimer(defaultPowerupInterval - 2500, bs.WeakCall(self._startFlashing)) + bs.gameTimer(defaultPowerupInterval - 1000, bs.WeakCall(self.handleMessage, bs.DieMessage())) def delpor(self): Portal.currentnum -= 1 self.port.delete() - def handleMessage(self,m): + def handleMessage(self, m): self._handleMessageSanityCheck() - if isinstance(m,PowerupAcceptMessage): + if isinstance(m, PowerupAcceptMessage): factory = self.getFactory() if self.powerupType == 'health': - bs.playSound(factory.healthPowerupSound,3,position=self.node.position) - bs.playSound(factory.powerupSound,3,position=self.node.position) + bs.playSound(factory.healthPowerupSound, 3, position=self.node.position) + bs.playSound(factory.powerupSound, 3, position=self.node.position) self._powersGiven = True self.handleMessage(bs.DieMessage()) - elif isinstance(m,_TouchedMessage): + elif isinstance(m, _TouchedMessage): if not self._powersGiven: node = bs.getCollisionInfo("opposingNode") if node is not None and node.exists(): - #We won't tell the spaz about the bunny. It'll just happen. + # We won't tell the spaz about the bunny. It'll just happen. if self.powerupType == 'bunny': - p=node.getDelegate().getPlayer() + p = node.getDelegate().getPlayer() if 'bunnies' not in p.gameData: p.gameData['bunnies'] = BuddyBunny.BunnyBotSet(p) p.gameData['bunnies'].doBunny() self._powersGiven = True self.handleMessage(bs.DieMessage()) - #a Spaz doesn't know what to do with a snoball powerup. All the snowball functionality - #is handled through SnoBallz.py to minimize modifications to the original game files + # a Spaz doesn't know what to do with a snoball powerup. All the snowball functionality + # is handled through SnoBallz.py to minimize modifications to the original game files elif self.powerupType == 'snoball': - spaz=node.getDelegate() + spaz = node.getDelegate() SnoBallz.snoBall().getFactory().giveBallz(spaz) self._powersGiven = True self.handleMessage(bs.DieMessage()) elif self.powerupType == 'portal': t = bsSpaz.gPowerupWearOffTime - if Portal.currentnum < Portal.maxportals : + if Portal.currentnum < Portal.maxportals: Portal.currentnum += 1 - if self.node.position in Portal.lastpos : - self.port = Portal.Portal(position1 = None,r = 0.9,color = (random.random(),random.random(),random.random()),activity = bs.getActivity()) - bs.gameTimer(t,bs.Call(self.delpor)) - else : + if self.node.position in Portal.lastpos: + self.port = Portal.Portal(position1=None, r=0.9, + color=(random.random(), random.random(), random.random()), + activity=bs.getActivity()) + bs.gameTimer(t, bs.WeakCall(self.delpor)) + else: m = self.node.position Portal.lastpos.append(m) - self.port = Portal.Portal(position1 = self.node.position,r = 0.9,color = (random.random(),random.random(),random.random()),activity = bs.getActivity()) - bs.gameTimer(t,bs.Call(self.delpor)) + self.port = Portal.Portal(position1=self.node.position, r=0.9, + color=(random.random(), random.random(), random.random()), + activity=bs.getActivity()) + bs.gameTimer(t, bs.WeakCall(self.delpor)) + self._powersGiven = True + self.handleMessage(bs.DieMessage()) + elif self.powerupType == "fly": + spaz = node.getDelegate() + tex = bs.Powerup.getFactory().texFly + spaz._flashBillboard(tex) + spaz.jumpTo3DFly = True + + def reset(): + spaz.jumpTo3DFly = False + if spaz.node.exists(): + bs.playSound(bs.Powerup.getFactory().powerdownSound, + position=self.node.position) + + if spaz.powerupsExpire: + spaz.node.miniBillboard1Texture = tex + t = bs.getGameTime() + spaz.node.miniBillboard1StartTime = t + spaz.node.miniBillboard1EndTime = t + bsSpaz.gPowerupWearOffTime + bs.gameTimer(bsSpaz.gPowerupWearOffTime, reset) + self._powersGiven = True + self.handleMessage(bs.DieMessage()) + elif self.powerupType == "motionTweaker": + bs.getSharedObject('globals').slowMotion = bs.getSharedObject('globals').slowMotion is False + self._powersGiven = True + self.handleMessage(bs.DieMessage()) + elif self.powerupType == 'antiGrav': + spaz = node.getDelegate() + spaz.setAntiGravCount(min(spaz.antiGravCount + 3, 3)) + self._powersGiven = True + self.handleMessage(bs.DieMessage()) + elif self.powerupType == 'headache': + spaz = node.getDelegate() + spaz.setHeadacheCount(spaz.headacheCount + 3) self._powersGiven = True self.handleMessage(bs.DieMessage()) else: - node.handleMessage(PowerupMessage(self.powerupType,sourceNode=self.node)) - - elif isinstance(m,bs.DieMessage): + node.handleMessage(PowerupMessage(self.powerupType, sourceNode=self.node)) + + elif isinstance(m, bs.DieMessage): if self.node.exists(): if (m.immediate): self.node.delete() else: - curve = bs.animate(self.node,"modelScale",{0:1,100:0}) - bs.gameTimer(100,self.node.delete) + curve = bs.animate(self.node, "modelScale", {0: 1, 100: 0}) + bs.gameTimer(100, self.node.delete) - elif isinstance(m,bs.OutOfBoundsMessage): + elif isinstance(m, bs.OutOfBoundsMessage): self.handleMessage(bs.DieMessage()) - elif isinstance(m,bs.HitMessage): + elif isinstance(m, bs.HitMessage): # dont die on punches (thats annoying) if m.hitType != 'punch': self.handleMessage(bs.DieMessage()) else: - bs.Actor.handleMessage(self,m) + bs.Actor.handleMessage(self, m) + bsPowerup.PowerupFactory = NewPowerupFactory bsPowerup.Powerup = NewPowerup