def _dropBombCluster(self): if False: bs.newNode('locator', attrs={'position': (8, 6, -5.5)}) bs.newNode('locator', attrs={'position': (8, 6, -2.3)}) bs.newNode('locator', attrs={'position': (-7.3, 6, -5.5)}) bs.newNode('locator', attrs={'position': (-7.3, 6, -2.3)}) delay = 0 for i in range(random.randrange(1, 3)): types = ["normal", "ice", "sticky", "impact"] magic = random.choice(types) bt = magic pos = (-7.3 + 15.3 * random.random(), 11, -5.5 + 2.1 * random.random()) vel = ((-5.0 + random.random() * 30.0) * (-1.0 if pos[0] > 0 else 1.0), -4.0, 0) bs.gameTimer(delay, bs.Call(self._dropBomb, pos, vel, bt)) delay += 100 self._setMeteorTimer()
def _dropPowerups(self, standardPoints=False, powerupType=None): """ Generic powerup drop """ if standardPoints: pts = self.getMap().powerupSpawnPoints for i, pt in enumerate(pts): bs.gameTimer(1000 + i * 500, bs.Call(self._dropPowerup, i, powerupType)) else: pt = (self._powerupCenter[0] + random.uniform( -1.0 * self._powerupSpread[0], 1.0 * self._powerupSpread[0]), self._powerupCenter[1], self._powerupCenter[2] + random.uniform( -self._powerupSpread[1], self._powerupSpread[1])) # drop one random one somewhere.. bs.Powerup( position=pt, powerupType=bs.Powerup.getFactory().getRandomPowerupType( excludeTypes=self._excludePowerups)).autoRetain()
def spawnPlayerSpaz(self, player, position=(0, 0, 0), angle=None): posList = ((0, 5, 0), (9, 11, 0), (0, 12, 0), (-11, 11, 0)) try: pos = posList[player.gameData['lastPoint']] except: pos = (0, 5, 0) position = (pos[0] + random.random() * 2 - 1, pos[1], pos[2]) name = player.getName() color = player.color highlight = player.highlight lightColor = bsUtils.getNormalizedColor(color) displayColor = bs.getSafeColor(color, targetIntensity=0.75) spaz = bs.PlayerSpaz(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 if self._raceStarted: 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) if not self._raceStarted: player.gameData['lastPoint'] = 0 bs.gameTimer(250, bs.Call(self.checkPt, player)) return spaz
def newInit(self, color=(1, 1, 1), highlight=(0.5, 0.5, 0.5), character="Spaz", player=None, powerupsExpire=True): oldInit(self, color=color, highlight=highlight, character=character, player=player, powerupsExpire=powerupsExpire) eff = bs.getConfig()["effectsMod"]["effect"] self.lastPos = self.node.position def doCirle(): if self.isAlive(): p = self.node.position p2 = self.lastPos diff = (bs.Vector(p[0]-p2[0],0.0,p[2]-p2[2])) dist = (diff.length()) if dist > 0.2: c = bs.getConfig()["effectsMod"]["color"] r = bs.newNode('locator',attrs={'shape':'circle','position':p,'color':self.node.color if c else (5,5,5),'opacity':1,'drawBeauty':False,'additive':False,'size':[0.2]}) bsUtils.animateArray(r,'size',1,{0:[0.2],2500:[0.2],3000:[0]}) bs.gameTimer(3000,r.delete) self.lastPos = self.node.position def doFire(): if self.isAlive(): bs.emitBGDynamics(position=self.node.position,velocity=(0,10,0),count=100,spread=0.3,scale=3,chunkType='sweat'); def getPos(): return self.node.position def doEffects(): if eff == 'path': bs.gameTimer(200,bs.Call(doCirle),repeat=True) elif eff == 'fire': self._color = bs.Timer(100,bs.WeakCall(doFire),repeat=True) bs.gameTimer(200,doEffects) seff = bs.getConfig()["effectsMod"]["spawnEffect"] if seff == "none": pass elif seff == 'show':doRing(self,seff) elif seff == 'xplode':doRing(self,seff) else: delay = 0 for i in range(5): bs.gameTimer(delay,bs.Call(doRing,self,seff)) delay += 300
def _dropBombCluster(self): # random note: code like this is a handy way to plot out extents and debug things if False: bs.newNode('locator', attrs={'position': (8, 6, -5.5)}) bs.newNode('locator', attrs={'position': (8, 6, -2.3)}) bs.newNode('locator', attrs={'position': (-7.3, 6, -5.5)}) bs.newNode('locator', attrs={'position': (-7.3, 6, -2.3)}) # drop several bombs in series.. delay = 0 for i in range(random.randrange(1, 3)): # drop them somewhere within our bounds with velocity pointing toward the opposite side pos = (-7.3 + 15.3 * random.random(), 11, -5.5 + 2.1 * random.random()) vel = ((-5.0 + random.random() * 30.0) * (-1.0 if pos[0] > 0 else 1.0), -4.0, 0) bs.gameTimer(delay, bs.Call(self._dropBomb, pos, vel)) delay += 100 self._setMeteorTimer()
def _handleHitOwnFlag(self, team, val): # keep track of when each player is touching their own flag so we can award points when returned srcNode = bs.getCollisionInfo('sourceNode') try: player = srcNode.getDelegate().getPlayer() except Exception: player = None if player is not None and player.exists(): if val: player.gameData['touchingOwnFlag'] += 1 else: player.gameData['touchingOwnFlag'] -= 1 # if return-time is zero, just kill it immediately.. otherwise keep track of touches and count down if float(self.settings['Flag Touch Return Time']) <= 0.0: if not team.gameData['homeFlagAtBase'] and team.gameData[ 'flag']._heldCount == 0: # use a node message to kill the flag instead of just killing our team's. # (avoids redundantly killing new flags if multiple body parts generate callbacks in one step) node = bs.getCollisionInfo("opposingNode") if node is not None and node.exists(): self._awardPlayersTouchingOwnFlag(team) node.handleMessage(bs.DieMessage()) # takes a non-zero amount of time to return else: if val: team.gameData['flagReturnTouches'] += 1 if team.gameData['flagReturnTouches'] == 1: team.gameData['touchReturnTimer'] = bs.Timer( 100, call=bs.Call(self._touchReturnUpdate, team), repeat=True) team.gameData['touchReturnTimerTicking'] = None else: team.gameData['flagReturnTouches'] -= 1 if team.gameData['flagReturnTouches'] == 0: team.gameData['touchReturnTimer'] = None team.gameData['touchReturnTimerTicking'] = None if team.gameData['flagReturnTouches'] < 0: bs.printError( 'CTF: flagReturnTouches < 0; this shouldn\'t happen.')
def __init__(self,position = (0,2,0),owner = None,prank=0,prefix = 'smoothy',prefixColor = (1,1,1),prefixAnim = {0:(1,1,1),500:(0.5,0.5,0.5)},prefixAnimate = False,particles = False): self.position = position self.owner = owner #particles if particles: self.timer = bs.Timer(10,bs.Call(a),repeat = True) #prefix n = bs.newNode('math', owner=self.owner, attrs={'input1': (0, 1.5, 0), 'operation': 'add'}) self.owner.connectAttr('position', n, 'input2') self._Text = bs.newNode('text', owner=self.owner, attrs={'text':" #"+str(prank), #prefix text 'inWorld':True, 'shadow':1.2, 'flatness':1.0, 'color':prefixColor, 'scale':0.0, 'hAlign':'center'}) n.connectAttr('output', self._Text, 'position') bs.animate(self._Text, 'scale', {0: 0.0, 1000: 0.01}) #smooth prefix spawn #animate prefix if prefixAnimate: bsUtils.animateArray(self._Text, 'color',3, prefixAnim,True) #animate prefix color
def onBegin(self): bs.TeamGameActivity.onBegin(self) self._excludePowerups = ['speed'] self.setupStandardTimeLimit(self.settings['Time Limit']) self.setupStandardPowerupDrops() self._baseRegionMaterials = {} for team in self.teams: m = self._baseRegionMaterials[team.getID()] = bs.Material() m.addActions(conditions=('theyHaveMaterial',bs.getSharedObject('playerMaterial')), actions=(('modifyPartCollision','collide',True), ('modifyPartCollision','physical',False), ('call','atConnect',bs.Call(self._handleBaseCollide,team)))) # create a score region and flag for each team for team in self.teams: team.gameData['basePos'] = self.getMap().getFlagPosition(team.getID()) bs.newNode('light', attrs={'position': team.gameData['basePos'], 'intensity':0.6, 'heightAttenuated':False, 'volumeIntensityScale':0.1, 'radius':0.1, 'color': team.color}) self.projectFlagStand(team.gameData['basePos']) team.gameData['flag'] = bs.Flag(touchable=False, position=team.gameData['basePos'], color=team.color) p = team.gameData['basePos'] region = bs.newNode('region', owner=team.gameData['flag'].node, attrs={'position':(p[0],p[1]+0.75,p[2]), 'scale': (0.5,0.5,0.5), 'type': 'sphere', 'materials':[self._baseRegionMaterials[team.getID()]]})
def spawnDummy(self, player, myClone): #playerNode = bs.getActivity()._getPlayerNode(player) spz = self.scoreSet._players[player.getName()].getSpaz() t = bs.getGameTime() if t - player.gameData[ 'cloneSpawnTime'] > self.minLife or player.gameData[ 'cloneSpawnTime'] == 0: if not spz is None: pos = spz.node.position player.gameData['lastSpawn'] = pos else: pos = player.gameData['lastSpawn'] else: player.gameData['lastSpawn'] = player.gameData['safeSpawn'] pos = player.gameData['safeSpawn'] bs.gameTimer( 1000, bs.Call(self._bots.spawnCBot, player, myClone, pos=pos, spawnTime=1000, onSpawnCall=self.setSpawnTime))
def onBegin(self): bs.TeamGameActivity.onBegin(self) # bs.gameTimer(t,self._decrementMeteorTime,repeat=True) # kick off the first wave in a few seconds t = self.settings[JungleHunterLanguage.spawnDelay] * 1000 if self.settings['Epic Mode']: t /= 4 # bs.gameTimer(t,self._setMeteorTimer) self._timer = bs.OnScreenTimer() self._timer.start() self._updateScoreBoard() bs.gameTimer(4000, self._checkEndGame) # 4秒之后检测一波 self._bots = bs.BotSet() bs.gameTimer(1000, bs.Call(self._bots.spawnBot, NinjaPrey, pos=self.getMap().getFFAStartPosition(self.players), spawnTime=100), repeat=False) bs.gameTimer(t, bs.WeakCall(self.botsGener), repeat=True)
def checkStar(val): self._powersGiven = True if spaz.isAlive(): setattr(spaz.node, 'invincible', val) if val and spaz.isAlive(): if spaz.node.frozen: spaz.node.handleMessage(bs.ThawMessage()) bs.playSound( bs.Powerup.getFactory().superStarSound, position=spaz.node.position) spaz.colorSet = bs.Timer(100, bs.Call(colorChanger), repeat=True) if spaz._cursed: spaz._cursed = False # remove cursed material factory = spaz.getFactory() for attr in [ 'materials', 'rollerMaterials' ]: materials = getattr(spaz.node, attr) if factory.curseMaterial in materials: setattr( spaz.node, attr, tuple(m for m in materials if m != factory.curseMaterial)) spaz.node.curseDeathTime = 0 if not val and spaz.isAlive(): spaz.node.color = spaz.getPlayer().color spaz.node.highlight = spaz.getPlayer( ).highlight spaz.colorSet = None bs.playSound( bs.Powerup.getFactory().powerdownSound, position=spaz.node.position) spaz.node.billboardOpacity = 0.0
def __init__(self, pos=(0, 4, 0), vel=(0, 0, 0)): bs.Actor.__init__(self) self.speedMul = 1.0 self.hp = 100 self.x, self.y, self.z = pos # Our 'base' self.touchedSound = bs.getSound('error') # DON'T TOUCH THE CHILD!!!!!1!!!1!!11!! self.tex1 = bs.getTexture('landMine') self.tex2 = bs.getTexture('landMineLit') self.node = bs.newNode('prop', delegate=self, attrs={ 'position': pos, 'velocity': vel, 'body': 'sphere', 'model': bs.getModel('bomb'), 'shadowSize': 0.3, 'colorTexture': self.tex1, 'materials': [bs.getSharedObject('objectMaterial')], 'extraAcceleration': (0, 20, 0) }) bs.gameTimer(1000, bs.Call(self._update), True) self.textureSequence = \ bs.newNode('textureSequence', owner=self.node, attrs={ 'rate':100, 'inputTextures':(self.tex1, self.tex2)})
def doRaceTimer(self): self.raceTimer = RaceTimer() self.raceTimer.onFinish = bs.WeakCall(self.timerCallback) bs.gameTimer(1000, bs.Call(self.raceTimer.start))
def atomicBlast(pos = (0,0,0)): x, y, z = pos _blast((x,y,z), 1.5) bs.gameTimer(50, call = bs.Call(_blast, (x,y+1,z), 1)) bs.gameTimer(200, call = bs.Call(_blast, (x,y+2,z), 4))
def onTransitionIn(self): bs.Activity.onTransitionIn(self) global gDidInitialTransition random.seed(123) try: import install except ImportError: pass else: # check needed methods if hasattr(bs, "get_setting") and hasattr(install, "update_modpack"): if bs.get_setting("auto-update", False): install.update_modpack(True) self._logoNode = None self._customLogoTexName = None self._wordActors = [] env = bs.getEnvironment() vrMode = bs.getEnvironment()['vrMode'] if not bs.getEnvironment().get('toolbarTest', True): self.myName = bs.NodeActor( bs.newNode( 'text', attrs={ 'vAttach': 'bottom', 'hAlign': 'center', 'color': (1, 1, 1, 1) if vrMode else (1, 1, 1, 1), 'flatness': 1.0, 'shadow': 1.0 if vrMode else 0.5, 'scale': (0.65 if (env['interfaceType'] == 'small' or vrMode) else 0.7), # FIXME need a node attr for this 'position': (0, 25), 'vrDepth': -10, 'text': u'\xa9 2019 Eric Froemling' })) fullScreen = bsInternal._getSetting("TV Border") if env['interfaceType'] != 'small' or env['vrMode']: if fullScreen: position = (0, -10) else: position = (-425, 10) else: if fullScreen: position = (0, -10) else: position = (-425, 35) self.moderName = bs.NodeActor( bs.newNode( 'text', attrs={ 'vAttach': 'bottom', 'hAlign': 'center', 'color': (0.8, 0.8, 0.8, 0.8) if vrMode else (0.8, 0.8, 0.8, 0.8), 'flatness': 1.0, 'shadow': 1.0 if vrMode else 0.5, 'scale': (0.55 if (env['interfaceType'] == 'small' or vrMode) else 0.7), # FIXME need a node attr for this 'position': position, 'vrDepth': -10, 'text': u'\xa9 ModPack is created by Daniil Rakhov' })) self._hostIsNavigatingText = bs.NodeActor( bs.newNode('text', attrs={ 'text': bs.Lstr(resource='hostIsNavigatingMenusText', subs=[ ('${HOST}', bsInternal._getAccountDisplayString()) ]), 'clientOnly': True, 'position': (0, -200), 'flatness': 1.0, 'hAlign': 'center' })) if not gDidInitialTransition: if hasattr(self, 'myName'): bs.animate(self.myName.node, 'opacity', {2300: 0, 3000: 1.0}) if hasattr(self, 'moderName'): bs.animate(self.moderName.node, 'opacity', { 2300: 0, 3300: 1.0 }) # FIXME - shouldn't be doing things conditionally based on whether # the host is vr mode or not (clients may not be or vice versa) # - any differences need to happen at the engine level # so everyone sees things in their own optimal way vrMode = env['vrMode'] interfaceType = env['interfaceType'] # in cases where we're doing lots of dev work lets # always show the build number forceShowBuildNumber = True if not bs.getEnvironment().get('toolbarTest', True): text = "BROODYs WORLD" try: from multiversion import get_version except ImportError: path = os.path.join(env["userScriptsDirectory"], "about_modpack.json") if os.path.exists(path): try: data = json.load(open(path)) except Exception: pass else: text += " v." + str( data.get("version", { "v": "???" }).get("v")) else: text += " v." + str(get_version()) if env['debugBuild'] or env['testBuild']: if env['debugBuild']: text += " [debug]" else: text += " [test]" if forceShowBuildNumber: text = "based on " + str(env['version']) + "\n" + text self.version = bs.NodeActor( bs.newNode('text', attrs={ 'vAttach': 'bottom', 'hAttach': 'right', 'hAlign': 'right', 'flatness': 1.0, 'vrDepth': -10, 'shadow': 0.5, 'color': (0.5, 0.6, 0.5, 0.7), 'scale': 0.7 if (interfaceType == 'small' or vrMode) else 0.85, 'position': (-260, 10) if vrMode else (-10, 30), 'text': text })) if not gDidInitialTransition: bs.animate(self.version.node, 'opacity', { 0: 0, 3000: 0, 4000: 1.0 }) # throw in beta info.. self.betaInfo = self.betaInfo2 = None if env['testBuild'] and not env['kioskMode']: self.betaInfo = bs.NodeActor( bs.newNode('text', attrs={ 'vAttach': 'center', 'hAlign': 'center', 'color': (1, 1, 1, 1), 'shadow': 0.5, 'flatness': 0.5, 'scale': 1, 'vrDepth': -60, 'position': (230, 125) if env['kioskMode'] else (230, 35), 'text': bs.Lstr(resource="testBuildText") })) if not gDidInitialTransition: bs.animate(self.betaInfo.node, 'opacity', {1300: 0, 1800: 1.0}) model = bs.getModel('thePadLevel') treesModel = bs.getModel('trees') bottomModel = bs.getModel('thePadLevelBottom') borModel = bs.getCollideModel('thePadLevelCollide') testColorTexture = bs.getTexture('thePadLevelColor') treesTexture = bs.getTexture('treesColor') bgTex = bs.getTexture('alwaysLandBGColor') bgModel = bs.getModel('alwaysLandBG') vrBottomFillModel = bs.getModel('thePadVRFillBottom') vrTopFillModel = bs.getModel('thePadVRFillTop') bsGlobals = bs.getSharedObject('globals') bsGlobals.cameraMode = 'rotate' bsGlobals.tint = (1.1, 1.1, 1.0) self.bottom = bs.NodeActor( bs.newNode('terrain', attrs={ 'model': bottomModel, 'lighting': False, 'reflection': 'soft', 'reflectionScale': [0.45], 'colorTexture': testColorTexture })) self.node = bs.newNode('terrain', delegate=self, attrs={ 'collideModel': borModel, 'model': model, 'colorTexture': testColorTexture, 'materials': [bs.getSharedObject('footingMaterial')] }) self.vrBottomFill = bs.NodeActor( bs.newNode('terrain', attrs={ 'model': vrBottomFillModel, 'lighting': False, 'vrOnly': True, 'colorTexture': testColorTexture })) self.vrTopFill = bs.NodeActor( bs.newNode('terrain', attrs={ 'model': vrTopFillModel, 'vrOnly': True, 'lighting': False, 'colorTexture': bgTex })) self.terrain = bs.NodeActor( bs.newNode('terrain', attrs={ 'model': model, 'colorTexture': testColorTexture, 'reflection': 'soft', 'reflectionScale': [0.3] })) self.trees = bs.NodeActor( bs.newNode('terrain', attrs={ 'model': treesModel, 'lighting': False, 'reflection': 'char', 'reflectionScale': [0.1], 'colorTexture': treesTexture })) self.bg = bs.NodeActor( bs.newNode('terrain', attrs={ 'model': bgModel, 'color': (0.92, 0.91, 0.9), 'lighting': False, 'background': True, 'colorTexture': bgTex })) textOffsetV = 0 self._ts = 0.86 self._language = None self._updateTimer = bs.Timer(2000, bs.Call(self._update, False), repeat=True) self._update(True) bs.gameTimer(55000, bs.Call(self.fireworks)) bsUtils.animateArray(bs.getSharedObject("globals"), "tint", 3, {0:(1.1,1.1,1.0), 7500:(1.25, 1.21, 1.075), 30000:(1.25, 1.21, 1.075), \ 57500:(1.1, 0.86, 0.74), 67500:(1.1, 0.86, 0.74), \ 90000:(0, 0.27, 0.51), 120000:(0, 0.27, 0.51), 142500:(1.3, 1.06, 1.02), \ 157500:(1.3, 1.06, 1.02), 180000:(1.3, 1.25, 1.2), 195500:(1.3, 1.25, 1.2), \ 220000:(1.1,1.1,1.0)}) bsInternal._addCleanFrameCallback(bs.WeakCall(self._startPreloads)) random.seed() class News(object): def __init__(self, activity): self._valid = True self._messageDuration = 10000 self._messageSpacing = 2000 self._text = None self._activity = weakref.ref(activity) self._fetchTimer = bs.Timer(1000, bs.WeakCall(self._tryFetchingNews), repeat=True) self._tryFetchingNews() def _tryFetchingNews(self): if bsInternal._getAccountState() == 'SIGNED_IN': self._fetchNews() self._fetchTimer = None def _fetchNews(self): try: launchCount = bs.getConfig()['launchCount'] except Exception: launchCount = None global gLastNewsFetchTime gLastNewsFetchTime = time.time() # UPDATE - we now just pull news from MRVs news = bsInternal._getAccountMiscReadVal('n', None) if news is not None: self._gotNews(news) def _changePhrase(self): global gLastNewsFetchTime if time.time() - gLastNewsFetchTime > 100.0: self._fetchNews() self._text = None else: if self._text is not None: if len(self._phrases) == 0: for p in self._usedPhrases: self._phrases.insert(0, p) val = self._phrases.pop() if val == '__ACH__': vr = bs.getEnvironment()['vrMode'] bsUtils.Text( bs.Lstr(resource='nextAchievementsText'), color=(1,1,1,1) if vr else (0.95,0.9,1,0.4), hostOnly=True, maxWidth=200, position=(-300, -35), hAlign='right', transition='fadeIn', scale=0.9 if vr else 0.7, flatness=1.0 if vr else 0.6, shadow=1.0 if vr else 0.5, hAttach="center", vAttach="top", transitionDelay=1000, transitionOutDelay=self._messageDuration)\ .autoRetain() import bsAchievement achs = [ a for a in bsAchievement.gAchievements if not a.isComplete() ] if len(achs) > 0: a = achs.pop( random.randrange(min(4, len(achs)))) a.createDisplay(-180, -35, 1000, outDelay=self._messageDuration, style='news') if len(achs) > 0: a = achs.pop( random.randrange(min(8, len(achs)))) a.createDisplay(180, -35, 1250, outDelay=self._messageDuration, style='news') else: s = self._messageSpacing keys = { s: 0, s + 1000: 1.0, s + self._messageDuration - 1000: 1.0, s + self._messageDuration: 0.0 } bs.animate(self._text.node, "opacity", dict([[k, v] for k, v in keys.items()])) self._text.node.text = val def _gotNews(self, news): # run this stuff in the context of our activity since we need # to make nodes and stuff.. should fix the serverGet call so it activity = self._activity() if activity is None or activity.isFinalized(): return with bs.Context(activity): self._phrases = [] # show upcoming achievements in non-vr versions # (currently too hard to read in vr) self._usedPhrases = ( ['__ACH__'] if not bs.getEnvironment()['vrMode'] else []) + [s for s in news.split('<br>\n') if s != ''] self._phraseChangeTimer = bs.Timer( self._messageDuration + self._messageSpacing, bs.WeakCall(self._changePhrase), repeat=True) sc = 1.2 if ( bs.getEnvironment()['interfaceType'] == 'small' or bs.getEnvironment()['vrMode']) else 0.8 self._text = bs.NodeActor( bs.newNode( 'text', attrs={ 'vAttach': 'top', 'hAttach': 'center', 'hAlign': 'center', 'vrDepth': -20, 'shadow': 1.0 if bs.getEnvironment()['vrMode'] else 0.4, 'flatness': 0.8, 'vAlign': 'top', 'color': ((1, 1, 1, 1) if bs.getEnvironment()['vrMode'] else (0.7, 0.65, 0.75, 1.0)), 'scale': sc, 'maxWidth': 900.0 / sc, 'position': (0, -10) })) self._changePhrase() if not env['kioskMode'] and not env.get('toolbarTest', True): self._news = News(self) # bring up the last place we were, or start at the main menu otherwise with bs.Context('UI'): try: mainWindow = bsUI.gMainWindow except Exception: mainWindow = None # when coming back from a kiosk-mode game, jump to # the kiosk start screen.. if bsUtils.gRunningKioskModeGame: if bs.getEnvironment()['kioskMode']: bsUI.uiGlobals['mainMenuWindow'] = \ bsUI.KioskWindow().getRootWidget() # ..or in normal cases go back to the main menu else: if mainWindow == 'Gather': bsUI.uiGlobals['mainMenuWindow'] = \ bsUI.GatherWindow(transition=None).getRootWidget() elif mainWindow == 'Watch': bsUI.uiGlobals['mainMenuWindow'] = \ bsUI.WatchWindow(transition=None).getRootWidget() elif mainWindow == 'Team Game Select': bsUI.uiGlobals['mainMenuWindow'] = \ bsUI.TeamsWindow(sessionType=bs.TeamsSession, transition=None).getRootWidget() elif mainWindow == 'Free-for-All Game Select': bsUI.uiGlobals['mainMenuWindow'] = \ bsUI.TeamsWindow(sessionType=bs.FreeForAllSession, transition=None).getRootWidget() elif mainWindow == 'Coop Select': bsUI.uiGlobals['mainMenuWindow'] = \ bsUI.CoopWindow(transition=None).getRootWidget() else: bsUI.uiGlobals['mainMenuWindow'] = \ bsUI.MainMenuWindow(transition=None).getRootWidget() # attempt to show any pending offers immediately. # If that doesn't work, try again in a few seconds # (we may not have heard back from the server) # ..if that doesn't work they'll just have to wait # until the next opportunity. if not bsUI._showOffer(): def tryAgain(): if not bsUI._showOffer(): # try one last time.. bs.realTimer(2000, bsUI._showOffer) bs.realTimer(2000, tryAgain) gDidInitialTransition = True
def _update(self, forceUpdate=False): if hasattr(self, 'moderName') and not forceUpdate: if not bs.get_setting("in_menu_author_name", True): bs.animate(self.moderName.node, 'opacity', { 0: self.moderName.node.opacity, 500: 0.0 }) else: if self.moderName.node.opacity < 1.0: bs.animate(self.moderName.node, 'opacity', { 0: self.moderName.node.opacity, 500: 1.0 }) bs.gameTimer(500, bs.Call(self.change_text_position)) else: self.change_text_position() l = bs.getLanguage() if l != self._language: self._language = l env = bs.getEnvironment() y = 20 gScale = 1.1 self._wordActors = [] baseDelay = 1000 delay = baseDelay delayInc = 20 baseX = -170 x = baseX - 20 spacing = 55 * gScale yExtra = 0 if env['kioskMode'] else 0 x1 = x delay1 = delay for shadow in (True, False): x = x1 delay = delay1 self._makeWord('H', x - 15, y - 23, scale=1.3 * gScale, delay=delay - 500, vrDepthOffset=3, shadow=True) self._makeWord('a', x + 38, y - 23, scale=1.3 * gScale, delay=delay - 400, vrDepthOffset=3, shadow=True) self._makeWord('r', x + 88, y - 23, scale=1.3 * gScale, delay=delay - 300, vrDepthOffset=3, shadow=True) self._makeWord('d', x + 138, y - 23, scale=1.3 * gScale, delay=delay - 200, vrDepthOffset=3, shadow=True) self._makeWord('C', x + 188, y - 23, scale=1.3 * gScale, delay=delay - 100, vrDepthOffset=3, shadow=True) self._makeWord('o', x + 238, y - 23, scale=1.3 * gScale, delay=delay, vrDepthOffset=3, shadow=True) self._makeWord('r', x + 288, y - 23, scale=1.3 * gScale, delay=delay + 100, vrDepthOffset=3, shadow=True) self._makeWord('e', x + 338, y - 23, scale=1.3 * gScale, delay=delay + 200, vrDepthOffset=3, shadow=True) self._makeWord('◉', x + 162, y - 98, scale=3 * gScale, delay=delay + 600, vrDepthOffset=3, shadow=True)
def _setReady(self, ready): import bsInternal profileName = self.profileNames[self.profileIndex] # handle '_edit' as a special case if profileName == '_edit' and ready: import bsUI with bs.Context('UI'): bsUI.PlayerProfilesWindow(inMainMenu=False) # give their input-device UI ownership too # (prevent someone else from snatching it in crowded games) bsInternal._setUIInputDevice(self._player.getInputDevice()) return if not ready: self._player.assignInputCall( 'leftPress', bs.Call(self.handleMessage, ChangeMessage('team', -1))) self._player.assignInputCall( 'rightPress', bs.Call(self.handleMessage, ChangeMessage('team', 1))) self._player.assignInputCall( 'bombPress', bs.Call(self.handleMessage, ChangeMessage('character', 1))) self._player.assignInputCall( 'upPress', bs.Call(self.handleMessage, ChangeMessage('profileIndex', -1))) self._player.assignInputCall( 'downPress', bs.Call(self.handleMessage, ChangeMessage('profileIndex', 1))) self._player.assignInputCall( ('jumpPress', 'pickUpPress', 'punchPress'), bs.Call(self.handleMessage, ChangeMessage('ready', 1))) self.ready = False self._updateText() self._player.setName('untitled', real=False) else: self._player.assignInputCall( ('leftPress', 'rightPress', 'upPress', 'downPress', 'jumpPress', 'bombPress', 'pickUpPress'), self._doNothing) self._player.assignInputCall( ('jumpPress', 'bombPress', 'pickUpPress', 'punchPress'), bs.Call(self.handleMessage, ChangeMessage('ready', 0))) # store the last profile picked by this input for reuse inputDevice = self._player.getInputDevice() name = inputDevice.getName() uniqueID = inputDevice.getUniqueIdentifier() try: deviceProfiles = bs.getConfig()['Default Player Profiles'] except Exception: deviceProfiles = bs.getConfig()['Default Player Profiles'] = {} # make an exception if we have no custom profiles and are set # to random; in that case we'll want to start picking up custom # profiles if/when one is made so keep our setting cleared haveCustomProfiles = (True if [ p for p in self.profiles if p not in ('_random', '_edit', '__account__') ] else False) if profileName == '_random' and not haveCustomProfiles: try: del (deviceProfiles[name + ' ' + uniqueID]) except Exception: pass else: deviceProfiles[name + ' ' + uniqueID] = profileName bs.writeConfig() # set this player's short and full name self._player.setName(self._getName(), self._getName(full=True), real=True) self.ready = True self._updateText() # inform the session that this player is ready bs.getSession().handleMessage(PlayerReadyMessage(self))
def restart(): bsInternal._chatMessage('Rebooting Server... Thanks For Playing!') bsInternal._chatMessage('You Can Also Join Again Using IP & Port') text = 'IP: %s Port: %s' % (ip, port) bsInternal._chatMessage(text) bs.realTimer(3000, bs.Call(bs.quit))
def __init__(self, vrOverlayCenterOffset=None): """ Instantiate a map. """ import bsInternal bs.Actor.__init__(self) self.preloadData = self.preload(onDemand=True) def text(): #bySoby t = bs.newNode('text', attrs={ 'text': u'Message 1', 'scale': 1, 'maxWidth': 0, 'position': (35, 615), 'shadow': 0.5, 'flatness': 1.2, 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'hAlign': 'right', 'vAttach': 'bottom' }) bs.animate(t, 'opacity', {0: 0.0, 500: 1.0, 6500: 1.0, 7000: 0.0}) bs.gameTimer(7000, t.delete) ## t = bs.newNode('text', attrs={ 'text': u'Message 2', 'scale': 1.3, 'maxWidth': 0, 'position': (0, 138), 'shadow': 0.5, 'flatness': 0.0, 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'hAlign': 'center', 'vAttach': 'bottom' }) bs.animate(t, 'opacity', { 8500: 0.0, 9000: 1.0, 14500: 1.0, 15000: 0.0 }) bs.gameTimer(15000, t.delete) #bySoby t = bs.newNode('text', attrs={ 'text': u'Message 3', 'scale': 1, 'maxWidth': 0, 'position': (0, 138), 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'shadow': 0.5, 'flatness': 1.0, 'hAlign': 'center', 'vAttach': 'bottom' }) bs.animate(t, 'opacity', { 17500: 0.0, 18500: 1.0, 24500: 1.0, 25000: 0.0 }) bs.gameTimer(25000, t.delete) #bySoby..............................Dont Edit This t = bs.newNode( 'text', attrs={ 'text': u'\ue04c/em To Use Emotes , /perk To Get Special Abilities\ue04c', 'scale': 1.2, 'maxWidth': 0, 'position': (0, 139), 'shadow': 0.5, 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'flatness': 0.0, 'hAlign': 'center', 'vAttach': 'bottom' }) bs.animate(t, 'opacity', { 27000: 0.0, 27500: 1.0, 33500: 1.0, 34000: 0.0 }) bs.gameTimer(34000, t.delete) t = bs.newNode('text', attrs={ 'text': u'Message 4', 'scale': 0.8, 'maxWidth': 0, 'position': (0, 138), 'shadow': 0.5, 'flatness': 1.0, 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'hAlign': 'center', 'vAttach': 'bottom' }) bs.animate(t, 'opacity', { 36000: 0.0, 36500: 1.0, 42500: 1.0, 43000: 0.0 }) bs.gameTimer(43000, t.delete) ## t = bs.newNode('text', attrs={ 'text': u'\ue047| Happy Bombsquading|\ue047', 'scale': 1, 'maxWidth': 0, 'position': (0, 138), 'shadow': 0.5, 'flatness': 1.0, 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'hAlign': 'center', 'vAttach': 'bottom' }) bs.animate(t, 'opacity', { 45000: 0.0, 45500: 1.0, 50500: 1.0, 51000: 0.0 }) bs.gameTimer(51000, t.delete) bs.gameTimer(3500, bs.Call(text)) bs.gameTimer(56000, bs.Call(text), repeat=True) def stats_shower(): global num global scr p_list = [] n_list = [] s_list = [] s_itr = iter(s_list) for i in bsInternal._getForegroundHostSession().players: Name = i.getName() n_list.append(Name) pb_id = i.get_account_id() p_list.append(pb_id) f = open( bs.getEnvironment()['systemScriptsDirectory'] + "/pStats.json", "r") stats = json.loads(f.read()) for p in range(int(len(p_list))): if p_list[p] in stats: player_stat = stats[str(p_list[p])] s_msg = str(n_list[p].encode( "utf-8")) + "'s Stats This Season:\n" + "Rank " + str( player_stat["rank"]) + ", " + str( player_stat["scores"]) + " scores, " + str( player_stat["kills"]) + " kills, " + str( player_stat["deaths"]) + " deaths." s_list.append(s_msg) else: s_msg = str((n_list[p].encode("utf-8"))) + "Is not Registered" s_list.append(s_msg) t = bs.newNode('text', attrs={ 'text': s_list[num], 'scale': 1.0, 'maxWidth': 0, 'position': (250, 650), 'shadow': 0.5, 'flatness': 1.0, 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'hAlign': 'center', 'vAttach': 'bottom' }) bs.animate(t, 'opacity', {0: 0.0, 500: 1.0, 6500: 1.0, 7000: 0.0}) bs.gameTimer(7000, t.delete) p = bs.newNode('text', attrs={ 'text': cmdsetg.credit, 'scale': 1.0, 'maxWidth': 0, 'position': (-100, 50), 'shadow': 0.5, 'flatness': 1.0, 'color': ((0 + random.random() * 1.0), (0 + random.random() * 1.0), (0 + random.random() * 1.0)), 'hAlign': 'center', 'vAttach': 'bottom' }) bs.animate(p, 'opacity', {0: 0.0, 500: 1.0, 6500: 1.0, 7000: 0.0}) bs.gameTimer(7000, p.delete) if num < len(s_list): num += 1 if num == len(s_list): num *= 0 if num > len(s_list): num *= 0 bs.gameTimer(3000, bs.Call(stats_shower)) bs.gameTimer(10000, bs.Call(stats_shower), repeat=True) # set some defaults bsGlobals = bs.getSharedObject('globals') # area-of-interest bounds aoiBounds = self.getDefBoundBox("areaOfInterestBounds") if aoiBounds is None: print 'WARNING: no "aoiBounds" found for map:', self.getName() aoiBounds = (-1, -1, -1, 1, 1, 1) bsGlobals.areaOfInterestBounds = aoiBounds # map bounds mapBounds = self.getDefBoundBox("levelBounds") if mapBounds is None: print 'WARNING: no "levelBounds" found for map:', self.getName() mapBounds = (-30, -10, -30, 30, 100, 30) bsInternal._setMapBounds(mapBounds) # shadow ranges try: bsGlobals.shadowRange = [ self.defs.points[v][1] for v in [ 'shadowLowerBottom', 'shadowLowerTop', 'shadowUpperBottom', 'shadowUpperTop' ] ] except Exception: pass # in vr, set a fixed point in space for the overlay to show up at.. # by default we use the bounds center but allow the map to override it center = ((aoiBounds[0] + aoiBounds[3]) * 0.5, (aoiBounds[1] + aoiBounds[4]) * 0.5, (aoiBounds[2] + aoiBounds[5]) * 0.5) if vrOverlayCenterOffset is not None: center = (center[0] + vrOverlayCenterOffset[0], center[1] + vrOverlayCenterOffset[1], center[2] + vrOverlayCenterOffset[2]) bsGlobals.vrOverlayCenter = center bsGlobals.vrOverlayCenterEnabled = True self.spawnPoints = self.getDefPoints("spawn") or [(0, 0, 0, 0, 0, 0)] self.ffaSpawnPoints = self.getDefPoints("ffaSpawn") or [(0, 0, 0, 0, 0, 0)] self.spawnByFlagPoints = (self.getDefPoints("spawnByFlag") or [(0, 0, 0, 0, 0, 0)]) self.flagPoints = self.getDefPoints("flag") or [(0, 0, 0)] self.flagPoints = [p[:3] for p in self.flagPoints] # just want points self.flagPointDefault = self.getDefPoint("flagDefault") or (0, 1, 0) self.powerupSpawnPoints = self.getDefPoints("powerupSpawn") or [(0, 0, 0)] self.powerupSpawnPoints = \ [p[:3] for p in self.powerupSpawnPoints] # just want points self.tntPoints = self.getDefPoints("tnt") or [] self.tntPoints = [p[:3] for p in self.tntPoints] # just want points self.isHockey = False self.isFlying = False self._nextFFAStartIndex = 0
def __init__(self, color=(1, 1, 1), highlight=(0.5, 0.5, 0.5), character="Spaz", player=None, powerupsExpire=True): """ Create a spaz for the provided bs.Player. Note: this does not wire up any controls; you must call connectControlsToPlayer() to do so. """ # convert None to an empty player-ref if player is None: player = bs.Player(None) Spaz.__init__(self, color=color, highlight=highlight, character=character, sourcePlayer=player, startInvincible=True, powerupsExpire=powerupsExpire) self.lastPlayerAttackedBy = None # FIXME - should use empty player ref self.lastAttackedTime = 0 self.lastAttackedType = None self.heldCount = 0 self.lastPlayerHeldBy = None # FIXME - should use empty player ref here self._player = player profile = self._player.get_account_id() ### if profile in mbal.AdminList: ##u'\u2B50' # ADMIN PermissionEffect(owner=self.node, prefix=bs.getSpecialChar('crown'), posPrefix=(0, 2.2, 0), particles=True, isAdmin=True, prefixAnimate=True) if profile in mbal.Fighter1stList: #1st fighter PermissionEffect(owner=self.node, prefix=bs.getSpecialChar('trophy4'), posPrefix=(-0.3, 1.8, 0), particles=True) if profile in mbal.Fighter2nd3rd: #2. 3. fighter PermissionEffect(owner=self.node, prefix=bs.getSpecialChar('trophy3'), posPrefix=(-0.3, 1.8, 0)) if profile in mbal.FighterTop15List: #top15 fighter PermissionEffect(owner=self.node, prefix=bs.getSpecialChar('trophy2'), posPrefix=(-0.3, 1.8, 0)) if profile in mbal.Scorer1stList: #1st scorer PermissionEffect(owner=self.node, prefix=bs.getSpecialChar('trophy4'), posPrefix=(0.3, 1.8, 0), particles=True) if profile in mbal.Scorer2nd3rdList: #2. 3. scorer PermissionEffect(owner=self.node, prefix=bs.getSpecialChar('trophy3'), posPrefix=(0.3, 1.8, 0)) if profile in mbal.ScorerTop15List: #top15 scorer PermissionEffect(owner=self.node, prefix=bs.getSpecialChar('trophy2'), posPrefix=(0.3, 1.8, 0)) if profile in mbal.autoKickList: #kick him every time clID = self._player.getInputDevice().getClientID() kickName = self._player.getName() bs.screenMessage(kickName + ' in blacklist' + ' auto kicking in 3 seconds', color=(0, 0.9, 0)) def kickIt(): bsInternal._disconnectClient(clID) bs.gameTimer(4000, bs.Call(kickIt)) # grab the node for this player and wire it to follow our spaz (so players' controllers know where to draw their guides, etc) if player.exists(): playerNode = bs.getActivity()._getPlayerNode(player) self.node.connectAttr('torsoPosition', playerNode, 'position')
def __init__(self, position=(0, 1, 0), owner=None, prefix='MythB', posPrefix=(0, 1.8, 0), isAdmin=False, prefixColor=(1, 1, 1), prefixAnimate=False, particles=False): self.position = position self.owner = owner def a(): self.emit() if particles: self.timer = bs.Timer(10, bs.Call(a), repeat=True) m = bs.newNode('math', owner=self.owner, attrs={ 'input1': posPrefix, 'operation': 'add' }) self.owner.connectAttr('position', m, 'input2') self._Text = bs.newNode('text', owner=self.owner, attrs={ 'text': prefix, 'inWorld': True, 'shadow': 1.2, 'flatness': 1.0, 'color': prefixColor, 'scale': 0.0, 'vAlign': 'center', 'hAlign': 'center' }) m.connectAttr('output', self._Text, 'position') if not isAdmin: bs.animate(self._Text, 'scale', { 0: 0.0, 1000: 0.01 }) #smooth spawn #animate if prefixAnimate: bs.animate(self._Text, 'opacity', { 0: 0.0, 500: 1.0, 1000: 1.0, 1500: 0 }, loop=True) if isAdmin: self._AdminHereText = bs.newNode('text', owner=self.owner, attrs={ 'text': u'\ue043 Admin Is Playing !', 'shadow': 1.2, 'flatness': 1.0, 'position': (0, 10), 'color': (0.5, 0.5, 0.5), 'scale': 0.8, 'vAttach': 'bottom', 'hAlign': 'center' }) #FIXME we dont wanna two "admin here text" if two admins are playing same time bs.animate(self._Text, 'scale', {0: 0.0, 1000: 0.0165}) self._Adminlight = bs.newNode( 'light', owner=self.owner, attrs={ 'intensity': 0.5, #'volumeIntensityScale':0.1, 'heightAttenuated': False, 'radius': 0.1, 'color': self.owner.color }) self.owner.connectAttr('position', self._Adminlight, 'position')
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
def submitKill(self, showPoints=True): self._multiKillCount += 1 if self._multiKillCount == 1: score = 0 name = None elif self._multiKillCount == 2: score = 20 name = bs.Lstr(resource='twoKillText') color = (0.1, 1.0, 0.0, 1) scale = 1.0 delay = 0 sound = self._scoreSet()._orchestraHitSound elif self._multiKillCount == 3: score = 40 name = bs.Lstr(resource='threeKillText') color = (1.0, 0.7, 0.0, 1) scale = 1.1 delay = 300 sound = self._scoreSet()._orchestraHitSound2 elif self._multiKillCount == 4: score = 60 name = bs.Lstr(resource='fourKillText') color = (1.0, 1.0, 0.0, 1) scale = 1.2 delay = 600 sound = self._scoreSet()._orchestraHitSound3 elif self._multiKillCount == 5: score = 80 name = bs.Lstr(resource='fiveKillText') color = (1.0, 0.5, 0.0, 1) scale = 1.3 delay = 900 sound = self._scoreSet()._orchestraHitSound4 else: score = 100 name = bs.Lstr(resource='multiKillText', subs=[('${COUNT}', str(self._multiKillCount))]) color = (1.0, 0.5, 0.0, 1) scale = 1.3 delay = 1000 sound = self._scoreSet()._orchestraHitSound4 def _apply(name, score, showPoints, color, scale, sound): # only award this if they're still alive and we can get their pos try: ourPos = self.getSpaz().node.position except Exception: return # jitter position a bit since these often come in clusters ourPos = (ourPos[0] + (random.random() - 0.5) * 2.0, ourPos[1] + (random.random() - 0.5) * 2.0, ourPos[2] + (random.random() - 0.5) * 2.0) activity = self.getActivity() if activity is not None: bsUtils.PopupText( # (('+'+str(score)+' ') if showPoints else '')+name, bs.Lstr(value=( ('+' + str(score) + ' ') if showPoints else '') + '${N}', subs=[('${N}', name)]), color=color, scale=scale, position=ourPos).autoRetain() bs.playSound(sound) self.score += score self.accumScore += score # inform a running game of the score if score != 0 and activity is not None: activity.handleMessage(PlayerScoredMessage(score=score)) if name is not None: bs.gameTimer( 300 + delay, bs.Call(_apply, name, score, showPoints, color, scale, sound)) # keep the tally rollin'... # set a timer for a bit in the future self._multiKillTimer = bs.Timer(1000, self._endMultiKill)
def __init__(self, position=(0, 1, 0), powerupType='tripleBombs', expire=True): bs.Actor.__init__(self) factory = self.getFactory() if gSettingsEnabled: settings = bs.get_settings() else: settings = {} self.powerupType = powerupType self._powersGiven = False if powerupType == 'tripleBombs': tex = factory.texBomb name = 'TripleBombs' elif powerupType == 'multiBombs': tex = factory.texMultiBombs name = 'MultiBombs' elif powerupType == 'punch': tex = factory.texPunch name = 'Gloves' elif powerupType == 'speedPunch': tex = factory.texSpeedPunch name = 'Gloves 2.0' elif powerupType == 'fireworkBombs': tex = factory.texFireworkBomb name = 'FireWorks' elif powerupType == 'killLaKillBombs': tex = factory.texKillLaKillBomb name = 'KillAll' elif powerupType == 'poisonBombs': tex = factory.texPoisonBomb name = 'PoisonBomb' elif powerupType == 'pandoraBox': tex = factory.texPandoraBox name = 'PandoraBox' elif powerupType == 'yellowShield': tex = factory.texYellowShield name = 'YellowShield' elif powerupType == 'jumpingBombs': tex = factory.texJumpingBomb name = 'JumpingBomb' elif powerupType == 'tpBombs': tex = factory.texTpBombs name = 'TPBomb' elif powerupType == 'iceBombs': tex = factory.texIceBombs name = 'IcyBombs' elif powerupType == 'impactBombs': tex = factory.texImpactBombs name = 'ImpactBombs' elif powerupType == 'landMines': tex = factory.texLandMines name = 'LandMines' elif powerupType == 'stickyBombs': tex = factory.texStickyBombs name = 'StickyBombs' elif powerupType == 'shield': tex = factory.texShield name = 'Bubble' elif powerupType == 'health': tex = factory.texHealth name = 'Health' elif powerupType == 'curse': tex = factory.texCurse name = 'Pls Touch Me' elif powerupType == 'unbreakable': tex = factory.texUnb name = 'Unbreakable' elif powerupType == 'dirtBombs': tex = factory.texDirt name = 'DirtBomb' elif powerupType == 'speed': tex = factory.texSpeed # new powerups begin elif powerupType == 'alan': tex = factory.texAlan name = 'Boss' elif powerupType == 'rdm': tex = factory.texRDM name = 'RandomBomb' elif powerupType == 'randomCharacter': tex = factory.RandomCharacter name = 'Random Char' elif powerupType == 'troll': tex = factory.Troll name = 'FunPack' elif powerupType == 'mj': tex = factory.texmj name = 'MJ' elif powerupType == 'impactMess': tex = factory.teximpactMess name = 'ImpactMess' elif powerupType == 'Motion': tex = factory.texMotion name = 'Motion' elif powerupType == 'invisibility': tex = factory.texInvisibility name = 'Invisibile' elif powerupType == 'hijump': tex = factory.texHiJump name = 'Hi-Jump' elif powerupType == 'ballon': tex = factory.texBallon name = 'Ballon' elif powerupType == 'BlockPowerup': tex = factory.texBlock name = 'Block' elif powerupType == 'iceImpact': tex = factory.texiceImpact name = 'IceImpact' elif powerupType == 'goldenBomb': tex = factory.texGoldenBomb name = 'BlastyBomb' elif powerupType == 'tbomb': tex = factory.textbomb name = 'TBomb' elif powerupType == 'gluebomb': tex = factory.texgluebomb name = 'Broken Glue' elif powerupType == 'weedbomb': tex = factory.texweedbomb name = 'WeedBomb' elif powerupType == 'bot': tex = factory.texBot name = 'Buddy Bot' elif powerupType == 'celebrate': tex = factory.texcelebrate name = 'Celebrate' elif powerupType == 'FloatingMine': tex = factory.texFloatingMine name = 'LandMines' elif powerupType == 'TouchMe': tex = factory.texTouchMe name = 'TouchMe' elif powerupType == 'radius': tex = factory.texRadius name = 'Radius' elif powerupType == 'sleep': tex = factory.texSleep name = 'Sleepy' elif powerupType == 'night': tex = factory.texNight name = 'NiteNite' elif powerupType == 'spazBomb': tex = factory.texSpazBomb name = 'SpazBomb' elif powerupType == 'curseBomb': tex = factory.texcurseBomb name = 'CurseBomb' elif powerupType == 'characterBomb': tex = factory.texcharacterBomb name = 'CharBomb' elif powerupType == 'mjBomb': tex = factory.texmjBomb name = 'MJBomb' elif powerupType == 'trioBomb': tex = factory.textrioBomb name = 'ImpactTrio' elif powerupType == 'speedBomb': tex = factory.texspeedBomb name = 'ShockWave' elif powerupType == 'healBomb': tex = factory.texhealBomb name = 'HealthBomb' elif powerupType == 'nightBomb': tex = factory.texNightBomb name = 'AtomBomb' elif powerupType == 'revengeBomb': tex = factory.texrevengeBomb name = 'RevengeBomb' elif powerupType == 'blastBomb': tex = factory.texblastBomb name = 'blastBomb' elif powerupType == 'knockBomb': tex = factory.texknockBomb name = 'KnockBomb' elif powerupType == 'stickyIce': tex = factory.texstickyIce name = 'StickyIce' elif powerupType == 'stickyIceTrio': tex = factory.texstickyIceTrio name = 'StickyIceTrio' elif powerupType == 'stickyIceMess': tex = factory.texstickyIceMess name = 'StickyIceMess' elif powerupType == 'stickyMess': tex = factory.texStickyMess name = 'StickyMess' elif powerupType == 'icyMess': tex = factory.texIcyMess name = 'IcyMess' elif powerupType == 'icyTrio': tex = factory.texicyTrio name = 'IcyTrio' elif powerupType == 'weee': tex = factory.texWeee name = 'Health' elif powerupType == 'tnt': tex = factory.texTnt name = 'TNT' elif powerupType == 'boomBomb': tex = factory.texboomBomb name = 'KaboomBomb' elif powerupType == 'name': tex = factory.texName name = 'NewName' elif powerupType == 'highlight': tex = factory.texHighlight name = 'HighLight' elif powerupType == 'spotlight': tex = factory.texSpotlight name = 'Spotlight' elif powerupType == 'jumpFly': tex = factory.texjumpFly name = 'FlyJump' elif powerupType == 'use': tex = factory.texuse name = 'FlyBomb' elif powerupType == "antiGrav": tex = factory.texAntiGrav name = 'AntiGrav' elif powerupType == "BlackHole": tex = factory.texBlackHole name = 'BlackHole' elif powerupType == "Slippery": tex = factory.texSlippery name = 'LuckyBlock' elif powerupType == "Box": tex = factory.texBox name = 'Box' elif powerupType == 'snoball': tex = factory.texSno mod = factory.snoModel name = "shieldBall" elif powerupType == 'pass': return else: raise Exception("invalid powerupType: " + str(powerupType)) if len(position) != 3: raise Exception("expected 3 floats for position") if powerupType == 'poisonBombs': refScale = (0, 3, 0) ref = 'soft' elif powerupType == 'pandoraBox': ref = 'soft' refScale = (1, 1, 1) elif powerupType == 'dirtBombs': ref = 'soft' refScale = (1, 0.4, 0.16) else: refScale = [0.95] ref = 'powerup' self.node = bs.newNode('prop', delegate=self, attrs={ 'body': 'box', 'position': position, 'model': factory.model, 'lightModel': factory.modelSimple, 'shadowSize': 0.48, 'colorTexture': tex, 'reflection': ref, 'reflectionScale': refScale, 'materials': (factory.powerupMaterial, bs.getSharedObject('objectMaterial')) }) prefixAnim = { 0: (1, 0, 0), 250: (1, 1, 0), 250 * 2: (0, 1, 0), 250 * 3: (0, 1, 1), 250 * 4: (1, 0, 1), 250 * 5: (0, 0, 1), 250 * 6: (1, 0, 0) } color = (0, 0, 1) if don.powerupName: m = bs.newNode('math', owner=self.node, attrs={ 'input1': (0, 0.7, 0), 'operation': 'add' }) self.node.connectAttr('position', m, 'input2') self.nodeText = bs.newNode('text', owner=self.node, attrs={ 'text': str(name), 'inWorld': True, 'shadow': 1.0, 'flatness': 1.0, 'color': color, 'scale': 0.0, 'hAlign': 'center' }) m.connectAttr('output', self.nodeText, 'position') bs.animate(self.nodeText, 'scale', {0: 0, 140: 0.016, 200: 0.01}) bs.animateArray( self.nodeText, 'color', 3, { 0: (0, 0, 2), 500: (0, 2, 0), 1000: (2, 0, 0), 1500: (2, 2, 0), 2000: (2, 0, 2), 2500: (0, 1, 6), 3000: (1, 2, 0) }, True) bs.emitBGDynamics(position=self.nodeText.position, velocity=self.node.position, count=200, scale=1.4, spread=2.01, chunkType='sweat') if don.shieldOnPowerUps: self.nodeShield = bs.newNode('shield', owner=self.node, attrs={ 'color': color, 'position': (self.node.position[0], self.node.position[1], self.node.position[2] + 0.5), 'radius': 1.2 }) self.node.connectAttr('position', self.nodeShield, 'position') bsUtils.animateArray(self.nodeShield, 'color', 3, prefixAnim, True) if don.discoLights: self.nodeLight = bs.newNode('light', attrs={ 'position': self.node.position, 'color': color, 'radius': 0.2, 'volumeIntensityScale': 0.5 }) self.node.connectAttr('position', self.nodeLight, 'position') bsUtils.animateArray(self.nodeLight, 'color', 3, prefixAnim, True) bs.animate(self.nodeLight, "intensity", { 0: 1.0, 1000: 1.8, 2000: 1.0 }, loop=True) bs.gameTimer(8000, self.nodeLight.delete) if don.powerupTimer: self.powerupHurt = bs.newNode('shield', owner=self.node, attrs={ 'color': (1, 1, 1), 'radius': 0.1, 'hurt': 1, 'alwaysShowHealthBar': True }) self.node.connectAttr('position', self.powerupHurt, 'position') bs.animate(self.powerupHurt, 'hurt', { 0: 0, defaultPowerupInterval - 1000: 1 }) bs.gameTimer(defaultPowerupInterval - 1000, bs.Call(self.do_delete)) curve = bs.animate(self.node, "modelScale", {0: 0, 140: 1.6, 200: 1}) bs.gameTimer(200, curve.delete) if expire: bs.gameTimer(defaultPowerupInterval - 2500, bs.WeakCall(self._startFlashing)) bs.gameTimer(defaultPowerupInterval - 1000, bs.WeakCall(self.handleMessage, bs.DieMessage()))
def checkExistsSpaz(): if spaz.node.exists(): bs.gameTimer(10, bs.Call(checkExistsSpaz)) else: spaz.spazLight.delete() print '[QUAKE DEBUG] spazLight deleted'
def raisePlayer(self, player): player.actor.handleMessage(FlyMessage()) if player.isAlive(): bs.gameTimer(50,bs.Call(self.raisePlayer,player)) """spaz.node.handleMessage("impulse",spaz.node.position[0],spaz.node.position[1],spaz.node.position[2],
def _organizer(self): self.blablabla = bs.Timer(random.randrange(1000, 15000), bs.Call(self._doNight)) #do night
def showCompletionBanner(self, sound=True): global gLastAchievementDisplayTime gLastAchievementDisplayTime = bs.getRealTime() # just piggy-back onto any current activity... # (should we use the session instead?..) activity = bs.getActivity(exceptionOnNone=False) # if this gets called while this achievement is occupying a slot already, ignore it.. # (probably should never happen in real life but whatevs..) if self._completionBannerSlot is not None: return if activity is None: print 'showCompletionBanner() called with no current activity!' return if sound: bs.playSound(bs.getSound('achievement'), hostOnly=True) else: bs.gameTimer( 500, bs.Call(bs.playSound, bs.getSound('ding'), hostOnly=True)) yOffs = 0 inTime = 300 outTime = 3500 baseVRDepth = 200 # find the first free slot i = 0 while True: if not i in gCompletionBannerSlots: #print 'ADDING SLOT',i,'FOR',self gCompletionBannerSlots.add(i) self._completionBannerSlot = i # remove us from that slot when we close.. # use a real-timer in the UI context so the removal runs even if our activity/session dies with bs.Context('UI'): bs.realTimer(inTime + outTime, self._removeBannerSlot) break i += 1 yOffs = 110 * self._completionBannerSlot objs = [] obj = bsUtils.Image(bs.getTexture('shadow'), position=(-30, 30 + yOffs), front=True, attach='bottomCenter', transition='inBottom', vrDepth=baseVRDepth - 100, transitionDelay=inTime, transitionOutDelay=outTime, color=(0.0, 0.1, 0, 1), scale=(1000, 300)).autoRetain() objs.append(obj) obj.node.hostOnly = True obj = bsUtils.Image(bs.getTexture('light'), position=(-180, 60 + yOffs), front=True, attach='bottomCenter', vrDepth=baseVRDepth, transition='inBottom', transitionDelay=inTime, transitionOutDelay=outTime, color=(1.8, 1.8, 1.0, 0.0), scale=(40, 300)).autoRetain() objs.append(obj) obj.node.hostOnly = True obj.node.premultiplied = True c = bs.newNode('combine', owner=obj.node, attrs={'size': 2}) bsUtils.animate( c, 'input0', { inTime: 0, inTime + 400: 30, inTime + 500: 40, inTime + 600: 30, inTime + 2000: 0 }) bsUtils.animate( c, 'input1', { inTime: 0, inTime + 400: 200, inTime + 500: 500, inTime + 600: 200, inTime + 2000: 0 }) c.connectAttr('output', obj.node, 'scale') bsUtils.animate(obj.node, 'rotate', {0: 0.0, 350: 360.0}, loop=True) obj = bsUtils.Image(self.getIconTexture(True), position=(-180, 60 + yOffs), attach='bottomCenter', front=True, vrDepth=baseVRDepth - 10, transition='inBottom', transitionDelay=inTime, transitionOutDelay=outTime, scale=(100, 100)).autoRetain() objs.append(obj) obj.node.hostOnly = True # flash color = self.getIconColor(True) c = bs.newNode('combine', owner=obj.node, attrs={'size': 3}) keys = { inTime: 1.0 * color[0], inTime + 400: 1.5 * color[0], inTime + 500: 6.0 * color[0], inTime + 600: 1.5 * color[0], inTime + 2000: 1.0 * color[0] } bsUtils.animate(c, 'input0', keys) keys = { inTime: 1.0 * color[1], inTime + 400: 1.5 * color[1], inTime + 500: 6.0 * color[1], inTime + 600: 1.5 * color[1], inTime + 2000: 1.0 * color[1] } bsUtils.animate(c, 'input1', keys) keys = { inTime: 1.0 * color[2], inTime + 400: 1.5 * color[2], inTime + 500: 6.0 * color[2], inTime + 600: 1.5 * color[2], inTime + 2000: 1.0 * color[2] } bsUtils.animate(c, 'input2', keys) c.connectAttr('output', obj.node, 'color') obj = bsUtils.Image(bs.getTexture('achievementOutline'), modelTransparent=bs.getModel('achievementOutline'), position=(-180, 60 + yOffs), front=True, attach='bottomCenter', vrDepth=baseVRDepth, transition='inBottom', transitionDelay=inTime, transitionOutDelay=outTime, scale=(100, 100)).autoRetain() obj.node.hostOnly = True # flash color = (2, 1.4, 0.4, 1) c = bs.newNode('combine', owner=obj.node, attrs={'size': 3}) keys = { inTime: 1.0 * color[0], inTime + 400: 1.5 * color[0], inTime + 500: 6.0 * color[0], inTime + 600: 1.5 * color[0], inTime + 2000: 1.0 * color[0] } bsUtils.animate(c, 'input0', keys) keys = { inTime: 1.0 * color[1], inTime + 400: 1.5 * color[1], inTime + 500: 6.0 * color[1], inTime + 600: 1.5 * color[1], inTime + 2000: 1.0 * color[1] } bsUtils.animate(c, 'input1', keys) keys = { inTime: 1.0 * color[2], inTime + 400: 1.5 * color[2], inTime + 500: 6.0 * color[2], inTime + 600: 1.5 * color[2], inTime + 2000: 1.0 * color[2] } bsUtils.animate(c, 'input2', keys) c.connectAttr('output', obj.node, 'color') objs.append(obj) obj = bsUtils.Text(bs.Lstr(value='${A}:', subs=[('${A}', bs.Lstr(resource='achievementText')) ]), position=(-120, 91 + yOffs), front=True, vAttach='bottom', vrDepth=baseVRDepth - 10, transition='inBottom', flatness=0.5, transitionDelay=inTime, transitionOutDelay=outTime, color=(1, 1, 1, 0.8), scale=0.65).autoRetain() objs.append(obj) obj.node.hostOnly = True obj = bsUtils.Text(self.getDisplayString(), position=(-120, 50 + yOffs), front=True, vAttach='bottom', transition='inBottom', vrDepth=baseVRDepth, flatness=0.5, transitionDelay=inTime, transitionOutDelay=outTime, flash=True, color=(1, 0.8, 0, 1.0), scale=1.5).autoRetain() objs.append(obj) obj.node.hostOnly = True obj = bsUtils.Text(bs.getSpecialChar('ticket'), position=(-120 - 170 + 5, 75 + yOffs - 20), front=True, vAttach='bottom', hAlign='center', vAlign='center', transition='inBottom', vrDepth=baseVRDepth, transitionDelay=inTime, transitionOutDelay=outTime, flash=True, color=(0.5, 0.5, 0.5, 1), scale=3.0).autoRetain() objs.append(obj) obj.node.hostOnly = True obj = bsUtils.Text('+' + str(self.getAwardTicketValue()), position=(-120 - 180 + 5, 80 + yOffs - 20), vAttach='bottom', front=True, hAlign='center', vAlign='center', transition='inBottom', vrDepth=baseVRDepth, flatness=0.5, shadow=1.0, transitionDelay=inTime, transitionOutDelay=outTime, flash=True, color=(0, 1, 0, 1), scale=1.5).autoRetain() objs.append(obj) obj.node.hostOnly = True # add the 'x 2' if we've got pro if bsUtils._havePro(): obj = bsUtils.Text('x 2', position=(-120 - 180 + 45, 80 + yOffs - 50), vAttach='bottom', front=True, hAlign='center', vAlign='center', transition='inBottom', vrDepth=baseVRDepth, flatness=0.5, shadow=1.0, transitionDelay=inTime, transitionOutDelay=outTime, flash=True, color=(0.4, 0, 1, 1), scale=0.9).autoRetain() objs.append(obj) obj.node.hostOnly = True obj = bsUtils.Text( self.getDescriptionComplete(), # self.getDescriptionCompleteLocalized(), position=(-120, 30 + yOffs), front=True, vAttach='bottom', transition='inBottom', vrDepth=baseVRDepth - 10, flatness=0.5, transitionDelay=inTime, transitionOutDelay=outTime, color=(1.0, 0.7, 0.5, 1.0), scale=0.8).autoRetain() objs.append(obj) obj.node.hostOnly = True for obj in objs: bs.gameTimer(outTime + 1000, bs.WeakCall(obj.handleMessage, bs.DieMessage()))
def _serverStatusCheckThread(self, fetchedAddress, fetchedPort): height = 200 width = 360 class PingThread(threading.Thread): def __init__(self, address, port, call): threading.Thread.__init__(self) self._address = bs.utf8(address) self._port = port self._call = call def run(self): try: import socket socket_type = bsUtils._getIPAddressType(self._address) s = socket.socket(socket_type, socket.SOCK_DGRAM) s.connect((self._address, self._port)) accessible = False start_time = time.time() s.settimeout(1) for i in range(3): s.send('\x0b') try: # 11: BS_PACKET_SIMPLE_PING result = s.recv(10) except Exception: result = None if result == '\x0c': # 12: BS_PACKET_SIMPLE_PONG accessible = True break time.sleep(1) s.close() ping = int((time.time() - start_time) * 1000.0) bs.callInGameThread( bs.Call(self._call, self._address, self._port, ping if accessible else None)) except Exception as e: print(e) if fetchedPort != None: PingThread(fetchedAddress, fetchedPort, bs.Call(self.fetchedDataCallBack)).start() if self._rootWidget.exists(): fadeToBack() else: if self._rootWidget.exists(): fadeToRed() if self.buttonChecker == True: self.sb.delete() self.ob.delete() self.buttonChecker = False bs.textWidget(edit=self.t, text='') bs.textWidget(edit=self.pt, text='') bs.textWidget(edit=self.pvt, text='') bs.textWidget(edit=self.ts, text='') bs.textWidget(edit=self.tvs, text='') bs.textWidget( edit=self.lt, text=bs.Lstr( resource='gatherWindow.addressFetchErrorText'), color=(1, 1, 1))
def _startNextWave(self): # this could happen if we beat a wave as we die.. # we dont wanna respawn players and whatnot if this happens if self._gameOver: return # respawn applicable players if self._wave > 1 and not self.isWaitingForContinue(): for player in self.players: if (not player.isAlive() and player.gameData['respawnWave'] == self._wave): self.spawnPlayer(player) self._updatePlayerSpawnInfo() self.showZoomMessage( bs.Lstr( value='${A} ${B}', subs=[('${A}', bs.Lstr(resource='waveText')), ('${B}', str(self._wave))]), scale=1.0, duration=1000, trail=True) bs.gameTimer(400, bs.Call(bs.playSound, self._newWaveSound)) t = 0 dt = 200 botAngle = random.random()*360.0 if self._wave == 1: spawnTime = 3973 t += 500 else: spawnTime = 2648 offs = 0 # debugging # populate waves # generate random waves in endless mode if self._preset in ['endless', 'endlessTournament']: level = self._wave botTypes2 = [bs.BomberBot, bs.ToughGuyBot, bs.ChickBot, bs.NinjaBot, bs.BomberBotPro, bs.ToughGuyBotPro, bs.ChickBotPro, bs.BomberBotProShielded, bs.PirateBot, bs.NinjaBotProShielded, bs.MelBot, bs.ToughGuyBotProShielded, bs.ChickBotProShielded ] if level > 5: botTypes2 += [ bs.PirateBot, bs.ChickBotProShielded, bs.ToughGuyBotProShielded, bs.NinjaBotProShielded, bot.SantaBot, bot.BomberTNTBot, ] if level > 7: botTypes2 += [ bs.PirateBot, bs.ChickBotProShielded, bs.ToughGuyBotProShielded, bs.NinjaBotProShielded, ] if level > 10: botTypes2 += [ bs.ChickBotProShielded, bs.ChickBotProShielded, bs.ChickBotProShielded, bs.ChickBotProShielded ] if level > 13: botTypes2 += [ bs.ChickBotProShielded, bs.ChickBotProShielded, bs.ChickBotProShielded, bs.ChickBotProShielded ] botLevels = [[b for b in botTypes2 if b.pointsMult == 1], [b for b in botTypes2 if b.pointsMult == 2], [b for b in botTypes2 if b.pointsMult == 3], [b for b in botTypes2 if b.pointsMult == 4]] if not all([len(a) > 0 for a in botLevels]): raise Exception() targetPoints = level*3-2 minDudes = min(1+level/3, 10) maxDudes = min(10, level+1) maxLevel = 4 if level > 6 else( 3 if level > 3 else(2 if level > 2 else 1)) groupCount = 3 distribution = self._getDistribution( targetPoints, minDudes, maxDudes, groupCount, maxLevel) allEntries = [] for group in distribution: entries = [] for entry in group: botLevel = botLevels[entry[0]-1] botType = botLevel[random.randrange(len(botLevel))] r = random.random() if r < 0.5: spacing = 10 elif r < 0.9: spacing = 20 else: spacing = 40 split = random.random() > 0.3 for i in range(entry[1]): if split and i % 2 == 0: entries.insert( 0, {"type": botType, "spacing": spacing}) else: entries.append( {"type": botType, "spacing": spacing}) if len(entries) > 0: allEntries += entries allEntries.append( {"type": None, "spacing": 40 if random.random() < 0.5 else 80}) angleRand = random.random() if angleRand > 0.75: baseAngle = 130 elif angleRand > 0.5: baseAngle = 210 elif angleRand > 0.25: baseAngle = 20 else: baseAngle = -30 baseAngle += (0.5-random.random())*20.0 wave = {'baseAngle': baseAngle, 'entries': allEntries} else: wave = self._waves[self._wave-1] entries = [] try: botAngle = wave['baseAngle'] except Exception: botAngle = 0 entries += wave['entries'] thisTimeBonus = 0 thisFlawlessBonus = 0 for info in entries: if info is None: continue botType = info['type'] if botType == 'delay': spawnTime += info['duration'] continue if botType is not None: thisTimeBonus += botType.pointsMult * 20 thisFlawlessBonus += botType.pointsMult * 5 # if its got a position, use that try: point = info['point'] except Exception: point = None if point is not None: bs.gameTimer( t, bs.WeakCall( self.addBotAtPoint, point, botType, spawnTime)) t += dt else: try: spacing = info['spacing'] except Exception: spacing = 5.0 botAngle += spacing*0.5 if botType is not None: bs.gameTimer( t, bs.WeakCall( self.addBotAtAngle, botAngle, botType, spawnTime)) t += dt botAngle += spacing*0.5 # we can end the wave after all the spawning happens bs.gameTimer(t+spawnTime-dt+10, bs.WeakCall(self._setCanEndWave)) # reset our time bonus self._timeBonus = thisTimeBonus self._flawlessBonus = thisFlawlessBonus vrMode = bs.getEnvironment()['vrMode'] self._timeBonusText = bs.NodeActor( bs.newNode( 'text', attrs={'vAttach': 'top', 'hAttach': 'center', 'hAlign': 'center', 'vrDepth': -30, 'color': (1, 1, 0, 1) if True else(1, 1, 0.5, 1), 'shadow': 1.0 if True else 0.5, 'flatness': 1.0 if True else 0.5, 'position': (0, -60), 'scale': 0.8 if True else 0.6, 'text': bs.Lstr( value='${A}: ${B}', subs=[('${A}', bs.Lstr( resource='timeBonusText')), ('${B}', str(self._timeBonus))])})) bs.gameTimer(5000, bs.WeakCall(self._startTimeBonusTimer)) self._waveText = bs.NodeActor( bs.newNode( 'text', attrs={'vAttach': 'top', 'hAttach': 'center', 'hAlign': 'center', 'vrDepth': -10, 'color': (1, 1, 1, 1) if True else(0.7, 0.7, 0.7, 1.0), 'shadow': 1.0 if True else 0.7, 'flatness': 1.0 if True else 0.5, 'position': (0, -40), 'scale': 1.3 if True else 1.1, 'text': bs.Lstr( value='${A} ${B}', subs=[('${A}', bs.Lstr(resource='waveText')), ('${B}', str(self._wave) + ('' if self._preset in ['endless', 'endlessTournament'] else('/' + str(len(self._waves)))))])}))