def _awardTimeBonus(self,bonus): bs.playSound(self._cashRegisterSound) bs.PopupText(bs.Lstr(value='+${A} ${B}',subs=[('${A}',str(bonus)),('${B}',bs.Lstr(resource='timeBonusText'))]), color=(1,1,0.5,1), scale=1.0, position=(0,3,-1)).autoRetain() self._score.add(self._timeBonus) self._updateScores()
def handleMessage(self, msg): if isinstance(msg, bs.DieMessage): if not self.node.exists(): return self._updTimer = None bs.playSound(self.popSound, position=self.node.position) bs.PopupText("Goodbye!", position=self.node.position).autoRetain() self.node.delete() elif isinstance(msg, bs.OutOfBoundsMessage): self.handleMessage(bs.DieMessage()) else: bs.Actor.handleMessage(self, msg)
def callRound(self): self.roundNum += 1 self.num = random.randint(0, 15) num = self.num self.simon = random.choice([True, False]) if num < 9: line = "Run to the " + self.options[num] + " circle!" elif num < 15: line = "Run to the " + self.options[num] + "!" else: line = "Run outside of the circles!" if self.simon: line = "Simon says " + line[0].lower() + line[1:] self.text = bs.PopupText(line, position=(0, 5, -4), color=(1, 1, 1), randomOffset=0.5, offset=(0, 0, 0), scale=2.0).autoRetain() self.time -= 100 bs.gameTimer(self.time, self.checkRound)
def _awardFlawlessBonus(self): bs.playSound(self._cashRegisterSound) bs.PopupText(bs.Lstr(value='+${A} ${B}', subs=[('${A}', str(self._flawlessBonus)), ('${B}', bs.Lstr(resource='perfectWaveText'))]), color=(1, 1, 0.2, 1), scale=1.2, position=(0, 2, -1)).autoRetain() self._score.add(self._flawlessBonus) self._updateScores()
def _awardLivesBonus(self, ): bonus = self._lives * 30 bs.playSound(self._cashRegisterSound) bs.PopupText(bs.Lstr(value='+${A} ${B}', subs=[('${A}', str(bonus)), ('${B}', bs.Lstr(resource='livesBonusText')) ]), color=(0.7, 1.0, 0.3, 1), scale=1.3, position=(0, 1, -1)).autoRetain() self._score.add(bonus) self._updateScores()
def _awardCompletionBonus(self): bonus = 200 bs.playSound(self._cashRegisterSound) bs.PopupText(bs.Lstr(value='+${A} ${B}', subs=[('${A}', str(bonus)), ('${B}', bs.Lstr(resource='completionBonusText'))]), color=(0.7, 0.7, 1.0, 1), scale=1.6, position=(0, 1.5, -1)).autoRetain() self._score.add(bonus) self._updateScores()
def handleMessage(self, msg): self._handleMessageSanityCheck() if isinstance(msg, PowerupAcceptMessage): factory = self.getFactory() if self.powerupType == 'health': bs.playSound(factory.healthPowerupSound, 3, position=self.node.position) elif self.powerupType == 'deathBomb': bs.playSound(bs.getSound("gunCocking"), 3, position=self.node.position) bs.PopupText("Bomb has been planted", position=self.node.position).autoRetain() bs.playSound(factory.powerupSound, 3, position=self.node.position) self._powersGiven = True self.handleMessage(bs.DieMessage()) elif isinstance(msg, _TouchedMessage): if not self._powersGiven: node = bs.getCollisionInfo("opposingNode") if node is not None and node.exists(): node.handleMessage( PowerupMessage(self.powerupType, sourceNode=self.node)) elif isinstance(msg, bs.DieMessage): if self.node.exists(): if (msg.immediate): self.node.delete() else: curve = bs.animate(self.node, "modelScale", {0: 1, 100: 0}) bs.gameTimer(100, self.node.delete) elif isinstance(msg, bs.OutOfBoundsMessage): self.handleMessage(bs.DieMessage()) elif isinstance(msg, bs.HitMessage): # dont die on punches (thats annoying) if msg.hitType != 'punch': self.handleMessage(bs.DieMessage()) else: bs.Actor.handleMessage(self, msg)
def registerBotDie(self,m): self.killed += 1 self._score2 += 1 self.updateScore() if len(self._bots.getLivingBots()) == 0 and not self.stop: self.stop = True self.num += 1 self.killed = 0 bs.PopupText(bs.Lstr(value='+${A} ${B}',subs=[('${A}',str(int(bs.getGameTime() - self.time)/1000)),('${B}',bs.Lstr(resource='timeBonusText'))]), color=(1,1,0.5,1), scale=1.0, position=self.spaz.node.position if self.spaz is not None and self.spaz.node.exists() else (0,5,0)).autoRetain() self._score2 += int((bs.getGameTime() - self.time)/1000) self.updateScore() self.waveDelay() def offstop(): self.stop = False bs.gameTimer(1000,offstop) if str(m.badGuy).lower().find('eric') != -1: # Warning! shit code! self.doEnd(outcome = 'victory') # But works - not touch.
class ProtectionGame(bs.TeamGameActivity): @classmethod def getName(cls): return 'Protection' @classmethod def getScoreInfo(cls): return { 'scoreName': 'Survived', 'scoreType': 'seconds', 'noneIsWinner': True } @classmethod def getDescription(cls, sessionType): return 'Protect your twin.' @classmethod def supportsSessionType(cls, sessionType): return True if (issubclass(sessionType, bs.TeamsSession) or issubclass( sessionType, bs.FreeForAllSession)) else False @classmethod def getSupportedMaps(cls, sessionType): return bs.getMapsSupportingPlayType("melee") @classmethod def getSettings(cls, sessionType): settings = [("Lives Per Player", { 'default': 1, 'minValue': 1, 'maxValue': 10, 'increment': 1 }), ("Time Limit", { 'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120), ('5 Minutes', 300), ('10 Minutes', 600), ('20 Minutes', 1200)], 'default': 0 }), ("Respawn Times", { 'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0), ('Long', 2.0), ('Longer', 4.0)], 'default': 1.0 }), ("Epic Mode", { 'default': False })] if issubclass(sessionType, bs.TeamsSession): settings.append(("Solo Mode", {'default': False})) settings.append(("Balance Total Lives", {'default': False})) return settings def __init__(self, settings): bs.TeamGameActivity.__init__(self, settings) if self.settings['Epic Mode']: self._isSlowMotion = True # show messages when players die since it's meaningful here self.announcePlayerDeaths = True try: self._soloMode = settings['Solo Mode'] except Exception: self._soloMode = False self._scoreBoard = bs.ScoreBoard() self._bots = myBots() self.spazClones = [] def getInstanceDescription(self): return 'Last team standing wins.' if isinstance( self.getSession(), bs.TeamsSession) else 'Protect your twin!' def getInstanceScoreBoardDescription(self): return 'last team standing wins' if isinstance( self.getSession(), bs.TeamsSession) else 'Protect your twin!' def onTransitionIn(self): bs.TeamGameActivity.onTransitionIn( self, music='Epic' if self.settings['Epic Mode'] else 'Survival') self._startGameTime = bs.getGameTime() def onTeamJoin(self, team): team.gameData['survivalSeconds'] = None team.gameData['spawnOrder'] = [] def onPlayerJoin(self, player): # no longer allowing mid-game joiners here... too easy to exploit if self.hasBegun(): player.gameData['lives'] = 0 player.gameData['icons'] = [] # make sure our team has survival seconds set if they're all dead # (otherwise blocked new ffa players would be considered 'still alive' in score tallying) if self._getTotalTeamLives(player.getTeam( )) == 0 and player.getTeam().gameData['survivalSeconds'] is None: player.getTeam().gameData['survivalSeconds'] = 0 bs.screenMessage(bs.Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', player.getName(full=True))]), color=(0, 1, 0)) return player.gameData['lives'] = self.settings['Lives Per Player'] if self._soloMode: player.gameData['icons'] = [] player.getTeam().gameData['spawnOrder'].append(player) self._updateSoloMode() else: # create our icon and spawn player.gameData['icons'] = [ Icon(player, position=(0, 50), scale=0.8) ] if player.gameData['lives'] > 0: self.spawnPlayer(player) # dont waste time doing this until begin if self.hasBegun(): self._updateIcons() def _updateSoloMode(self): # for both teams, find the first player on the spawn order list with lives remaining # and spawn them if they're not alive for team in self.teams: # prune dead players from the spawn order team.gameData['spawnOrder'] = [ p for p in team.gameData['spawnOrder'] if p.exists() ] for player in team.gameData['spawnOrder']: if player.gameData['lives'] > 0: if not player.isAlive(): self.spawnPlayer(player) break def _updateIcons(self): # in free-for-all mode, everyone is just lined up along the bottom if isinstance(self.getSession(), bs.FreeForAllSession): count = len(self.teams) xOffs = 85 x = xOffs * (count - 1) * -0.5 for i, team in enumerate(self.teams): if len(team.players) == 1: player = team.players[0] for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs # in teams mode we split up teams else: if self._soloMode: # first off, clear out all icons for player in self.players: player.gameData['icons'] = [] # now for each team, cycle through our available players adding icons for team in self.teams: if team.getID() == 0: x = -60 xOffs = -78 else: x = 60 xOffs = 78 isFirst = True testLives = 1 while True: playersWithLives = [ p for p in team.gameData['spawnOrder'] if p.exists() and p.gameData['lives'] >= testLives ] if len(playersWithLives) == 0: break for player in playersWithLives: player.gameData['icons'].append( Icon(player, position=(x, (40 if isFirst else 25)), scale=1.0 if isFirst else 0.5, nameMaxWidth=130 if isFirst else 75, nameScale=0.8 if isFirst else 1.0, flatness=0.0 if isFirst else 1.0, shadow=0.5 if isFirst else 1.0, showDeath=True if isFirst else False, showLives=False)) x += xOffs * (0.8 if isFirst else 0.56) isFirst = False testLives += 1 # non-solo mode else: for team in self.teams: if team.getID() == 0: x = -50 xOffs = -85 else: x = 50 xOffs = 85 for player in team.players: for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs def _getSpawnPoint(self, player): # in solo-mode, if there's an existing live player on the map, spawn at whichever # spot is farthest from them (keeps the action spread out) if self._soloMode: livingPlayer = None for team in self.teams: for player in team.players: if player.isAlive(): p = player.actor.node.position livingPlayer = player livingPlayerPos = p break if livingPlayer: playerPos = bs.Vector(*livingPlayerPos) points = [] for team in self.teams: startPos = bs.Vector( *self.getMap().getStartPosition(team.getID())) points.append([(startPos - playerPos).length(), startPos]) points.sort() return points[-1][1] else: return None else: return None def spawnPlayer(self, player): self.spawnPlayerSpaz(player, self._getSpawnPoint(player)) if not self._soloMode: bs.gameTimer(300, bs.Call(self._printLives, player)) # if we have any icons, update their state for icon in player.gameData['icons']: icon.handlePlayerSpawned() def spawnPlayerByDummy(self, player): if player.gameData[ 'lives'] > 0: #only try to spawn if player still has lives. Might have died during recheck delay... found = False for bot in self._bots.getLivingBots(): #Look for bot to spawn by if bot.playa == player: found = True #print("Found player") self.spawnPlayerSpaz(player, bot.node.position) if not self._soloMode: bs.gameTimer(300, bs.Call(self._printLives, player)) # if we have any icons, update their state for icon in player.gameData['icons']: icon.handlePlayerSpawned() if not found: #Didn't find clone. This can happen if player dies btw clone death and clone spawn #print('did not find player.') bs.gameTimer(1000, bs.Call( self.spawnPlayerByDummy, player)) #wait one second and try again for spawn def spawnDummy(self, player, myClone): #playerNode = bs.getActivity()._getPlayerNode(player) spz = self.scoreSet._players[player.getName()].getSpaz() if not spz is None: pos = spz.node.position player.gameData['lastSpawn'] = pos else: pos = player.gameData['lastSpawn'] bs.gameTimer( 1000, bs.Call(self._bots.spawnCBot, player, myClone, pos=pos, spawnTime=1000)) def _printLives(self, player): if not player.exists() or not player.isAlive(): return try: pos = player.actor.node.position except Exception, e: print 'EXC getting player pos in bsElim', e return bs.PopupText('x' + str(player.gameData['lives'] - 1), color=(1, 1, 0, 1), offset=(0, -0.8, 0), randomOffset=0.0, scale=1.8, position=pos).autoRetain()
class GravityFalls(bs.TeamGameActivity): @classmethod def getName(cls): return 'Gravity Falls' @classmethod def getScoreInfo(cls): return { 'scoreName': 'Survived', 'scoreType': 'seconds', 'noneIsWinner': True } @classmethod def getDescription(cls, sessionType): return 'Last remaining alive wins.' @classmethod def supportsSessionType(cls, sessionType): return True if (issubclass(sessionType, bs.TeamsSession) or issubclass( sessionType, bs.FreeForAllSession)) else False @classmethod def getSupportedMaps(cls, sessionType): return bs.getMapsSupportingPlayType("melee") @classmethod def getSettings(cls, sessionType): settings = [("Lives Per Player", { 'default': 1, 'minValue': 1, 'maxValue': 10, 'increment': 1 }), ("Time Limit", { 'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120), ('5 Minutes', 300), ('10 Minutes', 600), ('20 Minutes', 1200)], 'default': 0 }), ("Respawn Times", { 'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0), ('Long', 2.0), ('Longer', 4.0)], 'default': 1.0 }), ("Epic Mode", { 'default': False })] if issubclass(sessionType, bs.TeamsSession): settings.append(("Solo Mode", {'default': False})) settings.append(("Balance Total Lives", {'default': False})) return settings def __init__(self, settings): bs.TeamGameActivity.__init__(self, settings) if self.settings['Epic Mode']: self._isSlowMotion = True self.announcePlayerDeaths = True try: self._soloMode = settings['Solo Mode'] except Exception: self._soloMode = False self._scoreBoard = bs.ScoreBoard() def getInstanceDescription(self): return 'Last team standing wins.' if isinstance( self.getSession(), bs.TeamsSession) else 'Last one standing wins.' def getInstanceScoreBoardDescription(self): return 'last team standing wins' if isinstance( self.getSession(), bs.TeamsSession) else 'last one standing wins' def onTransitionIn(self): bs.TeamGameActivity.onTransitionIn( self, music='Epic' if self.settings['Epic Mode'] else 'Survival') self._startGameTime = bs.getGameTime() def onTeamJoin(self, team): team.gameData['survivalSeconds'] = None team.gameData['spawnOrder'] = [] def _updateSoloMode(self): # for both teams, find the first player on the spawn order list with lives remaining # and spawn them if they're not alive for team in self.teams: # prune dead players from the spawn order team.gameData['spawnOrder'] = [ p for p in team.gameData['spawnOrder'] if p.exists() ] for player in team.gameData['spawnOrder']: if player.gameData['lives'] > 0: if not player.isAlive(): self.spawnPlayer(player) break def _updateIcons(self): # in free-for-all mode, everyone is just lined up along the bottom if isinstance(self.getSession(), bs.FreeForAllSession): count = len(self.teams) xOffs = 85 x = xOffs * (count - 1) * -0.5 for i, team in enumerate(self.teams): if len(team.players) == 1: player = team.players[0] for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs # in teams mode we split up teams else: if self._soloMode: # first off, clear out all icons for player in self.players: player.gameData['icons'] = [] # now for each team, cycle through our available players adding icons for team in self.teams: if team.getID() == 0: x = -60 xOffs = -78 else: x = 60 xOffs = 78 isFirst = True testLives = 1 while True: playersWithLives = [ p for p in team.gameData['spawnOrder'] if p.exists() and p.gameData['lives'] >= testLives ] if len(playersWithLives) == 0: break for player in playersWithLives: player.gameData['icons'].append( Icon(player, position=(x, (40 if isFirst else 25)), scale=1.0 if isFirst else 0.5, nameMaxWidth=130 if isFirst else 75, nameScale=0.8 if isFirst else 1.0, flatness=0.0 if isFirst else 1.0, shadow=0.5 if isFirst else 1.0, showDeath=True if isFirst else False, showLives=False)) x += xOffs * (0.8 if isFirst else 0.56) isFirst = False testLives += 1 # non-solo mode else: for team in self.teams: if team.getID() == 0: x = -50 xOffs = -85 else: x = 50 xOffs = 85 for player in team.players: for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs def _getSpawnPoint(self, player): # in solo-mode, if there's an existing live player on the map, spawn at whichever # spot is farthest from them (keeps the action spread out) if self._soloMode: livingPlayer = None for team in self.teams: for player in team.players: if player.isAlive(): p = player.actor.node.position livingPlayer = player livingPlayerPos = p break if livingPlayer: playerPos = bs.Vector(*livingPlayerPos) points = [] for team in self.teams: startPos = bs.Vector( *self.getMap().getStartPosition(team.getID())) points.append([(startPos - playerPos).length(), startPos]) points.sort() return points[-1][1] else: return None else: return None def spawnPlayer(self, player): self.spawnPlayerSpaz(player, (0, 5, 0)) if not self._soloMode: bs.gameTimer(300, bs.Call(self._printLives, player)) # if we have any icons, update their state for icon in player.gameData['icons']: icon.handlePlayerSpawned() 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 _printLives(self, player): if not player.exists() or not player.isAlive(): return try: pos = player.actor.node.position except Exception, e: print 'EXC getting player pos in bsElim', e return bs.PopupText('x' + str(player.gameData['lives'] - 1), color=(1, 1, 0, 1), offset=(0, -0.8, 0), randomOffset=0.0, scale=1.8, position=pos).autoRetain()
def doHitAtPosition(self, pos, player): activity = self.getActivity() # ignore hits if the game is over or if we've already been hit if activity.hasEnded() or self._hit or not self._nodes: return 0 diff = (bs.Vector(*pos) - self._position) diff[ 1] = 0.0 # disregard y difference (our target point probably isnt exactly on the ground anyway) dist = diff.length() bullsEye = False points = 0 if dist <= self._r3 + self._rFudge: # inform our activity that we were hit self._hit = True self.getActivity().handleMessage(self.TargetHitMessage()) keys = {0: (1, 0, 0), 49: (1, 0, 0), 50: (1, 1, 1), 100: (0, 1, 0)} cDull = (0.3, 0.3, 0.3) if dist <= self._r1 + self._rFudge: bullsEye = True self._nodes[1].color = cDull self._nodes[2].color = cDull bs.animateArray(self._nodes[0], 'color', 3, keys, loop=True) popupScale = 1.8 popupColor = (1, 1, 0, 1) streak = player.gameData['streak'] points = 10 + min(20, streak * 2) bs.playSound(bs.getSound('bellHigh')) if streak > 0: bs.playSound( bs.getSound( 'orchestraHit4' if streak > 3 else 'orchestraHit3' if streak > 2 else 'orchestraHit2' if streak > 1 else 'orchestraHit')) elif dist <= self._r2 + self._rFudge: self._nodes[0].color = cDull self._nodes[2].color = cDull bs.animateArray(self._nodes[1], 'color', 3, keys, loop=True) popupScale = 1.25 popupColor = (1, 0.5, 0.2, 1) points = 4 bs.playSound(bs.getSound('bellMed')) else: self._nodes[0].color = cDull self._nodes[1].color = cDull bs.animateArray(self._nodes[2], 'color', 3, keys, loop=True) popupScale = 1.0 popupColor = (0.8, 0.3, 0.3, 1) points = 2 bs.playSound(bs.getSound('bellLow')) # award points/etc.. (technically should probably leave this up to the activity) popupStr = "+" + str(points) # if there's more than 1 player in the game, include their names and colors # so they know who got the hit if len(activity.players) > 1: popupColor = bs.getSafeColor(player.color, targetIntensity=0.75) popupStr += ' ' + player.getName() bs.PopupText(popupStr, position=self._position, color=popupColor, scale=popupScale).autoRetain() # give this player's team points and update the score-board player.getTeam().gameData['score'].add(points) activity._updateScoreBoard() # also give this individual player points (only applies in teams mode) activity.scoreSet.playerScored(player, points, showPoints=False, screenMessage=False) bs.animateArray(self._nodes[0], 'size', 1, { 800: self._nodes[0].size, 1000: [0.0] }) bs.animateArray(self._nodes[1], 'size', 1, { 850: self._nodes[1].size, 1050: [0.0] }) bs.animateArray(self._nodes[2], 'size', 1, { 900: self._nodes[2].size, 1100: [0.0] }) bs.gameTimer(1100, bs.Call(self.handleMessage, bs.DieMessage())) return bullsEye
class ZombieHorde(bs.TeamGameActivity): @classmethod def getName(cls): return 'Zombie Horde' @classmethod def getScoreInfo(cls): return { 'scoreName': 'score', 'scoreType': 'points', 'noneIsWinner': False, 'lowerIsBetter': False } @classmethod def getDescription(cls, sessionType): return 'Kill walkers, not players!' @classmethod def supportsSessionType(cls, sessionType): return True if (issubclass(sessionType, bs.TeamsSession) or issubclass( sessionType, bs.FreeForAllSession)) else False @classmethod def getSupportedMaps(cls, sessionType): return bs.getMapsSupportingPlayType("melee") @classmethod def getSettings(cls, sessionType): settings = [("Lives Per Player", { 'default': 1, 'minValue': 1, 'maxValue': 10, 'increment': 1 }), ("Max Zombies", { 'default': 10, 'minValue': 5, 'maxValue': 50, 'increment': 5 }), ("Time Limit", { 'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120), ('5 Minutes', 300), ('10 Minutes', 600), ('20 Minutes', 1200)], 'default': 120 }), ("Respawn Times", { 'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0), ('Long', 2.0), ('Longer', 4.0)], 'default': 1.0 }), ("Epic Mode", { 'default': False })] if issubclass(sessionType, bs.TeamsSession): settings.append(("Solo Mode", {'default': False})) settings.append(("Balance Total Lives", {'default': False})) return settings def __init__(self, settings): bs.TeamGameActivity.__init__(self, settings) if self.settings['Epic Mode']: self._isSlowMotion = True # show messages when players die since it's meaningful here self.announcePlayerDeaths = True try: self._soloMode = settings['Solo Mode'] except Exception: self._soloMode = False self._scoreBoard = bs.ScoreBoard() self.spazList = [] self.zombieQ = 0 def getInstanceDescription(self): return 'Kill walkers, not players!' if isinstance( self.getSession(), bs.TeamsSession) else 'Kill walkers, not players!' def getInstanceScoreBoardDescription(self): return 'Kill walkers, not players!' if isinstance( self.getSession(), bs.TeamsSession) else 'Kill walkers, not players!' def onTransitionIn(self): bs.TeamGameActivity.onTransitionIn( self, music='Epic' if self.settings['Epic Mode'] else 'Survival') self._startGameTime = bs.getGameTime() def onTeamJoin(self, team): team.gameData['score'] = 0 team.gameData['spawnOrder'] = [] self._updateScoreBoard() def onPlayerJoin(self, player): # no longer allowing mid-game joiners here... too easy to exploit if self.hasBegun(): player.gameData['lives'] = 0 player.gameData['icons'] = [] # make sure our team has survival seconds set if they're all dead # (otherwise blocked new ffa players would be considered 'still alive' in score tallying) #if self._getTotalTeamLives(player.getTeam()) == 0 and player.getTeam().gameData['survivalSeconds'] is None: # player.getTeam().gameData['survivalSeconds'] = 1000 bs.screenMessage(bs.Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', player.getName(full=True))]), color=(0, 1, 0)) return player.gameData['lives'] = self.settings['Lives Per Player'] if self._soloMode: player.gameData['icons'] = [] player.getTeam().gameData['spawnOrder'].append(player) self._updateSoloMode() else: # create our icon and spawn player.gameData['icons'] = [ Icon(player, position=(0, 50), scale=0.8) ] if player.gameData['lives'] > 0: self.spawnPlayer(player) # dont waste time doing this until begin if self.hasBegun(): self._updateIcons() def _updateSoloMode(self): # for both teams, find the first player on the spawn order list with lives remaining # and spawn them if they're not alive for team in self.teams: # prune dead players from the spawn order team.gameData['spawnOrder'] = [ p for p in team.gameData['spawnOrder'] if p.exists() ] for player in team.gameData['spawnOrder']: if player.gameData['lives'] > 0: if not player.isAlive(): self.spawnPlayer(player) break def _updateIcons(self): # in free-for-all mode, everyone is just lined up along the bottom if isinstance(self.getSession(), bs.FreeForAllSession): count = len(self.teams) xOffs = 85 x = xOffs * (count - 1) * -0.5 for i, team in enumerate(self.teams): if len(team.players) == 1: player = team.players[0] for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs # in teams mode we split up teams else: if self._soloMode: # first off, clear out all icons for player in self.players: player.gameData['icons'] = [] # now for each team, cycle through our available players adding icons for team in self.teams: if team.getID() == 0: x = -60 xOffs = -78 else: x = 60 xOffs = 78 isFirst = True testLives = 1 while True: playersWithLives = [ p for p in team.gameData['spawnOrder'] if p.exists() and p.gameData['lives'] >= testLives ] if len(playersWithLives) == 0: break for player in playersWithLives: player.gameData['icons'].append( Icon(player, position=(x, (40 if isFirst else 25)), scale=1.0 if isFirst else 0.5, nameMaxWidth=130 if isFirst else 75, nameScale=0.8 if isFirst else 1.0, flatness=0.0 if isFirst else 1.0, shadow=0.5 if isFirst else 1.0, showDeath=True if isFirst else False, showLives=False)) x += xOffs * (0.8 if isFirst else 0.56) isFirst = False testLives += 1 # non-solo mode else: for team in self.teams: if team.getID() == 0: x = -50 xOffs = -85 else: x = 50 xOffs = 85 for player in team.players: for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs def _getSpawnPoint(self, player): # in solo-mode, if there's an existing live player on the map, spawn at whichever # spot is farthest from them (keeps the action spread out) if self._soloMode: livingPlayer = None for team in self.teams: for player in team.players: if player.isAlive(): p = player.actor.node.position livingPlayer = player livingPlayerPos = p break if livingPlayer: playerPos = bs.Vector(*livingPlayerPos) points = [] for team in self.teams: startPos = bs.Vector( *self.getMap().getStartPosition(team.getID())) points.append([(startPos - playerPos).length(), startPos]) points.sort() return points[-1][1] else: return None else: return None def spawnPlayer(self, player): """This next line is the default spawn line. But we need to spawn our special guy""" #self.spawnPlayerSpaz(player,self._getSpawnPoint(player)) #position = self._getSpawnPoint(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 = 20 #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 = PlayerSpaz_Zom(color=player.color, highlight=player.highlight, character=player.character, player=player) player.setActor(spaz) #For some reason, I can't figure out how to get a list of all spaz. #Therefore, I am making the list here so I can get which spaz belongs #to the player supplied by HitMessage. self.spazList.append(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( enablePickUp=False ) #Unfortunately, I can't figure out how to prevent picking up other player but allow other pickup. 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) #Start code to spawn special guy: #End of code to spawn special guy if not self._soloMode: bs.gameTimer(300, bs.Call(self._printLives, player)) # if we have any icons, update their state for icon in player.gameData['icons']: icon.handlePlayerSpawned() def _printLives(self, player): if not player.exists() or not player.isAlive(): return try: pos = player.actor.node.position except Exception, e: print 'EXC getting player pos in bsElim', e return bs.PopupText('x' + str(player.gameData['lives'] - 1), color=(1, 1, 0, 1), offset=(0, -0.8, 0), randomOffset=0.0, scale=1.8, position=pos).autoRetain()
class FillErUp(bs.TeamGameActivity): @classmethod def getName(cls): return 'Fill \'Er Up' @classmethod def getScoreInfo(cls): return { 'scoreName': 'score', 'scoreType': 'points', 'noneIsWinner': False, 'lowerIsBetter': False } @classmethod def getDescription(cls, sessionType): return 'Fill your crate with boxes' @classmethod def supportsSessionType(cls, sessionType): return True if (issubclass(sessionType, bs.FreeForAllSession)) else False @classmethod def getSupportedMaps(cls, sessionType): return ['Doom Shroom', 'Courtyard'] @classmethod def getSettings(cls, sessionType): settings = [("Time Limit", { 'choices': [('30 Seconds', 30), ('1 Minute', 60), ('90 Seconds', 90), ('2 Minutes', 120), ('3 Minutes', 180), ('5 Minutes', 300)], 'default': 60 }), ("Respawn Times", { 'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0), ('Long', 2.0), ('Longer', 4.0)], 'default': 1.0 }), ("Curse Box Chance (lower = more chance)", { 'default': 10, 'minValue': 5, 'maxValue': 15, 'increment': 1 }), ("Curse Box Points", { 'default': -2, 'minValue': -10, 'maxValue': -1, 'increment': 1 }), ("Boxes Per Player", { 'default': 1.0, 'minValue': 0.5, 'maxValue': 3.0, 'increment': 0.5 }), ("Epic Mode", { 'default': False })] if issubclass(sessionType, bs.TeamsSession): settings.append(("Solo Mode", {'default': False})) settings.append(("Balance Total Lives", {'default': False})) return settings def __init__(self, settings): bs.TeamGameActivity.__init__(self, settings) if self.settings['Epic Mode']: self._isSlowMotion = True # show messages when players die since it's meaningful here self.announcePlayerDeaths = True try: self._soloMode = settings['Solo Mode'] except Exception: self._soloMode = False self._scoreBoard = bs.ScoreBoard() self.totBoxes = [] #Create a special powerup material for our boxes that allows pickup. self.fpowerupMaterial = bs.Material() # pass a powerup-touched message to applicable stuff pam = bs.Powerup.getFactory().powerupAcceptMaterial self.fpowerupMaterial.addActions( conditions=(("theyHaveMaterial", pam)), actions=(("modifyPartCollision", "collide", True), ("modifyPartCollision", "physical", False), ("message", "ourNode", "atConnect", bsPowerup._TouchedMessage()))) # we DO wanna be picked up #self.powerupMaterial.addActions( # conditions=("theyHaveMaterial",bs.getSharedObject('pickupMaterial')), # actions=( ("modifyPartCollision","collide",False))) self.fpowerupMaterial.addActions( conditions=("theyHaveMaterial", bs.getSharedObject('footingMaterial')), actions=(("impactSound", bs.Powerup.getFactory().dropSound, 0.5, 0.1))) #Create a material to prevent TNT box pickup self.noPickMat = bs.Material() self.noPickMat.addActions( conditions=("theyHaveMaterial", bs.getSharedObject('pickupMaterial')), actions=(("modifyPartCollision", "collide", False))) def getInstanceDescription(self): return 'Steal all the health boxes for yourself' if isinstance( self.getSession(), bs.TeamsSession) else 'Fill your crate with boxes' def getInstanceScoreBoardDescription(self): return 'Steal all the health boxes for yourself' if isinstance( self.getSession(), bs.TeamsSession) else 'Fill your crate with boxes' def onTransitionIn(self): bs.TeamGameActivity.onTransitionIn( self, music='Epic' if self.settings['Epic Mode'] else 'Survival') self._startGameTime = bs.getGameTime() def onTeamJoin(self, team): team.gameData['survivalSeconds'] = None team.gameData['spawnOrder'] = [] team.gameData['score'] = 0 def onPlayerJoin(self, player): #player.gameData['lives'] = 1 player.getTeam().gameData['score'] = 0 player.gameData['home'] = None player.gameData['crate'] = None self._updateScoreBoard() if self._soloMode: #player.gameData['icons'] = [] player.getTeam().gameData['spawnOrder'].append(player) self._updateSoloMode() else: # create our icon and spawn #player.gameData['icons'] = [Icon(player,position=(0,50),scale=0.8)] self.spawnPlayer(player) # dont waste time doing this until begin if self.hasBegun(): pass #self._updateIcons() def _updateSoloMode(self): # for both teams, find the first player on the spawn order list with lives remaining # and spawn them if they're not alive for team in self.teams: # prune dead players from the spawn order team.gameData['spawnOrder'] = [ p for p in team.gameData['spawnOrder'] if p.exists() ] for player in team.gameData['spawnOrder']: if player.gameData['lives'] > 0: if not player.isAlive(): self.spawnPlayer(player) break def _getSpawnPoint(self, player): # in solo-mode, if there's an existing live player on the map, spawn at whichever # spot is farthest from them (keeps the action spread out) if self._soloMode: livingPlayer = None for team in self.teams: for player in team.players: if player.isAlive(): p = player.actor.node.position livingPlayer = player livingPlayerPos = p break if livingPlayer: playerPos = bs.Vector(*livingPlayerPos) points = [] for team in self.teams: startPos = bs.Vector( *self.getMap().getStartPosition(team.getID())) points.append([(startPos - playerPos).length(), startPos]) points.sort() return points[-1][1] else: return None else: return None 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 _printLives(self, player): if not player.exists() or not player.isAlive(): return try: pos = player.actor.node.position except Exception, e: print 'EXC getting player pos in bsElim', e return bs.PopupText('x' + str(player.gameData['lives'] - 1), color=(1, 1, 0, 1), offset=(0, -0.8, 0), randomOffset=0.0, scale=1.8, position=pos).autoRetain()
class SafeZoneGame(bs.TeamGameActivity): @classmethod def getName(cls): return 'PUBG' @classmethod def getDescription(cls, sessionType): return 'Get To The Safe Zone!!' @classmethod def getScoreInfo(cls): return { 'scoreName': 'Survived', 'scoreType': 'seconds', 'noneIsWinner': True } @classmethod def supportsSessionType(cls, sessionType): return True if (issubclass(sessionType, bs.TeamsSession) or issubclass( sessionType, bs.FreeForAllSession)) else False @classmethod def getSupportedMaps(cls, sessionType): return ['Football Stadium', 'Hockey Stadium'] @classmethod def getSettings(cls, sessionType): return [("Time Limit", { 'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120), ('5 Minutes', 300), ('10 Minutes', 600), ('20 Minutes', 1200)], 'default': 0 }), ("Lives Per Player", { 'default': 2, 'minValue': 1, 'maxValue': 10, 'increment': 1 }), ("Respawn Times", { 'choices': [('Short', 0.5), ('Normal', 1.0)], 'default': 1.0 }), ("Epic Mode", { 'default': False }), ("Balance Total Lives", { 'default': True })] def __init__(self, settings): bs.TeamGameActivity.__init__(self, settings) if self.settings['Epic Mode']: self._isSlowMotion = True self._tickSound = bs.getSound('tick') self.announcePlayerDeaths = True def onTransitionIn(self): bs.TeamGameActivity.onTransitionIn( self, music='Epic' if self.settings['Epic Mode'] else 'Survival') self._startGameTime = bs.getGameTime() def onTeamJoin(self, team): team.gameData['survivalSeconds'] = None team.gameData['spawnOrder'] = [] def onPlayerJoin(self, player): if self.hasBegun(): player.gameData['lives'] = 0 player.gameData['icons'] = [] if self._getTotalTeamLives(player.getTeam( )) == 0 and player.getTeam().gameData['survivalSeconds'] is None: player.getTeam().gameData['survivalSeconds'] = 0 bs.screenMessage(bs.Lstr(resource='playerDelayedJoinText', subs=[('${PLAYER}', player.getName(full=True))]), color=(0, 1, 0)) return player.gameData['lives'] = self.settings['Lives Per Player'] player.gameData['icons'] = [Icon(player, position=(0, 50), scale=0.8)] if player.gameData['lives'] > 0: self.spawnPlayer(player) if self.hasBegun(): self._updateIcons() def showInfo(playGong=True): activity = bs.getActivity() name = activity.getInstanceDisplayString() bsUtils.ZoomText(name, maxWidth=800, lifespan=2500, jitter=2.0, position=(0, 0), flash=False, color=(0.93 * 1.25, 0.9 * 1.25, 1.0 * 1.25), trailColor=(0.15, 0.05, 1.0, 0.0)).autoRetain() if playGong: bs.gameTimer(200, bs.Call(bs.playSound, bs.getSound('gong'))) desc = activity.getInstanceDescription() if type(desc) in [unicode, str]: desc = [desc] # handle simple string case if type(desc[0]) not in [unicode, str]: raise Exception("Invalid format for instance description") subs = [] for i in range(len(desc) - 1): subs.append(('${ARG' + str(i + 1) + '}', str(desc[i + 1]))) translation = bs.Lstr(translate=('gameDescriptions', desc[0]), subs=subs) if ('Epic Mode' in activity.settings and activity.settings['Epic Mode']): translation = bs.Lstr(resource='epicDescriptionFilterText', subs=[('${DESCRIPTION}', translation)]) vr = bs.getEnvironment()['vrMode'] d = bs.newNode('text', attrs={ 'vAttach': 'center', 'hAttach': 'center', 'hAlign': 'center', 'color': (1, 1, 1, 1), 'shadow': 1.0 if vr else 0.5, 'flatness': 1.0 if vr else 0.5, 'vrDepth': -30, 'position': (0, 80), 'scale': 1.2, 'maxWidth': 700, 'text': translation }) c = bs.newNode("combine", owner=d, attrs={ 'input0': 1.0, 'input1': 1.0, 'input2': 1.0, 'size': 4 }) c.connectAttr('output', d, 'color') keys = {500: 0, 1000: 1.0, 2500: 1.0, 4000: 0.0} bsUtils.animate(c, "input3", keys) bs.gameTimer(4000, d.delete) def onBegin(self): bs.TeamGameActivity.onBegin(self) self.setupStandardTimeLimit(self.settings['Time Limit']) bs.gameTimer(5000, self.spawnZone) self._bots = bs.BotSet() bs.gameTimer(3000, bs.Call(self.addBot, 'left')) bs.gameTimer(3000, bs.Call(self.addBot, 'right')) if len(self.initialPlayerInfo) > 4: bs.gameTimer(5000, bs.Call(self.addBot, 'right')) bs.gameTimer(5000, bs.Call(self.addBot, 'left')) self._choseText = bs.newNode('text', attrs={ 'vAttach': 'bottom', 'hAttach': 'left', 'text': ' ', 'opacity': 1.0, 'maxWidth': 150, 'hAlign': 'center', 'vAlign': 'center', 'shadow': 1.0, 'flatness': 1.0, 'color': (1, 1, 1), 'scale': 1, 'position': (50, 155) }) if (isinstance(self.getSession(), bs.TeamsSession) and self.settings['Balance Total Lives'] and len(self.teams[0].players) > 0 and len(self.teams[1].players) > 0): if self._getTotalTeamLives( self.teams[0]) < self._getTotalTeamLives(self.teams[1]): lesserTeam = self.teams[0] greaterTeam = self.teams[1] else: lesserTeam = self.teams[1] greaterTeam = self.teams[0] addIndex = 0 while self._getTotalTeamLives( lesserTeam) < self._getTotalTeamLives(greaterTeam): lesserTeam.players[addIndex].gameData['lives'] += 1 addIndex = (addIndex + 1) % len(lesserTeam.players) self._updateIcons() bs.gameTimer(1000, self._update, repeat=True) def spawnZone(self): self.zonePos = (random.randrange(-10, 10), 0.0, random.randrange(-5, 5)) self.zone = bs.newNode('locator', attrs={ 'shape': 'circle', 'position': self.zonePos, 'color': (1, 1, 0), 'opacity': 0.5, 'drawBeauty': True, 'additive': False }) self.zoneLimit = bs.newNode('locator', attrs={ 'shape': 'circleOutline', 'position': self.zonePos, 'color': (1, 0.2, 0.2), 'opacity': 0.8, 'drawBeauty': True, 'additive': False }) bsUtils.animateArray( self.zone, 'size', 1, { 0: [0], 300: [self.getPlayersCount() * 0.85], 350: [self.getPlayersCount() * 1] }) bsUtils.animateArray( self.zoneLimit, 'size', 1, { 0: [0], 300: [self.getPlayersCount() * 1.2], 350: [self.getPlayersCount() * 1.1] }) bs.playSound(bs.getSound('laserReverse')) self.startTimer() self.moveZone() def deleteZone(self): scl = self.zone.size bsUtils.animateArray(self.zone, 'size', 1, {0: scl, 350: [0]}) def a(): self.zone.delete() self.zone = None self.zoneLimit.delete() self.zoneLimit = None bs.playSound(bs.getSound('shieldDown')) bs.gameTimer(1000, self.spawnZone) bs.gameTimer(350, a) def moveZone(self): if self.zonePos[0] > 0: x = random.randrange(0, 10) else: x = random.randrange(-10, 0) if self.zonePos[2] > 0: y = random.randrange(0, 5) else: y = random.randrange(-5, 0) newPos = (x, 0.0, y) bsUtils.animateArray(self.zone, 'position', 3, { 0: self.zone.position, 8000: newPos }) bsUtils.animateArray(self.zoneLimit, 'position', 3, { 0: self.zoneLimit.position, 8000: newPos }) def startTimer(self): count = self.getPlayersCount() self._timeRemaining = count if count > 2 else count * 2 self._timerX = bs.Timer(1000, bs.WeakCall(self.tick), repeat=True) tint = bs.getSharedObject('globals').tint # bsUtils.animateArray(bs.getSharedObject('globals'),'tint',3,{0:tint,self._timeRemaining*1500:(1.0,0.5,0.5),self._timeRemaining*1550:tint}) def stopTimer(self): self._time = None self._timerX = None def tick(self): self.check4Players() self._time = bs.NodeActor( bs.newNode('text', attrs={ 'vAttach': 'top', 'hAttach': 'center', 'text': 'Kill timer: ' + str(self._timeRemaining) + 's', 'opacity': 0.8, 'maxWidth': 100, 'hAlign': 'center', 'vAlign': 'center', 'shadow': 1.0, 'flatness': 1.0, 'color': (1, 1, 1), 'scale': 1.5, 'position': (0, -50) })) self._timeRemaining -= 1 bs.playSound(self._tickSound) def check4Players(self): if self._timeRemaining <= 0: self.stopTimer() bs.gameTimer(1500, self.deleteZone) for player in self.players: if not player.actor is None: if player.actor.isAlive(): p1 = player.actor.node.position p2 = self.zone.position diff = (bs.Vector(p1[0] - p2[0], 0.0, p1[2] - p2[2])) dist = (diff.length()) if dist > (self.getPlayersCount() * 0.7): player.actor.handleMessage(bs.DieMessage()) def getPlayersCount(self): count = 0 for player in self.players: if not player.actor is None: if player.actor.isAlive(): count += 1 return count def _getTotalTeamLives(self, team): return sum(player.gameData['lives'] for player in team.players) def onPlayerLeave(self, player): bs.TeamGameActivity.onPlayerLeave(self, player) player.gameData['icons'] = None bs.gameTimer(0, self._updateIcons) def _updateIcons(self): if isinstance(self.getSession(), bs.FreeForAllSession): count = len(self.teams) xOffs = 85 x = xOffs * (count - 1) * -0.5 for i, team in enumerate(self.teams): if len(team.players) == 1: player = team.players[0] for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs else: for team in self.teams: if team.getID() == 0: x = -50 xOffs = -85 else: x = 50 xOffs = 85 for player in team.players: for icon in player.gameData['icons']: icon.setPositionAndScale((x, 30), 0.7) icon.updateForLives() x += xOffs def spawnPlayer(self, player): spaz = self.spawnPlayerSpaz(player) spaz.connectControlsToPlayer(enablePunch=False, enableBomb=False, enablePickUp=False) bs.gameTimer(300, bs.Call(self._printLives, player)) for icon in player.gameData['icons']: icon.handlePlayerSpawned() def _printLives(self, player): if not player.exists() or not player.isAlive(): return try: pos = player.actor.node.position except Exception, e: print 'EXC getting player pos in bsElim', e return bs.PopupText('x' + str(player.gameData['lives'] - 1), color=(1, 1, 0, 1), offset=(0, -0.8, 0), randomOffset=0.0, scale=1.8, position=pos).autoRetain()