def _updatePlayerOrder(self): # calc all player distances for player in self.players: try: pos = bs.Vector(*player.actor.node.position) except Exception: pos = None if pos is not None: rIndex = player.gameData['lastRegion'] r1 = self._regions[rIndex] r1Pt = bs.Vector(*r1._pt[:3]) r2 = self._regions[0] if rIndex == len( self._regions) - 1 else self._regions[rIndex + 1] r2Pt = bs.Vector(*r2._pt[:3]) r1Dist = (pos - r1Pt).length() r2Dist = (pos - r2Pt).length() amt = 1.0 - (r2Dist / (r2Pt - r1Pt).length()) amt = player.gameData['lap'] + (rIndex + amt) * ( 1.0 / len(self._regions)) player.gameData['distance'] = amt # sort players by distance and update their ranks pList = [[player.gameData['distance'], player] for player in self.players] pList.sort(reverse=True) for i, p in enumerate(pList): try: p[1].gameData['rank'] = i if p[1].actor is not None: n = p[1].actor.distanceTxt if n.exists(): n.text = str(i + 1) if p[1].isAlive() else '' except Exception: bs.printException('error updating player orders')
def zUpdate(self): # update one of our bot lists each time through.. # first off, remove dead bots from the list # (we check exists() here instead of dead.. we want to keep them around even if they're just a corpse) #####This is overloaded from bsSpaz to prevent zombies from attacking player Zombies. try: botList = self._botLists[self._botUpdateList] = [ b for b in self._botLists[self._botUpdateList] if b.exists() ] except Exception: bs.printException("error updating bot list: " + str(self._botLists[self._botUpdateList])) self._botUpdateList = (self._botUpdateList + 1) % self._botListCount # update our list of player points for the bots to use playerPts = [] for player in bs.getActivity().players: try: if player.isAlive(): if player.gameData[ 'lives'] > 0: #If the player has lives, add to attack points playerPts.append( (bs.Vector(*player.actor.node.position), bs.Vector(*player.actor.node.velocity))) except Exception: bs.printException('error on bot-set _update') for b in botList: b._setPlayerPts(playerPts) b._updateAI()
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 loadAllCharacters(self): account_id = self._player.get_account_id() if account_id is None: return items = db.getData(account_id)['i'] if items is not None: if isinstance(getattr(self, "characterNames", None), list): try: if 'unlock-chars' in items: self.characterNames.append('Steve') self.characterNames.append('Raphael') # for name,profile in self.profiles.items(): # character = profile.get("character","Spaz") # if (character not in self.characterNames # and character in bsSpaz.appearances): # self.characterNames.append(character) for i, k in bsSpaz.appearances.items(): if k.style != 'spaz' and i not in self.characterNames: self.characterNames.append(i) bs.screenMessage( 'All Characters Unlocked', color=(0, 1, 0), clients=[self._player.getInputDevice().getClientID()], transient=True) elif 'logicon' in items: self.characterNames.append('Logicon') bs.screenMessage( 'Logicon Unlocked', color=(0, 1, 0), clients=[self._player.getInputDevice().getClientID()], transient=True) except: bs.printException()
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 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 try: if killed and bs.getActivity().announcePlayerDeaths: 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 reloadProfiles(self): # we may have gained or lost character names if the user bought something; reload these too.. self.characterNamesLocalUnlocked = bsSpaz.getAppearances() self.characterNamesLocalUnlocked.sort(key=lambda x: x.lower()) # self.characterNamesAll = bsSpaz.getAppearances(includeLocked=True) # self.characterNamesAll.sort(key=lambda x:x.lower()) # do any overall prep we need to such as creating account profile.. bsUtils._ensureHaveAccountPlayerProfile() # grab available player profiles # try: self.profiles = dict(bs.getConfig()['Player Profiles']) # except Exception: self.profiles = {} # # add in a random one so we're ok even if there's no user-created profiles # self.profiles['_random'] = {} # self.profileNames = self.profiles.keys() # self.profileNames.sort(key=lambda x:x.lower()) for chooser in self.choosers: try: chooser.reloadProfiles() chooser.updateFromPlayerProfile() except Exception: bs.printException('exception reloading profiles')
def _updateBoxState(self): claimerHold = False userperHold = False for player in self.getActivity().players: try: if player.actor.isAlive( ) and player.actor.node.holdNode.exists(): holdingBox = (player.actor.node.holdNode == self.node) else: holdingBox = False except Exception: bs.printException("exception checking hold flag") if holdingBox: if self.claimedBy is None: self.claimedBy = player claimerHold = True else: if self.claimedBy == player: claimerHold = True else: userperHold = True #release claim on any other existing boxes for box in self.getActivity().boxes: if box <> self and box.claimedBy == self.claimedBy: box.claimedBy = None #Blow up this box if it belongs to someone else if (not claimerHold) and userperHold: self.handleMessage(bs.HitMessage())
def _updateBots(self): bots = self._bots.getLivingBots() for bot in bots: bot.targetFlag = None # if we're waiting on a continue, stop here so they don't keep scoring if self.isWaitingForContinue(): self._bots.stopMoving() return # if we've got a flag and no player are holding it, find the closest bot to it, and make them the designated flag-bearer if self._flag.node.exists(): for p in self.players: try: if p.actor.isAlive( ) and p.actor.node.holdNode == self._flag.node: return except Exception: bs.printException("exception checking hold node") pass fp = bs.Vector(*self._flag.node.position) closestBot = None for bot in bots: if bot.heldCount > 0: continue # if a bot is picked up he should forget about the flag bp = bs.Vector(*bot.node.position) l = (bp - fp).length() if (closestBot is None or l < closestLen): closestLen = l closestBot = bot if closestBot is not None: closestBot.targetFlag = self._flag
def zUpdate(self): # update one of our bot lists each time through.. # first off, remove dead bots from the list # (we check exists() here instead of dead.. we want to keep them around even if they're just a corpse) #####This is overloaded from bsSpaz to walk over other players' mines, but not source player. try: botList = self._botLists[self._botUpdateList] = [b for b in self._botLists[self._botUpdateList] if b.exists()] except Exception: bs.printException("error updating bot list: "+str(self._botLists[self._botUpdateList])) self._botUpdateList = (self._botUpdateList+1)%self._botListCount # update our list of player points for the bots to use playerPts = [] for player in bs.getActivity().players: try: if player.exists(): if not player is self.sourcePlayer: #If the player has lives, add to attack points for m in player.gameData['mines']: if not m.isHome and m.exists(): playerPts.append((bs.Vector(*m.node.position), bs.Vector(0,0,0))) except Exception: bs.printException('error on bot-set _update') for b in botList: b._setPlayerPts(playerPts) b._updateAI()
def run(self): try: bsInternal._setThreadName("SimpleGetThread") response = urllib2.urlopen(self._url) bs.callInGameThread(bs.Call(self._runCallback, response.read())) except: bs.printException() bs.callInGameThread(bs.Call(self._runCallback, None))
def _awardFlawlessBonus(self,player): bs.playSound(self._cashRegisterSound) try: if player.isAlive(): self.scoreSet.playerScored(player,self._flawlessBonus,scale=1.2,color=(0.6,1.0,0.6,1.0), title=bs.Lstr(resource='flawlessWaveText'), screenMessage=False) except Exception: bs.printException()
def _awardCompletionBonus(self): bs.playSound(self._cashRegisterSound) for player in self.players: try: if player.isAlive(): self.scoreSet.playerScored(player,int(100/len(self.initialPlayerInfo)),scale=1.4,color=(0.6,0.6,1.0,1.0), title=bs.Lstr(resource='completionBonusText'),screenMessage=False) except Exception: bs.printException()
def callback(): if fadeout: bsInternal._unlockAllInput() try: bsInternal._newHostSession(session) except Exception: import bsMainMenu bs.printException("exception running session", session) # drop back into a main menu session.. bsInternal._newHostSession(bsMainMenu.MainMenuSession)
def _getName(self, full=False): nameRaw = name = self.profileNames[self.profileIndex] clamp = False if name == '_random': try: inputDevice = self._player.getInputDevice() except Exception: inputDevice = None if inputDevice is not None: name = inputDevice._getDefaultPlayerName() else: name = 'Invalid' if not full: clamp = True elif name == '__account__': try: inputDevice = self._player.getInputDevice() except Exception: inputDevice = None if inputDevice is not None: name = inputDevice._getAccountName(full) else: name = 'Invalid' if not full: clamp = True elif name == '_edit': # FIXME - this causes problems as an Lstr, but its ok to # explicitly translate for now since this is only shown on the host. name = (bs.Lstr( resource='createEditPlayerText', fallbackResource='editProfileWindow.titleNewText').evaluate()) else: # if we have a regular profile marked as global with an icon, # use it (for full only) if full: try: if self.profiles[nameRaw].get('global', False): icon = (bs.uni( self.profiles[nameRaw]['icon'] if 'icon' in self. profiles[nameRaw] else bs.getSpecialChar('logo'))) name = icon + name except Exception: bs.printException('Error applying global icon') else: # we now clamp non-full versions of names so there's at # least some hope of reading them in-game clamp = True if clamp: # in python < 3.5 some unicode chars can have length 2, so we need # to convert to raw int vals for safe trimming nameChars = bs.uniToInts(name) if len(nameChars) > 10: name = bs.uniFromInts(nameChars[:10]) + '...' return name
def _displayBanner(ach): try: import bsAchievement # FIXME - need to get these using the UI context somehow instead of trying to inject # these into whatever activity happens to be active.. (since that won't work while in client mode) a = bsInternal._getForegroundHostActivity() if a is not None: with bs.Context(a): bsAchievement.getAchievement(ach).announceCompletion() except Exception: bs.printException('error showing server ach')
def getDisplayString(self): try: if self._level != '': import bsCoopGame campaignName,campaignLevel = self._level.split(':') n = bsCoopGame.getCampaign(campaignName).getLevel(campaignLevel).getDisplayString() else: n = '' except Exception,e: n = '' bs.printException()
def install(self): if not self.checkSupported(): bs.screenMessage(InstallerLanguage.notSupported % (self.characterName, self.platform)) return bs.screenMessage(InstallerLanguage.installing % self.characterName) try: for model in self.models: systemModel = self.modelsDir + model modModel = self.characterFilesDir + model shutil.copy(modModel, systemModel) for texture in self.textures: if self.platform == 'android': if texture.endswith('.dds'): continue else: if texture.endswith('.ktx'): continue systemTex = self.texturesDir + texture modTex = self.characterFilesDir + texture shutil.copy(modTex, systemTex) for au in self.audio: systemAudio = self.audioDir + au modAudio = self.characterFilesDir + au shutil.copy(modAudio, systemAudio) bs.screenMessage(InstallerLanguage.success % self.characterName, color=(0, 1, 0)) try: __import__("wolverine") __import__("editor") except Exception: bs.printException() try: import wolverine import editor except Exception: bs.printException() bs.reloadMedia() modPath = bs.getEnvironment()['userScriptsDirectory'] + "/" if os.path.exists(modPath + "installWolverine.py"): os.remove(modPath + "installWolverine.py") if os.path.exists(modPath + "installWolverine.pyc"): os.remove(modPath + "installWolverine.pyc") except IOError, e: bs.screenMessage(InstallerLanguage.fail % self.characterName, color=(1, 0, 0)) bs.screenMessage(str(e), color=(1, 0, 0)) print e
def _updateIcon(self): if self.profileNames[self.profileIndex] == '_edit': tex = bs.getTexture('black') tintTex = bs.getTexture('black') self.icon.color = (1, 1, 1) self.icon.texture = tex self.icon.tintTexture = tintTex self.icon.tintColor = (0, 1, 0) return try: texName = bsSpaz.appearances[self.characterNames[ self.characterIndex]].iconTexture tintTexName = bsSpaz.appearances[self.characterNames[ self.characterIndex]].iconMaskTexture except Exception: bs.printException('Error updating char icon list') texName = 'neoSpazIcon' tintTexName = 'neoSpazIconColorMask' tex = bs.getTexture(texName) tintTex = bs.getTexture(tintTexName) self.icon.color = (1, 1, 1) self.icon.texture = tex self.icon.tintTexture = tintTex c = self.getColor() c2 = self.getHighlight() canSwitchTeams = len(self.getLobby()._teams) > 1 # if we're initing, flash if not self._inited: bsUtils.animateArray(self.icon, 'color', 3, { 150: (1, 1, 1), 250: (2, 2, 2), 350: (1, 1, 1) }) # blend in teams mode; switch instantly in ffa-mode if canSwitchTeams: bsUtils.animateArray(self.icon, 'tintColor', 3, { 0: self.icon.tintColor, 100: c }) else: self.icon.tintColor = c self.icon.tint2Color = c2 # finColor = (0.2+0.8*c[0],0.2+0.8*c[1],0.2+0.8*c[2]) # store the icon info the the player self._player._setIconInfo(texName, tintTexName, c, c2)
def removeAllChoosersAndKickPlayers(self): 'removes all player choosers & kicks attached players from the session' for chooser in list( self.choosers): # copy the list; can change under us try: player = chooser.getPlayer() if player is not None and player.exists(): player.removeFromGame() except Exception: bs.printException('Error removing chooser player') self.removeAllChoosers()
def _awardLocalAchievement(ach): try: a = getAchievement(ach) if a is not None and not a.isComplete(): # report new achievements to the game-service.. bsInternal._reportAchievement(ach) # and to our account.. bsInternal._addTransaction({'type': 'ACHIEVEMENT', 'name': ach}) # now attempt to show a banner _displayBanner(ach) except Exception: bs.printException()
def handleMessage(self, m): if isinstance(m, bs.FlagPickedUpMessage): try: player = m.node.getDelegate().getPlayer() if player.exists(): m.flag.lastHoldingPlayer = player except Exception: bs.printException( 'exception in Football FlagPickedUpMessage; this shoudln\'t happen' ) m.flag.heldCount += 1 elif isinstance(m, bs.FlagDroppedMessage): m.flag.heldCount -= 1 # respawn dead players if they're still in the game elif isinstance(m, bs.PlayerSpazDeathMessage): bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior self.respawnPlayer(m.spaz.getPlayer()) # jasonhu5 player = m.spaz.getPlayer() killer = m.killerPlayer self._handleKillScore(player, killer) # # respawn dead flags elif isinstance(m, bs.FlagDeathMessage): if not self.hasEnded(): self._flagRespawnTimer = bs.Timer(3000, self._spawnFlag) self._flagRespawnLight = bs.NodeActor( bs.newNode('light', attrs={ 'position': self._flagSpawnPos, 'heightAttenuated': False, 'radius': 0.15, 'color': (1.0, 1.0, 0.3) })) bs.animate(self._flagRespawnLight.node, "intensity", { 0: 0, 250: 0.15, 500: 0 }, loop=True) bs.gameTimer(3000, self._flagRespawnLight.node.delete) else: bs.TeamGameActivity.handleMessage(self, m) # augment standard behavior
def reloadProfiles(self): # we may have gained or lost character names if the user # bought something; reload these too.. self.characterNamesLocalUnlocked = bsSpaz.getAppearances() self.characterNamesLocalUnlocked.sort(key=lambda x: x.lower()) # do any overall prep we need to such as creating account profile.. bsUtils._ensureHaveAccountPlayerProfile() for chooser in self.choosers: try: chooser.reloadProfiles() chooser.updateFromPlayerProfile() except Exception: bs.printException('exception reloading profiles')
def _displayNextAchievement(): global gAchievementDisplayTimer global gAchievementsToDisplay # pull the first achievement off the list and display it, or kill the display-timer if the list is empty if len(gAchievementsToDisplay) > 0: try: a, sound = gAchievementsToDisplay.pop(0) a.showCompletionBanner(sound) except Exception: bs.printException("error showing next achievement") gAchievementsToDisplay = [] gAchievementDisplayTimer = None else: gAchievementDisplayTimer = None
def _bUpdate(self): # update one of our bot lists each time through.. # first off, remove dead bots from the list # (we check exists() here instead of dead.. we want to keep them around even if they're just a corpse) try: botList = self._botLists[self._botUpdateList] = \ [b for b in self._botLists[self._botUpdateList] if b.exists()] except Exception: bs.printException('error updating bot list: ' + str(self._botLists[self._botUpdateList])) self._botUpdateList = (self._botUpdateList + 1) % self._botListCount # update our list of player points for the bots to use playerPts = [] try: #if player.isAlive() and not (player is self.sourcePlayer): # playerPts.append((bs.Vector(*player.actor.node.position), # bs.Vector(*player.actor.node.velocity))) for n in bs.getNodes(): if n.getNodeType() == 'spaz': s = n.getDelegate() if isinstance(s, bsSpaz.SpazBot): if not s in self.getLivingBots(): if hasattr(s, 'sourcePlayer'): if not s.sourcePlayer is self.sourcePlayer: playerPts.append((bs.Vector(*n.position), bs.Vector(*n.velocity))) else: playerPts.append((bs.Vector(*n.position), bs.Vector(*n.velocity))) elif isinstance(s, bsSpaz.PlayerSpaz): try: if not (s.getPlayer().getTeam() is self.sourcePlayer.getTeam()): playerPts.append((bs.Vector(*n.position), bs.Vector(*n.velocity))) except: pass except Exception: bs.printException('error on bot-set _update') for b in botList: b._setPlayerPts(playerPts) b._updateAI()
def _update(self): try: botList = self._botLists[self._botUpdateList] = [b for b in self._botLists[self._botUpdateList] if b.exists()] except Exception: bs.printException("error updating bot list: "+str(self._botLists[self._botUpdateList])) self._botUpdateList = (self._botUpdateList+1)%self._botListCount playerPts = [] for player in bs.getActivity().teams[(self.team+1)%2].players: try: if player.isAlive(): playerPts.append((bs.Vector(*player.actor.node.position), bs.Vector(*player.actor.node.velocity))) except Exception: bs.printException('error on bot-set _update') for b in botList: b._setPlayerPts(playerPts) b._updateAI()
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 _cb_checkUpdateData(self, data): try: if data: m, v = process_server_data(data) mods = [Mod(d) for d in m.values()] for mod in mods: mod._mods = {m.base: m for m in mods} if mod.isInstalled() and mod.checkUpdate(): if config.get("auto-update-old-mods", True): if mod.is_old(): bs.screenMessage("updating '" + str(mod.name) + "'") def cb(mod, success): if success: bs.screenMessage("'" + str(mod.name) + "' updated") mod.install(cb) else: if not mod.is_old(): bs.screenMessage("Update for '" + mod.name + "' available! Check the ModManager") except Exception, e: bs.printException() bs.screenMessage("failed to check for updates")
def _updateFlagState(self): for team in self.teams: team.gameData['holdingFlag'] = False self._holdingPlayers = [] for player in self.players: try: if player.actor.isAlive( ) and player.actor.node.holdNode.exists(): holdingFlag = ( player.actor.node.holdNode.getNodeType() == 'flag') else: holdingFlag = False except Exception: bs.printException("exception checking hold flag") if holdingFlag: self._holdingPlayers.append(player) player.getTeam().gameData['holdingFlag'] = True holdingTeams = set(t for t in self.teams if t.gameData['holdingFlag']) prevState = self._flagState if len(holdingTeams) > 1: self._flagState = self.FLAG_CONTESTED self._scoringTeam = None self._flag.light.color = (0.6, 0.6, 0.1) self._flag.node.color = (1.0, 1.0, 0.4) elif len(holdingTeams) == 1: holdingTeam = list(holdingTeams)[0] self._flagState = self.FLAG_HELD self._scoringTeam = holdingTeam self._flag.light.color = bs.getNormalizedColor(holdingTeam.color) self._flag.node.color = holdingTeam.color else: self._flagState = self.FLAG_UNCONTESTED self._scoringTeam = None self._flag.light.color = (0.2, 0.2, 0.2) self._flag.node.color = (1, 1, 1) if self._flagState != prevState: bs.playSound(self._swipSound)
def handleMessage(self, m): if isinstance(m, 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 m.what == 'team': if len(self.getLobby()._teams) > 1: bs.playSound(self._swishSound) self._selectedTeamIndex = (self._selectedTeamIndex + m.value ) % len(self.getLobby()._teams) self._updateText() self.updatePosition() self._updateIcon() elif m.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 + m.value) % len( self.profileNames) self.updateFromPlayerProfile() elif m.what == 'character': bs.playSound(self._clickSound) # update our index in our local list of characters self.characterIndex = (self.characterIndex + m.value) % len( self.characterNames) self._updateText() self._updateIcon() elif m.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: try: 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 except Exception: bs.printException('auto balance error') if forceTeamSwitch: bs.playSound(self._errorSound) self.handleMessage(ChangeMessage('team', 1)) else: bs.playSound(self._punchSound) self._setReady(m.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 createDisplay(self, x, y, delay, outDelay=None, color=None, style='postGame'): if style == 'postGame': inGameColors = False inMainMenu = False hAttach = vAttach = attach = 'center' elif style == 'inGame': inGameColors = True inMainMenu = False hAttach = 'left' vAttach = 'top' attach = 'topLeft' elif style == 'news': inGameColors = True inMainMenu = True hAttach = 'center' vAttach = 'top' attach = 'topCenter' else: raise Exception('invalid style "' + style + '"') # attempt to determine what campaign we're in # (so we know whether to show "hard mode only") if inMainMenu: hmo = False else: try: hmo = (self._hardModeOnly and bs.getSession()._campaignInfo['campaign'] == 'Easy') except Exception: bs.printException("unable to determine campaign") hmo = False activity = bs.getActivity() if inGameColors: objs = [] outDelayFin = (delay + outDelay) if outDelay is not None else None if color is not None: c1 = (2.0 * color[0], 2.0 * color[1], 2.0 * color[2], color[3]) c2 = color else: c1 = (1.5, 1.5, 2, 1.0) c2 = (0.8, 0.8, 1.0, 1.0) if hmo: c1 = (c1[0], c1[1], c1[2], c1[3] * 0.6) c2 = (c2[0], c2[1], c2[2], c2[3] * 0.2) objs.append( bsUtils.Image(self.getIconTexture(False), hostOnly=True, color=c1, position=(x - 25, y + 5), attach=attach, transition='fadeIn', transitionDelay=delay, vrDepth=4, transitionOutDelay=outDelayFin, scale=(40, 40)).autoRetain()) txt = self.getDisplayString() txtS = 0.85 txtMaxW = 300 objs.append( bsUtils.Text(txt, hostOnly=True, maxWidth=txtMaxW, position=(x, y + 2), transition='fadeIn', scale=txtS, flatness=0.6, shadow=0.5, hAttach=hAttach, vAttach=vAttach, color=c2, transitionDelay=delay + 50, transitionOutDelay=outDelayFin).autoRetain()) # txt2 = self.getDescriptionLocalized() txt2S = 0.62 txt2MaxW = 400 objs.append( bsUtils.Text(self.getDescriptionFull() if inMainMenu else self.getDescription(), hostOnly=True, maxWidth=txt2MaxW, position=(x, y - 14), transition='fadeIn', vrDepth=-5, hAttach=hAttach, vAttach=vAttach, scale=txt2S, flatness=1.0, shadow=0.5, color=c2, transitionDelay=delay + 100, transitionOutDelay=outDelayFin).autoRetain()) if hmo: t = bsUtils.Text(bs.Lstr(resource='difficultyHardOnlyText'), hostOnly=True, maxWidth=txt2MaxW * 0.7, position=(x + 60, y + 5), transition='fadeIn', vrDepth=-5, hAttach=hAttach, vAttach=vAttach, hAlign='center', vAlign='center', scale=txtS * 0.8, flatness=1.0, shadow=0.5, color=(1, 1, 0.6, 1), transitionDelay=delay + 100, transitionOutDelay=outDelayFin).autoRetain() t.node.rotate = 10 objs.append(t) # ticket-award awardX = -100 objs.append( bsUtils.Text(bs.getSpecialChar('ticket'), hostOnly=True, position=(x + awardX + 33, y + 7), transition='fadeIn', scale=1.5, hAttach=hAttach, vAttach=vAttach, hAlign='center', vAlign='center', color=(1, 1, 1, 0.2 if hmo else 0.4), transitionDelay=delay + 50, transitionOutDelay=outDelayFin).autoRetain()) objs.append( bsUtils.Text('+' + str(self.getAwardTicketValue()), hostOnly=True, position=(x + awardX + 28, y + 16), transition='fadeIn', scale=0.7, flatness=1, hAttach=hAttach, vAttach=vAttach, hAlign='center', vAlign='center', color=(c2), transitionDelay=delay + 50, transitionOutDelay=outDelayFin).autoRetain()) else: complete = self.isComplete() objs = [] cIcon = self.getIconColor(complete) if hmo and not complete: cIcon = (cIcon[0], cIcon[1], cIcon[2], cIcon[3] * 0.3) objs.append( bsUtils.Image(self.getIconTexture(complete), hostOnly=True, color=cIcon, position=(x - 25, y + 5), attach=attach, vrDepth=4, transition='inRight', transitionDelay=delay, transitionOutDelay=None, scale=(40, 40)).autoRetain()) if complete: objs.append( bsUtils.Image( bs.getTexture('achievementOutline'), hostOnly=True, modelTransparent=bs.getModel('achievementOutline'), color=(2, 1.4, 0.4, 1), vrDepth=8, position=(x - 25, y + 5), attach=attach, transition='inRight', transitionDelay=delay, transitionOutDelay=None, scale=(40, 40)).autoRetain()) else: if not complete: awardX = -100 objs.append( bsUtils.Text(bs.getSpecialChar('ticket'), hostOnly=True, position=(x + awardX + 33, y + 7), transition='inRight', scale=1.5, hAttach=hAttach, vAttach=vAttach, hAlign='center', vAlign='center', color=(1, 1, 1, 0.4) if complete else (1, 1, 1, (0.1 if hmo else 0.2)), transitionDelay=delay + 50, transitionOutDelay=None).autoRetain()) objs.append( bsUtils.Text('+' + str(self.getAwardTicketValue()), hostOnly=True, position=(x + awardX + 28, y + 16), transition='inRight', scale=0.7, flatness=1, hAttach=hAttach, vAttach=vAttach, hAlign='center', vAlign='center', color=((0.8, 0.93, 0.8, 1.0) if complete else (0.6, 0.6, 0.6, (0.2 if hmo else 0.4))), transitionDelay=delay + 50, transitionOutDelay=None).autoRetain()) # show 'hard-mode-only' only over incomplete achievements # when that's the case.. if hmo: t = bsUtils.Text( bs.Lstr(resource='difficultyHardOnlyText'), hostOnly=True, maxWidth=300 * 0.7, position=(x + 60, y + 5), transition='fadeIn', vrDepth=-5, hAttach=hAttach, vAttach=vAttach, hAlign='center', vAlign='center', scale=0.85 * 0.8, flatness=1.0, shadow=0.5, color=(1, 1, 0.6, 1), transitionDelay=delay + 50, transitionOutDelay=None).autoRetain() t.node.rotate = 10 objs.append(t) objs.append( bsUtils.Text(self.getDisplayString(), hostOnly=True, maxWidth=300, position=(x, y + 2), transition='inRight', scale=0.85, flatness=0.6, hAttach=hAttach, vAttach=vAttach, color=((0.8, 0.93, 0.8, 1.0) if complete else (0.6, 0.6, 0.6, (0.2 if hmo else 0.4))), transitionDelay=delay + 50, transitionOutDelay=None).autoRetain()) objs.append( bsUtils.Text(self.getDescriptionComplete() if complete else self.getDescription(), hostOnly=True, maxWidth=400, position=(x, y - 14), transition='inRight', vrDepth=-5, hAttach=hAttach, vAttach=vAttach, scale=0.62, flatness=1.0, color=((0.6, 0.6, 0.6, 1.0) if complete else (0.6, 0.6, 0.6, (0.2 if hmo else 0.4))), transitionDelay=delay + 100, transitionOutDelay=None).autoRetain()) return objs