def handleMessage(self, m): if not self.node.exists(): return if isinstance(m, bs.OutOfBoundsMessage): self.node.delete() elif isinstance(m, bs.DieMessage): self.node.delete() # TODO - add functoional for speed-up on picked up elif isinstance(m, bs.PickedUpMessage): bs.Blast(position=self.node.position, blastType='impact', blastRadius=0.8).autoRetain() bs.playSound(self.touchedSound, position=self.node.position, volume=4) self.x, self.y, self.z = m.node.position # I SAID DON'T TOUCH! self.speedMul = 3.0 self.hp -= 10 + random.randint(-3, 3) if self.hp < 0: bs.Blast(position=self.node.position, blastRadius=0.5, blastType='tnt') self.handleMessage(bs.DieMessage()) elif isinstance(m, bs.DroppedMessage): self.speedMul = 1.0 else: bs.Actor.handleMessage(self, m)
def _updateBoxState(self): for team in self.teams: team.gameData['holdingBox'] = False self._holdingPlayers = [] for player in self.players: try: if player.actor.isAlive() and player.actor.node.holdNode.exists(): holdingBox = (player.actor.node.holdNode == self._box.node) else: holdingBox = False except Exception: bs.printException("exception checking hold flag") if holdingBox: self._holdingPlayers.append(player) player.getTeam().gameData['holdingBox'] = True if self._box is not None and self._box.exists(): self._box.heldBy = len(self._holdingPlayers) self._box.updateFloatyness() holdingTeams = set(t for t in self.teams if t.gameData['holdingBox']) prevState = self._boxState if len(holdingTeams) > 1: self._boxState = self.BOX_CONTESTED self._scoringTeam = None elif len(holdingTeams) == 1: holdingTeam = list(holdingTeams)[0] self._boxState = self.BOX_HELD self._scoringTeam = holdingTeam else: self._boxState = self.BOX_UNCONTESTED self._scoringTeam = None if self._boxState != prevState: bs.playSound(self._swipSound)
def handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) player = m.spaz.getPlayer() self.respawnPlayer(player) killer = m.killerPlayer if killer is None: return if killer.getTeam() is player.getTeam(): if isinstance(self.getSession(), bs.FreeForAllSession): newScore = player.getTeam().gameData['score'] - 1 if not self.settings['Allow Negative Scores']: newScore = max(0, newScore) player.getTeam().gameData['score'] = newScore else: bs.playSound(self._dingSound) for team in self.teams: if team is not killer.getTeam(): team.gameData['score'] += 1 else: killer.getTeam().gameData['score'] += 1 bs.playSound(self._dingSound) try: killer.actor.setScoreText( str(killer.getTeam().gameData['score']) + '/' + str(self._scoreToWin), color=killer.getTeam().color, flash=True) except Exception: pass self._updateScoreBoard() if any(team.gameData['score'] >= self._scoreToWin for team in self.teams): bs.gameTimer(500, self.endGame) else: bs.TeamGameActivity.handleMessage(self, m)
def onBegin(self): bs.TeamGameActivity.onBegin(self) self.setupStandardTimeLimit(self.settings['Time Limit']) self.setupStandardPowerupDrops(enableTNT=False) self._ballSpawnPos = self.getMap().getFlagPosition(None) self._spawnBall() #for night mode we need night actor. And same goodies for nigh mode if self.settings['Night Mode']: self._nightSpawny(),self._flagKaleFlash() # set up the two score regions defs = self.getMap().defs self._scoreRegions = [] self._scoreRegions.append(bs.NodeActor(bs.newNode("region", attrs={'position':(13.75, 0.85744967453, 0.1095578275), 'type':"box", 'scale': (1.05,1.1,3.8), 'materials':[self._scoreRegionMaterial]}))) self._scoreRegions.append(bs.NodeActor(bs.newNode("region", attrs={'position':(-13.55, 0.85744967453, 0.1095578275), 'type':"box", 'scale': (1.05,1.1,3.8), 'materials':[self._scoreRegionMaterial]}))) self._updateScoreBoard() bs.playSound(self._chantSound)
def spawnPlayerSpaz(self, player, position=(0, 0, 0), angle=None): name = player.getName() color = player.color highlight = player.highlight lightColor = bsUtils.getNormalizedColor(color) displayColor = bs.getSafeColor(color, targetIntensity=0.75) spaz = AntiGravityPlayerSpaz(color=color, highlight=highlight, character=player.character, player=player) player.setActor(spaz) if isinstance(self.getSession(), bs.CoopSession) and self.getMap().getName() in [ 'Courtyard', 'Tower D' ]: mat = self.getMap().preloadData['collideWithWallMaterial'] spaz.node.materials += (mat, ) spaz.node.rollerMaterials += (mat, ) spaz.node.name = name spaz.node.nameColor = displayColor spaz.connectControlsToPlayer() 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) bs.gameTimer(1000, bs.Call(self.raisePlayer, player)) return spaz
def spawnPlayer(self, player): if isinstance(self.getSession(), bs.TeamsSession): position = self.getMap().getStartPosition(player.getTeam().getID()) else: # otherwise do free-for-all spawn locations position = self.getMap().getFFAStartPosition(self.players) angle = None #spaz = self.spawnPlayerSpaz(player) # lets reconnect this player's controls to this # spaz but *without* the ability to attack or pick stuff up #spaz.connectControlsToPlayer(enablePunch=False, # enableBomb=False, # enablePickUp=False) # also lets have them make some noise when they die.. #spaz.playBigDeathSound = True name = player.getName() lightColor = bsUtils.getNormalizedColor(player.color) displayColor = bs.getSafeColor(player.color, targetIntensity=0.75) spaz = Player(color=player.color, highlight=player.highlight, character=player.character, player=player) player.setActor(spaz) # we want a bigger area-of-interest in co-op mode # if isinstance(self.getSession(),bs.CoopSession): spaz.node.areaOfInterestRadius = 5.0 # else: spaz.node.areaOfInterestRadius = 5.0 # if this is co-op and we're on Courtyard or Runaround, add the material that allows us to # collide with the player-walls # FIXME; need to generalize this if isinstance(self.getSession(), bs.CoopSession) and self.getMap().getName() in ['Courtyard', 'Tower D']: mat = self.getMap().preloadData['collideWithWallMaterial'] spaz.node.materials += (mat,) spaz.node.rollerMaterials += (mat,) spaz.node.name = name spaz.node.nameColor = displayColor spaz.connectControlsToPlayer( enableJump=True, enablePunch=True, enablePickUp=False, enableBomb=True, enableRun=True, enableFly=False) self.scoreSet.playerGotNewSpaz(player,spaz) # 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)
def givePowers(self): for player in self.players: if not player.actor is None: if player.actor.isAlive(): #This teleport the player if player.actor.landMineCount == 1: pos = self.getMap().getFFAStartPosition(self.players) player.actor.handleMessage(bs.StandMessage(pos)) bs.Blast(position=pos, blastRadius=1.0, blastType='smoke').autoRetain() bs.playSound(bs.getSound('shieldDown')) player.actor.landMineCount = 0 #The player will be fly with the explosions elif player.actor.landMineCount == 2: pos = player.actor.node.position bs.Blast(position=(pos[0], pos[1] - 0.5, pos[2]), blastRadius=1.0, blastType='smoke').autoRetain() player.actor.handleMessage(bs.PowerupMessage('health')) player.actor.landMineCount = 0 elif player.actor.landMineCount == 3: mPlayer = player.actor self.freezeAll(mPlayer) player.actor.landMineCount = 0
def __init__(self, data): self._width = 350 self._height = 200 self._rootWidget = bs.containerWidget( size=(self._width, self._height), color=(0.45, 0.63, 0.15), transition='inScale', scale=1.8 if bsUI.gSmallUI else 1.35 if bsUI.gMedUI else 1.0) self._data = copy.deepcopy(data) bs.playSound(bs.getSound('cashRegister')) bs.playSound(bs.getSound('swish')) self._cancelButton = bs.buttonWidget(parent=self._rootWidget, scale=0.5, position=(40, self._height - 40), size=(50, 50), label='', onActivateCall=self.close, autoSelect=True, color=(0.45, 0.63, 0.15), icon=bs.getTexture('crossOut'), iconScale=1.2) bs.containerWidget(edit=self._rootWidget, cancelButton=self._cancelButton) t = bs.textWidget(parent=self._rootWidget, position=(self._width * 0.5, self._height * 0.5), size=(0, 0), color=(1.0, 3.0, 1.0), scale=2.0, hAlign="center", vAlign="center", text=data['code'], maxWidth=self._width * 0.85)
def adminKick(self, popupWindow, choice): def getIndex(): for i in bsInternal._getGameRoster(): if i["clientID"] == self._popupPartyMemberClientID: return bsInternal._getGameRoster().index(i) if choice == "kick": if self._popupPartyMemberIsHost: bs.playSound(bs.getSound('error')) bs.screenMessage(bs.Lstr(resource='internal.cantKickHostError'), color=(1, 0, 0)) else: print self._popupPartyMemberClientID result = bsInternal._disconnectClient( self._popupPartyMemberClientID) if not result: bs.playSound(bs.getSound('error')) bs.screenMessage( bs.Lstr(resource='getTicketsWindow.unavailableText'), color=(1, 0, 0)) else: f = open(bs.getEnvironment()['userScriptsDirectory'] + "/ban.txt", 'a') for i in bsInternal._getGameRoster(): cid = i['clientID'] if cid == self._popupPartyMemberClientID: bsInternal._chatMessage("/kick " + str(cid)) f.write(i['players'][0]['nameFull'] + ' - ' + eval(bsInternal._getGameRoster()[getIndex()] ["specString"])["n"] + '\n') bs.textWidget(edit=self._textField, text='')
def onBegin(self): bs.TeamGameActivity.onBegin(self) self._excludePowerups = ['speed'] self.setupStandardTimeLimit(self.settings['Time Limit']) self.setupStandardPowerupDrops() self._puckSpawnPos = self.getMap().getFlagPosition(None) self._spawnPuck() # set up the two score regions defs = self.getMap().defs self._scoreRegions = [] self._scoreRegions.append( bs.NodeActor( bs.newNode("region", attrs={ 'position': defs.boxes["goal1"][0:3], 'scale': defs.boxes["goal1"][6:9], 'type': "box", 'materials': [self._scoreRegionMaterial] }))) self._scoreRegions.append( bs.NodeActor( bs.newNode("region", attrs={ 'position': defs.boxes["goal2"][0:3], 'scale': defs.boxes["goal2"][6:9], 'type': "box", 'materials': [self._scoreRegionMaterial] }))) self._updateScoreBoard() bs.playSound(self._chantSound)
def onPlayerLeave(self, player): bs.TeamGameActivity.onPlayerLeave(self, player) # a player leaving disqualifies the team if 'Entire Team Must Finish' # is on (otherwise in teams mode everyone could just leave except the # leading player to win) if isinstance(self.getSession(), bs.TeamsSession ) and self.settings.get('Entire Team Must Finish'): # FIXME translate this bs.screenMessage(bs.Lstr( translate=('statements', '${TEAM} is disqualified because ${PLAYER} left'), subs=[('${TEAM}', player.getTeam().name), ('${PLAYER}', player.getName(full=True))]), color=(1, 1, 0)) player.getTeam().gameData['finished'] = True player.getTeam().gameData['time'] = None player.getTeam().gameData['lap'] = 0 bs.playSound(bs.getSound("boo")) for player in player.getTeam().players: player.gameData['lap'] = 0 player.gameData['finished'] = True try: player.actor.handleMessage(bs.DieMessage()) except Exception: pass # delay by one tick so team/player lists will be updated bs.gameTimer(1, self._checkEndGame)
def onBegin(self): bs.TeamGameActivity.onBegin(self) self.winners = [] self.setupStandardTimeLimit(self.settings['Time Limit']) # set up the score region self._scoreRegions = [] defs = self.getMap().defs self._scoreRegions.append( bs.NodeActor( bs.newNode('region', attrs={ 'position': defs.boxes['goal1'][0:3], 'scale': defs.boxes['goal1'][6:9], 'type': 'box', 'materials': (self.scoreRegionMaterial, ) }))) self._updateScoreBoard() self.updateBoxes() #Preload the play area with mines while len(self.mines) < self.settings['Start Mines']: x = random.uniform(-11.3, 11.3) y = random.uniform(-5.2, 5.7) pos = [x, 0.32, y] self._makeMine(pos) bs.playSound(self._chantSound) #Set up the timer for mine spawning bs.gameTimer(int(1000 / self.settings['Mines per Second']), bs.WeakCall(self.mineUpdate), repeat=True) bs.gameTimer(1000, self._update, repeat=True)
def _handleSplat(self,m): node = bs.getCollisionInfo("opposingNode") if (node is not self.owner and bs.getGameTime() - self._lastStickySoundTime > 1000): self._lastStickySoundTime = bs.getGameTime() bs.playSound(self.getFactory().stickyImpactSound, 2.0, position=self.node.position)
def _handleWarn(self, m): if self.node.exists(): if self.textureSequence.exists(): self.textureSequence.rate = 30 bs.playSound(self.getFactory().warnSound, 0.5, position=self.node.position) else: return
def arm(self): """ Arms land-mines and impact-bombs so that they will explode on impact. """ if not self.node.exists(): return factory = self.getFactory() if self.bombType == 'landMine': self.textureSequence = bs.newNode('textureSequence', owner=self.node, attrs={'inputTextures':(factory.landMineLitTex, factory.landMineTex),'rate':30}) bs.gameTimer(500,self.textureSequence.delete) # we now make it explodable. bs.gameTimer(250,bs.WeakCall(self._addMaterial,factory.landMineBlastMaterial)) elif self.bombType == 'impact': self.textureSequence = bs.newNode('textureSequence', owner=self.node, attrs={'inputTextures':(factory.impactLitTex, factory.impactTex, factory.impactTex),'rate':100}) bs.gameTimer(250,bs.WeakCall(self._addMaterial,factory.landMineBlastMaterial)) else: raise Exception('arm() should only be called on land-mines or impact bombs') self.textureSequence.connectAttr('outputTexture',self.node,'colorTexture') bs.playSound(factory.activateSound,0.5,position=self.node.position)
def handleMessage(self, m): self._handleMessageSanityCheck() 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) self._powersGiven = True self.handleMessage(bs.DieMessage()) elif isinstance(m, _TouchedMessage): if not self._powersGiven and not self.picked: node = bs.getCollisionInfo("opposingNode") if node is not None and node.exists(): 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}) if some.show_powerup_name: curve1 = bs.animate(self._powText, "scale", { 0: 0.01, 100: 0 }) if hasattr(self, 'nodeLight'): curve2 = bs.animate(self.nodeLight, "radius", { 0: 0.5, 100: 0 }) bs.gameTimer(100, self.node.delete) elif isinstance(m, bs.OutOfBoundsMessage): self.handleMessage(bs.DieMessage()) elif isinstance(m, bs.PickedUpMessage): self.picked = True elif isinstance(m, bs.DroppedMessage): self.picked = False elif isinstance(m, bs.HitMessage): # dont die on punches (thats annoying) msg = m if some.interactive_powerups: 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 m.hitType != 'punch': self.handleMessage(bs.DieMessage()) else: bs.Actor.handleMessage(self, m)
def _tick(self): self._updateFlagState() # give holding players points for player in self.players: if player.gameData['atFlag'] > 0: self.scoreSet.playerScored(player, 3, screenMessage=False, display=False) scoringTeam = None if self._scoringTeam is None else self._scoringTeam( ) if scoringTeam: if scoringTeam.gameData['timeRemaining'] > 0: bs.playSound(self._tickSound) scoringTeam.gameData['timeRemaining'] = max( 0, scoringTeam.gameData['timeRemaining'] - 1) self._updateScoreBoard() if scoringTeam.gameData['timeRemaining'] > 0: self._flag.setScoreText( str(scoringTeam.gameData['timeRemaining'])) # announce numbers we have sounds for try: bs.playSound(self._countDownSounds[ scoringTeam.gameData['timeRemaining']]) except Exception: pass # winner if scoringTeam.gameData['timeRemaining'] <= 0: self.endGame()
def onBegin(self): bs.TeamGameActivity.onBegin(self) self.setupStandardTimeLimit(self.settings['Time Limit']) self.setupStandardPowerupDrops() self._flagSpawnPos = self.getMap().getFlagPosition(None) self._spawnFlag() # set up the two score regions self._scoreRegions = [] defs = self.getMap().defs self._scoreRegions.append( bs.NodeActor( bs.newNode('region', attrs={ 'position': defs.boxes['goal1'][0:3], 'scale': defs.boxes['goal1'][6:9], 'type': 'box', 'materials': (self.scoreRegionMaterial, ) }))) self._scoreRegions.append( bs.NodeActor( bs.newNode('region', attrs={ 'position': defs.boxes['goal2'][0:3], 'scale': defs.boxes['goal2'][6:9], 'type': 'box', 'materials': (self.scoreRegionMaterial, ) }))) self._updateScoreBoard() bs.playSound(self._chantSound)
def spawnPlayer(self, player): position = self.getMap().getFFAStartPosition(self.players) angle = None name = player.getName() lightColor = bsUtils.getNormalizedColor(player.color) displayColor = bs.getSafeColor(player.color, targetIntensity=0.75) spaz = NewPlayerSpaz(color=player.color, highlight=player.highlight, character=player.character, player=player) player.setActor(spaz) player.gameData['boxes'] = 0 spaz.node.name = name spaz.node.nameColor = displayColor spaz.connectControlsToPlayer(enablePickUp=False) if self.settings['Equip Boxing Gloves']: spaz.equipBoxingGloves() if self.settings['Equip Shield']: spaz.equipShields() spaz.playBigDeathSound = True self.scoreSet.playerGotNewSpaz(player, spaz) 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)
def onTransitionIn(self): bs.CoopGameActivity.onTransitionIn(self, music='Football') self._scoreBoard = bs.ScoreBoard() self._flagSpawnPos = self.getMap().getFlagPosition(None) self._spawnFlag() # set up the two score regions self.scoreRegions = [] defs = self.getMap().defs self.scoreRegions.append( bs.NodeActor( bs.newNode('region', attrs={ 'position': defs.boxes['goal1'][0:3], 'scale': defs.boxes['goal1'][6:9], 'type': 'box', 'materials': [self._scoreRegionMaterial] }))) self.scoreRegions.append( bs.NodeActor( bs.newNode('region', attrs={ 'position': defs.boxes['goal2'][0:3], 'scale': defs.boxes['goal2'][6:9], 'type': 'box', 'materials': [self._scoreRegionMaterial] }))) bs.playSound(self._chantSound)
def _handleKillScore(self, player, killer): if killer is None: return killerID = killer.getID() mission = self._playerMissions.get(killerID) if not mission.get('mission') in [2]: return # handle team-kills if killer.getTeam() is player.getTeam(): pass else: team = killer.getTeam() team.gameData['score'] += 7 # tell all players to celebrate for player in team.players: try: player.actor.node.handleMessage('celebrate', 2000) except Exception: pass # end game if we won if team.gameData['score'] >= self.settings['Score to Win']: self.endGame() bs.playSound(self._scoreSound) bs.playSound(self._cheerSound) self.cameraFlash(duration=10) self._updateScoreBoard()
def _tick(self): self._updateBoxState() # award points to all living players holding the flag for player in self._holdingPlayers: if player.exists(): self.scoreSet.playerScored(player, 3, screenMessage=False, display=False) scoringTeam = self._scoringTeam if scoringTeam is not None: if scoringTeam.gameData['timeRemaining'] > 0: bs.playSound(self._tickSound) scoringTeam.gameData['timeRemaining'] = max(0, scoringTeam.gameData['timeRemaining']-1) self._updateScoreBoard() if scoringTeam.gameData['timeRemaining'] > 0: self._box.setScoreText(str(scoringTeam.gameData['timeRemaining'])) # announce numbers we have sounds for try: bs.playSound(self._countDownSounds[scoringTeam.gameData['timeRemaining']]) except Exception: pass # winner if scoringTeam.gameData['timeRemaining'] <= 0: self.endGame()
def handleMessage(self, m): if isinstance(m, bs.DieMessage): if self.node is not None and self.node.exists(): bs.playSound(bs.getSound('shatter'), position=self.node.position) bs.emitBGDynamics(position=self.node.position, velocity=(0, 4, 0), count=14, scale=0.8, chunkType='spark', spread=1.5) self.node.delete() self.bodyNode.delete() elif isinstance(m, bs.OutOfBoundsMessage): self.node.delete() self.bodyNode.delete() elif isinstance(m, bs.HitMessage): self.node.handleMessage("impulse", m.pos[0], m.pos[1], m.pos[2], m.velocity[0], m.velocity[1], m.velocity[2], 1.0 * m.magnitude, 1.0 * m.velocityMagnitude, m.radius, 0, m.forceDirection[0], m.forceDirection[1], m.forceDirection[2]) else: bs.Actor.handleMessage(self, m)
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.7 elif self.blastType == 'landMine': mag *= 1.5 elif self.blastType == 'tnt': mag *= 2.6 node.handleMessage(bs.HitMessage(pos=t, velocity=(0,0.1,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)
def _onEggPlayerCollide(self): if not self.hasEnded(): eggNode, playerNode = bs.getCollisionInfo( 'sourceNode', 'opposingNode') if eggNode is not None and playerNode is not None: egg = eggNode.getDelegate() spaz = playerNode.getDelegate() player = (spaz.getPlayer() if hasattr(spaz, 'getPlayer') else None) if player is not None and player.exists() and egg is not None: player.getTeam().gameData['score'] += 1 # displays a +1 (and adds to individual player score in # teams mode) self.scoreSet.playerScored(player, 1, screenMessage=False) if self._maxEggs < 5: self._maxEggs += 1.0 elif self._maxEggs < 10: self._maxEggs += 0.5 elif self._maxEggs < 30: self._maxEggs += 0.3 self._updateScoreBoard() bs.playSound(self._collectSound, 0.5, position=egg.node.position) # create a flash light = bs.newNode('light', attrs={'position': eggNode.position, 'heightAttenuated': False, 'radius': 0.1, 'color': (1, 1, 0)}) bs.animate(light, 'intensity', { 0: 0, 100: 1.0, 200: 0}, loop=False) bs.gameTimer(200, light.delete) egg.handleMessage(bs.DieMessage())
def _onCapsulePlayerCollide(self): if not self.hasEnded(): capsuleNode, playerNode = bs.getCollisionInfo('sourceNode','opposingNode') if capsuleNode is not None and playerNode is not None: capsule = capsuleNode.getDelegate() spaz = playerNode.getDelegate() player = spaz.getPlayer() if hasattr(spaz,'getPlayer') else None if player is not None and player.exists() and capsule is not None: if player.isAlive(): if capsuleNode.colorTexture == self._capsuleLuckyTex: player.gameData['capsules'] += 4 bsUtils.PopupText('BONUS!', color=(1,1,0), scale=1.5, position=(capsuleNode.position)).autoRetain() bs.playSound(self._luckyCollectSound,1.0,position=capsuleNode.position) bs.emitBGDynamics(position=capsuleNode.position,velocity=(0,0,0),count=int(6.4+random.random()*24),scale=1.2, spread=2.0,chunkType='spark'); bs.emitBGDynamics(position=capsuleNode.position,velocity=(0,0,0),count=int(4.0+random.random()*6),emitType='tendrils'); else: player.gameData['capsules'] += 1 bs.playSound(self._collectSound,0.6,position=capsuleNode.position) # create a flash light = bs.newNode('light', attrs={'position': capsuleNode.position, 'heightAttenuated':False, 'radius':0.1, 'color':(1,1,0)}) # Create a short text informing about your inventory self._handleCapsuleStorage(playerNode.position,player) bs.animate(light,'intensity',{0:0,100:0.5,200:0},loop=False) bs.gameTimer(200,light.delete) capsule.handleMessage(bs.DieMessage())
def handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior player = m.spaz.getPlayer() player.gameData['lives'] -= 1 if player.gameData['lives'] < 0: player.gameData['lives'] = 0 # if we have any icons, update their state for icon in player.gameData['icons']: icon.handlePlayerDied() # play big death sound on our last death # or for every one in solo mode if self._soloMode or player.gameData['lives'] == 0: bs.playSound(bs.Spaz.getFactory().singlePlayerDeathSound) # if we hit zero lives, we're dead (and our team might be too) if player.gameData['lives'] == 0: # if the whole team is now dead, mark their survival time.. if self._getTotalTeamLives(player.getTeam()) == 0: player.getTeam().gameData['survivalSeconds'] = ( bs.getGameTime() - self._startGameTime) / 1000 else: # otherwise, in regular mode, respawn.. if not self._soloMode: self.respawnPlayer(player) # in solo, put ourself at the back of the spawn order if self._soloMode: player.getTeam().gameData['spawnOrder'].remove(player) player.getTeam().gameData['spawnOrder'].append(player)
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 = BrickMan(color=player.color, highlight=player.highlight, character=player.character, player=player) player.setActor(spaz) spaz.node.name = '建筑师\n'.decode('utf8') + name spaz.node.nameColor = displayColor spaz.connectControlsToPlayer() self.scoreSet.playerGotNewSpaz(player, spaz) # 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) spaz.connectControlsToPlayer(enablePunch=True, enableBomb=True, enablePickUp=False) spaz.playBigDeathSound = True spaz.initArchitect() return spaz
def _apply(name, score, showPoints, color, scale, sound): # only award this if they're still alive and we can get their pos try: ourPos = self.getSpaz().node.position except Exception: return # jitter position a bit since these often come in clusters ourPos = (ourPos[0] + (random.random() - 0.5) * 2.0, ourPos[1] + (random.random() - 0.5) * 2.0, ourPos[2] + (random.random() - 0.5) * 2.0) activity = self.getActivity() if activity is not None: bsUtils.PopupText( # (('+'+str(score)+' ') if showPoints else '')+name, bs.Lstr(value=( ('+' + str(score) + ' ') if showPoints else '') + '${N}', subs=[('${N}', name)]), color=color, scale=scale, position=ourPos).autoRetain() bs.playSound(sound) self.score += score self.accumScore += score # inform a running game of the score if score != 0 and activity is not None: activity.handleMessage(PlayerScoredMessage(score=score))
def _spawnMine(self, player): #Don't spawn mines if player is dead if not player.exists() or not player.isAlive(): return gameData = player.getTeam().gameData # no more mines for players who've already won # to get a working draw if gameData['minesPlanted'] >= self.settings['Mines to win']: return gameData['minesPlanted'] += 1 gameData['tailLength'] = gameData['minesPlanted'] * self.tailIncrease + 2 if gameData['minesPlanted'] >= self.settings['Mines to win'] - 10: num2win = self.settings['Mines to win'] - gameData['minesPlanted'] + 1 if num2win in self._countDownSounds: bs.playSound(self._countDownSounds[num2win]) self._updateScoreBoard() if player.getTeam().gameData['tailLength'] < 2: return pos = player.actor.node.position pos = (pos[0], pos[1] + 2, pos[2]) mine = bs.Bomb(position=pos, velocity=(0, 0, 0), bombType='landMine', blastRadius=2.0, sourcePlayer=player, owner=player).autoRetain() player.gameData['mines'].append(mine) bs.gameTimer(int(self.mineDelay * 1000), bs.WeakCall(mine.arm)) bs.gameTimer(int(int(player.getTeam().gameData['tailLength'] + 1) * self.mineDelay * 1000), bs.WeakCall(self._removeMine, player, mine))
def _tick(self): self._updateBoxState() # award points to all living players holding the flag for player in self._holdingPlayers: if player.exists(): self.scoreSet.playerScored(player, 3, screenMessage=False, display=False) scoringTeam = self._scoringTeam if scoringTeam is not None: if scoringTeam.gameData['timeRemaining'] > 0: bs.playSound(self._tickSound) scoringTeam.gameData['timeRemaining'] = max(0, scoringTeam.gameData['timeRemaining'] - 1) self._updateScoreBoard() if scoringTeam.gameData['timeRemaining'] > 0: self._box.setScoreText(str(scoringTeam.gameData['timeRemaining'])) # announce numbers we have sounds for try: bs.playSound(self._countDownSounds[scoringTeam.gameData['timeRemaining']]) except Exception: pass # winner if scoringTeam.gameData['timeRemaining'] <= 0: self.endGame()
def setAutoUpdate(self, val): # FIXME: properly disable checkbox if not self.checkUpdates.value: bs.playSound(bs.getSound("error")) self.autoUpdates.value = False return config["auto-update-old-mods"] = bool(val) bs.writeConfig()
def __init__(self, mod, onok, swish=True, back=False): self._back = back self.mod = mod self.onok = bs.WeakCall(onok) if swish: bs.playSound(bs.getSound('swish')) self._rootWidget = ConfirmWindow("Are you sure you want to delete " + mod.filename + "?", self.ok).getRootWidget()
def _doLight4(self): self.lights[3].color = (0.0, 1.0, 0) bs.playSound(self._beep2Sound) for l in self.lights: bs.animate(l, 'opacity', {0: 1.0, 1000: 0.0}) bs.gameTimer(1000, l.delete) self.incTimer = None self.onFinish() del self
def spawnPlayer(self, player): if isinstance(self.getSession(), bs.TeamsSession): position = self.getMap().getStartPosition(player.getTeam().getID()) else: # otherwise do free-for-all spawn locations position = self.getMap().getFFAStartPosition(self.players) angle = None # spaz = self.spawnPlayerSpaz(player) # lets reconnect this player's controls to this # spaz but *without* the ability to attack or pick stuff up # spaz.connectControlsToPlayer(enablePunch=False, # enableBomb=False, # enablePickUp=False) # also lets have them make some noise when they die.. # spaz.playBigDeathSound = True name = player.getName() lightColor = bsUtils.getNormalizedColor(player.color) displayColor = bs.getSafeColor(player.color, targetIntensity=0.75) spaz = Player(color=player.color, highlight=player.highlight, character=player.character, player=player) player.setActor(spaz) # we want a bigger area-of-interest in co-op mode # if isinstance(self.getSession(),bs.CoopSession): spaz.node.areaOfInterestRadius = 5.0 # else: spaz.node.areaOfInterestRadius = 5.0 # if this is co-op and we're on Courtyard or Runaround, add the material that allows us to # collide with the player-walls # FIXME; need to generalize this if isinstance(self.getSession(), bs.CoopSession) and self.getMap().getName() in ["Courtyard", "Tower D"]: mat = self.getMap().preloadData["collideWithWallMaterial"] spaz.node.materials += (mat,) spaz.node.rollerMaterials += (mat,) spaz.node.name = name spaz.node.nameColor = displayColor spaz.connectControlsToPlayer( enableJump=True, enablePunch=True, enablePickUp=False, enableBomb=True, enableRun=True, enableFly=False ) self.scoreSet.playerGotNewSpaz(player, spaz) # 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)
def __init__(self): global quittoapply if quittoapply is not None: quittoapply.delete() quittoapply = None bs.playSound(bs.getSound('swish')) text = "Quit BS to reload mods?" if bs.getEnvironment()["platform"] == "android": text += "\n(On Android you have to kill the activity)" self._rootWidget = quittoapply = ConfirmWindow(text, self._doFadeAndQuit).getRootWidget()
def _spawnBox(self): bs.playSound(self._swipSound) self._flashBoxSpawn() self._box = MagicBox(position=self._boxSpawnPos) self._boxState = self.BOX_NEW self._box.light = bs.newNode('light', owner=self._box.node, attrs={'intensity':0.2, 'radius':0.3, 'color': (0.2, 0.2, 0.2)}) self._box.node.connectAttr('position', self._box.light, 'position') self._updateBoxState()
def _cb_select_tab(self, index, refresh=True): bs.playSound(bs.getSound('click01')) self._selectedTab = self.tabs[index] label = self._selectedTab["label"] for i, tab in enumerate(self.tabs): button = tab["button"] if i == index: button.set(color=(0.5, 0.4, 0.93), textColor=(0.85, 0.75, 0.95)) # lit else: button.set(color=(0.52, 0.48, 0.63), textColor=(0.65, 0.6, 0.7)) # unlit if refresh: self._refresh(refreshTabs=False)
def _reload_module(self): bs.screenMessage("reloading " + self._filename) self._prepare_reload() self._import_module() #self._module = import_module(self._filename[:-3], package=IMPORT_FOLDER.split("/")[-2]) with open(IMPORT_FOLDER + self._filename, "r") as f: self._module_md5 = md5(f.read()).hexdigest() self._did_print_error = False if self._is_available() and self._type == "game": self._game = self._module.bsGetGames()[0] else: self._game = None bs.playSound(bs.getSound('swish'))
def _spawnPuck(self, team): puckPos = self.getMap().getStartPosition(team.getID()) lightcolor = team.color bs.playSound(self._swipSound) bs.playSound(self._whistleSound) self._flashPuckSpawn(puckPos) puck = Puck(position=puckPos, team=team) puck.light = bs.newNode( "light", owner=puck.node, attrs={"intensity": 0.3, "heightAttenuated": False, "radius": 0.2, "color": lightcolor}, ) puck.node.connectAttr("position", puck.light, "position") self.pucks.append(puck)
def __init__(self, mod, onok, swish=True, back=False): self._back = back self.mod = mod self.onok = bs.WeakCall(onok) if swish: bs.playSound(bs.getSound('swish')) text = "Do you want to update %s?" if mod.isInstalled() else "Do you want to install %s?" text = text %(mod.filename) if mod.changelog and mod.isInstalled(): text += "\n\nChangelog:" for change in mod.changelog: text += "\n"+change height = 100 * (1 + len(mod.changelog) * 0.3) if mod.isInstalled() else 100 width = 360 * (1 + len(mod.changelog) * 0.15) if mod.isInstalled() else 360 self._rootWidget = ConfirmWindow(text, self.ok, height=height, width=width).getRootWidget()
def _setChosenOnePlayer(self, player): try: for p in self.players: p.gameData['FrozenLight'] = None bs.playSound(self._swipSound) if player is None or not player.exists(): self._flag = bs.Flag(color=(1,0.9,0.2), position=self._flagSpawnPos, touchable=False) self._chosenOnePlayer = None l = bs.newNode('light', owner=self._flag.node, attrs={'position': self._flagSpawnPos, 'intensity':0.6, 'heightAttenuated':False, 'volumeIntensityScale':0.1, 'radius':0.1, 'color': (1.2,1.2,0.4)}) self._flashFlagSpawn() else: if player.actor is not None: self._flag = None self._chosenOnePlayer = player if player.actor.node.exists(): if self.settings['Frozen One Gets Gloves']: player.actor.handleMessage(bs.PowerupMessage('punch')) player.actor.frozen = True player.actor.node.frozen = 1 # use a color that's partway between their team color and white color = [0.3+c*0.7 for c in bs.getNormalizedColor(player.getTeam().color)] l = player.gameData['FrozenLight'] = bs.NodeActor(bs.newNode('light', attrs={"intensity":0.6, "heightAttenuated":False, "volumeIntensityScale":0.1, "radius":0.13, "color": color})) bs.animate(l.node, 'intensity', {0:1.0, 200:0.4, 400:1.0}, loop=True) player.actor.node.connectAttr('position',l.node,'position') except Exception, e: import traceback print 'EXC in _setChosenOnePlayer' traceback.print_exc(e) traceback.print_stack()
def endGame(self): # stop our on-screen timer so players can see what they got self._timer.stop() results = bs.TeamGameResults() # if we won, set our score to the elapsed time # (there should just be 1 team here since this is co-op) # ..if we didn't win, leave scores as default (None) which means we lost if self._won: elapsedTime = bs.getGameTime()-self._timer.getStartTime() self.cameraFlash() bs.playSound(self._winSound) for team in self.teams: team.celebrate() # woooo! par-tay! results.setTeamScore(team,elapsedTime) # ends this activity.. self.end(results)
def _updateBoxState(self): for team in self.teams: team.gameData['holdingBox'] = False self._holdingPlayers = [] for player in self.players: try: if player.actor.isAlive() and player.actor.node.holdNode.exists(): holdingBox = (player.actor.node.holdNode == self._box.node) else: holdingBox = False except Exception: bs.printException("exception checking hold flag") if holdingBox: self._holdingPlayers.append(player) player.getTeam().gameData['holdingBox'] = True if self._box is not None and self._box.exists(): self._box.heldBy = len(self._holdingPlayers) self._box.updateFloatyness() holdingTeams = set(t for t in self.teams if t.gameData['holdingBox']) #bs.screenMessage("holding: "+str(len(holdingTeams))) prevState = self._boxState if len(holdingTeams) > 1: self._boxState = self.BOX_CONTESTED self._scoringTeam = None #self._box.light.color = (0.6,0.6,0.1) #self._box.node.color = (1.0,1.0,0.4) elif len(holdingTeams) == 1: holdingTeam = list(holdingTeams)[0] self._boxState = self.BOX_HELD self._scoringTeam = holdingTeam #self._box.light.color = bs.getNormalizedColor(holdingTeam.color) #self._box.node.color = holdingTeam.color else: self._boxState = self.BOX_UNCONTESTED self._scoringTeam = None #self._box.light.color = (0.2,0.2,0.2) #self._box.node.color = (1,1,1) if self._boxState != prevState: bs.playSound(self._swipSound)
def handleMessage(self,m): if isinstance(m,bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self,m) # augment standard behavior player = m.spaz.getPlayer() self.respawnPlayer(player) killer = m.killerPlayer if killer is None: return # handle team-kills if killer.getTeam() is player.getTeam(): # in free-for-all, killing yourself loses you a point if isinstance(self.getSession(),bs.FreeForAllSession): player.getTeam().gameData['score'] = max(0,player.getTeam().gameData['score']-1) # in teams-mode it gives a point to the other team else: bs.playSound(self._dingSound) for team in self.teams: if team is not killer.getTeam(): team.gameData['score'] += 1 # killing someone on another team nets a kill else: killer.getTeam().gameData['score'] += 1 bs.playSound(self._dingSound) # in FFA show our score since its hard to find on the scoreboard try: killer.actor.setScoreText(str(killer.getTeam().gameData['score'])+'/'+str(self._scoreToWin),color=killer.getTeam().color,flash=True) except Exception: pass self._updateScoreBoard() # if someone has won, set a timer to end shortly # (allows the dust to clear and draws to occur if deaths are close enough) if any(team.gameData['score'] >= self._scoreToWin for team in self.teams): bs.gameTimer(500,self.endGame) else: bs.TeamGameActivity.handleMessage(self,m)
def handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior player = m.spaz.getPlayer() player.gameData['lives'] -= 1 # if we have any icons, update their state for icon in player.gameData['icons']: icon.handlePlayerDied() # play big death sound on our last death or for every one in solo mode if player.gameData['lives'] == 0: bs.playSound(bs.Spaz.getFactory().singlePlayerDeathSound) # if we hit zero lives we're dead and the game might be over if player.gameData['lives'] == 0 and not self.timeLimitOnly: # if the whole team is dead, make note of how long they lasted if all(teammate.gameData['lives'] == 0 for teammate in player.getTeam().players): # log the team survival if we're the last player on the team player.getTeam().gameData['survivalSeconds'] = (bs.getGameTime()-self._startGameTime)/1000 # if someone has won, set a timer to end shortly # (allows the dust to settle and draws to occur if deaths are close enough) if len(self._getLivingTeams()) < 2: self._roundEndTimer = bs.Timer(1000, self.endGame) # we still have lives; yay! else: self.respawnPlayer(player) else: # default handler: super(self.__class__, self).handleMessage(m)#bs.TeamGameActivity.handleMessage(self,m)
def handleMessage(self, m): if isinstance(m, bs.HitMessage): if not self.node.exists(): return if self.node.invincible == True: bs.playSound(self.getFactory().blockSound, 1.0, position=self.node.position) return True # if we were recently hit, don't count this as another # (so punch flurries and bomb pileups essentially count as 1 hit) gameTime = bs.getGameTime() if self._lastHitTime is None or gameTime - self._lastHitTime > 1000: self._numTimesHit += 1 self._lastHitTime = gameTime mag = m.magnitude * self._impactScale velocityMag = m.velocityMagnitude * self._impactScale damageScale = 0.22 # if they've got a shield, deliver it to that instead.. if self.shield is not None: if m.flatDamage: damage = m.flatDamage * self._impactScale else: # hit our spaz with an impulse but tell it to only return theoretical damage; not apply the impulse.. self.node.handleMessage("impulse", m.pos[0], m.pos[1], m.pos[2], m.velocity[0], m.velocity[1], m.velocity[2], mag, velocityMag, m.radius, 1, m.forceDirection[0], m.forceDirection[1], m.forceDirection[2]) damage = damageScale * self.node.damage self.shieldHitPoints -= damage self.shield.hurt = 1.0 - self.shieldHitPoints / self.shieldHitPointsMax # its a cleaner event if a hit just kills the shield without damaging the player.. # however, massive damage events should still be able to damage the player.. # this hopefully gives us a happy medium. maxSpillover = 500 if self.shieldHitPoints <= 0: # fixme - transition out perhaps?.. self.shield.delete() self.shield = None bs.playSound(self.getFactory().shieldDownSound, 1.0, position=self.node.position) # emit some cool lookin sparks when the shield dies t = self.node.position bs.emitBGDynamics(position=(t[0], t[1]+0.9, t[2]), velocity=self.node.velocity, count=random.randrange(20, 30), scale=1.0, spread=0.6, chunkType='spark') else: bs.playSound(self.getFactory().shieldHitSound, 0.5, position=self.node.position) # emit some cool lookin sparks on shield hit bs.emitBGDynamics(position=m.pos, velocity=(m.forceDirection[0]*1.0, m.forceDirection[1]*1.0, m.forceDirection[2]*1.0), count=min(30, 5+int(damage*0.005)), scale=0.5, spread=0.3, chunkType='spark') # if they passed our spillover threshold, pass damage along to spaz if self.shieldHitPoints <= -maxSpillover: leftoverDamage = -maxSpillover - self.shieldHitPoints shieldLeftoverRatio = leftoverDamage / damage # scale down the magnitudes applied to spaz accordingly.. mag *= shieldLeftoverRatio velocityMag *= shieldLeftoverRatio else: return True # good job shield! else: shieldLeftoverRatio = 1.0 if m.flatDamage: damage = m.flatDamage * self._impactScale * shieldLeftoverRatio else: # hit it with an impulse and get the resulting damage #bs.screenMessage(str(velocityMag)) if self.multiplyer > 3.0: # at about 8.0 the physics glitch out velocityMag *= min((3.0 + (self.multiplyer-3.0)/4), 7.5) ** 1.9 else: velocityMag *= self.multiplyer ** 1.9 self.node.handleMessage("impulse", m.pos[0], m.pos[1], m.pos[2], m.velocity[0], m.velocity[1], m.velocity[2], mag, velocityMag, m.radius, 0, m.forceDirection[0], m.forceDirection[1], m.forceDirection[2]) damage = damageScale * self.node.damage self.node.handleMessage("hurtSound") # play punch impact sound based on damage if it was a punch if m.hitType == 'punch': self.onPunched(damage) # if damage was significant, lets show it #if damage > 350: bsUtils.showDamageCount('-'+str(int(damage/10))+"%",m.pos,m.forceDirection) # lets always add in a super-punch sound with boxing gloves just to differentiate them if m.hitSubType == 'superPunch': bs.playSound(self.getFactory().punchSoundStronger, 1.0, position=self.node.position) if damage > 500: sounds = self.getFactory().punchSoundsStrong sound = sounds[random.randrange(len(sounds))] else: sound = self.getFactory().punchSound bs.playSound(sound, 1.0, position=self.node.position) # throw up some chunks bs.emitBGDynamics(position=m.pos, velocity=(m.forceDirection[0]*0.5, m.forceDirection[1]*0.5, m.forceDirection[2]*0.5), count=min(10, 1+int(damage*0.0025)), scale=0.3, spread=0.03) bs.emitBGDynamics(position=m.pos, chunkType='sweat', velocity=(m.forceDirection[0]*1.3, m.forceDirection[1]*1.3+5.0, m.forceDirection[2]*1.3), count=min(30, 1 + int(damage * 0.04)), scale=0.9, spread=0.28) # momentary flash hurtiness = damage*0.003 hurtiness = min(hurtiness, 750 * 0.003) punchPos = (m.pos[0]+m.forceDirection[0]*0.02, m.pos[1]+m.forceDirection[1]*0.02, m.pos[2]+m.forceDirection[2]*0.02) flashColor = (1.0, 0.8, 0.4) light = bs.newNode("light", attrs={'position':punchPos, 'radius':0.12+hurtiness*0.12, 'intensity':0.3*(1.0+1.0*hurtiness), 'heightAttenuated':False, 'color':flashColor}) bs.gameTimer(60, light.delete) flash = bs.newNode("flash", attrs={'position':punchPos, 'size':0.17+0.17*hurtiness, 'color':flashColor}) bs.gameTimer(60, flash.delete) if m.hitType == 'impact': bs.emitBGDynamics(position=m.pos, velocity=(m.forceDirection[0]*2.0, m.forceDirection[1]*2.0, m.forceDirection[2]*2.0), count=min(10, 1 + int(damage * 0.01)), scale=0.4, spread=0.1) if self.hitPoints > 0: # its kinda crappy to die from impacts, so lets reduce impact damage # by a reasonable amount if it'll keep us alive if m.hitType == 'impact' and damage > self.hitPoints: # drop damage to whatever puts us at 10 hit points, or 200 less than it used to be # whichever is greater (so it *can* still kill us if its high enough) newDamage = max(damage-200, self.hitPoints-10) damage = newDamage self.node.handleMessage("flash") # if we're holding something, drop it if damage > 0.0 and self.node.holdNode.exists(): self.node.holdNode = bs.Node(None) #self.hitPoints -= damage self.multiplyer += min(damage / 2000, 0.15) if damage/2000 > 0.05: self.setScoreText(str(int((self.multiplyer-1)*100))+"%") #self.node.hurt = 1.0 - self.hitPoints/self.hitPointsMax self.node.hurt = 0.0 # if we're cursed, *any* damage blows us up if self._cursed and damage > 0: bs.gameTimer(50, bs.WeakCall(self.curseExplode, m.sourcePlayer)) # if we're frozen, shatter.. otherwise die if we hit zero #if self.frozen and (damage > 200 or self.hitPoints <= 0): # self.shatter() #elif self.hitPoints <= 0: # self.node.handleMessage(bs.DieMessage(how='impact')) # if we're dead, take a look at the smoothed damage val # (which gives us a smoothed average of recent damage) and shatter # us if its grown high enough #if self.hitPoints <= 0: # damageAvg = self.node.damageSmoothed * damageScale # if damageAvg > 1000: # self.shatter() elif isinstance(m, bs.DieMessage): self.oob_effect() super(self.__class__, self).handleMessage(m) elif isinstance(m, bs.PowerupMessage): if m.powerupType == 'health': if self.multiplyer > 2: self.multiplyer *= 0.5 else: self.multiplyer *= 0.75 self.multiplyer = max(1, self.multiplyer) self.setScoreText(str(int((self.multiplyer-1)*100))+"%") super(self.__class__, self).handleMessage(m) else: super(self.__class__, self).handleMessage(m)
def _cb_info(self, withSound=False): if withSound: bs.playSound(bs.getSound('swish')) ModInfoWindow(self._selectedMod, self, originWidget=self.modInfoButton)
def _doLight2(self): self.lights[1].color = (1.0, 0, 0) bs.playSound(self._beep1Sound)
def _extraDebrisSound(): bs.playSound(factory.debrisFallSound, position=p) bs.playSound(factory.woodDebrisFallSound, position=p)
def __init__( self, position=(0, 1, 0), velocity=(0, 0, 0), blastRadius=2.0, blastType="normal", sourcePlayer=None, hitType="explosion", hitSubType="normal", ): """ Instantiate with given values. """ bs.Actor.__init__(self) factory = Bomb.getFactory() self.blastType = blastType self.sourcePlayer = sourcePlayer self.hitType = hitType self.hitSubType = hitSubType # blast radius self.radius = blastRadius self.node = bs.newNode( "region", attrs={ "position": ( position[0], position[1] - 0.1, position[2], ), # move down a bit so we throw more stuff upward "scale": (self.radius, self.radius, self.radius), "type": "sphere", "materials": (factory.blastMaterial, bs.getSharedObject("attackMaterial")), }, delegate=self, ) 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 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, "color": (0.6, 0.6, 1.0) if self.blastType == "ice" else (1, 0.3, 0.1), "volumeIntensityScale": 10.0, }, ) 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")} ) 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 0.05) ######## # 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 _extraBoom(): bs.playSound(factory.getRandomExplodeSound(), position=p)
def _doLight3(self): self.lights[2].color = (1.0, 0.3, 0) bs.playSound(self._beep1Sound)