diff --git a/mods/catch_to_live.json b/mods/catch_to_live.json new file mode 100644 index 0000000..8697553 --- /dev/null +++ b/mods/catch_to_live.json @@ -0,0 +1,5 @@ +{ + "name": "CatchToLive", + "author": "Deva", + "category": "minigames" +} diff --git a/mods/catch_to_live.py b/mods/catch_to_live.py new file mode 100755 index 0000000..29b864f --- /dev/null +++ b/mods/catch_to_live.py @@ -0,0 +1,377 @@ +# coding=utf-8 +# coding=utf8 +import bs +import bsUtils +import random + + +class CheckNeedNewMadMessage(object): + def __init__(self, spaz=None): + self.spaz = spaz + + +class ClearProtectMessage(object): + def __init__(self): + pass + + +class grimPlayer(bs.PlayerSpaz): + def __init__(self, color, highlight, character, player, gameProtectionTime=3, hitPoints=5): + bs.PlayerSpaz.__init__(self, color=color, highlight=highlight, character=character, player=player) + self._inmad = False # 默认不是处于疯狂状态 + self._madProtect = False # 默认处于无保护状态 + self.hitPoints = hitPoints * 1000 + self.hitPointsMax = self.hitPoints + self.gameProtectionTime = gameProtectionTime + self._startMadTime = None + self._allMadTime = None + self._startProtectTime = None + + self.normalColor = color + self.madColor = (1, 0, 0) + self.protectColor = (0, 0, 1) + + def handleMessage(self, m): + if isinstance(m, bs.PickedUpMessage): + if not self.getPlayer().isAlive(): + return + oppoSpaz = m.node.getDelegate() + if not oppoSpaz.getPlayer().isAlive(): + return + + # 让对方放手 + oppoSpaz.onPickUpRelease() + oppoSpaz.onPickUpPress() + oppoSpaz.onPickUpRelease() + if self._madProtect: + bs.PlayerSpaz.handleMessage(self, m) + return + if oppoSpaz._inmad: + oppoSpaz.stopMad() + oppoSpaz.protectAdd() + leftTime = (oppoSpaz._allMadTime - bs.getGameTime() + oppoSpaz._startMadTime) + self.onMad(leftTime) + + bs.PlayerSpaz.handleMessage(self, m) + elif isinstance(m, bs.DieMessage): + self._inmad = False + if not self._dead and not m.immediate: + self._activity().handleMessage(CheckNeedNewMadMessage(self)) + bs.PlayerSpaz.handleMessage(self, m) + else: + bs.PlayerSpaz.handleMessage(self, m) + + def protectAdd(self): + # self.setScoreText(str(self.gameProtectionTime) + 's Crazy Protection') + self.setScoreText('Anti-Crazy') + self.node.color = self.protectColor + self._madProtect = True + self._startProtectTime = bs.getGameTime() + bs.gameTimer(self.gameProtectionTime * 1000, bs.Call(self.protectClear, self._startProtectTime)) + + # add hockey + self.node.hockey = True + + def protectClear(self, checkProtectStartTime): + if self._madProtect and self._startProtectTime == checkProtectStartTime: + self._madProtect = False + if self._inmad: + # 躲不了系统给的MAD + return + self.node.color = self.normalColor + + # add hockey + self.node.hockey = False + + def onMad(self, madTime=10000): + # 10秒后炸掉 + if self._inmad: + return + self._inmad = True + self.getPlayer().assignInputCall('pickUpPress', self.onPickUpPress) + self.getPlayer().assignInputCall('pickUpRelease', self.onPickUpRelease) + self.node.hockey = True + self.node.color = self.madColor + self._startMadTime = bs.getGameTime() + self._allMadTime = madTime + bs.gameTimer(madTime, bs.WeakCall(self.madExplode, self._startMadTime)) + + def stopMad(self): + self._inmad = False + self.getPlayer().assignInputCall('pickUpPress', lambda: None) + self.getPlayer().assignInputCall('pickUpRelease', lambda: None) + self.node.hockey = False + self.node.color = self.normalColor + + def madExplode(self, checkStartTime): + if self._inmad and self._startMadTime == checkStartTime: + self.shatter(extreme=True) + self.handleMessage(bs.DieMessage()) + + +def bsGetAPIVersion(): + return 4 + + +def bsGetGames(): + return [CatchToLiveGame] + + +class CatchToLiveGame(bs.TeamGameActivity): + @classmethod + def getName(cls): + return 'Catch To Live' + + @classmethod + def getScoreInfo(cls): + return {'scoreName': 'Survived', + 'scoreType': 'milliseconds', + 'scoreVersion': 'B'} + + @classmethod + def getDescription(cls, sessionType): + return 'If you\'re CRAZY and don\'t wanna die\nThen PICKUP others!' + + @classmethod + def getSupportedMaps(cls, sessionType): + # return ['Rampage'] + return bs.getMapsSupportingPlayType("melee") + + @classmethod + def getSettings(cls, sessionType): + return [("Mad Time To Die (Approximate)", {'minValue': 5, 'default': 10, 'increment': 1}), + ("Protection Time After Catching", {'minValue': 1, 'default': 3, 'increment': 1}), + ("Player HP", { + 'choices': [('normal', 1), ('2 times', 2), ('3 times', 3), ('5 times', 5), ('7 times', 7), + ('10 times', 10)], 'default': 5}), + ("Epic Mode", {'default': False}), + ("Allow Landmine", {'default': True})] + + # we support teams, free-for-all, and co-op sessions + @classmethod + def supportsSessionType(cls, sessionType): + return True if (issubclass(sessionType, bs.FreeForAllSession)) else False + + def __init__(self, settings): + bs.TeamGameActivity.__init__(self, settings) + + if self.settings['Epic Mode']: self._isSlowMotion = True + + # print messages when players die (since its meaningful in this game) + self.announcePlayerDeaths = True + + self._lastPlayerDeathTime = None + + # called when our game is transitioning in but not ready to start.. + # ..we can go ahead and set our music and whatnot + def onTransitionIn(self): + bs.TeamGameActivity.onTransitionIn(self, music='Epic' if self.settings['Epic Mode'] else 'Survival') + + # called when our game actually starts + def onBegin(self): + # self.playerList = [] + bs.TeamGameActivity.onBegin(self) + self._madTime = self.settings['Mad Time To Die (Approximate)'] * 1000 + + # bs.gameTimer(t,self._decrementMeteorTime,repeat=True) + + # kick off the first wave in a few seconds + t = 3000 + if self.settings['Epic Mode']: t /= 4 + # bs.gameTimer(t,self._setMeteorTimer) + + self._timer = bs.OnScreenTimer() + self._timer.start() + + bs.gameTimer(10, bs.WeakCall(self.updateSpazText), repeat=True) + + bs.gameTimer(t, bs.WeakCall(self.handleMessage, CheckNeedNewMadMessage()), repeat=False) + bs.gameTimer(1000, self._checkNeedMad, repeat=True) + + # bs.gameTimer(5000, self._checkEndGame) # 4秒之后检测一波 + + def updateSpazText(self): + for team in self.teams: + for player in team.players: + try: + if player.actor._inmad: + leftTime = (player.actor._allMadTime - bs.getGameTime() + player.actor._startMadTime) / 1000.0 + if leftTime > 0.0: + player.actor.setScoreText('Crazy') + # player.actor.setScoreText('%.2f' % (leftTime), color=(1, 1, 1)) + else: + player.actor.setScoreText('') + elif player.actor._madProtect: + player.actor.setScoreText('Anti-Crazy') + else: + player.actor.setScoreText('') + except: + pass + + # overriding the default character spawning.. + def spawnPlayer(self, player): + + position = self.getMap().getFFAStartPosition(self.players) + angle = 20 + name = player.getName() + + lightColor = bsUtils.getNormalizedColor(player.color) + displayColor = bs.getSafeColor(player.color, targetIntensity=0.75) + + spaz = grimPlayer(color=player.color, + highlight=player.highlight, + character=player.character, + player=player, + gameProtectionTime=self.settings['Protection Time After Catching'], + hitPoints=self.settings['Player HP']) + player.setActor(spaz) + # For some reason, I can't figure out how to get a list of all spaz. + # Therefore, I am making the list here so I can get which spaz belongs + # to the player supplied by HitMessage. + # self.playerList.append(spaz) + + spaz.node.name = name + spaz.node.nameColor = displayColor + spaz.connectControlsToPlayer() + self.scoreSet.playerGotNewSpaz(player, spaz) + + # add landmine + spaz.bombTypeDefault = 'landMine' # random.choice(['ice', 'impact', 'landMine', 'normal', 'sticky', 'tnt']) + spaz.bombType = spaz.bombTypeDefault + + # move to the stand position and add a flash of light + spaz.handleMessage(bs.StandMessage(position, angle if angle is not None else random.uniform(0, 360))) + t = bs.getGameTime() + bs.playSound(self._spawnSound, 1, position=spaz.node.position) + light = bs.newNode('light', attrs={'color': lightColor}) + spaz.node.connectAttr('position', light, 'position') + bsUtils.animate(light, 'intensity', {0: 0, 250: 1, 500: 0}) + bs.gameTimer(500, light.delete) + + # lets reconnect this player's controls to this + # spaz but *without* the ability to attack or pick stuff up + spaz.connectControlsToPlayer(enablePunch=False, + enableBomb=self.settings['Allow Landmine'], + enablePickUp=False) + # player.assignInputCall('pickUpPress', lambda: None) + # player.assignInputCall('pickUpRelease', lambda: None) + # also lets have them make some noise when they die.. + spaz.playBigDeathSound = True + + return spaz + + def onPlayerJoin(self, player): + # don't allow joining after we start + # (would enable leave/rejoin tomfoolery) + if self.hasBegun(): + bs.screenMessage(bs.Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', player.getName(full=True))]), + color=(0, 1, 0)) + # for score purposes, mark them as having died right as the game started + player.gameData['noScore'] = True + return + self.spawnPlayer(player) + + def onPlayerLeave(self, player): + # augment default behavior... + bs.TeamGameActivity.onPlayerLeave(self, player) + # a departing player may trigger game-over + bs.gameTimer(100, bs.Call(self._checkEndGame)) + + # various high-level game events come through this method + def handleMessage(self, m): + + if isinstance(m, bs.PlayerSpazDeathMessage): + + bs.TeamGameActivity.handleMessage(self, m) # (augment standard behavior) + + deathTime = bs.getGameTime() + + # record the player's moment of death + m.spaz.getPlayer().gameData['deathTime'] = deathTime + + # in co-op mode, end the game the instant everyone dies (more accurate looking) + # in teams/ffa, allow a one-second fudge-factor so we can get more draws + if isinstance(self.getSession(), bs.CoopSession): + # teams will still show up if we check now.. check in the next cycle + bs.pushCall(self._checkEndGame) + self._lastPlayerDeathTime = deathTime # also record this for a final setting of the clock.. + else: + bs.gameTimer(1000, self._checkEndGame) + + elif isinstance(m, CheckNeedNewMadMessage): + self._checkNeedMad() + else: + # default handler: + bs.TeamGameActivity.handleMessage(self, m) + + def _checkNeedMad(self): + # print('check if we need a new mad') + alivePlayers = [] + for team in self.teams: + for player in team.players: + if player.isAlive(): + alivePlayers.append(player) + if player.actor._inmad: + # print('no need for new mad') + return + + if len(alivePlayers) == 0: + return + + selectedPlayer = random.choice(alivePlayers) + selectedPlayer.actor.onMad(random.randint(self._madTime - 2500, self._madTime + 2500)) + + def _checkEndGame(self): + livingTeamCount = 0 + for team in self.teams: + for player in team.players: + if player.isAlive(): + livingTeamCount += 1 + break + + # in co-op, we go till everyone is dead.. otherwise we go until one team remains + if isinstance(self.getSession(), bs.CoopSession): + if livingTeamCount <= 0: self.endGame() + else: + if livingTeamCount <= 1: self.endGame() + + def endGame(self): + + curTime = bs.getGameTime() + + # mark 'death-time' as now for any still-living players + # and award players points for how long they lasted. + # (these per-player scores are only meaningful in team-games) + for team in self.teams: + for player in team.players: + + # throw an extra fudge factor +1 in so teams that + # didn't die come out ahead of teams that did + if 'deathTime' not in player.gameData: player.gameData['deathTime'] = curTime + 1 + if 'noScore' in player.gameData: player.gameData['deathTime'] = self._timer.getStartTime() + + # award a per-player score depending on how many seconds they lasted + # (per-player scores only affect teams mode; everywhere else just looks at the per-team score) + score = (player.gameData['deathTime'] - self._timer.getStartTime()) / 1000 + if 'deathTime' not in player.gameData: score += 50 # a bit extra for survivors + self.scoreSet.playerScored(player, score, screenMessage=False) + + # stop updating our time text, and set the final time to match + # exactly when our last guy died. + self._timer.stop(endTime=self._lastPlayerDeathTime) + + # ok now calc game results: set a score for each team and then tell the game to end + results = bs.TeamGameResults() + + # remember that 'free-for-all' mode is simply a special form of 'teams' mode + # where each player gets their own team, so we can just always deal in teams + # and have all cases covered + for team in self.teams: + + # set the team score to the max time survived by any player on that team + longestLife = 0 + for player in team.players: + longestLife = max(longestLife, (player.gameData['deathTime'] - self._timer.getStartTime())) + results.setTeamScore(team, longestLife) + + self.end(results=results) diff --git a/mods/random_door.json b/mods/random_door.json new file mode 100644 index 0000000..a426a28 --- /dev/null +++ b/mods/random_door.json @@ -0,0 +1,6 @@ +{ + "name": "Random Door Powerup", + "author": "Deva", + "category": "libraries", + "requires": ["BuddyBunny", "SnoBallz"] +} diff --git a/mods/random_door.py b/mods/random_door.py new file mode 100755 index 0000000..ad0aed5 --- /dev/null +++ b/mods/random_door.py @@ -0,0 +1,186 @@ +# coding=utf-8 +import bs +import bsUtils +import bsVector +import bsBomb +from math import cos +from random import randrange +import weakref +import types +import random +import copy + + +class doorHitSpazMessage(): + def __init__(self): + pass + + +class doorStartUseMessage(): + def __init__(self): + pass + + +class randomDoor(bs.Actor): + def __init__(self, position=(0, 1, 0), velocity=(5, 0, 5), sourcePlayer=None, owner=None): + bs.Actor.__init__(self) + + activity = bs.getActivity() + factory = self.getFactory() + # spawn at the provided point + self._spawnPos = (position[0], position[1] + 0.1, position[2]) + self.node = bs.newNode("prop", + attrs={'model': factory.doorModel, + 'body': 'sphere', + 'colorTexture': factory.texColor, + 'reflection': 'soft', + 'modelScale': 1, + 'bodyScale': 1, + 'density': 1, + 'reflectionScale': [0.8], + 'shadowSize': 0.1, + 'position': self._spawnPos, + 'velocity': velocity, + 'materials': [bs.getSharedObject('objectMaterial'), factory.ballMaterial] + }, + delegate=self) + self.sourcePlayer = sourcePlayer + self.owner = owner + if factory._autoDisappear: # defaults to True. + # Snowballs should melt after some time + bs.gameTimer(6500, bs.WeakCall(self._disappear)) + self._hitNodes = set() + self._used = False + self.canUse = False + + def _disappear(self): + self._used = True + if self.exists(): + scl = self.node.modelScale + bsUtils.animate(self.node, "modelScale", {0: scl * 1.0, 300: scl * 0.5, 500: 0.0}) + bs.gameTimer(550, bs.WeakCall(self.handleMessage, bs.DieMessage())) + + def handleMessage(self, m): + super(self.__class__, self).handleMessage(m) + + if isinstance(m, bs.DieMessage): + self.node.delete() + elif isinstance(m, bs.OutOfBoundsMessage): + self.handleMessage(bs.DieMessage()) + elif isinstance(m, bs.DroppedMessage): + bs.gameTimer(200, bs.WeakCall(self.handleMessage, doorStartUseMessage())) + elif isinstance(m, doorStartUseMessage): + self.canUse = True + elif isinstance(m, doorHitSpazMessage): + if not self.canUse: + return + if self._used: + return + oppoNode = bs.getCollisionInfo("opposingNode") + if oppoNode is not None and oppoNode.exists(): + activity = self._activity() + pos = self.getFactory().getRandomPosition(activity) + oppoNode.handleMessage(bs.StandMessage(pos)) + bs.Blast(position=pos, blastRadius=1.0, blastType='smoke').autoRetain() + bs.playSound(bs.getSound('shieldDown')) + + self._disappear() + + @classmethod + def getFactory(cls): + """ + Returns a shared randomDoorFactory object, creating it if necessary. + """ + activity = bs.getActivity() + if activity is None: raise Exception("no current activity") + try: + return activity._sharedRandomDoorFactory + except Exception: + f = activity._sharedRandomDoorFactory = randomDoorFactory() + return f + + +def dropRandomDoor(self): + # print 'Test drop' + if self.bombCount > 0: + self.bombCount -= 1 + self.setRandomDoorCount() + + p = self.node.positionForward + v = self.node.velocity + + door = randomDoor(position=(p[0], p[1] - 0.0, p[2]), + velocity=(v[0], v[1], v[2]), + sourcePlayer=self.sourcePlayer, + owner=self.node).autoRetain() + + self._pickUp(door.node) + return door + + f = types.MethodType(self.__class__.dropBomb, self, self.__class__) + self.dropBomb = f + self.bombCount = 1 + return self.dropBomb() + + +def setRandomDoorCount(self): + if self.node.exists(): + if self.bombCount != 0: + self.node.counterText = 'x' + str(self.bombCount) + self.node.counterTexture = bs.Powerup.getFactory().texDoor + else: + self.node.counterText = '' + + +class randomDoorFactory(object): + def __init__(self): + + self.texColor = bs.getTexture("cyborgColor") + self.doorModel = bs.getModel("frostyPelvis") + self.ballMaterial = bs.Material() + self.impactSound = bs.getSound('impactMedium') + self.ballMaterial.addActions( + conditions=((('weAreYoungerThan', 5), 'or', ('theyAreYoungerThan', 100)), + 'and', ('theyHaveMaterial', bs.getSharedObject('objectMaterial'))), + actions=(('modifyNodeCollision', 'collide', False))) + self.ballMaterial.addActions( + conditions=('theyHaveMaterial', bs.getSharedObject('pickupMaterial')), + actions=(('modifyPartCollision', 'useNodeCollide', False))) + self.ballMaterial.addActions(actions=('modifyPartCollision', 'friction', 0.3)) + self.ballMaterial.addActions(conditions=('theyHaveMaterial', bs.getSharedObject('playerMaterial')), actions=( + ('modifyPartCollision', 'physical', False), ('message', 'ourNode', 'atConnect', doorHitSpazMessage()))) + + self.defaultBallTimeout = 300 + self._autoDisappear = True + self.positionSpan = None + + def giveRD(self, spaz): + f = types.MethodType(dropRandomDoor, spaz, spaz.__class__) + spaz.dropBomb = f + spaz.bombCount = 3 # give 3 random doors + f2 = types.MethodType(setRandomDoorCount, spaz, spaz.__class__) + spaz.setRandomDoorCount = f2 + spaz.setRandomDoorCount() + + def setpositionSpan(self, positionSpan): + self.positionSpan = positionSpan + + def getRandomPosition(self, activity): + if self.positionSpan is not None: + ru = random.uniform + ps = self.positionSpan + return (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)) + + pts = copy.copy(activity.getMap().ffaSpawnPoints) + pts2 = activity.getMap().powerupSpawnPoints + for i in pts2: + pts.append(i) + pos = [[999, -999], [999, -999], [999, -999]] + for pt in pts: + for i in range(3): + pos[i][0] = min(pos[i][0], pt[i]) + pos[i][1] = max(pos[i][1], pt[i]) + + self.setpositionSpan(pos) + # print repr(pos) + return self.getRandomPosition(activity) diff --git a/mods/snowyPowerup.py b/mods/snowyPowerup.py index 54c9d83..7b18328 100644 --- a/mods/snowyPowerup.py +++ b/mods/snowyPowerup.py @@ -1,14 +1,16 @@ import bs import random -#add for bunny buddy: +# add for bunny buddy: import BuddyBunny import SnoBallz +# add for random door +import random_door import bsPowerup from bsPowerup import PowerupMessage, PowerupAcceptMessage, _TouchedMessage, PowerupFactory, Powerup - defaultPowerupInterval = 8000 + class NewPowerupFactory(PowerupFactory): def __init__(self): self._lastPowerupType = None @@ -25,12 +27,16 @@ 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... + # Add for randomDoor: + self.texDoor = bs.getTexture("cyborgColor") + self.doorModel = bs.getModel("frostyPelvis") + self.healthPowerupSound = bs.getSound("healthPowerup") self.powerupSound = bs.getSound("powerup01") self.powerdownSound = bs.getSound("powerdown01") @@ -44,22 +50,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) @@ -69,26 +75,29 @@ def getRandomPowerupType(self, forceType=None, excludeTypes=None): # example: bsFootball.py:456 excludeTypes.append('snoball') excludeTypes.append('bunny') + excludeTypes.append('randomDoor') else: excludeTypes = [] return PowerupFactory.getRandomPowerupType(self, forceType, excludeTypes) def getDefaultPowerupDistribution(): - return (('tripleBombs',3), - ('iceBombs',3), - ('punch',3), - ('impactBombs',3), - ('landMines',2), - ('stickyBombs',3), - ('shield',2), - ('health',1), - ('bunny',2), - ('curse',1), - ('snoball',3)) + return (('tripleBombs', 3), + ('iceBombs', 3), + ('punch', 3), + ('impactBombs', 3), + ('landMines', 2), + ('stickyBombs', 3), + ('shield', 2), + ('health', 1), + ('bunny', 2), + ('curse', 1), + ('snoball', 3), + ('randomDoor', 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. @@ -97,101 +106,121 @@ def __init__(self,position=(0,1,0),powerupType='tripleBombs',expire=True): bs.Actor.__init__(self) factory = self.getFactory() - self.powerupType = powerupType; + self.powerupType = powerupType self._powersGiven = False 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 == '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 == '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 == 'randomDoor': + tex = factory.texDoor + mod = factory.doorModel + mScl = 1.2 + 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 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 not 'bunnies' 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 == 'randomDoor': + spaz = node.getDelegate() + random_door.randomDoor().getFactory().giveRD(spaz) + 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