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 playerLostSpaz(self, player, killed=False, killer=None): name = player.getName() p = self._players[name] p._spaz = None p.streak = 0 if killed: p.accumKilledCount += 1 p.killedCount += 1 if killer is not None: k = self._players[killer.getName()] if killer.getTeam() == player.getTeam() and killer != player and bs.getGameTime() - k.lastBetrayTime > 1000: k.accumBetrayCount += 1 k.betrayCount += 1 if k.betrayCount > betrayLimit-3: bs.screenMessage('You have been betraying too much. Warns: {}/3'.format(k.betrayCount-(betrayLimit-3)),color=(1,0,0),clients=[killer.getInputDevice().getClientID()],transient=True) if k.betrayCount >= betrayLimit: bs.screenMessage(u'You\'re not supposed to betray da homies! Get Rekt {}!'.format(killer.getName(True)),color=(1,0,0)) bsInternal._disconnectClient(killer.getInputDevice().getClientID()) k.score -= 20 k.accumScore -= 20 k.lastBetrayTime = bs.getGameTime() try: if killed and bs.getActivity().announcePlayerDeaths: k = self._players[killer.getName()] if killer == player: bs.screenMessage( bs.Lstr(resource='nameSuicideKidFriendlyText' if bsInternal._getSetting('Kid Friendly Mode') else 'nameSuicideText', subs=[('${NAME}', name)]), top=True, color=player.color, image=player.getIcon()) elif killer is not None: if killer.getTeam() == player.getTeam(): bs.screenMessage(bs.Lstr(resource='nameBetrayedText', subs=[('${NAME}', killer.getName()), ('${VICTIM}', name)]), top=True, color=killer.color, image=killer.getIcon()) else: bs.screenMessage(bs.Lstr(resource='nameKilledText', subs=[('${NAME}', killer.getName()), ('${VICTIM}', name)]), top=True, color=killer.color, image=killer.getIcon()) else: bs.screenMessage(bs.Lstr(resource='nameDiedText', subs=[('${NAME}', name)]), top=True, color=player.color, image=player.getIcon()) except Exception, e: bs.printException('Error announcing kill')
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 #only drop a life if dummy was kilt if player.gameData['lives'] < 0: bs.printError( 'Got lives < 0 in Elim; this shouldnt happen. solo:' + str(self._soloMode)) player.gameData['lives'] = 0 # 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) else: # otherwise, in regular mode, respawn.. if not self._soloMode: self.spawnPlayerByDummy(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) if isinstance(m, bs.SpazBotDeathMessage): if isinstance(m.badGuy, SpazClone): player = m.badGuy.sourcePlayer if player in self.players: t = bs.getGameTime() #only take away a life if clone lifed longer than minimum length if t - player.gameData['cloneSpawnTime'] > self.minLife: player.gameData['lives'] -= 1 # if we hit zero lives, we're dead (and our team might be too) if player.gameData['lives'] < 1: # if the whole team is now dead, mark their survival time.. #if all(teammate.gameData['lives'] == 0 for teammate in player.getTeam().players): if self._getTotalTeamLives(player.getTeam()) == 0: player.getTeam().gameData['survivalSeconds'] = ( bs.getGameTime() - self._startGameTime) / 1000 playerNode = bs.getActivity()._getPlayerNode( player) spz = self.scoreSet._players[ player.getName()].getSpaz() if not spz is None: spz.handleMessage(bs.DieMessage()) for icon in player.gameData['icons']: icon.handlePlayerDied() else: self.spawnDummy(player, SpazClone) # if we have any icons, update their state for icon in player.gameData['icons']: icon.updateForLives() bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior
def _handleBaseCollide(self,team): cval = bs.getCollisionInfo('opposingNode') try: player = cval.getDelegate().getPlayer() except Exception: return if player is None or not player.exists(): return # if its another team's player, they scored playerTeam = player.getTeam() if playerTeam is not team: # (prevent multiple simultaneous scores) if bs.getGameTime() != self._lastScoreTime: self._lastScoreTime = bs.getGameTime() self.scoreSet.playerScored(player,50,bigMessage=True) bs.playSound(self._scoreSound) self._flashBase(team) # move all players on the scoring team back to their start # and add flashes of light so its noticable for p in playerTeam.players: if p.isAlive(): pos = p.actor.node.position light = bs.newNode('light', attrs={'position':pos, 'color':playerTeam.color, 'heightAttenuated':False, 'radius':0.4}) bs.gameTimer(500,light.delete) bs.animate(light,'intensity',{0:0,100:1.0,500:0}) newPos = self.getMap().getStartPosition(playerTeam.getID()) light = bs.newNode('light', attrs={'position':newPos, 'color':playerTeam.color, 'radius':0.4, 'heightAttenuated':False}) bs.gameTimer(500,light.delete) bs.animate(light,'intensity',{0:0,100:1.0,500:0}) p.actor.handleMessage(bs.StandMessage(newPos,random.uniform(0,360))) # have teammates celebrate for player in playerTeam.players: try: player.actor.node.handleMessage('celebrate',2000) except Exception: pass playerTeam.gameData['score'] += 1 self._updateScoreBoard() if playerTeam.gameData['score'] >= self.settings['Score to Win']: self.endGame()
def throwBall(self, spaz): t = bs.getGameTime() #Figure bomb timeout based on other owned powerups: bTime = self.defaultBallTimeout if spaz.bombType == 'impact': bTime *= 2 if spaz.bombCount > 1: bTime /= 2 if t - spaz.lastBallTime > bTime: spaz.lastBallTime = t #Figure out which way spaz is facing p1 = spaz.node.positionCenter p2 = spaz.node.positionForward direction = [p1[0] - p2[0], p2[1] - p1[1], p1[2] - p2[2]] direction[1] = 0.03 #This is the upward throw angle #Make a velocity vector for the snowball mag = 20.0 / bsVector.Vector(*direction).length() vel = [v * mag for v in direction] #print vel if spaz.bombType == 'impact': explodeIt = True else: explodeIt = False snoBall(spaz.node.position, vel, spaz.getPlayer(), spaz.getPlayer(), explodeIt).autoRetain()
def giveBallz(self, spaz): spaz.punchCallback = self.throwBall spaz.lastBallTime = bs.getGameTime() if self._powerExpire: weakSpaz = weakref.ref(spaz) spaz.snoExpireTimer = bs.Timer( self._powerLife, bs.WeakCall(self.takeBallz, weakSpaz))
def endGame(self): current_time = bs.getGameTime() for team in self.teams: for player in team.players: if 'deathTime' not in player.gameData: player.gameData['deathTime'] = current_time + 1 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) results = bs.TeamGameResults() 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)
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 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 endGame(self): curTime = bs.getGameTime() for team in self.teams: for player in team.players: if 'notIn' in player.gameData: player.gameData['deathTime'] = 0 elif 'deathTime' not in player.gameData: player.gameData['deathTime'] = curTime + 1 score = (player.gameData['deathTime'] - self._timer.getStartTime()) / 1000 if 'deathTime' not in player.gameData: score += 50 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)
def checkEnd(self): for player in self.players: if player.gameData['distance'] >= self.settings['Laps']: player.getTeam().gameData['time'] = ( bs.getGameTime() - self._timer.getStartTime()) player.actor.node.delete() self.endGame()
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 endGame(self): curTime = bs.getGameTime() for team in self.teams: for player in team.players: if 'deathTime' not in player.gameData: player.gameData['deathTime'] = curTime + 1 score = (player.gameData['deathTime'] - self._timer.getStartTime()) / 1000 if 'deathTime' not in player.gameData: score += 50 self.scoreSet.playerScored(player, score, screenMessage=False) self._timer.stop(endTime=self._lastPlayerDeathTime) results = bs.TeamGameResults() for team in self.teams: longestLife = 0 for player in team.players: longestLife = max(longestLife, (player.gameData['deathTime'] - self._timer.getStartTime())) results.setTeamScore(team, longestLife) self.end(results=results)
def _dropPowerups(self, standardPoints=False, forceFirst=None): """ Generic powerup drop """ # if its been a minute since our last wave finished emerging, stop # giving out land-mine powerups. (prevents players from waiting # around for them on purpose and filling the map up) if bs.getGameTime() - self._lastWaveEndTime > 60000: extraExcludes = ['landMines'] else: extraExcludes = [] if standardPoints: pts = self.getMap().powerupSpawnPoints for i, pt in enumerate(pts): bs.gameTimer( 1000 + i * 500, bs.Call(self._dropPowerup, i, forceFirst if i == 0 else None)) else: pt = (self._powerupCenter[0] + random.uniform( -1.0 * self._powerupSpread[0], 1.0 * self._powerupSpread[0]), self._powerupCenter[1], self._powerupCenter[2] + random.uniform( -self._powerupSpread[1], self._powerupSpread[1])) # drop one random one somewhere.. bs.Powerup( position=pt, powerupType=bs.Powerup.getFactory().getRandomPowerupType( excludeTypes=self._excludePowerups + extraExcludes)).autoRetain()
def onPunchPress(self): """ Called to 'press punch' on this spaz; used for player or AI connections. Override for land grab: catch double-punch to switch bombs! """ if not self.node.exists() or self.frozen or self.node.knockout > 0.0: return if self.punchCallback is not None: self.punchCallback(self) t = bs.getGameTime() self._punchedNodes = set() # reset this.. ########This catches punches and switches between bombs and mines #if t - self.lastPunchTime < 500: if self.landMineCount < 1: self.landMineCount = 1 bs.animate(self.node,"billboardOpacity",{0:0.0,100:1.0,400:1.0}) else: self.landMineCount = 0 bs.animate(self.node,"billboardOpacity",{0:1.0,400:0.0}) if t - self.lastPunchTime > self._punchCooldown: self.lastPunchTime = t self.node.punchPressed = True if not self.node.holdNode.exists(): bs.gameTimer(100,bs.WeakCall(self._safePlaySound,self.getFactory().swishSound,0.8))
def check(): if int((bs.getGameTime() - start_time) * 1000) >= 141000: self._fireworks = None self._fireworks = bs.Timer(200000, bs.Call(self.fireworks)) else: run() self._fireworks = bs.Timer(500, bs.Call(check), True)
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 fireworks(self): def run(): pos = (random.randint(-10, 10), random.randrange(14, 15), random.randint(-10, 10)) bs.emitBGDynamics(position=pos, velocity=tuple([ 1.0 * random.randrange(1, 2) for i in range(3) ]), count=random.randint(1000, 1200), scale=1, spread=0.8, chunkType='spark') start_time = bs.getGameTime() def start(): def check(): if int((bs.getGameTime() - start_time) * 1000) >= 141000: self._fireworks = None self._fireworks = bs.Timer(200000, bs.Call(self.fireworks)) else: run() self._fireworks = bs.Timer(500, bs.Call(check), True) check() start()
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 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 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 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, KillerGetScoreMessage): bs.screenMessage(m.text, top=True, color=m.killer.color, image=m.killer.getIcon()) m.killer.getTeam().gameData['arrows'] = min( m.killer.getTeam().gameData['arrows'] + m.score, self._maxArrows) self._updateScoreBoard() else: # default handler: bs.TeamGameActivity.handleMessage(self, m)
def checkEnd(self): for team in self.teams: c = 0 for player in team.players: if player.gameData['piece'] == 'king' and player.isAlive(): c += 1 if c == 0: self.endGame() if bs.getGameTime() > 60000: self.endGame()
def endGame(self): curTime = bs.getGameTime() if not self.timeLimitOnly: # 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 'survivalSeconds' in player.gameData: score = player.gameData['survivalSeconds'] elif 'survivalSeconds' in team.gameData: score = team.gameData['survivalSeconds'] else: score = (curTime - self._startGameTime) / 1000 + 1 #if 'survivalSeconds' not in player.gameData: # player.gameData['survivalSeconds'] = (curTime - self._startGameTime)/1000 + 1 # print('extraBonusSwag for player') # 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['survivalSeconds']) self.scoreSet.playerScored(player, score, screenMessage=False) # 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: if 'survivalSeconds' in player.gameData: time = player.gameData['survivalSeconds'] elif 'survivalSeconds' in team.gameData: time = team.gameData['survivalSeconds'] else: time = (curTime - self._startGameTime) / 1000 + 1 longestLife = max(longestLife, time) results.setTeamScore(team, longestLife) self.end(results=results) else: results = bs.TeamGameResults() for team in self.teams: deaths = sum( [0 - player.gameData['lives'] for player in team.players]) results.setTeamScore(team, deaths) self.end(results=results)
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 endGame(self): curTime = bs.getGameTime() if not self.timeLimitOnly: # 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 'survivalSeconds' in player.gameData: score = player.gameData['survivalSeconds'] elif 'survivalSeconds' in team.gameData: score = team.gameData['survivalSeconds'] else: score = (curTime - self._startGameTime)/1000 + 1 #if 'survivalSeconds' not in player.gameData: # player.gameData['survivalSeconds'] = (curTime - self._startGameTime)/1000 + 1 # print('extraBonusSwag for player') # 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['survivalSeconds']) self.scoreSet.playerScored(player, score, screenMessage=False) # 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: if 'survivalSeconds' in player.gameData: time = player.gameData['survivalSeconds'] elif 'survivalSeconds' in team.gameData: time = team.gameData['survivalSeconds'] else: time = (curTime - self._startGameTime)/1000 + 1 longestLife = max(longestLife, time) results.setTeamScore(team, longestLife) self.end(results=results) else: results = bs.TeamGameResults() for team in self.teams: deaths = sum([0 - player.gameData['lives'] for player in team.players]) results.setTeamScore(team, deaths) self.end(results=results)
def onPlayerLeave(self, player): # augment default behavior... bs.TeamGameActivity.onPlayerLeave(self, player) #end the game if everyone left the party. deathTime = bs.getGameTime() if isinstance(self.getSession(), bs.FreeForAllSession): bs.pushCall(self._checkEndGame) self._lastPlayerDeathTime = deathTime # also record this for a final setting of the clock.. else: bs.gameTimer(1000, self._checkEndGame)
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 handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior player = m.spaz.getPlayer() respawnPoints = None print([player, m.spaz.hitPoints, "killed by", m.killerPlayer]) if m.killerPlayer is None: pass #Don't take away a life for non-violent death elif m.killerPlayer == m.spaz.getPlayer(): pass #No credit for suicide! elif m.spaz.hitPoints > 0: #Spaz died, but had positive hit points. Probably fell. Take points from player. #tossing or knocking off a player respawns them w/o taking life. print([player, "died from fall.", m.spaz.hitPoints]) pass else: player.gameData['lives'] -= 1 #Remove this spaz from the list of active spazzes if m.spaz in self.spazList: self.spazList.remove(m.spaz) if player.gameData['lives'] < 0: bs.printError( 'Got lives < 0 in Elim; this shouldnt happen. solo:' + str(self._soloMode)) 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 all(teammate.gameData['lives'] == 0 for teammate in player.getTeam().players): if self._getTotalTeamLives(player.getTeam()) == 0: player.getTeam().gameData['survivalSeconds'] = ( bs.getGameTime() - self._startGameTime) / 1000 self.winners.append(player) 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) else: bs.TeamGameActivity.handleMessage(self, m)
def architectSetStop(self): if 'architectProgress' not in self.extras: # 不存在计时器正在运行 return nowTime = bs.getGameTime() if nowTime - self.lastDropTime < self.architectCoolDown: return self.lastDropTime = nowTime progress = self.extras['architectProgress'].finishAndGetProgress() del self.extras['architectProgress'] size = ((progress - 0.2) / 0.8) * 3.5 + 0.7 self.architectDropBrick(size)
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 archerShotArrowStop(self): if self.noMoreArrows(): return if 'archerProgress' not in self.extras: # 不存在计时器正在运行 return nowTime = bs.getGameTime() if nowTime - self.lastDropTime < self.archerCoolDown: return self.lastDropTime = nowTime progress = self.extras['archerProgress'].finishAndGetProgress() del self.extras['archerProgress'] v1 = (progress - 0.2) / 0.8 self.archerRealShot(v1)
def handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior player = m.spaz.getPlayer() player.gameData["survivalSeconds"] = bs.getGameTime() if len(self._getLivingTeams()) < 2: self._roundEndTimer = bs.Timer(1000, self.endGame) else: # default handler: super(self.__class__, self).handleMessage(m) # bs.TeamGameActivity.handleMessage(self,m)
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 handleMessage(self,m): if isinstance(m, bs.PlayerSpazDeathMessage): super(self.__class__, self).handleMessage(m)#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) else: # default handler: super(self.__class__, self).handleMessage(m)#bs.TeamGameActivity.handleMessage(self,m)
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 # 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)
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 onTransitionIn(self): bs.TeamGameActivity.onTransitionIn(self, music='Epic' if self.settings['Epic Mode'] else 'Survival') self._startGameTime = bs.getGameTime()
def onTransitionIn(self): bs.TeamGameActivity.onTransitionIn(self, music="Epic" if self.settings["Epic Mode"] else "Survival") self._startGameTime = bs.getGameTime()