From b9d05b8cca338b0a746e12b0b707037904606603 Mon Sep 17 00:00:00 2001 From: abhinaypandey02 Date: Thu, 13 Jul 2017 13:20:03 +0530 Subject: [PATCH 1/4] allEquiped.py You get Gloves, Shield & Impact Bombs as you spawn! --- mods/allEquiped.py | 129 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 mods/allEquiped.py diff --git a/mods/allEquiped.py b/mods/allEquiped.py new file mode 100644 index 0000000..0709248 --- /dev/null +++ b/mods/allEquiped.py @@ -0,0 +1,129 @@ +import bs + +def bsGetAPIVersion(): + return 4 + +def bsGetGames(): + return [DeathMatchGame] + +class DeathMatchGame(bs.TeamGameActivity): + + @classmethod + def getName(cls): + return 'All Equiped' + + @classmethod + def getDescription(cls,sessionType): + return ('You get the maximum possible benfit!\nJust use It!') + + @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): + return [("KOs to Win Per Player",{'minValue':1,'default':5,'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})] + + + def __init__(self,settings): + bs.TeamGameActivity.__init__(self,settings) + if self.settings['Epic Mode']: self._isSlowMotion = True + + # print messages when players die since it matters here.. + self.announcePlayerDeaths = True + + self._scoreBoard = bs.ScoreBoard() + + def getInstanceDescription(self): + return ('Defeat ${ARG1} of your enemies.',self._scoreToWin) + + def getInstanceScoreBoardDescription(self): + return ('KO ${ARG1} enemies',self._scoreToWin) + + def onTransitionIn(self): + bs.TeamGameActivity.onTransitionIn(self, music='Epic' if self.settings['Epic Mode'] else 'GrandRomp') + + def onTeamJoin(self,team): + team.gameData['score'] = 0 + if self.hasBegun(): self._updateScoreBoard() + + def onBegin(self): + bs.TeamGameActivity.onBegin(self) + self.setupStandardTimeLimit(self.settings['Time Limit']) + if len(self.teams) > 0: + self._scoreToWin = self.settings['KOs to Win Per Player'] * max(1,max(len(t.players) for t in self.teams)) + else: self._scoreToWin = self.settings['KOs to Win Per Player'] + self._updateScoreBoard() + self._dingSound = bs.getSound('dingSmall') + + def spawnPlayer(self,player): + + spaz = self.spawnPlayerSpaz(player) + spaz.connectControlsToPlayer(enablePunch=True, + enableBomb=True, + enablePickUp=True) + + spaz.equipBoxingGloves() + spaz.equipShields() + spaz.bombType = 'impact' + + def handleMessage(self,m): + + if isinstance(m,bs.PlayerSpazDeathMessage): + bs.TeamGameActivity.handleMessage(self,m) # augment standard behavior + + player = m.spaz.getPlayer() + self.respawnPlayer(player) + + killer = m.killerPlayer + if killer is None: return + + # handle team-kills + if killer.getTeam() is player.getTeam(): + + # in free-for-all, killing yourself loses you a point + if isinstance(self.getSession(),bs.FreeForAllSession): + player.getTeam().gameData['score'] = max(0,player.getTeam().gameData['score']-1) + + # in teams-mode it gives a point to the other team + else: + bs.playSound(self._dingSound) + for team in self.teams: + if team is not killer.getTeam(): + team.gameData['score'] += 1 + + # killing someone on another team nets a kill + else: + killer.getTeam().gameData['score'] += 1 + bs.playSound(self._dingSound) + # in FFA show our score since its hard to find on the scoreboard + try: killer.actor.setScoreText(str(killer.getTeam().gameData['score'])+'/'+str(self._scoreToWin),color=killer.getTeam().color,flash=True) + except Exception: pass + + self._updateScoreBoard() + + # if someone has won, set a timer to end shortly + # (allows the dust to clear and draws to occur if deaths are close enough) + if any(team.gameData['score'] >= self._scoreToWin for team in self.teams): + bs.gameTimer(500,self.endGame) + + else: bs.TeamGameActivity.handleMessage(self,m) + + def _updateScoreBoard(self): + for team in self.teams: + self._scoreBoard.setTeamValue(team,team.gameData['score'],self._scoreToWin) + + def endGame(self): + results = bs.TeamGameResults() + for t in self.teams: results.setTeamScore(t,t.gameData['score']) + self.end(results=results) From bd6d2889239a148e10cb7621d87ee6df63ba624e Mon Sep 17 00:00:00 2001 From: abhinaypandey02 Date: Thu, 13 Jul 2017 13:21:58 +0530 Subject: [PATCH 2/4] Revert "allEquiped.py" --- mods/allEquiped.py | 129 --------------------------------------------- 1 file changed, 129 deletions(-) delete mode 100644 mods/allEquiped.py diff --git a/mods/allEquiped.py b/mods/allEquiped.py deleted file mode 100644 index 0709248..0000000 --- a/mods/allEquiped.py +++ /dev/null @@ -1,129 +0,0 @@ -import bs - -def bsGetAPIVersion(): - return 4 - -def bsGetGames(): - return [DeathMatchGame] - -class DeathMatchGame(bs.TeamGameActivity): - - @classmethod - def getName(cls): - return 'All Equiped' - - @classmethod - def getDescription(cls,sessionType): - return ('You get the maximum possible benfit!\nJust use It!') - - @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): - return [("KOs to Win Per Player",{'minValue':1,'default':5,'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})] - - - def __init__(self,settings): - bs.TeamGameActivity.__init__(self,settings) - if self.settings['Epic Mode']: self._isSlowMotion = True - - # print messages when players die since it matters here.. - self.announcePlayerDeaths = True - - self._scoreBoard = bs.ScoreBoard() - - def getInstanceDescription(self): - return ('Defeat ${ARG1} of your enemies.',self._scoreToWin) - - def getInstanceScoreBoardDescription(self): - return ('KO ${ARG1} enemies',self._scoreToWin) - - def onTransitionIn(self): - bs.TeamGameActivity.onTransitionIn(self, music='Epic' if self.settings['Epic Mode'] else 'GrandRomp') - - def onTeamJoin(self,team): - team.gameData['score'] = 0 - if self.hasBegun(): self._updateScoreBoard() - - def onBegin(self): - bs.TeamGameActivity.onBegin(self) - self.setupStandardTimeLimit(self.settings['Time Limit']) - if len(self.teams) > 0: - self._scoreToWin = self.settings['KOs to Win Per Player'] * max(1,max(len(t.players) for t in self.teams)) - else: self._scoreToWin = self.settings['KOs to Win Per Player'] - self._updateScoreBoard() - self._dingSound = bs.getSound('dingSmall') - - def spawnPlayer(self,player): - - spaz = self.spawnPlayerSpaz(player) - spaz.connectControlsToPlayer(enablePunch=True, - enableBomb=True, - enablePickUp=True) - - spaz.equipBoxingGloves() - spaz.equipShields() - spaz.bombType = 'impact' - - def handleMessage(self,m): - - if isinstance(m,bs.PlayerSpazDeathMessage): - bs.TeamGameActivity.handleMessage(self,m) # augment standard behavior - - player = m.spaz.getPlayer() - self.respawnPlayer(player) - - killer = m.killerPlayer - if killer is None: return - - # handle team-kills - if killer.getTeam() is player.getTeam(): - - # in free-for-all, killing yourself loses you a point - if isinstance(self.getSession(),bs.FreeForAllSession): - player.getTeam().gameData['score'] = max(0,player.getTeam().gameData['score']-1) - - # in teams-mode it gives a point to the other team - else: - bs.playSound(self._dingSound) - for team in self.teams: - if team is not killer.getTeam(): - team.gameData['score'] += 1 - - # killing someone on another team nets a kill - else: - killer.getTeam().gameData['score'] += 1 - bs.playSound(self._dingSound) - # in FFA show our score since its hard to find on the scoreboard - try: killer.actor.setScoreText(str(killer.getTeam().gameData['score'])+'/'+str(self._scoreToWin),color=killer.getTeam().color,flash=True) - except Exception: pass - - self._updateScoreBoard() - - # if someone has won, set a timer to end shortly - # (allows the dust to clear and draws to occur if deaths are close enough) - if any(team.gameData['score'] >= self._scoreToWin for team in self.teams): - bs.gameTimer(500,self.endGame) - - else: bs.TeamGameActivity.handleMessage(self,m) - - def _updateScoreBoard(self): - for team in self.teams: - self._scoreBoard.setTeamValue(team,team.gameData['score'],self._scoreToWin) - - def endGame(self): - results = bs.TeamGameResults() - for t in self.teams: results.setTeamScore(t,t.gameData['score']) - self.end(results=results) From 51f3f22070a2a3e449eb2f84a26459e8e70e4763 Mon Sep 17 00:00:00 2001 From: abhinaypandey02 Date: Thu, 14 Sep 2017 11:20:52 +0530 Subject: [PATCH 3/4] The Last Stand now for Teams! Earlier we were not able to play TheLastStand with Friends on Dedicated server but now you can play it with my mod! --- mods/bsLastStandWithFriends.json | 5 + mods/bsLastStandWithFriends.py | 521 +++++++++++++++++++++++++++++++ 2 files changed, 526 insertions(+) create mode 100644 mods/bsLastStandWithFriends.json create mode 100644 mods/bsLastStandWithFriends.py diff --git a/mods/bsLastStandWithFriends.json b/mods/bsLastStandWithFriends.json new file mode 100644 index 0000000..9b6aa98 --- /dev/null +++ b/mods/bsLastStandWithFriends.json @@ -0,0 +1,5 @@ +{ + "name": "Last Stand With Friends", + "author": "AbhinaY", + "category": "minigames" +} \ No newline at end of file diff --git a/mods/bsLastStandWithFriends.py b/mods/bsLastStandWithFriends.py new file mode 100644 index 0000000..191985f --- /dev/null +++ b/mods/bsLastStandWithFriends.py @@ -0,0 +1,521 @@ +import bs +import random + +def bsGetAPIVersion(): + # see bombsquadgame.com/apichanges + return 4 + +def bsGetGames(): + return [LastStandwithFriendsGame] + + +class Icon(bs.Actor): + + def __init__(self,player,position,scale,showLives=True,showDeath=True, + nameScale=1.0,nameMaxWidth=115.0,flatness=1.0,shadow=1.0): + bs.Actor.__init__(self) + + self._player = player + self._showLives = showLives + self._showDeath = showDeath + self._nameScale = nameScale + + self._outlineTex = bs.getTexture('characterIconMask') + + icon = player.getIcon() + self.node = bs.newNode('image', + owner=self, + attrs={'texture':icon['texture'], + 'tintTexture':icon['tintTexture'], + 'tintColor':icon['tintColor'], + 'vrDepth':400, + 'tint2Color':icon['tint2Color'], + 'maskTexture':self._outlineTex, + 'opacity':1.0, + 'absoluteScale':True, + 'attach':'bottomCenter'}) + self._nameText = bs.newNode('text', + owner=self.node, + attrs={'text':bs.Lstr(value=player.getName()), + 'color':bs.getSafeColor(player.getTeam().color), + 'hAlign':'center', + 'vAlign':'center', + 'vrDepth':410, + 'maxWidth':nameMaxWidth, + 'shadow':shadow, + 'flatness':flatness, + 'hAttach':'center', + 'vAttach':'bottom'}) + if self._showLives: + self._livesText = bs.newNode('text', + owner=self.node, + attrs={'text':'x0', + 'color':(1,1,0.5), + 'hAlign':'left', + 'vrDepth':430, + 'shadow':1.0, + 'flatness':1.0, + 'hAttach':'center', + 'vAttach':'bottom'}) + self.setPositionAndScale(position,scale) + + + + def setPositionAndScale(self,position,scale): + self.node.position = position + self.node.scale = [70.0*scale] + self._nameText.position = (position[0],position[1]+scale*52.0) + self._nameText.scale = 1.0*scale*self._nameScale + if self._showLives: + self._livesText.position = (position[0]+scale*10.0,position[1]-scale*43.0) + self._livesText.scale = 1.0*scale + + def updateForLives(self): + if self._player.exists(): + lives = self._player.gameData['lives'] + else: lives = 0 + if self._showLives: + if lives > 0: self._livesText.text = 'x'+str(lives-1) + else: self._livesText.text = '' + if lives == 0: + self._nameText.opacity = 0.2 + self.node.color = (0.7,0.3,0.3) + self.node.opacity = 0.2 + + def handlePlayerSpawned(self): + if not self.node.exists(): return + self.node.opacity = 1.0 + self.updateForLives() + + def handlePlayerDied(self): + if not self.node.exists(): return + if self._showDeath: + bs.animate(self.node,'opacity',{0:1.0,50:0.0,100:1.0,150:0.0,200:1.0,250:0.0, + 300:1.0,350:0.0,400:1.0,450:0.0,500:1.0,550:0.2}) + lives = self._player.gameData['lives'] + if lives == 0: bs.gameTimer(600,self.updateForLives) + + +class LastStandwithFriendsGame(bs.TeamGameActivity): + + @classmethod + def getName(cls): + return 'Last Stand with Friends!' + + @classmethod + def getScoreInfo(cls): + return {'scoreName':'Survived', + 'scoreType':'seconds', + 'noneIsWinner':True} + + @classmethod + def getDescription(cls,sessionType): + return 'Play The Last Stand with Friends now! by AbhinaY' + + @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 ['Rampage'] + + @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':True})] + + 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._spawnCenter = (0,5.5,-4.14) + self._tntSpawnPosition = (0,5.5,-6) + self._powerupCenter = (0,7,-4.14) + self._powerupSpread = (7,2) + + try: self._preset = self.settings['preset'] + except Exception: self._preset = 'default' + + self._excludePowerups = [] + + # for each bot type: spawn rate, increase, dIncrease + self._botSpawnTypes = {bs.BomberBot: [1.0, 0.0, 0.0], + bs.BomberBotPro: [0.0, 0.05, 0.001], + bs.BomberBotProShielded: [0.0, 0.02, 0.002], + bs.ToughGuyBot: [1.0, 0.0, 0.0], + bs.ToughGuyBotPro: [0.0, 0.05, 0.001], + bs.ToughGuyBotProShielded: [0.0, 0.02, 0.002], + bs.ChickBot: [0.3, 0.0, 0.0], + bs.ChickBotPro: [0.0, 0.05, 0.001], + bs.ChickBotProShielded: [0.0, 0.02, 0.002], + bs.NinjaBot: [0.3, 0.05, 0.0], + bs.MelBot: [0.1, 0.03, 0.001], + bs.PirateBot: [0.05, 0.02, 0.002] + } + + def getInstanceDescription(self): + return 'Play The Last Stand with Friends now! by AbhinaY!' if isinstance(self.getSession(),bs.TeamsSession) else 'Play The Last Stand with Friends now! by AbhinaY!' + + def getInstanceScoreBoardDescription(self): + return 'Play The Last Stand with Friends now! by AbhinaY!' if isinstance(self.getSession(),bs.TeamsSession) else 'Play The Last Stand with Friends now! by AbhinaY!' + + 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 _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 onPlayerLeave(self,player): + + bs.TeamGameActivity.onPlayerLeave(self,player) + + player.gameData['icons'] = None + + # remove us from spawn-order + if self._soloMode: + if player in player.getTeam().gameData['spawnOrder']: + player.getTeam().gameData['spawnOrder'].remove(player) + + # update icons in a moment since our team will be gone from the list then + bs.gameTimer(0, self._updateIcons) + + + def onBegin(self): + bs.TeamGameActivity.onBegin(self) + self.setupStandardTimeLimit(self.settings['Time Limit']) + self.setupStandardPowerupDrops() + bs.gameTimer(1,bs.WeakCall(self._startBotUpdates)) + + if self._soloMode: + self._vsText = bs.NodeActor(bs.newNode("text", + attrs={'position':(0,105), + 'hAttach':"center", + 'hAlign':'center', + 'maxWidth':200, + 'shadow':0.5, + 'vrDepth':390, + 'scale':0.6, + 'vAttach':"bottom", + 'color':(0.8,0.8,0.3,1.0), + 'text':bs.Lstr(resource='vsText')})) + + # if balance-team-lives is on, add lives to the smaller team until total lives match + 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() + + # we could check game-over conditions at explicit trigger points, + # but lets just do the simple thing and poll it... + bs.gameTimer(1000, self._update, repeat=True) + + self._bots = bs.BotSet() + + def _startBotUpdates(self): + self._botUpdateInterval = (3300 - 300*(len(self.players))) if self.settings['Epic Mode'] else (7800 - 300*(len(self.players))) + self._updateBots() + self._updateBots() + if len(self.players) > 2: self._updateBots() + if len(self.players) > 3: self._updateBots() + self._botUpdateTimer = bs.Timer(int(self._botUpdateInterval),bs.WeakCall(self._updateBots)) + + def _getTotalTeamLives(self,team): + return sum(player.gameData['lives'] for player in team.players) + + 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 _update(self): + + if self._soloMode: + # 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) + self._updateIcons() + break + + # if we're down to 1 or fewer living teams, start a timer to end the game + # (allows the dust to settle and draws to occur if deaths are close enough) + if len(self._getLivingTeams()) < 2: + self._roundEndTimer = bs.Timer(500,self.endGame) + def _updateBots(self): + self._botUpdateInterval = max(500,self._botUpdateInterval * 0.98) + self._botUpdateTimer = bs.Timer(int(self._botUpdateInterval),bs.WeakCall(self._updateBots)) + + botSpawnPoints = [[-5,5.5,-4.14],[0,5.5,-4.14],[5,5.5,-4.14]] + dists = [0,0,0] + playerPts = [] + for player in self.players: + try: + if player.isAlive(): + playerPts.append(player.actor.node.position) + except Exception,e: + print 'EXC in _updateBots',e + for i in range(3): + for p in playerPts: dists[i] += abs(p[0]-botSpawnPoints[i][0]) + # little random variation + dists[i] += random.random() * 5.0 + if dists[0] > dists[1] and dists[0] > dists[2]: + pt = botSpawnPoints[0] + elif dists[1] > dists[2]: + pt = botSpawnPoints[1] + else: pt = botSpawnPoints[2] + + pt = (pt[0]+3.0*(random.random()-0.5),pt[1],2.0*(random.random()-0.5)+pt[2]) + + # normalize our bot type total and find a random number within that + total = 0.0 + for t in self._botSpawnTypes.items(): + total += t[1][0] + r = random.random()*total + + # now go back through and see where this value falls + total = 0 + for t in self._botSpawnTypes.items(): + total += t[1][0] + if r <= total: + spazType = t[0] + break + + spawnTime = 1000 + self._bots.spawnBot(spazType,pos=pt,spawnTime=spawnTime) + + # after every spawn we adjust our ratios slightly to get more difficult.. + for t in self._botSpawnTypes.items(): + t[1][0] += t[1][1] # increase spawn rate + t[1][1] += t[1][2] # increase spawn rate increase rate + + def _getLivingTeams(self): + return [team for team in self.teams if len(team.players) > 0 and any(player.gameData['lives'] > 0 for player in team.players)] + + def endGame(self): + if self.hasEnded(): return + results = bs.TeamGameResults() + self._vsText = None # kill our 'vs' if its there + for team in self.teams: + results.setTeamScore(team, team.gameData['survivalSeconds']) + self.end(results=results) + From 4edeba4681423b1d4c0642e0fb5dde7514abe61c Mon Sep 17 00:00:00 2001 From: abhinaypandey02 Date: Thu, 14 Sep 2017 11:23:31 +0530 Subject: [PATCH 4/4] A new mod All Equipped Now Start all equipped with gloves+shield+impact bombs! --- mods/allEquipped.json | 5 ++ mods/allEquipped.py | 131 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 mods/allEquipped.json create mode 100644 mods/allEquipped.py diff --git a/mods/allEquipped.json b/mods/allEquipped.json new file mode 100644 index 0000000..60fa982 --- /dev/null +++ b/mods/allEquipped.json @@ -0,0 +1,5 @@ +{ + "name": "All Equiped", + "author": "AbhinaY", + "category": "minigames" +} diff --git a/mods/allEquipped.py b/mods/allEquipped.py new file mode 100644 index 0000000..8242823 --- /dev/null +++ b/mods/allEquipped.py @@ -0,0 +1,131 @@ +import bs + +def bsGetAPIVersion(): + return 4 + +def bsGetGames(): + return [DeathMatchGame] + +class DeathMatchGame(bs.TeamGameActivity): + + @classmethod + def getName(cls): + return 'All Equipped' + + @classmethod + def getDescription(cls,sessionType): + return ('No bombs!\n' + 'Knock out your enemies using your gloved hands!\n' + 'Powerups not included.') + + @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): + return [("KOs to Win Per Player",{'minValue':1,'default':5,'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})] + + + def __init__(self,settings): + bs.TeamGameActivity.__init__(self,settings) + if self.settings['Epic Mode']: self._isSlowMotion = True + + # print messages when players die since it matters here.. + self.announcePlayerDeaths = True + + self._scoreBoard = bs.ScoreBoard() + + def getInstanceDescription(self): + return ('Defeat ${ARG1} of your enemies.',self._scoreToWin) + + def getInstanceScoreBoardDescription(self): + return ('KO ${ARG1} enemies',self._scoreToWin) + + def onTransitionIn(self): + bs.TeamGameActivity.onTransitionIn(self, music='Epic' if self.settings['Epic Mode'] else 'GrandRomp') + + def onTeamJoin(self,team): + team.gameData['score'] = 0 + if self.hasBegun(): self._updateScoreBoard() + + def onBegin(self): + bs.TeamGameActivity.onBegin(self) + self.setupStandardTimeLimit(self.settings['Time Limit']) + if len(self.teams) > 0: + self._scoreToWin = self.settings['KOs to Win Per Player'] * max(1,max(len(t.players) for t in self.teams)) + else: self._scoreToWin = self.settings['KOs to Win Per Player'] + self._updateScoreBoard() + self._dingSound = bs.getSound('dingSmall') + + def spawnPlayer(self,player): + + spaz = self.spawnPlayerSpaz(player) + spaz.connectControlsToPlayer(enablePunch=True, + enableBomb=True, + enablePickUp=True) + + spaz.equipBoxingGloves() + spaz.equipShields() + spaz.bombType = 'impact' + + def handleMessage(self,m): + + if isinstance(m,bs.PlayerSpazDeathMessage): + bs.TeamGameActivity.handleMessage(self,m) # augment standard behavior + + player = m.spaz.getPlayer() + self.respawnPlayer(player) + + killer = m.killerPlayer + if killer is None: return + + # handle team-kills + if killer.getTeam() is player.getTeam(): + + # in free-for-all, killing yourself loses you a point + if isinstance(self.getSession(),bs.FreeForAllSession): + player.getTeam().gameData['score'] = max(0,player.getTeam().gameData['score']-1) + + # in teams-mode it gives a point to the other team + else: + bs.playSound(self._dingSound) + for team in self.teams: + if team is not killer.getTeam(): + team.gameData['score'] += 1 + + # killing someone on another team nets a kill + else: + killer.getTeam().gameData['score'] += 1 + bs.playSound(self._dingSound) + # in FFA show our score since its hard to find on the scoreboard + try: killer.actor.setScoreText(str(killer.getTeam().gameData['score'])+'/'+str(self._scoreToWin),color=killer.getTeam().color,flash=True) + except Exception: pass + + self._updateScoreBoard() + + # if someone has won, set a timer to end shortly + # (allows the dust to clear and draws to occur if deaths are close enough) + if any(team.gameData['score'] >= self._scoreToWin for team in self.teams): + bs.gameTimer(500,self.endGame) + + else: bs.TeamGameActivity.handleMessage(self,m) + + def _updateScoreBoard(self): + for team in self.teams: + self._scoreBoard.setTeamValue(team,team.gameData['score'],self._scoreToWin) + + def endGame(self): + results = bs.TeamGameResults() + for t in self.teams: results.setTeamScore(t,t.gameData['score']) + self.end(results=results)