def _saveState(self): w = self._rootWidget.getSelectedChild() for k, v in statedict(self).items(): if w == k: gWindowStates[self.__class__.__name__] = {'selName': v} return bs.printError('error saving state for ' + str(self.__class__))
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: 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 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 _handleHitOwnFlag(self,team,val): # keep track of when each player is touching their own flag so we can award points when returned srcNode = bs.getCollisionInfo('sourceNode') try: player = srcNode.getDelegate().getPlayer() except Exception: player = None if player is not None and player.exists(): if val: player.gameData['touchingOwnFlag'] += 1 else: player.gameData['touchingOwnFlag'] -= 1 # if return-time is zero, just kill it immediately.. otherwise keep track of touches and count down if float(self.settings['Flag Touch Return Time']) <= 0.0: if not team.gameData['homeFlagAtBase'] and team.gameData['flag']._heldCount == 0: # use a node message to kill the flag instead of just killing our team's. # (avoids redundantly killing new flags if multiple body parts generate callbacks in one step) node = bs.getCollisionInfo("opposingNode") if node is not None and node.exists(): self._awardPlayersTouchingOwnFlag(team) node.handleMessage(bs.DieMessage()) # takes a non-zero amount of time to return else: if val: team.gameData['flagReturnTouches'] += 1 if team.gameData['flagReturnTouches'] == 1: team.gameData['touchReturnTimer'] = bs.Timer(100,call=bs.Call(self._touchReturnUpdate,team),repeat=True) team.gameData['touchReturnTimerTicking'] = None else: team.gameData['flagReturnTouches'] -= 1 if team.gameData['flagReturnTouches'] == 0: team.gameData['touchReturnTimer'] = None team.gameData['touchReturnTimerTicking'] = None if team.gameData['flagReturnTouches'] < 0: bs.printError('CTF: flagReturnTouches < 0; this shouldn\'t happen.')
def handleMessage(self,m): if isinstance(m,bs.PlayerSpazDeathMessage): player = m.spaz.getPlayer() if player is None: bs.printError('FIXME: getPlayer() should no longer ever be returning None') return if not player.exists(): return self.scoreSet.playerLostSpaz(player) bs.gameTimer(100,self._checkRoundOver) elif isinstance(m,bs.PlayerScoredMessage): self._score.add(m.score) self._updateScores() elif isinstance(m,bs.SpazBotDeathMessage): pts,importance = m.badGuy.getDeathPoints(m.how) if m.killerPlayer is not None and m.killerPlayer.exists(): try: target = m.badGuy.node.position except Exception: target = None try: self.scoreSet.playerScored(m.killerPlayer,pts,target=target,kill=True,screenMessage=False,importance=importance) bs.playSound(self._dingSound if importance == 1 else self._dingSoundHigh,volume=0.6) except Exception,e: print 'EXC on last-stand SpazBotDeathMessage',e # normally we pull scores from the score-set, but if there's no player lets be explicit.. else: self._score.add(pts) self._updateScores()
def onBegin(self): # test... if not all(player.exists() for player in self.players): bs.printError("Nonexistant player in onBegin: "+str([str(p) for p in self.players])+': we are '+str(player)) bs.TeamGameActivity.onBegin(self) self.setupStandardTimeLimit(self.settings['Time Limit']) self.setupStandardPowerupDrops() self._flagSpawnPos = self.getMap().getFlagPosition(None) self.projectFlagStand(self._flagSpawnPos) self._setChosenOnePlayer(None) p = self._flagSpawnPos bs.gameTimer(1000,call=self._tick,repeat=True) m = self._resetRegionMaterial = bs.Material() m.addActions(conditions=('theyHaveMaterial',bs.getSharedObject('playerMaterial')), actions=(('modifyPartCollision','collide',True), ('modifyPartCollision','physical',False), ('call','atConnect',bs.WeakCall(self._handleResetCollide)))) self._resetRegion = bs.newNode('region', attrs={'position':(p[0],p[1]+0.75,p[2]), 'scale': (0.5,0.5,0.5), 'type': 'sphere', 'materials':[m] })
def spawnPlayer(self, player): """ Spawn *something* for the provided bs.Player. The default implementation simply calls spawnPlayerSpaz(). """ #Overloaded for this game to respawn at home instead of random FFA spots if not player.exists(): bs.printError('spawnPlayer() called for nonexistant player') return if player.gameData['home'] is None: pos = self.getMap().getFFAStartPosition(self.players) if player.gameData['crate'] is None: box = cargoBox(pos) box.setMovingText(box, player.getName(), player.color) player.gameData['crate'] = box position = [pos[0], pos[1] + 1.0, pos[2]] player.gameData['home'] = position else: position = player.gameData['home'] spaz = self.spawnPlayerSpaz(player, position) #Need to prevent accepting powerups: pam = bs.Powerup.getFactory().powerupAcceptMaterial for attr in ['materials', 'rollerMaterials', 'extrasMaterials']: materials = getattr(spaz.node, attr) if pam in materials: setattr(spaz.node, attr, tuple(m for m in materials if m != pam)) return spaz
def setActivity(self,activity): self._activity = None if activity is None else weakref.ref(activity) # load our media into this activity's context if activity is not None: if activity.isFinalized(): bs.printError('unexpected finalized activity') with bs.Context(activity): self._loadMedia()
def handleMessage(self, m): if isinstance(m, bs.PlayerScoredMessage): self._score.add(m.score) self._updateScores() # respawn dead players elif isinstance(m, bs.PlayerSpazDeathMessage): self._aPlayerHasBeenKilled = True player = m.spaz.getPlayer() if player is None: bs.printError('FIXME: getPlayer() should no' ' longer ever be returning None') return if not player.exists(): return self.scoreSet.playerLostSpaz(player) # respawn them shortly respawnTime = 2000 + len(self.initialPlayerInfo) * 1000 player.gameData['respawnTimer'] = bs.Timer( respawnTime, bs.Call(self.spawnPlayerIfExists, player)) player.gameData['respawnIcon'] = bs.RespawnIcon( player, respawnTime) elif isinstance(m, bs.SpazBotDeathMessage): if m.how == 'goal': return pts, importance = m.badGuy.getDeathPoints(m.how) if m.killerPlayer is not None: try: target = m.badGuy.node.position except Exception: target = None try: if m.killerPlayer is not None and m.killerPlayer.exists(): self.scoreSet.playerScored(m.killerPlayer, pts, target=target, kill=True, screenMessage=False, importance=importance) bs.playSound(self._dingSound if importance == 1 else self._dingSoundHigh, volume=0.6) except Exception as e: print 'EXC in Runaround handling SpazBotDeathMessage:', e # normally we pull scores from the score-set, but if there's no # player lets be explicit.. else: self._score.add(pts) self._updateScores() else: self.__superHandleMessage(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 #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 onBegin(self): self.mineTimers = [] bs.gameTimer(3500, bs.Call(self.doRaceTimer)) # test... if not all(player.exists() for player in self.players): bs.printError("Nonexistant player in onBegin: "+str([str(p) for p in self.players])) bs.TeamGameActivity.onBegin(self)
def onBegin(self): self.mineTimers = [] bs.gameTimer(3500, bs.Call(self.doRaceTimer)) # test... if not all(player.exists() for player in self.players): bs.printError("Nonexistant player in onBegin: " + str([str(p) for p in self.players])) bs.TeamGameActivity.onBegin(self)
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 handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior player = m.spaz.getPlayer() #print([player, m.spaz.hitPoints, "killed by", m.killerPlayer]) if player.gameData[ 'lives'] > 0: #Dying player was not zombie. Remove a life player.gameData['lives'] -= 1 else: #Dying player was a zombie. Give points to killer if m.killerPlayer.exists(): if m.killerPlayer.gameData['lives'] > 0: m.killerPlayer.getTeam().gameData['score'] += 2 self._updateScoreBoard() #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. Become a zombie. if player.gameData['lives'] == 0: self.respawnPlayerZombie(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) elif isinstance(m, bs.SpazBotDeathMessage): self._onSpazBotDied(m) bs.TeamGameActivity.handleMessage(self, m) #bs.PopupText("died",position=self._position,color=popupColor,scale=popupScale).autoRetain() else: bs.TeamGameActivity.handleMessage(self, m)
def _tick(self): # give the chosen one points player = self._getChosenOnePlayer() if player is not None: # this shouldnt happen, but just in case.. if not player.isAlive(): bs.printError('got dead player as chosen one in _tick') self._setChosenOnePlayer(None) else: scoringTeam = player.getTeam() self.scoreSet.playerScored(player, 3, screenMessage=False, display=False) scoringTeam.gameData['timeRemaining'] = max( 0, scoringTeam.gameData['timeRemaining'] - 1) # show the count over their head try: if scoringTeam.gameData['timeRemaining'] > 0: player.actor.setScoreText( str(scoringTeam.gameData['timeRemaining'])) except Exception: pass self._updateScoreBoard() # 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() # player is None else: # this shouldnt happen, but just in case.. # (chosen-one player ceasing to exist should trigger onPlayerLeave # which resets chosen-one) if self._chosenOnePlayer is not None: bs.printError('got nonexistant player as chosen one in _tick') self._setChosenOnePlayer(None)
def handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior player = m.spaz.getPlayer() #print([player, m.spaz.hitPoints, "killed by", m.killerPlayer]) 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): #ZombieHorde: don't care survival time #if self._getTotalTeamLives(player.getTeam()) == 0: # player.getTeam().gameData['survivalSeconds'] = (bs.getGameTime()-self._startGameTime)/1000 pass 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) elif isinstance(m, bs.SpazBotDeathMessage): self._onSpazBotDied(m) bs.TeamGameActivity.handleMessage(self, m) #bs.PopupText("died",position=self._position,color=popupColor,scale=popupScale).autoRetain() 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() if m.killerPlayer == player: player.getTeam().gameData['score'] /= 2 self._updateScoreBoard() #print([player, m.spaz.hitPoints, "killed by", m.killerPlayer]) if player.getTeam().gameData[ 'score'] == 0: #Only permadeath if they lost all their boxes. player.gameData['lives'] -= 1 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 whole team is too, since 0 boxes left) if player.gameData['lives'] == 0: pass # 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 #for p2 in player.getTeam().players: # p2.gameData['lives'] = 0 # self.scoreSet._players[player.getName()].getSpaz().handleMessage(bs.DieMessage()) 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 handleMessage(self, m): if isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment default try: player = m.spaz.getPlayer() if player is None: bs.printError('FIXME: getPlayer() should no ' 'longer ever be returning None') else: if not player.exists(): raise Exception() team = player.getTeam() except Exception: return if not player.gameData['finished']: self.respawnPlayer(player, respawnTime=1000) else: bs.TeamGameActivity.handleMessage(self, m)
def spawnPlayer(self, player): """ Spawn *something* for the provided bs.Player. The default implementation simply calls spawnPlayerSpaz(). """ #Overloaded for this game to spawn players in the end zone instead of FFA spots if not player.exists(): bs.printError('spawnPlayer() called for nonexistant player') return y = random.uniform(-5, 5.5) if self.settings['One-Way Trip'] == True: x = -11.8 else: x = 12.0 spz = self.spawnPlayerSpaz(player, position=[x, 0.35, y]) spz.connectControlsToPlayer(enablePunch=True, enableBomb=self.settings['Enable Bombs'], enablePickUp=True) return spz
def equipShields(self, decay=False): """ Give this spaz a nice energy shield. """ if not self.node.exists(): bs.printError('Can\'t equip shields; no node.') return factory = self.getFactory() if self.shield is None: self.shield = bs.newNode('shield', owner=self.node, attrs={ 'color': (1.5, 0, 0), 'radius': 1.3 }) self.node.connectAttr('positionCenter', self.shield, 'position') self.shieldHitPoints = self.shieldHitPointsMax = 6000 #self.shieldDecayRate = factory.shieldDecayRate if decay else 0 self.shield.hurt = 0 bs.playSound(factory.shieldUpSound, 1.0, position=self.node.position)
def spawnPlayer(self, player): #Overloaded for this game to respawn at home instead of random FFA spots if not player.exists(): bs.printError('spawnPlayer() called for nonexistant player') return if player.gameData['home'] is None: pos = self.getMap().getFFAStartPosition(self.players) bomb = myMine(pos, (0.0,0.0,0.0), 0.0, player, None).autoRetain() bomb.isHome = True bomb.handleMessage(bsBomb.ArmMessage()) position = [pos[0],pos[1]+0.3,pos[2]] player.gameData['home'] = position player.gameData['mines'].append(bomb) else: position = player.gameData['home'] spaz = self.spawnPlayerSpaz(player, position) # lets reconnect this player's controls to this # spaz but *without* the ability to attack or pick stuff up spaz.connectControlsToPlayer(enablePunch=True, enableBomb=True, enablePickUp=True) #Wire up the spaz with mines spaz.landMineCount = 1 spaz.node.billboardTexture = self._mineIconTex bs.animate(spaz.node,"billboardOpacity",{0:0.0,100:1.0,400:1.0}) t = bs.getGameTime() if t - spaz.lastMine < spaz.mineTimeout: spaz.node.billboardCrossOut = True bs.gameTimer((spaz.mineTimeout-t+spaz.lastMine),bs.WeakCall(spaz.unCrossBillboard)) spaz.dropEggs = self.settings['Eggs Not Bombs'] spaz.eggsHatch = self.settings['Snowman Eggs'] # also lets have them make some noise when they die.. spaz.playBigDeathSound = True
def equipShields(self, decay=False): """ Give this spaz a nice energy shield. """ if not self.node.exists(): bs.printError('Can\'t equip shields; no node.') return factory = self.getFactory() if self.shield is None: self.shield = bs.newNode('shield', owner=self.node, attrs={'color':self.node.color, 'radius':1.3}) self.node.connectAttr('positionCenter', self.shield, 'position') self.shieldHitPoints = self.shieldHitPointsMax = 650 self.shieldDecayRate = factory.shieldDecayRate if decay else 0 self.shield.hurt = 0 bs.playSound(factory.shieldUpSound, 1.0, position=self.node.position) if self.shieldDecayRate > 0: self.shieldDecayTimer = bs.Timer(500, bs.WeakCall(self.shieldDecay), repeat=True) self.shield.alwaysShowHealthBar = True # so user can see the decay
def respawnPlayerZombie(self, player, respawnTime=None): """ Given a bs.Player, sets up a standard respawn timer, along with the standard counter display, etc. At the end of the respawn period spawnPlayer() will be called if the Player still exists. An explicit 'respawnTime' can optionally be provided (in milliseconds). """ if player is None or not player.exists(): if player is None: bs.printError('None passed as player to respawnPlayer()') else: bs.printError( 'Nonexistant bs.Player passed to respawnPlayer(); call player.exists() to make sure a player is still there.' ) return if player.getTeam() is None: bs.printError('player has no team in respawnPlayer()') return if respawnTime is None: if len(player.getTeam().players) == 1: respawnTime = 3000 elif len(player.getTeam().players) == 2: respawnTime = 5000 elif len(player.getTeam().players) == 3: respawnTime = 6000 else: respawnTime = 7000 # if this standard setting is present, factor it in if 'Respawn Times' in self.settings: respawnTime *= self.settings['Respawn Times'] respawnTime = int(max(1000, respawnTime)) if respawnTime % 1000 != 0: respawnTime -= respawnTime % 1000 # we want whole seconds if player.actor and not self.hasEnded(): import bsSpaz player.gameData['respawnTimer'] = bs.Timer( respawnTime, bs.WeakCall(self.spawnPlayerIfExistsAsZombie, player)) player.gameData['respawnIcon'] = bsSpaz.RespawnIcon( player, respawnTime)
def handleMessage(self, msg): if isinstance(msg, ChangeMessage): # if we've been removed from the lobby, ignore this stuff if self._dead: print "WARNING: chooser got ChangeMessage after dying" return if not self._textNode.exists(): bs.printError('got ChangeMessage after nodes died') return if msg.what == 'team': if len(self.getLobby()._teams) > 1: bs.playSound(self._swishSound) self._selectedTeamIndex = ( (self._selectedTeamIndex + msg.value) % len(self.getLobby()._teams)) self._updateText() self.updatePosition() self._updateIcon() elif msg.what == 'profileIndex': if len(self.profileNames) == 1: # this should be pretty hard to hit now with # automatic local accounts.. bs.playSound(bs.getSound('error')) else: # pick the next player profile and assign our name # and character based on that bs.playSound(self._deekSound) self.profileIndex = ((self.profileIndex + msg.value) % len(self.profileNames)) self.updateFromPlayerProfile() elif msg.what == 'character': bs.playSound(self._clickSound) # update our index in our local list of characters self.characterIndex = ((self.characterIndex + msg.value) % len(self.characterNames)) self._updateText() self._updateIcon() elif msg.what == 'ready': forceTeamSwitch = False # team auto-balance kicks us to another team if we try to # join the team with the most players if not self.ready: if bs.getConfig().get('Auto Balance Teams', False): lobby = self.getLobby() if len(lobby._teams) > 1: session = bs.getSession() # first, calc how many players are on each team # ..we need to count both active players and # choosers that have been marked as ready. teamPlayerCounts = {} for team in lobby._teams: teamPlayerCounts[team().getID()] = \ len(team().players) for chooser in lobby.choosers: if chooser.ready: teamPlayerCounts[ chooser.getTeam().getID()] += 1 largestTeamSize = max(teamPlayerCounts.values()) smallestTeamSize = \ min(teamPlayerCounts.values()) # force switch if we're on the biggest team # and there's a smaller one available if (largestTeamSize != smallestTeamSize and teamPlayerCounts[self.getTeam().getID()] \ >= largestTeamSize): forceTeamSwitch = True if forceTeamSwitch: bs.playSound(self._errorSound) self.handleMessage(ChangeMessage('team', 1)) else: bs.playSound(self._punchSound) self._setReady(msg.value)
def Modify_onPlayerLeave(self, player): """ Called when a previously-accepted bs.Player leaves the session. """ # remove them from the game rosters pid = player.get_account_id() if pid is None: idset = { p.get_account_id() for p in self.players if p.get_account_id() is not None } diff = list(set(db.cache.keys()) - idset) else: diff = [pid] if len(diff) > 1: print 'more than one diff:', diff for i in diff: db.playerLeave(i) if player in self.players: bs.playSound(bs.getSound('playerLeft')) # this will be None if the player is still in the chooser team = player.getTeam() activity = self._activityWeak() # if he had no team, he's in the lobby # if we have a current activity with a lobby, ask them to remove him if team is None: with bs.Context(self): try: self._lobby.removeChooser(player) except Exception: bs.printException( 'Error: exception in Lobby.removeChooser()') # *if* he was actually in the game, announce his departure if team is not None and len(activity.players) <= 3: bs.screenMessage( bs.Lstr(resource='playerLeftText', subs=[('${PLAYER}', player.getName(full=True))])) # remove him from his team and session lists # (he may not be on the team list since player are re-added to # team lists every activity) if team is not None and player in team.players: # testing.. can remove this eventually if isinstance(self, bs.FreeForAllSession): if len(team.players) != 1: bs.printError("expected 1 player in FFA team") team.players.remove(player) # remove player from any current activity if activity is not None and player in activity.players: activity.players.remove(player) # run the activity callback unless its been finalized if not activity.isFinalized(): try: with bs.Context(activity): activity.onPlayerLeave(player) except Exception: bs.printException( 'exception in onPlayerLeave for activity', activity) else: bs.printError( "finalized activity in onPlayerLeave; shouldn't happen") player._setActivity(None) # reset the player - this will remove its actor-ref and clear # its calls/etc try: with bs.Context(activity): player._reset() except Exception: bs.printException( 'exception in player._reset in' ' onPlayerLeave for player', player) # if we're a non-team session, remove the player's team completely if not self._useTeams and team is not None: # if the team's in an activity, call its onTeamLeave callback if activity is not None and team in activity.teams: activity.teams.remove(team) if not activity.isFinalized(): try: with bs.Context(activity): activity.onTeamLeave(team) except Exception: bs.printException( 'exception in onTeamLeave for activity', activity) else: bs.printError("finalized activity in onPlayerLeave p2" "; shouldn't happen") # clear the team's game-data (so dying stuff will # have proper context) try: with bs.Context(activity): team._resetGameData() except Exception: bs.printException('exception clearing gameData for team:', team, 'for player:', player, 'in activity:', activity) # remove the team from the session self.teams.remove(team) try: with bs.Context(self): self.onTeamLeave(team) except Exception: bs.printException('exception in onTeamLeave for session', self) # clear the team's session-data (so dying stuff will # have proper context) try: with bs.Context(self): team._resetSessionData() except Exception: bs.printException('exception clearing sessionData for team:', team, 'in session:', self) # now remove them from the session list self.players.remove(player) else: print( 'ERROR: Session.onPlayerLeave called' ' for player not in our list.')
def handleMessage(self, m): if isinstance(m, bs.PlayerSpazHurtMessage): player = m.spaz.getPlayer() if player is None: bs.printError('FIXME: getPlayer() should no' ' longer ever be returning None') return if not player.exists(): return player.gameData['hasBeenHurt'] = True self._aPlayerHasBeenHurt = True elif isinstance(m, bs.PlayerScoredMessage): self._score.add(m.score) self._updateScores() elif isinstance(m, bs.PlayerSpazDeathMessage): self.__superHandleMessage(m) # augment standard behavior player = m.spaz.getPlayer() self._aPlayerHasBeenHurt = True # make note with the player when they can respawn if self._wave < 10: player.gameData['respawnWave'] = max(2, self._wave+1) elif self._wave < 15: player.gameData['respawnWave'] = max(2, self._wave+2) else: player.gameData['respawnWave'] = max(2, self._wave+3) bs.gameTimer(100, self._updatePlayerSpawnInfo) bs.gameTimer(100, self._checkRoundOver) elif isinstance(m, bs.SpazBotDeathMessage): pts, importance = m.badGuy.getDeathPoints(m.how) if m.killerPlayer is not None: # toss-off-map achievement if self._preset in ['training', 'trainingEasy']: if m.badGuy.lastAttackedType == ('pickedUp', 'default'): if not hasattr(self, '_throwOffKills'): self._throwOffKills = 0 self._throwOffKills += 1 if self._throwOffKills >= 3: self._awardAchievement('Off You Go Then') # land-mine achievement elif self._preset in ['rookie', 'rookieEasy']: if m.badGuy.lastAttackedType == ('explosion', 'landMine'): if not hasattr(self, '_landMineKills'): self._landMineKills = 0 self._landMineKills += 1 if self._landMineKills >= 3: self._awardAchievement('Mine Games') # tnt achievement elif self._preset in ['pro', 'proEasy']: if m.badGuy.lastAttackedType == ('explosion', 'tnt'): if not hasattr(self, '_tntKills'): self._tntKills = 0 self._tntKills += 1 if self._tntKills >= 3: bs.gameTimer( 500, bs.WeakCall( self._awardAchievement, 'Boom Goes the Dynamite')) elif self._preset in ['uber', 'uberEasy']: # uber mine achievement if m.badGuy.lastAttackedType == ('explosion', 'landMine'): if not hasattr(self, '_landMineKills'): self._landMineKills = 0 self._landMineKills += 1 if self._landMineKills >= 6: self._awardAchievement('Gold Miner') # uber tnt achievement if m.badGuy.lastAttackedType == ('explosion', 'tnt'): if not hasattr(self, '_tntKills'): self._tntKills = 0 self._tntKills += 1 if self._tntKills >= 6: bs.gameTimer( 500, bs.WeakCall( self._awardAchievement, 'TNT Terror')) try: target = m.badGuy.node.position except Exception: target = None try: killerPlayer = m.killerPlayer self.scoreSet.playerScored( killerPlayer, pts, target=target, kill=True, screenMessage=False, importance=importance) bs.playSound(self._dingSound if importance == 1 else self._dingSoundHigh, volume=0.6) except Exception: pass # normally we pull scores from the score-set, but if there's # no player lets be explicit.. else: self._score.add(pts) self._updateScores() else: self.__superHandleMessage(m)
def handleMessage(self, msg): if isinstance(msg, ChangeMessage): # if we've been removed from the lobby, ignore this stuff if msg.what == 'team' and not self._admin: self.change_count += 1 if self.change_count > change_limit - 5: bs.screenMessage( 'Spam Detected! Warn Count: {}/5'.format( self.change_count - (change_limit - 5)), clients=[self._player.getInputDevice().getClientID()], color=(1, 0.2, 0.2), transient=True) if self.change_count >= change_limit: bs.screenMessage('Lobby Spammer Get Rekt!', color=(1, 0.2, 0.2), transient=True) bsInternal._disconnectClient( self._player.getInputDevice().getClientID()) if self._dead: print "WARNING: chooser got ChangeMessage after dying" return if not self._textNode.exists(): bs.printError('got ChangeMessage after nodes died') return if msg.what == 'screen': self.screen = self.screens[( (self.screens.index(self.screen) + msg.value) % len(self.screens))] self._updateText() if msg.what == 'team': if len(self.getLobby()._teams) > 1: bs.playSound(self._swishSound) self._selectedTeamIndex = ((self._selectedTeamIndex + msg.value) % len(self.getLobby()._teams)) self._updateText() self.updatePosition() self._updateIcon() elif msg.what == 'profileIndex': if len(self.profileNames) == 1: # this should be pretty hard to hit now with # automatic local accounts.. bs.playSound(bs.getSound('error')) else: # pick the next player profile and assign our name # and character based on that bs.playSound(self._deekSound) self.profileIndex = ((self.profileIndex + msg.value) % len(self.profileNames)) self.updateFromPlayerProfile() elif msg.what == 'character': bs.playSound(self._clickSound) # update our index in our local list of characters self.characterIndex = ((self.characterIndex + msg.value) % len(self.characterNames)) # bs.screenMessage(self.characterNames[self.characterIndex]) self._updateText() self._updateIcon() elif msg.what == 'ready': forceTeamSwitch = False # team auto-balance kicks us to another team if we try to # join the team with the most players if not self.ready: if bs.getConfig().get('Auto Balance Teams', False): lobby = self.getLobby() if len(lobby._teams) > 1: session = bs.getSession() # first, calc how many players are on each team # ..we need to count both active players and # choosers that have been marked as ready. teamPlayerCounts = {} for team in lobby._teams: teamPlayerCounts[team().getID()] = \ len(team().players) for chooser in lobby.choosers: if chooser.ready: teamPlayerCounts[ chooser.getTeam().getID()] += 1 largestTeamSize = max(teamPlayerCounts.values()) smallestTeamSize = \ min(teamPlayerCounts.values()) # force switch if we're on the biggest team # and there's a smaller one available if (largestTeamSize != smallestTeamSize and teamPlayerCounts[self.getTeam().getID()] >= largestTeamSize): forceTeamSwitch = True if forceTeamSwitch: bs.playSound(self._errorSound) self.handleMessage(ChangeMessage('team', 1)) bs.screenMessage( "Unequal Teams!", color=(0.8, 0.5, 0.2), clients=[self._player.getInputDevice().getClientID()], transient=True) else: if msg.value != 2: bs.playSound(self._punchSound) self._setReady(msg.value)