def loadActor(self): if self.actor: self.actor.cleanup() self.actor = Actor('models/ralph', {'walk' : 'models/ralph-walk', 'run' : 'models/ralph-run'}) self.actor.reparentTo(self) self.actor.setScale(.2) # Setup a really simple nametag so we can know it's name. self.nameText = TextNode('%d-nameText' % self.doId) self.nameText.setText(self.name) self.nameText.setAlign(self.nameText.A_center) self.nameNP = self.attachNewNode(self.nameText) self.nameNP.setScale(.25) self.nameNP.setPos(0, 0, 1.2) self.nameNP.setBillboardPointEye() self.chatText = TextNode('%d-chatText' % self.doId) self.chatText.setText(self.chat) self.chatText.setAlign(self.chatText.A_center) self.chatText.setTextColor(0.5, 0.5, 1, 1) self.chatNP = self.attachNewNode(self.chatText) self.chatNP.setScale(.35) self.chatNP.setPos(0, 0, 1.6) self.chatNP.setBillboardPointEye()
def Game_Point(self): self.ignore("arrow_down") self.ignore("arrow_up") self.ignore("arrow_down-repeat") self.ignore("arrow_up-repeat") #self.text1 = addInstructions(0.5,"Is this Recyclable") self.text1 = TextNode('t1') self.text1.setText("is This Recyclable") self.text1.setTextColor(0,0,0,1) self.textNodePath1 = aspect2d.attachNewNode(self.text1) self.textNodePath1.setScale(0.07) self.textNodePath1.setPos(-0.1,-0.1,0.1) #text1.setTextColor(1,1,1) self.text1.setFrameColor(1, 0, 0, 1) self.text1.setFrameAsMargin(0.2, 0.2, 0.1, 0.1) self.text2 = TextNode('t2') self.text2.setText("Y/N") self.text2.setTextColor(0,0,0,1) self.textNodePath2 = aspect2d.attachNewNode(self.text2) self.textNodePath2.setScale(0.07) self.textNodePath2.setPos(0,0,0) #textNodePath2.setTextColor(1,1,1) self.text2.setFrameColor(1, 0, 0, 1) self.text2.setFrameAsMargin(0.2, 0.2, 0.1, 0.1) self.accept('y',self.answer,[0]) self.accept('n',self.answer,[1])
def setupCoins2(self): # display coins = 0 textN = TextNode('coin-score') textN.setText(str("Coins: " + str(self.coinsCollected2))) textN.setSlant(0.1) textNodePath = self.aspect2d.attachNewNode(textN) textNodePath.setPos(0, 0.95, 0.9) textNodePath.setScale(0.08) randNum = random.sample(range(0, 1500, 200), 6) # coins for i in range(6): randX = random.uniform(-3.0, 3.2) randY = float(randNum[i]) shape = BulletSphereShape(0.3) coinNode = BulletGhostNode('Coin-' + str(i)) coinNode.addShape(shape) np = self.render.attachNewNode(coinNode) np.setCollideMask(BitMask32.allOff()) np.setPos(randX, randY, 2) # Adding sphere model sphereNp = loader.loadModel('models/smiley.egg') sphereNp_tex = loader.loadTexture("models/sky/coin_2_tex.jpg") sphereNp.setTexture(sphereNp_tex, 1) sphereNp.reparentTo(np) sphereNp.setScale(0.45) sphereNp.hprInterval(2.5, Vec3(360, 0, 0)).loop() self.world2.attachGhost(coinNode) self.coins2.append(coinNode) print "node name:" + str(coinNode.getName())
class FastTextNode(DebugObject): """ Interface for the Panda3D TextNode. """ def __init__(self, font="Data/Font/Roboto-Bold.ttf", pixel_size=16, align="left", pos=Vec2(0), color=Vec3(1), parent=None): self._node = TextNode('FTN') self._node.set_text("Text") self._node.set_align(getattr(TextNode, "A_" + align)) self._node.set_text_color(color.x, color.y, color.z, 1) if parent is None: parent = Globals.base.aspect2d self._nodepath = parent.attach_new_node(self._node) self._nodepath.set_scale(pixel_size * 2.0 / float(Globals.base.win.get_y_size())) self._nodepath.set_pos(pos.x, 0, pos.y) font = Globals.loader.loadFont(font) font.set_outline(Vec4(0, 0, 0, 0.78), 1.6, 0.37) font.set_scale_factor(1.0) font.set_texture_margin(int(pixel_size / 4.0 * 2.0)) font.set_bg(Vec4(0, 0, 0, 0)) self._node.set_font(font) def set_text(self, text): self._node.set_text(text)
def initFishStaminaBar(self): self.legendaryGui = loader.loadModel('models/minigames/pir_m_gam_fsh_legendaryGui') self.iconBaseFrame = DirectFrame(relief = None, state = DGG.DISABLED, pos = (0, 0, 0), sortOrder = 30, image = self.legendaryGui.find('**/pir_t_gui_fsh_fishPortraitFrame'), image_scale = 0.17999999999999999, image_pos = (0, 0, 0)) self.iconBaseFrame.setTransparency(TransparencyAttrib.MAlpha) self.fishUINodePath = NodePath(self.iconBaseFrame) self.fishUINodePath.setPos(-0.29999999999999999, 0.0, 0.82999999999999996) self.fishUINodePath.reparentTo(hidden) self.iconCard = loader.loadModel('models/gui/treasure_gui') self.iconBaseFrame.iconImage = OnscreenImage(parent = self.iconBaseFrame, image = self.iconCard.find('**/%s*' % CollectionMap.Assets[self.myData['id']]), scale = 0.34999999999999998, hpr = (0, 0, 0), pos = (0.0, 0, 0.0)) self.fishNameLabel = TextNode('fishNameLabel') name = self.getName().split('_') self.fishNameLabel.setText(name[0]) self.fishNameLabel.setTextColor(1.0, 1.0, 1.0, 1.0) self.fishNameLabelNodePath = NodePath(self.fishNameLabel) self.fishNameLabelNodePath.setPos(0.29999999999999999, 0, 0.040000000000000001) self.fishNameLabelNodePath.setScale(0.044999999999999998) self.fishNameLabelNodePath.reparentTo(self.iconBaseFrame) self.fishStaminaBar = DirectWaitBar(parent = self.iconBaseFrame, relief = DGG.FLAT, state = DGG.DISABLED, range = 100, value = 0, sortOrder = 20, frameColor = (0, 0, 0, 1.0), pos = (0.070000000000000007, 0.0, -0.014999999999999999), hpr = (0, 0, 0), frameSize = (0, 0.71999999999999997, 0, 0.028000000000000001)) self.fishStaminaBar['value'] = self.staminaValue self.fishStaminaBar['barColor'] = FishingGlobals.fishingStaminaBarColor[int((self.staminaValue / 100.0) * (len(FishingGlobals.fishingStaminaBarColor) - 1))] self.fishStaminaValueLabel = TextNode('fishStaminaValueLabel') self.fishStaminaValueLabel.setText(str(self.staminaValue) + '//' + str(self.staminaValue)) self.fishStaminaValueLabel.setTextColor(1.0, 1.0, 1.0, 1.0) self.fishStaminaValueLabelNodePath = NodePath(self.fishStaminaValueLabel) self.fishStaminaValueLabelNodePath.setPos(0.66000000000000003, 0, -0.059999999999999998) self.fishStaminaValueLabelNodePath.setScale(0.044999999999999998) self.fishStaminaValueLabelNodePath.reparentTo(self.iconBaseFrame) self.fishStaminaBarFrame = DirectLabel(parent = self.iconBaseFrame, relief = None, state = DGG.DISABLED, frameColor = (1, 1, 1, 0.10000000000000001), pos = (0.44, 0.0, 0.0), hpr = (0, 0, 0), sortOrder = 25, image = self.legendaryGui.find('**/pir_t_gui_fsh_staminaBarForeground'), image_scale = (1.0, 0.0, 0.050000000000000003), image_pos = (0.0, 0.0, 0.0), image_hpr = (0.0, 0.0, 0.0)) self.fishStaminaBarFrame.setTransparency(TransparencyAttrib.MAlpha) self.fishStaminaBarFrame.setDepthTest(True) self.fishStaminaBarFrame.setDepthWrite(True)
def renderClickableModel(self, showModel=True, showName=False): ''' Render just the clickable (reference) model ''' # Hide all non clickable objects self.nonClickable.clearColor() self.nonClickable.hide() # Show the clickable model with the original texture and color self.clickableModel.clearColor() self.clickableModel.clearColorScale() if showModel: # Place it in front of the user, face-to-face (we try to randomly parametrize the position and orientation of the reference model but in a way that the user can clearly see it face-to-face) self.clickableModel.setPos(0,40,0) self.clickableModel = self.normalizeModelSize(self.clickableModel, self.minModelSize, self.maxModelSize, self.clickableModelSize) # set size (normalize size and set a random size in the normalized range) self.clickableModel.setHpr(random.uniform(-45, 45), random.uniform(-15, 15), 0) self.clickableModel.setColorScale(random.random(), random.random(), random.random(), 1.0) else: self.clickable.hide() if showName: if not hasattr(self, 'clickableText') or self.clickableText != self.clickableModelName: if hasattr(self, 'clickableText'): self.clickableText.remove() text = TextNode('reference model name') text.setText(self.clickableModelName) text.setAlign(TextNode.ACenter) self.clickableText = render2d.attachNewNode(text) self.clickableText.setScale( 0.2 ) self.clickableText.setPos( 0, 0, -0.8 )
def __init__(self, w, h, locationId = LocationIds.PORT_ROYAL_ISLAND): GuiPanel.GuiPanel.__init__(self, '', w, h, True) self.card = loader.loadModel('models/gui/pir_m_gui_fsh_legendaryScreen') self.storyImageCard = loader.loadModel('models/minigames/pir_m_gam_fsh_legendaryGui') self.UICompoments = { } self.setPos(-1.1499999999999999, 0.0, -0.59999999999999998) self['geom'] = self.card.find('**/background') self['geom_pos'] = (0.57999999999999996, 0.0, 0.63) self['geom_scale'] = (0.94999999999999996, 0.0, 0.84999999999999998) self.coinImage = OnscreenImage(parent = self, image = self.card.find('**/coin'), scale = 0.90000000000000002, hpr = (0, 0, 0), pos = (0.84999999999999998, 0, 0.84999999999999998)) self.titleTextNode = TextNode('legendPanelTitle') self.titleTextNode.setText(PLocalizer.LegendSelectionGui['panelTitle']) self.titleTextNode.setFont(PiratesGlobals.getPirateFont()) self.titleTextNode.setTextColor(0.87, 0.81999999999999995, 0.54000000000000004, 0.90000000000000002) self.titleTextNodePath = NodePath(self.titleTextNode) self.titleTextNodePath.setPos(0.65000000000000002, 0.0, 1.2) self.titleTextNodePath.setScale(0.070000000000000007) self.titleTextNodePath.reparentTo(self) self.introTextNode = TextNode('legendaryIntroTextNode') self.introTextNode.setText(PLocalizer.LegendSelectionGui['legendIntro']) self.introTextNode.setWordwrap(14.0) self.introTextNode.setTextColor(0.90000000000000002, 0.80000000000000004, 0.46999999999999997, 0.90000000000000002) self.introTextNodePath = NodePath(self.introTextNode) self.introTextNodePath.setPos(0.59999999999999998, 0.0, 0.5) self.introTextNodePath.setScale(0.042000000000000003) self.introTextNodePath.reparentTo(self) self.buttonRootNode = NodePath('button_RootNode') self.buttonRootNode.reparentTo(self) self.buttonRootNode.setPos(-0.080000000000000002, 0.0, 1.1499999999999999) self.iconCard = loader.loadModel('models/gui/treasure_gui') self.legendSelectionButtons = { } btnGeom = (self.card.find('**/fishButton/idle'), self.card.find('**/fishButton/idle'), self.card.find('**/fishButton/over')) for i in range(len(FishingGlobals.legendaryFishData)): fishName = FishingGlobals.legendaryFishData[i]['name'] fishId = FishingGlobals.legendaryFishData[i]['id'] assetsKey = CollectionMap.Assets[fishId] pos_x = 0.29999999999999999 pos_z = 0.0 - i * 0.25 button = GuiButton(parent = self.buttonRootNode, text = (fishName, fishName, fishName, fishName), text0_fg = (0.42999999999999999, 0.28999999999999998, 0.19, 1.0), text1_fg = (0.42999999999999999, 0.28999999999999998, 0.19, 1.0), text2_fg = (0.42999999999999999, 0.28999999999999998, 0.19, 1.0), text3_fg = (0.42999999999999999, 0.28999999999999998, 0.19, 1.0), text_scale = 0.035000000000000003, text_pos = (0.037999999999999999, -0.0050000000000000001), pos = (pos_x, 0, pos_z), hpr = (0, 0, 0), scale = 1.5, image = btnGeom, image_pos = (0, 0, 0), image_scale = 0.69999999999999996, sortOrder = 2, command = self.buttonClickHandle, extraArgs = [ fishId, assetsKey, locationId]) button.icon = OnscreenImage(parent = button, image = self.iconCard.find('**/%s*' % assetsKey), scale = 0.34999999999999998, hpr = (0, 0, 0), pos = (-0.123, 0, 0.0050000000000000001)) self.legendPanel = GuiPanel.GuiPanel('', 2.6000000000000001, 1.8999999999999999, True) self.legendPanel.setPos(-1.3, 0.0, -0.94999999999999996) self.legendPanel.background = OnscreenImage(parent = self.legendPanel, scale = (2.3999999999999999, 0, 1.8), image = self.storyImageCard.find('**/pir_t_gui_fsh_posterBackground'), hpr = (0, 0, 0), pos = (1.3, 0, 0.94999999999999996)) self.legendPanel.storyImage = OnscreenImage(parent = self.legendPanel, scale = 1, image = self.card.find('**/coin'), hpr = (0, 0, 0), pos = (1.8, 0, 1)) self.storyTextNode = TextNode('storyTextNode') self.storyTextNode.setText('') self.storyTextNode.setWordwrap(19.0) self.storyTextNode.setTextColor(0.23000000000000001, 0.089999999999999997, 0.029999999999999999, 1.0) self.storyTextNodePath = NodePath(self.storyTextNode) self.storyTextNodePath.setPos(0.33000000000000002, 0.0, 1.6699999999999999) self.storyTextNodePath.setScale(0.050000000000000003) self.storyTextNodePath.reparentTo(self.legendPanel) self.callBack = None self.legendPanel.hide()
def fontHasCharacters(name, font = font): if font: tn = TextNode('NameCheck') tn.setFont(font) for c in name: # Define c as unicode if not tn.hasCharacter(unichr(ord(c))): notify.info('name contains bad char: %s' % TextEncoder().encodeWtext(c)) return OTPLocalizer.NCBadCharacter % TextEncoder().encodeWtext(c)
def _show(self, ctb, identifier, parentnode): if self.node is not None: self.node.removeNode() tnode = TextNode(identifier) tnode.setText(ctb.text) r, g, b, a = ctb.textcolor.r / 255.0, ctb.textcolor.g / 255.0, ctb.textcolor.b / 255.0, ctb.textcolor.a / 255.0 tnode.setTextColor(r, g, b, a) node = NodePath(tnode) self._scale(tnode, node) node.reparentTo(parentnode) self.node = node
def draw(self): # stuffandeer stuffandeer otus for card in self.hand: textn = TextNode(card.name) textn.setText(card.name) textnp = card.model.attachNewNode(textn) textnp.setScale(0.3) textnp.setPos(card.model, -2, 0, 1) textnp.setHpr(card.model, 0, -90, -90) textn.setAlign(TextNode.ACenter)
def draw_mstr(self, mstr, box, identifier="", parameters=None): self.aspect = True if box.mode == "pixels": parent2d = self.get_parent_pixel2d() elif box.mode == "standard": parent2d = self.get_parent_render2d() elif box.mode == "aspect": parent2d = self.get_parent_aspect2d() tnode = TextNode(identifier) tnode.setText(mstr.value) # TODO: use more parameters if hasattr(parameters, "cardcolor"): tnode.setCardColor(*parameters.cardcolor) tnode.setCardAsMargin(0, 0, 0, 0) tnode.setCardDecal(True) if hasattr(parameters, "aspect"): self.aspect = parameters.aspect node = NodePath(tnode) self._scale(tnode, node, box.x, box.y, box.sizex, box.sizey) node.setBin("fixed", self.get_next_sortid()) node.setDepthTest(False) node.setDepthWrite(False) node.reparentTo(parent2d) return (mstr, node, tnode, box, parameters)
def drawBuilding(self, building, field): model = self.loader.loadModel('models/house') # model.setScale(0.05) model.reparentTo(field.model) building.model = model self.modelToBuilding[model.getKey()] = building player = self.game.currentPlayer() model.setTag('clickable', 'true') cs = CollisionSphere(0, 0, 0, 2) cnodePath = model.attachNewNode(CollisionNode('cnode')) cnodePath.node().addSolid(cs) # cnodePath.show() col = 256 * int(player.color) # set building title title = TextNode(str(building.model.getKey()) + '_title') title.setText(building.building) title.setCardColor(col, col, col, 1) title.setCardAsMargin(0.1, 0.1, 0.1, 0.1) title.setCardDecal(True) titleNode = self.render.attachNewNode(title) titleNode.reparentTo(building.model) titleNode.setScale(1.5) titleNode.setPos(0, 0, 3) titleNode.setBillboardPointEye()
def start(self): self._credits_node = aspect2d.attachNewNode("credits-node") text = TextNode('node name') text.setText(" A solar storm hits a moon base.\n Some vital systems are breaking.\n Get close to repair them before failure\nof four simultaneously, because this\ndestroy the base.") textNodePath = self._credits_node.attachNewNode(text) textNodePath.setScale(0.07) textNodePath.setPos((0.0, 0.0, 0.0)) DirectButton(text = ("Back", "Back", "Back", "Back"), pos=(0, 0, -0.8), scale=.15, command=self._butBack, parent=self._credits_node)
def createActor(self, render, username, x, y, z, h): actor = PlayerObject(render, username, x, y, z, h) # Displays username above Ralph character nameplate = TextNode('textNode username_' + str(username)) nameplate.setText(username) npNodePath = actor.actor.attachNewNode(nameplate) npNodePath.setScale(1.0) npNodePath.setBillboardPointEye() npNodePath.setZ(8.0) return actor
def generate(self): DistributedObject.announceGenerate(self) self.trolleyStation = self.cr.playGame.hood.loader.geom.find('**/prop_trolley_station_DNARoot') self.trolleyCar = self.trolleyStation.find('**/trolley_car') self.trolleyKey = self.trolleyStation.find('**/key') tn = TextNode('trolleycountdowntext') tn.setFont(CIGlobals.getMickeyFont()) tn.setTextColor(1, 0, 0, 1) self.countdownText = self.trolleyStation.attachNewNode(tn) self.countdownText.setScale(3.0) self.countdownText.setPos(14.58, 10.77, 11.17) self.acceptOnce('entertrolley_sphere', self.__handleTrolleyTrigger)
def drawFigures(self): for player in self.game.players: for figure in player.figures: if hasattr(figure, 'model'): continue if type(figure) == Ship: field = figure.field figure.model = self.loader.loadModel('models/ship') figure.model.reparentTo(field.model) cs = CollisionSphere(1.5, 0, 1, 1.3) cnodePath = figure.model.attachNewNode( CollisionNode('cnode')) cnodePath.node().addSolid(cs) # cnodePath.show() cs = CollisionSphere(0, 0, 1.4, 1.3) cnodePath = figure.model.attachNewNode( CollisionNode('cnode')) cnodePath.node().addSolid(cs) # cnodePath.show() cs = CollisionSphere(-1.8, 0, 1, 1) cnodePath = figure.model.attachNewNode( CollisionNode('cnode')) cnodePath.node().addSolid(cs) # cnodePath.show() figure.model.setScale(1.4) figure.model.setHpr(90, 0, 0) # figure.model.setTag('highlightable', 'true') figure.model.setTag('clickable', 'true') self.modelToFigure[figure.model.getKey()] = figure else: field = figure.field figure.model = self.loader.loadModel('models/warrior100') figure.model.reparentTo(field.model) cs = CollisionSphere(0, -.35, 7, 1) cnodePath = figure.model.attachNewNode( CollisionNode('cnode')) cnodePath.node().addSolid(cs) figure.model.setScale(0.35) figure.model.setTag('highlightable', 'true') figure.model.setTag('clickable', 'true') self.modelToFigure[figure.model.getKey()] = figure col = 256 * int(player.color) # set figure title title = TextNode(str(figure.model.getKey()) + '_title') title.setText(type(figure).__name__) title.setCardColor(col, col, col, 1) title.setCardAsMargin(0.1, 0.1, 0.1, 0.1) title.setCardDecal(True) titleNode = self.render.attachNewNode(title) titleNode.reparentTo(figure.model) titleNode.setScale(3) titleNode.setPos(0, 3, 10) if type(figure) == Ship: titleNode.setScale(1.5) titleNode.setPos(-1.5, 0, 3) titleNode.setBillboardPointEye()
class gameText(DirectObject): '''This class creates texts that will be part of the HUD of the game ''' def __init__(self, name, content, position, scale): #Writing our gameText and giving it a name(to help identifying which text is this) self.name = TextNode('%s'%name) self.name.setText("%s"%content) #now this gameText is child of hudTexts node self.textNodePath = hudTexts.attachNewNode(self.name) #positioning and scaling our gameText self.position = Vec3(*position) self.textNodePath.setX(self.position[0]), self.textNodePath.setZ(self.position[2]) self.textNodePath.setScale(scale)
def getTextSize(txt, style): tn = TextNode(txt) tn.setText(txt) tn.setFont(loader.loadFont(style['font'])) tn.setSlant(style['slant']) #tn.setFont(style['font']) fontSize = style['font-size'] lineHeight = tn.getLineHeight() f = tn.getFrameActual() return (tn.getWidth()*fontSize,\ (f[3]-f[2])*fontSize,\ lineHeight*fontSize,\ (0, f[1]*fontSize, f[2]*fontSize, f[3]*fontSize))
def addText(self,name,text,xpos,ypos,r,g,b,align): textNode=TextNode(name) textNode.setText(text) textNode.setFont(self.font) textNode.setTextColor(r,g,b,1.0) textNode.setAlign(align) textNodePath=self.containerNode.attachNewNode(textNode) textNodePath.setScale(self.fontScale) textNodePath.setPos((2.0/self.characterWidth*xpos)-1,0.0,(2.0/self.characterHeight*ypos)-1) return textNode
def initializePromptTextPart1(self): self.timerText = TextNode('timer') self.timerText.setText("Time:" + "0" + str(self.timer)) self.timerText.setShadow(0.05, 0.05) self.timerTextNodePath = aspect2d.attachNewNode(self.timerText) self.timerTextNodePath.setScale(0.07) self.timerTextNodePath.setPos(1.2,0,0.9) self.saveTimeText = TextNode('would you like to save?') self.saveTimeText.setText('')# self.saveTimeText.setShadow(0.05, 0.05) self.saveTimeTextNodePath = aspect2d.attachNewNode(self.saveTimeText) self.saveTimeTextNodePath.setScale(0.07) self.saveTimeTextNodePath.setPos(1.1, 0, 0.8)
def initializePressedDownKeysPart1(self): self.wText = TextNode('w') self.wText.setText("w") self.wText.setShadow(0.05, 0.05) self.wTextNodePath = aspect2d.attachNewNode(self.wText) self.wTextNodePath.setScale(0.07) self.wTextNodePath.setPos(-1.6,0,-0.75) self.sText = TextNode('s') self.sText.setText("s") self.sText.setShadow(0.05, 0.05) self.sTextNodePath = aspect2d.attachNewNode(self.sText) self.sTextNodePath.setScale(0.07) self.sTextNodePath.setPos(-1.35,0,-0.75)
def initializePressedDownKeysPart3(self): self.upText = TextNode('Up') self.upText.setText("Up") self.upText.setShadow(0.05, 0.05) self.upTextNodePath = aspect2d.attachNewNode(self.upText) self.upTextNodePath.setScale(0.07) self.upTextNodePath.setPos(-1.6,0,-0.85) self.downText = TextNode('Down') self.downText.setText("Down") self.downText.setShadow(0.05, 0.05) self.downTextNodePath = aspect2d.attachNewNode(self.downText) self.downTextNodePath.setScale(0.07) self.downTextNodePath.setPos(-1.35,0,-0.85)
def loadPickModelTextPart1(self): self.skin1Text = TextNode('skin1') self.skin1Text.setText("[1] - Fighter") self.skin1Text.setShadow(0.05, 0.05) self.skin1TextNodePath = aspect2d.attachNewNode(self.skin1Text) self.skin1TextNodePath.setScale(0.07) self.skin1TextNodePath.setPos(-1.3,0,0.3) self.skin2Text = TextNode('skin2') self.skin2Text.setText("[2] - Boeing707") self.skin2Text.setShadow(0.05, 0.05) self.skin2TextNodePath = aspect2d.attachNewNode(self.skin2Text) self.skin2TextNodePath.setScale(0.07) self.skin2TextNodePath.setPos(-0.1,0,0.3)
def initializePressedDownKeysPart4(self): self.rightText = TextNode('Left') self.rightText.setText("Left") self.rightText.setShadow(0.05, 0.05) self.rightTextNodePath = aspect2d.attachNewNode(self.rightText) self.rightTextNodePath.setScale(0.07) self.rightTextNodePath.setPos(-1.1,0,-0.85) self.leftText = TextNode('Right') self.leftText.setText("Right") self.leftText.setShadow(0.05, 0.05) self.leftTextNodePath = aspect2d.attachNewNode(self.leftText) self.leftTextNodePath.setScale(0.07) self.leftTextNodePath.setPos(-0.85,0,-0.85)
def loadPickModelTextPart3(self): self.skin5Text = TextNode('skin5') self.skin5Text.setText("[5] - Seeker") self.skin5Text.setShadow(0.05, 0.05) self.skin5TextNodePath = aspect2d.attachNewNode(self.skin5Text) self.skin5TextNodePath.setScale(0.07) self.skin5TextNodePath.setPos(-0.1,0,-0.5) self.skin6Text = TextNode('skin6') self.skin6Text.setText("[6] - Jeep") self.skin6Text.setShadow(0.05, 0.05) self.skin6TextNodePath = aspect2d.attachNewNode(self.skin6Text) self.skin6TextNodePath.setScale(0.07) self.skin6TextNodePath.setPos(1,0,-0.5)
def initializePressedDownKeysPart2(self): self.aText = TextNode('a') self.aText.setText("a") self.aText.setShadow(0.05, 0.05) self.aTextNodePath = aspect2d.attachNewNode(self.aText) self.aTextNodePath.setScale(0.07) self.aTextNodePath.setPos(-1.1,0,-0.75) self.dText = TextNode('d') self.dText.setText("d") self.dText.setShadow(0.05, 0.05) self.dTextNodePath = aspect2d.attachNewNode(self.dText) self.dTextNodePath.setScale(0.07) self.dTextNodePath.setPos(-0.85,0,-0.75)
def createActor(self, id, position, gameclient): actor = DynObject(render, id, position, gameclient) actor.motion_controller = NetworkObjectController(actor) self.addObject(actor) text = TextNode('node name_'+str(id)) text.setText('Ralph_'+str(id)) textNodePath = actor.actor.attachNewNode(text) textNodePath.setScale(1.0) textNodePath.setBillboardPointEye() textNodePath.setZ(8.0) # textNodePath.setX(2.0) return actor
def loadPickModelTextPart2(self): self.skin3Text = TextNode('skin3') self.skin3Text.setText("[3] - R2D2") self.skin3Text.setShadow(0.05, 0.05) self.skin3TextNodePath = aspect2d.attachNewNode(self.skin3Text) self.skin3TextNodePath.setScale(0.07) self.skin3TextNodePath.setPos(1,0,0.3) self.skin4Text = TextNode('skin4') self.skin4Text.setText("[4] - Blimp") self.skin4Text.setShadow(0.05, 0.05) self.skin4TextNodePath = aspect2d.attachNewNode(self.skin4Text) self.skin4TextNodePath.setScale(0.07) self.skin4TextNodePath.setPos(-1.3,0,-0.5)
class GUI(object): """ Handles the gui elements like showing the current stage """ def __init__(self, control): self.control = control self.gui_node = pixel2d.attach_new_node("GUI") self.gui_node.hide() self.gui_node.set_transparency(True) roboto_light = loader.loadFont("res/Roboto-Light.ttf") roboto_light.set_scale_factor(1) roboto_light.set_pixels_per_unit(120) self.text_stage = TextNode("TextStage") self.text_stage.set_text("Stage 1") self.text_stage.set_align(TextNode.A_left) self.text_stage.set_text_color(1, 1, 1, 1) self.text_stage.set_font(roboto_light) self.text_stage_np = self.gui_node.attach_new_node(self.text_stage) self.text_stage_np.set_scale(80.0) self.text_stage_np.set_pos(60, 0, -120) self.anim = None def show(self): self.gui_node.show() if self.anim is not None: self.anim.finish() self.anim = Sequence( LerpColorScaleInterval(self.gui_node, 0.2, Vec4(1), Vec4(1, 1, 1, 0), blendType="easeInOut") ) self.anim.start() def hide(self): self.gui_node.hide() if self.anim is not None: self.anim.finish() self.anim = Sequence( LerpColorScaleInterval(self.gui_node, 0.2, Vec4(1, 1, 1, 0), Vec4(1), blendType="easeInOut") ) self.anim.start() def set_stage(self, stage_nr): print(("Setting stage", stage_nr)) Sequence( LerpColorScaleInterval(self.text_stage_np, 0.4, Vec4(1, 1, 1, 0), Vec4(1), blendType="easeInOut"), Func(lambda *args: self.text_stage.set_text("Stage " + str(stage_nr))), LerpColorScaleInterval(self.text_stage_np, 0.4, Vec4(1), Vec4(1, 1, 1, 0), blendType="easeInOut"), ).start()
def __init__(self): # the tasktime the last sign in the textfield was written self.lastSign = 0.0 # the sign that is actually written in the textfield self.currentSign = 0 # the text to write in the textfield self.textfieldText = "" # stop will be used to check if the writing is finished or # somehow else stoped self.stop = False # the speed new letters are added to the text # the time, how long the text is shown after it is fully written self.showlength = 4 # the textfield to put instructions hints and everything else, that # should be slowly written on screen and disappear after a short while self.textfield = TextNode('textfield') self.textfield.clearText() self.textfield.setShadow(0.005, 0.005) self.textfield.setShadowColor(0, 0, 0, 1) self.textfield.setWordwrap(base.a2dRight*2-0.4) self.textfield.setCardActual( -0.1, base.a2dRight*2-0.3, 0.1, base.a2dBottom+0.5) self.textfield.setCardColor(0,0,0,0.45) self.textfield.setFlattenFlags(TextNode.FF_none) self.textfield.setTextScale(0.06) self.textfieldNodePath = aspect2d.attachNewNode(self.textfield) self.textfieldNodePath.setScale(1) self.textfieldNodePath.setPos(base.a2dLeft+0.2, 0, -0.4) self.hide()
class MyApp(ShowBase): def __init__(self, server): ShowBase.__init__(self) #the way the user interface can read held down buttons is by #setting the button to be true when it's pressed down, and then #it sets it back to false when it's released #I have a constant while loop that'll simply read the key dictionary #and act whenever one of the values reads True, or in this case 1 self.keys = {"w": 0, "s": 0, "d": 0, "a":0,"u":0, "e":0,"r": 0,"l": 0} self.initPart2() #part 2 of the init, the first one got taken up by alot of comments def initPart2(self): #assigns all of the variables needed in the class self.defineVariables() self.loadEnvironments() self.camera.setPos(29,-20,2) # self.camera.setHpr(-123.333, 0, 0) self.loadModels() self.initializeKeys1() self.initializeKeys2() self.startThreads() #these are the data variables that are being sent by the server. so far, #I haven't displayed any of these variables, as I've noticed they cause #a fair amount of lag/delay, but I am implementing the gyroscope values def defineVariables(self): self.initializePiVariables() self.initializePandaVarialbes() def initializePiVariables(self): self.ail = 0 self.ele = 0 self.thr = 0 self.rud = 0 self.gyroX = 0 self.gyroY = 0 self.yaw = 0 #initializing more global variables def initializePandaVarialbes(self): self.cameraSpeed = 0.5 self.moveSpeed = 0.2 self.quadDistance = 15 self.noYawInput = True self.throttlePower = "o " self.dX = 0 self.dTheta = 0 self.isMoving = False self.dictOfRecords = dict() self.keysPressedDown = set() self.username = "" self.initializePandaVariablesPart2() def initializePandaVariablesPart2(self): self.timer = 0.00 self.timerRunning = False self.timerLastModified = self.getTime() self.initializePromptTextPart1() self.initializePromptTextPart2() self.initializePressedDownKeyText() self.toggleLiftOff = True self.listOfModelPaths= ['models/fighter/fighter', 'models/boeing/boeing707', 'models/r2d2/r2d2', 'models/blimp/blimp', 'models/seeker/seeker', 'models/jeep/jeep'] self.modelIndex = 0 def initializePromptTextPart1(self): self.timerText = TextNode('timer') self.timerText.setText("Time:" + "0" + str(self.timer)) self.timerText.setShadow(0.05, 0.05) self.timerTextNodePath = aspect2d.attachNewNode(self.timerText) self.timerTextNodePath.setScale(0.07) self.timerTextNodePath.setPos(1.2,0,0.9) self.saveTimeText = TextNode('would you like to save?') self.saveTimeText.setText('')# self.saveTimeText.setShadow(0.05, 0.05) self.saveTimeTextNodePath = aspect2d.attachNewNode(self.saveTimeText) self.saveTimeTextNodePath.setScale(0.07) self.saveTimeTextNodePath.setPos(1.1, 0, 0.8) def initializePromptTextPart2(self): self.thrStatus = "" self.loadModelsText = "Select your model!\nPress [B] to go back!" line1 = "Press [H] for Help!\n" line2 = "Press [L] to load high scores!\n" line3 = "Press [G] to change skins!\n\n" line4 = "Throttle Status: " + self.thrStatus self.helperText = line1 + line2 + line3 + line4 self.helpText = TextNode('help') self.helpText.setText(self.helperText) self.helpTextNodePath = aspect2d.attachNewNode(self.helpText) self.helpTextNodePath.setScale(0.07) self.helpTextNodePath.setPos(-1.5,0,0.9) self.helpText.setShadow(0.05, 0.05) self.initializeUserInputText() def initializeUserInputText(self): self.loadModelText = TextNode('load models') self.loadModelText.setText("") self.loadModelTextNodePath = aspect2d.attachNewNode(self.loadModelText) self.loadModelTextNodePath.setScale(0.07) self.loadModelTextNodePath.setPos(-1.5,0,0.9) self.loadModelText.setShadow(0.05, 0.05) self.defaultText = "type in your name!" self.textObject=OnscreenText(text=self.defaultText,pos = (1.25,-0.95), scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1) self.nameEntry=DirectEntry(text = "",scale=.05,command=self.setText, initialText="Type Something", numLines = 2,focus=1, focusInCommand=self.clearText) self.nameEntry.setPos(1.05,0,-0.8) def initializePressedDownKeyText(self): self.initializePressedDownKeysPart1() self.initializePressedDownKeysPart2() self.initializePressedDownKeysPart3() self.initializePressedDownKeysPart4() def initializePressedDownKeysPart1(self): self.wText = TextNode('w') self.wText.setText("w") self.wText.setShadow(0.05, 0.05) self.wTextNodePath = aspect2d.attachNewNode(self.wText) self.wTextNodePath.setScale(0.07) self.wTextNodePath.setPos(-1.6,0,-0.75) self.sText = TextNode('s') self.sText.setText("s") self.sText.setShadow(0.05, 0.05) self.sTextNodePath = aspect2d.attachNewNode(self.sText) self.sTextNodePath.setScale(0.07) self.sTextNodePath.setPos(-1.35,0,-0.75) def initializePressedDownKeysPart2(self): self.aText = TextNode('a') self.aText.setText("a") self.aText.setShadow(0.05, 0.05) self.aTextNodePath = aspect2d.attachNewNode(self.aText) self.aTextNodePath.setScale(0.07) self.aTextNodePath.setPos(-1.1,0,-0.75) self.dText = TextNode('d') self.dText.setText("d") self.dText.setShadow(0.05, 0.05) self.dTextNodePath = aspect2d.attachNewNode(self.dText) self.dTextNodePath.setScale(0.07) self.dTextNodePath.setPos(-0.85,0,-0.75) def initializePressedDownKeysPart3(self): self.upText = TextNode('Up') self.upText.setText("Up") self.upText.setShadow(0.05, 0.05) self.upTextNodePath = aspect2d.attachNewNode(self.upText) self.upTextNodePath.setScale(0.07) self.upTextNodePath.setPos(-1.6,0,-0.85) self.downText = TextNode('Down') self.downText.setText("Down") self.downText.setShadow(0.05, 0.05) self.downTextNodePath = aspect2d.attachNewNode(self.downText) self.downTextNodePath.setScale(0.07) self.downTextNodePath.setPos(-1.35,0,-0.85) def initializePressedDownKeysPart4(self): self.rightText = TextNode('Left') self.rightText.setText("Left") self.rightText.setShadow(0.05, 0.05) self.rightTextNodePath = aspect2d.attachNewNode(self.rightText) self.rightTextNodePath.setScale(0.07) self.rightTextNodePath.setPos(-1.1,0,-0.85) self.leftText = TextNode('Right') self.leftText.setText("Right") self.leftText.setShadow(0.05, 0.05) self.leftTextNodePath = aspect2d.attachNewNode(self.leftText) self.leftTextNodePath.setScale(0.07) self.leftTextNodePath.setPos(-0.85,0,-0.85) def setText(self, textEntered): self.textObject.setText(textEntered) self.username = self.textObject.getText() #clear the text def clearText(self): self.nameEntry.enterText('') #returns the date for the timer method def getTime(self): time = str(datetime.datetime.now()) return (time[11:]) #this returns the string date in a format that is compatibile for #the save and load files method def getDateTime(self): time = str(datetime.datetime.now()) return time[:10] + "," + time[11:19] #loads the environments. So far I have the sky model and a jungle #environment. def loadEnvironments(self): self.disableMouse() self.environ = self.loader.loadModel("models/sky/blue-sky-sphere") self.environ.reparentTo(self.render) self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(0, 0, 0) self.environ1 = self.loader.loadModel("models/course/course1") self.environ1.reparentTo(self.render) self.environ1.setScale(2.0, 2.0, 2.0) self.environ1.setPos(0, 0, 0) self.environ1.setHpr(123,0,0) #this method will load all of the models. So far I only have two, but #I intend on adding more later def loadModels(self): self.loadPanda() self.loadQuad() #this method loads the panda model. It has a walk animation, as well #as a movement path. I modified parts of this code while following a panda3D tutorial: #https://www.panda3d.org/manual/index.php/Loading_and_Animating_the_Panda_Model def loadPanda(self): self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.pandaActor.setScale(0.005, 0.005, 0.005) self.pandaActor.reparentTo(self.render) self.pandaActor.setHpr(90,0,0) # Loop its animation. self.pandaActor.loop("walk") # Create the four lerp intervals needed for the panda to move pandaPosInterval1 = self.pandaActor.posInterval(13, Point3(-33, 0, -1), startPos=Point3(-41, 0,-1)) pandaPosInterval2 = self.pandaActor.posInterval(13, Point3(-41, 0, -1), startPos=Point3(-33, 0, -1)) pandaHprInterval1 = self.pandaActor.hprInterval(3, Point3(-90, 0, 0), startHpr=Point3(90, 0, 0)) pandaHprInterval2 = self.pandaActor.hprInterval(3, Point3(90, 0, 0), startHpr=Point3(-90, 0, 0)) # Create and play the sequence that coordinates the intervals. self.pandaPace = Sequence(pandaPosInterval1,pandaHprInterval1, pandaPosInterval2, pandaHprInterval2, name="pandaPace") self.pandaPace.loop() #this will load the quad model. As of right now, it is only a demo model #but I plan on making my own quad model later def loadQuad(self): # Load and transform the panda actor. self.quad = loader.loadModel('models/fighter/fighter') self.quad.reparentTo(self.render) self.quad.setScale(0.15, 0.15, 0.15) self.quad.setPos(self.camera, 0, self.quadDistance,-2) self.quad.setHpr(self.camera, 0,0,0) #sets the keyinputs. I split it into two methods to make it more #readable #the way the key inputs are read in panda is pressing the key down #generates one pulse, and then releasing the button generates another #pulse. Each time a pulse is fired, panda will set the value of a key #to be either True (when it's pressed down) or False (when it's not #pressed down). def initializeKeys1(self): self.accept("escape", sys.exit) self.accept("arrow_up", self.setKey, ["u", 1, server]) self.accept("arrow_up-up", self.setKey, ["u", 0, server]) self.accept("arrow_down", self.setKey, ["e", 1, server]) self.accept("arrow_down-up", self.setKey, ["e", 0, server]) self.accept("arrow_right", self.setKey, ["l", 1, server]) self.accept("arrow_right-up", self.setKey, ["l", 0, server]) self.accept("arrow_left", self.setKey, ["r", 1, server]) self.accept("arrow_left-up", self.setKey, ["r", 0, server]) self.accept('g', self.pickModel, []) #part two of initialize keys def initializeKeys2(self): self.accept("w", self.setKey, ["w", 1, server]) self.accept("w-up", self.setKey, ["w", 0, server]) self.accept("s", self.setKey, ["s", 1, server]) self.accept("s-up", self.setKey, ["s", 0, server]) self.accept("d", self.setKey, ["d", 1, server]) self.accept("d-up", self.setKey, ["d", 0, server]) self.accept("a", self.setKey, ["a", 1, server]) self.accept("a-up", self.setKey, ["a", 0, server]) self.accept('8', self.sendMsg, ['8', server]) #arm self.accept('9', self.sendMsg, ['9', server]) #disarm self.accept('l', self.displayHighScores, []) self.accept('p', self.startStopTimer, []) self.accept('h', self.getHelp, []) self.accept('b', self.returnToGame, []) self.accept('y', self.saveTime, []) self.accept('n', self.resetTime, []) self.accept('1', self.swapModel, [1]) self.accept('2', self.swapModel, [2]) self.accept('3', self.swapModel, [3]) self.accept('4', self.swapModel, [4]) self.accept('5', self.swapModel, [5]) self.accept('6', self.swapModel, [6]) #saves the times on a text file def swapModel(self, index): # self.modelIndex += 1 # self.modelIndex = self.modelIndex % len(self.listOfModelPaths) index -= 1 if index < len(self.listOfModelPaths): path = self.listOfModelPaths[index] self.quad.removeNode() self.quad = loader.loadModel(path) self.quad.reparentTo(self.render) scale = self.pickScale(path) self.quad.setScale(scale) self.quad.setPos(self.camera, 0, self.quadDistance,-2) self.quad.setHpr(self.camera, 0,0,0) #this is the overall method used to display the models when the [G] #button is pressed. I split it into a top down design so it is easier #to read def pickModel(self): self.loadPickModelPart1() self.loadPickModelPart2() self.loadPickModelPart3() self.loadPickModelTextPart1() self.loadPickModelTextPart2() self.loadPickModelTextPart3() #loads the Fighter and Boeing model def loadPickModelPart1(self): self.helpText.setText("") self.loadModelText.setText(self.loadModelsText) self.skin1 = self.loader.loadModel("models/fighter/fighter") self.skin1.reparentTo(self.render) self.skin1.setScale(0.1, 0.1, 0.1) self.skin1.setPos(self.camera, -4.5, self.quadDistance,2) self.skin1.setHpr(self.camera, 180, 0,0) self.skin2 = self.loader.loadModel("models/boeing/boeing707") self.skin2.reparentTo(self.render) self.skin2.setScale(0.08, 0.08, 0.08) self.skin2.setPos(self.camera, 0.5, self.quadDistance,2) self.skin2.setHpr(self.camera, 180, 0,0) #loads the R2D2 and blimp model def loadPickModelPart2(self): self.skin3 = self.loader.loadModel("models/r2d2/r2d2") self.skin3.reparentTo(self.render) self.skin3.setScale(0.5, 0.5, 0.5) self.skin3.setPos(self.camera, 4.5, self.quadDistance,2) self.skin3.setHpr(self.camera, 180, 0,0) self.skin4 = self.loader.loadModel("models/blimp/blimp") self.skin4.reparentTo(self.render) self.skin4.setScale(0.03, 0.03, 0.03) self.skin4.setPos(self.camera, -4.5, self.quadDistance,-0.5) self.skin4.setHpr(self.camera, 180, 0,0) #loads the seeker and jeep model def loadPickModelPart3(self): self.skin5 = self.loader.loadModel("models/seeker/seeker") self.skin5.reparentTo(self.render) self.skin5.setScale(0.8, 0.8, 0.8) self.skin5.setPos(self.camera, 0.5, self.quadDistance,-0.5) self.skin5.setHpr(self.camera, 180, 0,0) self.skin6 = self.loader.loadModel("models/jeep/jeep") self.skin6.reparentTo(self.render) self.skin6.setScale(0.17, 0.17, 0.17) self.skin6.setPos(self.camera, 4.5, self.quadDistance,-1.0) self.skin6.setHpr(self.camera, 0, 0,0) #loads label text for the figher and boeing def loadPickModelTextPart1(self): self.skin1Text = TextNode('skin1') self.skin1Text.setText("[1] - Fighter") self.skin1Text.setShadow(0.05, 0.05) self.skin1TextNodePath = aspect2d.attachNewNode(self.skin1Text) self.skin1TextNodePath.setScale(0.07) self.skin1TextNodePath.setPos(-1.3,0,0.3) self.skin2Text = TextNode('skin2') self.skin2Text.setText("[2] - Boeing707") self.skin2Text.setShadow(0.05, 0.05) self.skin2TextNodePath = aspect2d.attachNewNode(self.skin2Text) self.skin2TextNodePath.setScale(0.07) self.skin2TextNodePath.setPos(-0.1,0,0.3) #loads label text for R2D2 and the Blimp def loadPickModelTextPart2(self): self.skin3Text = TextNode('skin3') self.skin3Text.setText("[3] - R2D2") self.skin3Text.setShadow(0.05, 0.05) self.skin3TextNodePath = aspect2d.attachNewNode(self.skin3Text) self.skin3TextNodePath.setScale(0.07) self.skin3TextNodePath.setPos(1,0,0.3) self.skin4Text = TextNode('skin4') self.skin4Text.setText("[4] - Blimp") self.skin4Text.setShadow(0.05, 0.05) self.skin4TextNodePath = aspect2d.attachNewNode(self.skin4Text) self.skin4TextNodePath.setScale(0.07) self.skin4TextNodePath.setPos(-1.3,0,-0.5) #loads the label text for Seeker and Jeep def loadPickModelTextPart3(self): self.skin5Text = TextNode('skin5') self.skin5Text.setText("[5] - Seeker") self.skin5Text.setShadow(0.05, 0.05) self.skin5TextNodePath = aspect2d.attachNewNode(self.skin5Text) self.skin5TextNodePath.setScale(0.07) self.skin5TextNodePath.setPos(-0.1,0,-0.5) self.skin6Text = TextNode('skin6') self.skin6Text.setText("[6] - Jeep") self.skin6Text.setShadow(0.05, 0.05) self.skin6TextNodePath = aspect2d.attachNewNode(self.skin6Text) self.skin6TextNodePath.setScale(0.07) self.skin6TextNodePath.setPos(1,0,-0.5) #this is the overall method that will return how the model should #be sized. All of this is magic numbers, and I found them based on #my personal preference to how the models should look aesthetically def pickScale(self, path): if path == "models/fighter/fighter": return (0.15,0.15,0.15) elif path == "models/boeing/boeing707": return (0.1,0.1,0.1) elif path == "models/r2d2/r2d2": return (0.7,0.7,0.7) elif path == "models/blimp/blimp": return (0.05,0.05,0.05) elif path == "models/seeker/seeker": return (0.8,0.8,0.8) elif path == 'models/jeep/jeep': return (0.25,0.25,0.25) #This will save whatever time the user has, assuming the inputted #username isn't empty. It will save the data into a text file called #"Records" def saveTime(self): savedTime = self.timer if self.username != '': if (os.path.isfile('Records')): file = open('Records', "r") result = (self.username + "," + self.getDateTime() + "," + savedTime + "\n") stringOfRecords = file.read() stringOfRecords += result file = open('Records', "w") file.write(stringOfRecords) else: file = open('Records', "w") file.write(self.username + "," + self.getDateTime() + "," + savedTime + "\n") self.timerText.setText("Time: 00.0") self.timer = 0 #this will reset the timerText to 0:00 and the #timer variable back to zero. def resetTime(self): self.timerText.setText("Time: 00.0") self.timer = 0 #this will reset the menu screen to the default display. I had to add #a try block to it just in case some of the models don't properly load #if they don't load, and you try to delete them, the program will crash def returnToGame(self): try: self.helpText.setText(self.helperText) self.loadModelText.setText("") self.skin1.removeNode() self.skin2.removeNode() self.skin3.removeNode() self.skin4.removeNode() self.skin5.removeNode() self.skin6.removeNode() self.skin1Text.setText("") self.skin2Text.setText("") self.skin3Text.setText("") self.skin4Text.setText("") self.skin5Text.setText("") self.skin6Text.setText("") except: pass #This is the help menu when [H] is pressed def getHelp(self): line1 = "Press [B] to go back\n" line2 = "[W] - Move forwards\n" line3 = "[S] - Move backwards\n" line4 = "[D] - Move right\n" line5 = "[A] - Move left\n" line6 = "[Right Arrow] - Rotate right\n" line7 = "[Left Arrow] - Rotate left\n" line8 = "[Up Arrow] - Move up\n" line9 = "[Down Arrow] - Move down\n" line10 = "[8] - Arm Copter\n" line11 = "[9] - Disarm Copter" self.helpText.setText(line1 + line2 + line3 + line4 + line5 + line6 + line7 + line8 + line9 + line10 + line11) #opens up a file called "records" if it exists, and then proceeds to load #and read the data def displayHighScores(self): if (os.path.isfile('Records')): file = open('Records', 'r') stringRecords = file.read() stringRecords = stringRecords.split('\n')[:-1] self.dictOfRecords = dict() for person in stringRecords: person = person.split(',') key = person[0] #sets the key index to the person's name person = person[1:] #cuts the name part off now if key in self.dictOfRecords: self.dictOfRecords[key] += [person] else: self.dictOfRecords[key] = [person] self.organizeDictionaryOfRecords() #once the file has been read, this method will decipher the dictionary of #people with their lists of times. It will then sort them in descending order #this is all destructive, by the way. def organizeDictionaryOfRecords(self): for person in self.dictOfRecords: #jason, Jason if len(self.dictOfRecords[person]) > 1: self.sortTimes(self.dictOfRecords[person]) line1 = "Record Board: (date, datetime, time)\n" line2 = "Press [B] to go back\n" sortedStringOfRecords = line1 + line2 for person in self.dictOfRecords: sortedStringOfRecords += person + ":\n" for stats in self.dictOfRecords[person]: for stat in stats: sortedStringOfRecords += stat + "\t\t" sortedStringOfRecords += "\n" sortedStringOfRecords += "\n" self.helpText.setText(sortedStringOfRecords) #this is a variation of the merge method in merge sort, modified to sort #lists of lists. def merge(self, l, s1, s2, end): index1 = s1 index2 = s2 length = end - s1 aux = [None] * length for i in range(length): if (index1 == s2) or ((index2 != end) and (self.convertToSeconds(l[index1][2])>self.convertToSeconds(l[index2][2]))): aux[i] = l[index2] index2 += 1 else: aux[i] = l[index1] index1 += 1 for i in range(s1, end): l[i] = aux[i - s1] #when I was comparing times, I forgot I also had to compare times when it #read like 1:02, and I was no longer just comparing seconds. So I had to #write a method that will conver the time first to seconds before it #gets compared. def convertToSeconds(self, time): if ":" in time: minutes = float(time[:time.index(":")]) seconds = minutes * 60 + float(time[time.index(":") + 1:]) return seconds return float(time) #this is parent the "mergeSort", modified to sort the list of lists def sortTimes(self, listOfTimes): n = len(listOfTimes) step = 1 while (step < n): for s1 in range(0, n, 2 * step): s2 = min(s1 + step, n) end = min(s1 + 2 * step, n) self.merge(listOfTimes, s1, s2, end) step *= 2 #toggles the self.timerRunning variable, and sets the timerBegin variable #if the timer just started def startStopTimer(self): if not self.timerRunning: self.timerBegin = self.getTime() self.timerRunning = not self.timerRunning #to make things more organized, I combined all of the threaded methods #here, so I can modify/add more in the future if needed def startThreads(self): thread.start_new_thread(self.rotateQuad, (server,)) thread.start_new_thread(self.handleServerMsg, (server,)) thread.start_new_thread(self.moveCamera, (server,)) thread.start_new_thread(self.spinQuad, (server, )) thread.start_new_thread(self.evaluateHits, (server, )) thread.start_new_thread(self.runTimer, (server, )) #this method is only used for button actions that don't require buttons #to be held down. For example, pressing 8 and 9 will arm and disarm the #copter, and holding them down won't do anything. So sendMsg will basically #send a single pulse to the server, which will know what to do for #specific single pulses. def sendMsg(self, msg, server): server.send(bytes(msg)) #evalKey is only used by the down button. It essentially determines #if the copter is on the ground before it tries to lower the quad's #actual throttle. I do this to simulate more of a "real" effect, where #the quad in real life will only shut down once the quad in the #simulation has actually touched the ground. def evalKey(self, key, val, server): if self.quad.getZ() < 0 and not self.keys['e']: self.setKey(key, val, server) else: self.keys[key] = val #set key will merely change the dictionary of keys to whatever value #it is inputed. Then, it will send a pulse to the server, which will #read it as a double pulse and modify its own variables accordingly. def setKey(self, key, val, server): self.keys[key] = val server.send(bytes(key)) for key in self.keys: if self.keys[key]: self.keysPressedDown.add(key) else: if key in self.keysPressedDown: self.keysPressedDown.remove(key) # self.updatePressedDownKeys() self.setPressedDownKeys() def setPressedDownKeys(self): if self.keys['w']: self.wText.setText('w') else: self.wText.setText('') if self.keys['a']: self.aText.setText('a') else: self.aText.setText('') if self.keys['s']: self.sText.setText('s') else: self.sText.setText('') if self.keys['d']: self.dText.setText('d') else: self.dText.setText('') if self.keys['u']: self.upText.setText('Up') else: self.upText.setText('') if self.keys['e']: self.downText.setText('Down') else: self.downText.setText('') if self.keys['l']: self.leftText.setText('Right') else: self.leftText.setText('') if self.keys['r']: self.rightText.setText('Left') else: self.rightText.setText('') # def updatePressedDownKeys(self): pass def moveCamera(self, server): while True: try: if self.quad.getZ() < 0: server.send(bytes('1')) #ground else: server.send(bytes('0')) #air if self.quad.getZ() > 0: if self.keys["w"]: self.camera.setPos(self.camera, 0, self.moveSpeed, 0) self.quad.setPos(self.camera, 0, self.quadDistance, -2) self.tiltForward() elif self.keys["s"]: self.camera.setPos(self.camera, 0, -self.moveSpeed, 0) self.quad.setPos(self.camera, 0, self.quadDistance, -2) self.tiltBackward() else: self.pitchSelfLevel() if self.keys["d"]: self.quad.setHpr(self.quad, 0, 0, pi / 8) self.isMoving = True elif self.keys["a"]: self.quad.setHpr(self.quad, 0, 0, -pi / 8) self.isMoving = True elif not (self.keys['d'] and self.keys['a']): self.isMoving = False self.driftStabilize() self.moveCameraPart2(server) except: pass def moveCameraPart2(self, server): if self.keys["u"]: if self.thr >= 6.4: if self.toggleLiftOff: self.thrStatus = "Take off!" line1 = "Press [H] for Help!\n" line2 = "Press [L] to load high scores!\n" line3 = "Press [G] to change skins!\n\n" line4 = "Throttle Status: " + self.thrStatus self.helpText.setText(line1 + line2 + line3 + line4) self.toggleLiftOff = False self.camera.setPos(self.camera, 0, 0, self.moveSpeed / 2) self.quad.setPos(self.camera, 0, self.quadDistance, -2) else: self.thrStatus = "Starting up motors..." line1 = "Press [H] for Help!\n" line2 = "Press [L] to load high scores!\n" line3 = "Press [G] to change skins!\n\n" line4 = "Throttle Status: " + self.thrStatus self.helpText.setText(line1 + line2 + line3 + line4) self.moveCameraPart3(server) #this is the down arrow, but I had no other key to set it to : / #the keys sent must be of one character long because thats how #the server can read messages (it goes through each message #character by character) def moveCameraPart3(self, server): if self.keys["e"]: if self.quad.getZ() > -0.01: self.camera.setPos(self.camera, 0, 0, -self.moveSpeed / 2) self.quad.setPos(self.camera, 0, self.quadDistance, -2) elif self.thr < 5.3: self.thrStatus = "Landed!" line1 = "Press [H] for Help!\n" line2 = "Press [L] to load high scores!\n" line3 = "Press [G] to change skins!\n\n" line4 = "Throttle Status: " + self.thrStatus self.helpText.setText(line1 + line2 + line3 + line4) else: self.toggleLiftOff = True self.thrStatus = "Landing..." line1 = "Press [H] for Help!\n" line2 = "Press [L] to load high scores!\n" line3 = "Press [G] to change skins!\n\n" line4 = "Throttle Status: " + self.thrStatus self.helpText.setText(line1 + line2 + line3 + line4) self.moveCameraPart4(server) def moveCameraPart4(self, server): if self.keys["r"]: self.noYawInput = False elif self.keys['l']: self.noYawInput = False elif not (self.keys["r"] and self.keys["l"]): self.yawSelfLevel() time.sleep(0.01) #this method if replacing the if statement above will manually control #the rotation of the quad regardless of the overall orientation of #the physical quad. I'm going to leave the code here just in case #I ever need to manually control the quad in the future. # if self.keys["l"]: # self.camera.setHpr(self.camera, -self.cameraSpeed / 2, 0,0) # deltaX = - (cos(radians(90 - self.cameraSpeed)) * # self.quadDistance) * cos(radians(self.cameraSpeed)) # deltaY = (cos(radians(90 - self.cameraSpeed)) * # self.quadDistance) * sin(radians(self.cameraSpeed)) # self.camera.setPos(self.camera, deltaX, deltaY, 0) # self.quad.setHpr(self.camera, 0,self.quad.getP(),self.quad.getR()) # elif self.keys["r"]: # self.camera.setHpr(self.camera, self.cameraSpeed / 2, 0, 0) # deltaX = (cos(radians(90 - self.cameraSpeed)) * # self.quadDistance) * cos(radians(self.cameraSpeed)) # deltaY = (cos(radians(90 - self.cameraSpeed)) * # self.quadDistance) * sin(radians(self.cameraSpeed)) # self.camera.setPos(self.camera, deltaX, deltaY, 0) # self.quad.setHpr(self.camera,0,self.quad.getP(),self.quad.getR()) def tiltForward(self): desiredVal = -15 error = desiredVal - self.quad.getP() self.quad.setHpr(self.quad, 0, error * 0.05, 0) def tiltBackward(self): desiredVal = 15 error = desiredVal - self.quad.getP() self.quad.setHpr(self.quad, 0, error * 0.05, 0) def pitchSelfLevel(self): desiredVal = 0 error = desiredVal - self.quad.getP() self.quad.setHpr(self.quad, 0, error * 0.05, 0) #currently working on this aspect of the simulation: the quad is noted #to have random bursts of movement which causes a lot of jitter; trying #to see how I can manage to stabilize the motion def rotateQuad(self, server): #this rotates roll while True: try: self.updateSaveTimer() #this will rotate the quad error = self.gyroX / 2 - self.quad.getR() self.quad.setHpr(self.quad, 0, 0, error * 0.01) if self.isMoving: maxVelocity = 0.2 sign = 1 if self.quad.getR() < 0: sign = -1 error = (sign * maxVelocity) - self.dX self.dX += error * 0.01 self.camera.setPos(self.camera, self.dX, 0, 0) self.quad.setPos(self.camera, 0,self.quadDistance,-2) except: pass time.sleep(0.01) #This is prompted whenever the quad crosses the finish line. def updateSaveTimer(self): if not self.timerRunning and self.timer != 0: text = 'Would you like to\nsave this time?\n(Y/N)' self.saveTimeText.setText(text) else: self.saveTimeText.setText('') #This is another stability algorithm tha tI wrote. Eseentially, it will #bring the copter to a smooth stop instead of it being jittery. However, #this can only work so well, as the quad is still 90% affected by the #physical orientation. def driftStabilize(self): error = 0 - self.dX self.dX += error * 0.05 self.camera.setPos(self.camera, self.dX, 0, 0) self.quad.setPos(self.camera, 0,self.quadDistance,-2) #controls the yaw direction of the quad. def spinQuad(self, server): while True: try: if not self.noYawInput: sign = 1 if self.yaw < 0: sign = -1 self.dTheta = ((self.yaw / 100)) * self.cameraSpeed * 4 self.camera.setHpr(self.camera, self.dTheta, 0,0) absRotationSpeed = abs(self.dTheta) deltaX = sign * (cos(radians(90 - absRotationSpeed)) * self.quadDistance) * cos(radians(absRotationSpeed)) deltaY = (cos(radians(90 - absRotationSpeed)) * self.quadDistance) * sin(radians(absRotationSpeed)) self.camera.setPos(self.camera, deltaX, deltaY, 0) self.quad.setPos(self.camera, 0,self.quadDistance, -2) self.quad.setHpr(self.camera, 0,self.quad.getP(), self.quad.getR()) except: pass time.sleep(0.01) #yaw refers to the rotation about its z axis. This will smoothen out #the quad's z axis rotation def yawSelfLevel(self): self.noYawInput = True error = 0 - self.dTheta self.dTheta += error * 0.05 self.camera.setHpr(self.camera, self.dTheta, 0, 0) self.quad.setHpr(self.camera, 0, self.quad.getP(), self.quad.getR()) self.quad.setPos(self.camera, 0, self.quadDistance, -2) #generic evaluateHits function. Will add more onto it later. def evaluateHits(self, server): while True: try: x = self.quad.getX() y = self.quad.getY() if (x > 18 and x < 38) and (y > 9 and y < 14): self.handleTimer() # self.helpText.setText(str(self.thr)) except: pass time.sleep(0.1) #an issue that I ran into was having the timer run on and off when #the quad is hovering over the finish line, since it takes time #to actually physically cross the finish line. Therefore, I made a function #that makes sure the time between each time the quad hits the finish #line is greater than 1 second. def handleTimer(self): timeElapsed = self.calculateTime(self.getTime(), self.timerLastModified) self.timerLastModified = self.getTime() if int(timeElapsed[0]) >= 1 or int(timeElapsed[1]) >= 1: self.startStopTimer() #this time method is run continuously. However, it will only actually do #something if the self.timerRunning variable is true. It will update #the self.timerText text to the running time def runTimer(self, server): while True: if self.timerRunning: self.timer = self.calculateTime(self.getTime(),self.timerBegin) self.timerText.setText("Time: " + self.timer) time.sleep(0.1) #calculates the time elapsed given a current time and the start time. #return a string in the format MM:SS, unless one of those values = 0, #then it will ignore that part. def calculateTime(self, currentTime, startTime): (currentTime, startTime)=(currentTime.split(':'),startTime.split(':')) resultTimer = [] for timerIndex in range(len(startTime)): diff=float(currentTime[timerIndex])-float(startTime[timerIndex]) if diff < 0: diff += 60 resultTimer[timerIndex -1 ] -= 1 resultTimer.append(diff) time = "" (minutes,seconds)=(resultTimer[1],resultTimer[2]) if minutes != 0: time += str(minutes)[0] + ":" if seconds != 0: seconds = str(seconds)[:4] + ":" if seconds.index('.') == 1: seconds = "0" + seconds time += seconds return time[:-1] #this is a thread that is constantly run to update the server variables #I ended up not using a bunch of these variables, because I ran into #a lot of lag whenever I tried to constantly update textFields to read #whatever the server sends. def handleServerMsg(self, server): while True: msg = server.recv(1000).decode('UTF-8') try: msg = eval(msg) self.distance = msg["distance"] self.gyroX = msg["gyroX"] self.gyroY = msg["gyroY"] self.yaw = msg["yaw"] // 100 self.ele = msg["ele"] self.rud = msg["rud"] self.thr = msg["thr"] # print(self.thr) self.ail = msg["ail"] # print(self.thr) except: pass
class DPiece(DistributedSmoothNode): def __init__(self, cr): self.modelName = "" DistributedSmoothNode.__init__(self, cr) self.setCacheable(1) self.model = None self.tagText = None self.nameTag = None self.acceptOnce("BoardAnimationDone", self.show) def generate(self): DistributedSmoothNode.generate(self) self.activateSmoothing(True, False) self.startSmooth() def announceGenerate(self): DistributedSmoothNode.announceGenerate(self) self.reparentTo(render) self.d_getNameForNameTag() def disable(self): self.stopSmooth() DistributedSmoothNode.disable(self) def delete(self): if self.model is not None: self.model.removeNode() if self.nameTag is not None: self.nameTag.removeNode() DistributedSmoothNode.delete(self) def show(self): """Shows the piece and name tag of the player if they are already created. Otherwise it will spawn a task to check until it can finally be shown correctly.""" if self.model is not None: if self.model.isHidden(): self.model.show() self.model.setTransparency(1) LerpColorInterval(self.model, 1, self.model.getColor(), (0, 0, 0, 0)).start() else: taskMgr.doMethodLater(0.5, self.show, "retryShowPiece", extraArgs=[]) if self.nameTag is not None: if self.nameTag.isHidden(): self.nameTag.show() self.nameTag.setTransparency(1) LerpColorInterval(self.nameTag, 1, self.nameTag.getColor(), (0, 0, 0, 0)).start() else: taskMgr.doMethodLater(0.5, self.show, "retryShowPiece", extraArgs=[]) def setModel(self, modelName): """Set and load the given model and ask if the board animation has been finished yet to show the model.""" if modelName == "": return self.modelName = modelName self.model = base.loader.loadModel(self.modelName) self.model.reparentTo(self) self.model.hide() base.messenger.send("checkBoardAnimationDone") def d_getNameForNameTag(self): # this will call the createNameTag function through the server as the # server has stored the name self.sendUpdate("getNameForNameTag") def createNameTag(self, name): """Create the floating name above a player and set the name. If a name tag has already been created it will simply update the text to the new name.""" if self.nameTag is None: self.tagText = TextNode("NameTag") self.tagText.setText(name) self.tagText.setTextColor(0, 0, 0, 1) self.tagText.setAlign(TextNode.ACenter) self.nameTag = self.attachNewNode(self.tagText) self.nameTag.setBillboardAxis() self.nameTag.setZ(0.025) self.nameTag.setScale(0.007) self.nameTag.setShaderAuto(True) self.nameTag.hide() else: self.tagText.setText(name)
def __init__(self, name, parent, pos = (0.0, 0.0, -0.5), scale = 0.09, color = (1.0, 1.0, 0, 1), sfx = None): self.color = color self._displaySfx = sfx textNode = TextNode('messageLabel.' + name) textNode.setTextColor(self.color) textNode.setAlign(TextNode.ACenter) textNode.setFont(ToontownGlobals.getSignFont()) textNode.setShadow(0.06, 0.06) textNode.setShadowColor(0.5, 0.5, 0.5, 1.0) self.pos = pos self.scale = scale self.messageLabel = parent.attachNewNode(textNode) self.messageLabel.setPos(self.pos) self.messageLabel.setScale(self.scale) self.messageLabel.stash() self.transitionInterval = Sequence(name='%s.transitionInterval' % self.__class__.__name__)
def __init__(self, base, Golog, folder_path, parent=None): # Set up basic attributes self.base = base self.golog = Golog self.bools = {'textboxes': True} self.buttons = dict() self.window_tasks = dict() self.bt = None self.mw = None self.listener = DirectObject() self.folder_path = folder_path self.file_path = os.path.abspath(self.folder_path + '/' + self.golog.label + '.golog') self.has_window = False self.parent = parent #for autosaving up to original golog self.reset = self.basic_reset self.garbage = [] #list of deleted math_data/graphics_data etc. #create a 2d rende self.render2d = NodePath('2d render') self.camera2D = self.render2d.attachNewNode(Camera('2d Camera')) self.camera2D.setDepthTest(False) self.camera2D.setDepthWrite(False) lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setNearFar(-1000, 1000) self.camera2D.node().setLens(lens) # make a dictionary of mode_heads in the underlying golog if hasattr(self.golog, 'mode_heads'): m = 0 while m in self.golog.mode_heads.keys(): m += 1 #get smallest unused mode_head index self.index = m self.label = self.golog.label + "_mode_head_" + str(self.index) self.golog.mode_heads[self.index] = self else: self.golog.mode_heads = dict() self.index = 0 self.label = self.golog.label + "_mode_head_" + str(self.index) self.golog.mode_heads[self.index] = self ########## ### set up collision handling ### self.queue = CollisionHandlerQueue() self.selected = [[], []] #tracking previously selected nodes of each level # set up mouse picker self.pickerNode = CollisionNode('mouseRay') self.pickerNP = self.golog.camera.attachNewNode( self.pickerNode) #attach collision node to camera self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.pickerNode.set_into_collide_mask( 0 ) #so that collision rays don't collide into each other if there are two mode_heads self.golog.cTrav.addCollider( self.pickerNP, self.queue) #send collisions to self.queue # set up plane for picking self.planeNode = self.golog.render.attachNewNode("plane") self.planeNode.setTag( "mode_head", self.label) # tag to say it belongs to this mode_head self.planeNode.setTag("mode_node", 'plane') self.planeFromObject = self.planeNode.attachNewNode( CollisionNode("planeColNode")) self.planeFromObject.node().addSolid( CollisionPlane(Plane(Vec3(0, -1, 0), Point3(0, 0, 0)))) ### # set up preview text self.textNP = self.render2d.attachNewNode(TextNode('text node')) self.textNP.setScale(.2) self.textNP.setPos(-1, 0, 0) self.textNP.show() #set up dragging info self.grabbed_dict = None
class ObjectLabel(VisibleObject): default_shown = False ignore_light = True font_init = False font = None appearance = None shader = None def __init__(self, names): VisibleObject.__init__(self, names) self.fade = 1.0 @classmethod def create_shader(cls): cls.appearance = ModelAppearance() cls.appearance.has_attribute_color = True cls.appearance.has_material = False cls.appearance.texture = True cls.appearance.texture_index = 0 cls.appearance.nb_textures = 1 cls.appearance.transparency = True cls.appearance.transparency_blend = TransparencyBlend.TB_Alpha cls.appearance.alpha_mask = True cls.shader = BasicShader(lighting_model=FlatLightingModel()) def check_settings(self): if self.parent.body_class is None: print("No class for", self.parent.get_name()) return self.set_shown(bodyClasses.get_show_label(self.parent.body_class)) @classmethod def load_font(cls): font = fontsManager.get_font(settings.label_font, Font.STYLE_NORMAL) if font is not None: cls.font = font.load() else: cls.font = None cls.font_init = True def create_instance(self): #print("Create label for", self.get_name()) self.label = TextNode(self.parent.get_ascii_name() + '-label') if not self.font_init: self.load_font() if self.font is not None: self.label.set_font(self.font) name = bayer.decode_name(self.parent.get_label_text()) self.label.setText(name) self.label.setTextColor(*srgb_to_linear(self.parent.get_label_color())) #node=label.generate() #self.instance = self.context.annotation.attachNewNode(node) #self.instance.setBillboardPointEye() #node.setIntoCollideMask(GeomNode.getDefaultCollideMask()) #node.setPythonTag('owner', self.parent) cardMaker = CardMaker(self.get_ascii_name() + '-labelcard') cardMaker.setFrame(self.label.getFrameActual()) cardMaker.setColor(0, 0, 0, 0) card_node = cardMaker.generate() self.label_instance = NodePath(card_node) tnp = self.label_instance.attachNewNode(self.label) #self.label_instance.setTransparency(TransparencyAttrib.MAlpha) #card.setEffect(DecalEffect.make()) #Using look_at() instead of billboard effect to also rotate the collision solid #card.setBillboardPointEye() #Using a card holder as look_at() is changing the hpr parameters self.instance = NodePath('label-holder') self.label_instance.reparentTo(self.instance) self.instance.reparentTo(self.context.annotation) self.instance_ready = True if self.shader is None: self.create_shader() self.shader.apply(self, self.appearance) self.shader.update(self, self.appearance) TransparencyBlend.apply(self.appearance.transparency_blend, self.instance) self.instance.setCollideMask(GeomNode.getDefaultCollideMask()) self.instance.set_depth_write(False) self.instance.set_color_scale(LColor(1, 1, 1, 1)) card_node.setPythonTag('owner', self.parent) self.look_at = self.instance.attachNewNode("dummy")
def __init__(self): ShowBase.__init__(self) base.disableMouse() self.makeAcog = loader.loadModel("phase_5/models/cogdominium/tt_m_ara_cbr_barrelRoom.bam") self.makeAcog.reparentTo(render) self.stomper1 = (self.makeAcog.find('**/stomper_GRP_01')) self.stomper2 = (self.makeAcog.find('**/stomper_GRP_02')) self.stomper3 = (self.makeAcog.find('**/stomper_GRP_03')) self.stomper4 = (self.makeAcog.find('**/stomper_GRP_04')) self.stomper5 = (self.makeAcog.find('**/stomper_GRP_05')) self.stomper6 = (self.makeAcog.find('**/stomper_GRP_06')) self.stomper7 = (self.makeAcog.find('**/stomper_GRP_07')) self.stomper8 = (self.makeAcog.find('**/stomper_GRP_08')) self.stomper9 = (self.makeAcog.find('**/stomper_GRP_09')) self.stomper10 = (self.makeAcog.find('**/stomper_GRP_10')) self.stomper11 = (self.makeAcog.find('**/stomper_GRP_11')) self.stomper12 = (self.makeAcog.find('**/stomper_GRP_12')) self.stomper3.setPos(0, 0, 18.00) self.stomper5.setPos(0, 0, 10.00) self.stomper4.setPos(0, 0, 22.00) self.stomper2.setPos(0, 0, 7.00) self.stomper7.setPos(0, 0, 0) self.stomper8.setPos(0, 0, 5.00) self.stomper9.setPos(0, 0, 13.00) self.stomper10.setPos(0, 0, 10.00) self.stomper11.setPos(0, 0, 22.00) self.stomper12.setPos(0, 0, 7.00) self.music = loader.loadMusic("phase_3/audio/bgm/cco_make_a_cog.wav") self.music.play() self.music.setLoop(True) self.elevator = loader.loadModel("phase_5/models/cogdominium/cogdominiumElevator.bam") self.elevator.reparentTo(self.render) self.elevator.setY(25.37) self.elevator.find('**/floor_light_buttons').removeNode() self.rightDoor = (self.elevator.find('**/right_door')) self.leftDoor = (self.elevator.find('**/left_door')) self.leftDoor.setX(3.50) self.rightDoor.setX(-3.50) self.skelCog = Actor("phase_5/models/char/cogC_robot-lose-mod.bam", {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.skelCog.reparentTo(self.render) self.skelCog.setPos(-16, 0, -4.76) self.skelCog.setH(180) self.Lawbot = Actor('phase_3.5/models/char/suitC-mod.bam', {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.Lawbot.reparentTo(render) self.Lawbot.loop('neutral') self.TorsoTex = loader.loadTexture('phase_3.5/maps/l_blazer.jpg') self.Lawbot.find('**/torso').setTexture(self.TorsoTex, 1) self.ArmTex = loader.loadTexture('phase_3.5/maps/l_sleeve.jpg') self.Lawbot.find('**/arms').setTexture(self.ArmTex, 1) self.LegTex = loader.loadTexture('phase_3.5/maps/l_leg.jpg') self.Lawbot.find('**/legs').setTexture(self.LegTex, 1) self.Head = loader.loadModel('phase_3.5/models/char/suitC-heads.bam').find('**/flunky') self.headTexture = loader.loadTexture("phase_3.5/maps/bottom-feeder.jpg") self.Head.reparentTo(self.Lawbot.find('**/joint_head')) self.Lawbot.findAllMatches('**/joint_head').setTexture(self.headTexture, 1) self.icon = loader.loadModel('phase_3/models/gui/cog_icons.bam') self.icon.reparentTo(render) self.icon.reparentTo(self.Lawbot.find('**/joint_attachMeter')) self.icon.find('**/MoneyIcon').removeNode() self.icon.find('**/cog').removeNode() self.icon.find('**/SalesIcon').removeNode() self.icon.find('**/CorpIcon').removeNode() self.icon.setH(180) self.icon.setScale(0.70) self.Lawbot.setH(180.00) self.Lawbot.hide() self.Cashbot = Actor('phase_3.5/models/char/suitC-mod.bam', {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.Cashbot.reparentTo(render) self.Cashbot.loop('neutral') self.TorsoTex = loader.loadTexture('phase_3.5/maps/m_blazer.jpg') self.Cashbot.find('**/torso').setTexture(self.TorsoTex, 1) self.ArmTex = loader.loadTexture('phase_3.5/maps/m_sleeve.jpg') self.Cashbot.find('**/arms').setTexture(self.ArmTex, 1) self.LegTex = loader.loadTexture('phase_3.5/maps/m_leg.jpg') self.Cashbot.find('**/legs').setTexture(self.LegTex, 1) self.Head = loader.loadModel('phase_3.5/models/char/suitC-heads.bam').find('**/coldcaller') self.Head.reparentTo(self.Cashbot.find('**/joint_head')) self.icon = loader.loadModel('phase_3/models/gui/cog_icons.bam') self.icon.reparentTo(render) self.icon.reparentTo(self.Cashbot.find('**/joint_attachMeter')) self.icon.find('**/SalesIcon').removeNode() self.icon.find('**/cog').removeNode() self.icon.find('**/LegalIcon').removeNode() self.icon.find('**/CorpIcon').removeNode() self.icon.setH(180) self.icon.setScale(0.70) self.Cashbot.setH(180.00) self.Cashbot.hide() self.Sellbot = Actor('phase_3.5/models/char/suitC-mod.bam', {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.Sellbot.reparentTo(render) self.Sellbot.loop('neutral') self.TorsoTex = loader.loadTexture('phase_3.5/maps/s_blazer.jpg') self.Sellbot.find('**/torso').setTexture(self.TorsoTex, 1) self.ArmTex = loader.loadTexture('phase_3.5/maps/s_sleeve.jpg') self.Sellbot.find('**/arms').setTexture(self.ArmTex, 1) self.LegTex = loader.loadTexture('phase_3.5/maps/s_leg.jpg') self.Sellbot.find('**/legs').setTexture(self.LegTex, 1) self.Head = loader.loadModel('phase_3.5/models/char/suitC-heads.bam').find('**/coldcaller') self.Head.reparentTo(self.Sellbot.find('**/joint_head')) self.Head.reparentTo(self.Sellbot.find('**/joint_head')) self.icon = loader.loadModel('phase_3/models/gui/cog_icons.bam') self.icon.reparentTo(render) self.icon.reparentTo(self.Sellbot.find('**/joint_attachMeter')) self.icon.find('**/MoneyIcon').removeNode() self.icon.find('**/cog').removeNode() self.icon.find('**/LegalIcon').removeNode() self.icon.find('**/CorpIcon').removeNode() self.icon.setH(180) self.icon.setScale(0.70) self.Sellbot.setH(180.00) self.Sellbot.hide() self.Bossbot = Actor('phase_3.5/models/char/suitC-mod.bam', {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.Bossbot.reparentTo(render) self.Bossbot.loop('neutral') self.TorsoTex = loader.loadTexture('phase_3.5/maps/c_blazer.jpg') self.Bossbot.find('**/torso').setTexture(self.TorsoTex, 1) self.ArmTex = loader.loadTexture('phase_3.5/maps/c_sleeve.jpg') self.Bossbot.find('**/arms').setTexture(self.ArmTex, 1) self.LegTex = loader.loadTexture('phase_3.5/maps/c_leg.jpg') self.Bossbot.find('**/legs').setTexture(self.LegTex, 1) self.Head = loader.loadModel('phase_3.5/models/char/suitC-heads.bam') self.Head.find('**/coldcaller').hide() self.Head.find('**/gladhander').hide() self.Head.find('**/micromanager').hide() self.Head.find('**/moneybags').hide() self.Head.find('**/tightwad').hide() self.Head.reparentTo(self.Bossbot.find('**/joint_head')) self.icon = loader.loadModel('phase_3/models/gui/cog_icons.bam') self.icon.reparentTo(render) self.icon.reparentTo(self.Bossbot.find('**/joint_attachMeter')) self.icon.find('**/MoneyIcon').removeNode() self.icon.find('**/cog').removeNode() self.icon.find('**/LegalIcon').removeNode() self.icon.find('**/SalesIcon').removeNode() self.icon.setH(180) self.icon.setScale(0.70) self.Bossbot.setH(180.00) self.Bossbot.hide() self.Sourcebot = Actor('phase_3.5/models/char/suitC-mod.bam', {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.Sourcebot.reparentTo(render) self.Sourcebot.loop('neutral') self.TorsoTex = loader.loadTexture('phase_3.5/maps/t_blazer.jpg') self.Sourcebot.find('**/torso').setTexture(self.TorsoTex, 1) self.ArmTex = loader.loadTexture('phase_3.5/maps/t_sleeve.jpg') self.Sourcebot.find('**/arms').setTexture(self.ArmTex, 1) self.LegTex = loader.loadTexture('phase_3.5/maps/t_leg.jpg') self.Sourcebot.find('**/legs').setTexture(self.LegTex, 1) self.Head = loader.loadModel('phase_3.5/models/char/FlairDirector.egg') self.headTexture = loader.loadTexture("phase_3.5/maps/flair-director.jpg") self.Head.reparentTo(self.Sourcebot.find('**/joint_head')) self.Sourcebot.findAllMatches('**/joint_head').setTexture(self.headTexture, 1) self.Sourcebot.setH(180.00) self.Sourcebot.hide() self.Techbot = Actor('phase_3.5/models/char/suitC-mod.bam', {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.Techbot.reparentTo(render) self.Techbot.loop('neutral') self.TorsoTex = loader.loadTexture('phase_3.5/maps/t_blazer.jpg') self.Techbot.find('**/torso').setTexture(self.TorsoTex, 1) self.ArmTex = loader.loadTexture('phase_3.5/maps/t_sleeve.jpg') self.Techbot.find('**/arms').setTexture(self.ArmTex, 1) self.LegTex = loader.loadTexture('phase_3.5/maps/t_leg.jpg') self.Techbot.find('**/legs').setTexture(self.LegTex, 1) self.Head = loader.loadModel('phase_3.5/models/char/PayrollConvertor.egg') self.headTexture = loader.loadTexture("phase_3.5/maps/PayrollConvertor.png") self.Head.reparentTo(self.Techbot.find('**/joint_head')) self.Head.setPos(0, 0, -0.15) self.Head.setScale(0.93) self.Techbot.findAllMatches('**/joint_head').setTexture(self.headTexture, 1) self.Techbot.setH(180.00) self.Techbot.hide() self.Pilotbots = Actor('phase_3.5/models/char/suitC-mod.bam', {'neutral': 'phase_3.5/models/char/suitC-neutral.bam', 'victory': 'phase_4/models/char/suitC-victory.bam', 'walk': 'phase_3.5/models/char/suitC-walk.bam'}) self.Pilotbots.reparentTo(render) self.Pilotbots.loop('neutral') self.TorsoTex = loader.loadTexture('phase_3.5/maps/t_blazer.jpg') self.Pilotbots.find('**/torso').setTexture(self.TorsoTex, 1) self.ArmTex = loader.loadTexture('phase_3.5/maps/t_sleeve.jpg') self.Pilotbots.find('**/arms').setTexture(self.ArmTex, 1) self.LegTex = loader.loadTexture('phase_3.5/maps/t_leg.jpg') self.Pilotbots.find('**/legs').setTexture(self.LegTex, 1) self.Head = loader.loadModel('phase_3.5/models/char/ConstructionBot.egg') self.headTexture = loader.loadTexture("phase_3.5/maps/Buildbot.png") self.Head.reparentTo(self.Pilotbots.find('**/joint_head')) self.Head.setPos(0, 0, -0.15) self.icon.setH(180) self.Pilotbots.findAllMatches('**/joint_head').setTexture(self.headTexture, 1) self.Pilotbots.setH(180.00) self.Pilotbots.hide() #-----Sequences------# Walk1 = self.stomper1.posInterval(9.50, Point3(0, 0, 18.00)) Walk2 = self.stomper1.posInterval(9.50, Point3(0, 0, 0)) self.stomperPound1 = Sequence(Walk1, Walk2) self.stomperPound1.loop() Walk1 = self.stomper6.posInterval(9.50, Point3(0, 0, 18.00)) Walk2 = self.stomper6.posInterval(9.50, Point3(0, 0, 0)) self.stomperPound2 = Sequence(Walk1, Walk2) self.stomperPound2.loop() Walk1 = self.stomper3.posInterval(9.50, Point3(0, 0, 0)) Walk2 = self.stomper3.posInterval(9.50, Point3(0, 0, 18.00)) self.stomperPound3 = Sequence(Walk1, Walk2) self.stomperPound3.loop() Walk1 = self.stomper5.posInterval(5.50, Point3(0, 0, 0)) Walk2 = self.stomper5.posInterval(5.50, Point3(0, 0, 10.00)) self.stomperPound4 = Sequence(Walk1, Walk2) self.stomperPound4.loop() Walk1 = self.stomper4.posInterval(5.50, Point3(0, 0, 0)) Walk2 = self.stomper4.posInterval(5.50, Point3(0, 0, 22.00)) self.stomperPound5 = Sequence(Walk1, Walk2) self.stomperPound5.loop() Walk1 = self.stomper2.posInterval(3.50, Point3(0, 0, 0)) Walk2 = self.stomper2.posInterval(3.50, Point3(0, 0, 7.00)) self.stomperPound6 = Sequence(Walk1, Walk2) self.stomperPound6.loop() Walk1 = self.stomper7.posInterval(9.50, Point3(0, 0, 18.00)) Walk2 = self.stomper7.posInterval(9.50, Point3(0, 0, 0)) self.stomperPound7 = Sequence(Walk1, Walk2) self.stomperPound7.loop() Walk1 = self.stomper8.posInterval(5.50, Point3(0, 0, 5.00)) Walk2 = self.stomper8.posInterval(9.50, Point3(0, 0, 0)) self.stomperPound8 = Sequence(Walk1, Walk2) self.stomperPound8.loop() Walk1 = self.stomper9.posInterval(6.50, Point3(0, 0, 0)) Walk2 = self.stomper9.posInterval(6.50, Point3(0, 0, 13.00)) self.stomperPound9 = Sequence(Walk1, Walk2) self.stomperPound9.loop() Walk1 = self.stomper10.posInterval(5.50, Point3(0, 0, 0)) Walk2 = self.stomper10.posInterval(5.50, Point3(0, 0, 10.00)) self.stomperPound10 = Sequence(Walk1, Walk2) self.stomperPound10.loop() Walk1 = self.stomper11.posInterval(5.50, Point3(0, 0, 0)) Walk2 = self.stomper11.posInterval(5.50, Point3(0, 0, 22.00)) self.stomperPound11 = Sequence(Walk1, Walk2) self.stomperPound11.loop() Walk1 = self.stomper12.posInterval(3.50, Point3(0, 0, 0)) Walk2 = self.stomper12.posInterval(3.50, Point3(0, 0, 7.00)) self.stomperPound12 = Sequence(Walk1, Walk2) self.stomperPound12.loop() Walk1 = self.camera.posInterval(2.50, Point3(-20.98, -14.61, 9.74)) Spin1 = self.camera.hprInterval(1.00, Vec3(321.34, 348.11, 0)) cogSpin = self.Sellbot.hprInterval(1.50, Vec3(0, 0, 0)) Walk2 = self.camera.posInterval(5.0, Point3(-20.98, -14.61, 9.74)) Walk3 = self.camera.posInterval(1.50, Point3(-20.98, 1.40, 7.97)) Spin2 = self.camera.hprInterval(1.00, Vec3(281.31, 348.11, 0)) Walk4 = self.camera.posInterval(8.50, Point3(-20.98, 1.40, 7.97)) Walk5 = self.camera.posInterval(2.50, Point3(0, -19.61, 2.61)) Spin3 = self.camera.hprInterval(1.00, Vec3(0, 0, 0)) self.cameraMove = Sequence(Walk1, Spin1, cogSpin, Walk2, Walk3, Spin2, Walk4, Walk5, Spin3) Walk1 = self.camera.posInterval(1.50, Point3(0, -77.48, 3.42)) Spin1 = self.camera.hprInterval(1.00, Vec3(0, 0, 0)) Walk2 = self.camera.posInterval(2.50, Point3(0, -77.48, 3.42)) Walk3 = self.camera.posInterval(3.00, Point3(0, -22.48, 3.42)) Walk4 = self.camera.posInterval(2.00, Point3(0, -22.48, 3.42)) skelMove1 = self.skelCog.posInterval(0.50, Point3(-16, -0, 0)) skelMove2 = self.skelCog.posInterval(2.00, Point3(0, -0, 0)) self.cameraStart = Sequence(Walk1, Spin1, Walk2, Walk3, Walk4, skelMove1, skelMove2) Walk1 = self.camera.posInterval(15.50, Point3(6.31, -45.31, 9.27)) Spin1 = self.camera.hprInterval(0.00, Vec3(337.52, 0, 0)) Walk2 = self.camera.posInterval(0.00, Point3(6.08, -100.53, 9.27)) Walk3 = self.camera.posInterval(12.00, Point3(14.07, -77.33, 9.27)) Walk4 = self.camera.posInterval(0.00, Point3(18.93, -82.36, 25.51)) Spin2 = self.camera.hprInterval(0.00, Vec3(30.26, 347.91, 0)) Walk5 = self.camera.posInterval(15.00, Point3(0.44, -51.38, 21.411)) Spin3 = self.camera.hprInterval(0.00, Vec3(337.52, 0, 0)) self.cameraIntro = Sequence(Walk1, Spin1, Walk2, Walk3, Walk4, Spin2, Walk5, Spin3) self.cameraIntro.loop() #----camera---# self.camera.setPos(6.31, -82.36, 9.27) self.camera.setHpr(35.71, 0, 0) #--------Start-up-Menu--------# #-----buttons-------# #-----texts-------# self.logoLeft = OnscreenImage(image='phase_3/maps/cogcitycodeaffix-logo-hor-left[OLD].png', pos=(-0.46, 0, 0.2), scale=(0.7)) self.logoLeft.setTransparency(TransparencyAttrib.MAlpha) self.logoRight = OnscreenImage(image='phase_3/maps/cogcitycodeaffix-logo-hor-right[OLD].png', pos=(0.56, 0, 0.18), scale=(0.7)) self.logoRight.setTransparency(TransparencyAttrib.MAlpha) font = self.loader.loadFont("phase_3/models/fonts/vtRemingtonPortable.ttf") text = TextNode("play") text.setText("Press F1 to play") text.setFont(font) self.textNodePath = aspect2d.attachNewNode(text) self.textNodePath.setScale(0.09) self.textNodePath.setPos(-0.5, 0, -0.7) #-----optionText-----------# fps = "Show FPS: f2" self.textObject1 = OnscreenText(text=fps, pos=(-1.4, -0.97), scale=0.09, fg=(1, 0.5, 0.5, 1), align=TextNode.ACenter, mayChange=1) self.textObject1.setFont(font) fullscreen = "Fullscreen: f2" self.textObject2 = OnscreenText(text=fullscreen, pos=(-1.34, -0.88), scale=0.09, fg=(1, 0.5, 0.5, 1), align=TextNode.ACenter, mayChange=1) self.textObject2.setFont(font) audio = "Audio: f4" self.textObject3 = OnscreenText(text=audio, pos=(-1.48, -0.78), scale=0.09, fg=(1, 0.5, 0.5, 1), align=TextNode.ACenter, mayChange=1) self.textObject3.setFont(font) #------doneButton--------# font = self.loader.loadFont("phase_3/models/fonts/vtRemingtonPortable.ttf") bk_text = "" textObject = OnscreenText(text=bk_text, pos=(0.00, 0.73), scale=0.16, fg=(1, 0.5, 0.5, 1), align=TextNode.ACenter, mayChange=1) textObject.setFont(font) textObject.setColor(0.3, 0.3, 0.35, 1.0) def setText(status): if (status): bk_text = "Do you want to continue?" else: bk_text = "" textObject.setText(bk_text) self.DoneButton = DirectCheckButton(text="Continue", scale=0.12, pos=(0, 0, -0.80), command=setText) self.DoneButton.hide() #----------key/click-events-------# self.acceptOnce("f1-up", self.play) self.accept("f2-up", self.frameRate)
def load(self): from toontown.toonbase import ToontownGlobals from panda3d.core import TextNode textNode = TextNode('moviedialogue') textNode.setTextColor(0, 0, 0, 1) textNode.setCardColor(1, 1, 1, 1) textNode.setCardAsMargin(0, 0, 0, 0) textNode.setCardDecal(True) textNode.setWordwrap(27.0) textNode.setAlign(TextNode.ACenter) textNode.setFont(ToontownGlobals.getToonFont()) self._dialogueLabel = aspect2d.attachNewNode(textNode) self._dialogueLabel.setScale(0.06, 0.06, 0.06) self._dialogueLabel.setPos(0.32, 0, -0.75) self._dialogueLabel.reparentTo(hidden)
class BossBattleTimer: def __init__(self): self.text = None self.textNodePath = None self.flashTrack = None self.textSequence = None self.startTime = 0 self.endTime = 0 def load(self): self.text = TextNode('BossBattleTimer') self.text.setAlign(TextNode.ACenter) self.text.setFlattenFlags(TextNode.FFMedium) self.text.setFont(getSuitFont()) self.text.setTextScale(0.075) self.text.setTextColor(*TEXT_WHITE) self.textNodePath = aspect2d.attachNewNode(self.text) self.textNodePath.reparentTo(base.a2dBottomLeft) self.textNodePath.setPos(0.60, 0.0, 0.15) def makeFlashTrack(self): return Track( (0.25, Func(self.text.setTextColor, *TEXT_GREEN)), (0.50, Func(self.text.setTextColor, *TEXT_WHITE)), (0.75, Func(self.text.setTextColor, *TEXT_GREEN)), (1.0, Func(self.text.setTextColor, *TEXT_WHITE)), (1.25, Func(self.text.setTextColor, *TEXT_GREEN)), (1.50, Func(self.text.setTextColor, *TEXT_WHITE)), (1.75, Func(self.text.setTextColor, *TEXT_GREEN)), (2.0, Func(self.text.setTextColor, *TEXT_WHITE)), ) def makeGrowShrinkSequence(self): return Sequence( LerpScaleInterval(self.textNodePath, duration=2.0, scale=1.1, startScale=0.9), LerpScaleInterval(self.textNodePath, duration=2.0, scale=0.9, startScale=1.1), ) def destroy(self): if self.flashTrack: self.flashTrack.finish() self.flashTrack = None if self.textSequence: self.textSequence.finish() self.textSequence = None if self.text: self.text.setText('') if self.textNodePath: self.textNodePath.removeNode() def start(self, startTime): self.startTime = startTime self.endTime = 0 if self.textNodePath: taskMgr.doMethodLater(0.05, self.updateText, 'updateBossText-%s' % self.startTime) self.textSequence = self.makeGrowShrinkSequence() self.textSequence.loop() def updateText(self, task=None): self.text.setText(str(round(time() - self.startTime, 3)) + ' seconds') if self.endTime != 0: return Task.done return Task.again def stop(self, endTime): self.endTime = endTime taskMgr.remove('updateBossText-%s' % self.startTime) if self.textNodePath: self.text.setText( str(round(self.endTime - self.startTime, 3)) + ' seconds') self.flashTrack = self.makeFlashTrack() self.flashTrack.start()
def __init__(self, name): NodePath.__init__(self, name) DirectObject.__init__(self) self.setPythonTag('Sprite', self) global SpriteCounter SpriteCounter += 1 self.__id = int(SpriteCounter) #- Use PGItem to detect mouse and keyboard input via PGTop (eg, aspect2d, pixel2d, etc) self.__pgItem = PGItem(name) self.__pgItem.setActive(True) self.__pgItemNp = self.attachNewNode(self.__pgItem) #- Use TextNode to generate both text and cards for displaying background images self.__textNode = TextNode(name) self.__textNodeNp = None #self.__textNodeNp = self.attachNewNode(self.__textNode) #self.__textNode.setCardDecal(True) #- This is what we would do, should Sprite support being non-under PGTop self.accept(self.__pgItem.getPressEvent(MouseButton.one()), self.__onMouse, [Sprite.MouseLeftDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.two()), self.__onMouse, [Sprite.MouseCenterDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.three()), self.__onMouse, [Sprite.MouseRightDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.four()), self.__onMouse, [Sprite.MouseFourDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.five()), self.__onMouse, [Sprite.MouseFiveDown]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.one()), self.__onMouse, [Sprite.MouseLeftUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.two()), self.__onMouse, [Sprite.MouseCenterUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.three()), self.__onMouse, [Sprite.MouseRightUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.four()), self.__onMouse, [Sprite.MouseFourUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.five()), self.__onMouse, [Sprite.MouseFiveUp]) self.accept(self.__pgItem.getPressEvent(MouseButton.wheelDown()), self.__onMouse, [Sprite.MouseScrollDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.wheelUp()), self.__onMouse, [Sprite.MouseScrollUp]) self.accept(self.__pgItem.getEnterEvent(), self.__onMouse, [Sprite.MouseEnter]) self.accept(self.__pgItem.getExitEvent(), self.__onMouse, [Sprite.MouseExit]) self.accept(self.__pgItem.getWithinEvent(), self.__onMouse, [Sprite.MouseWithin]) self.accept(self.__pgItem.getWithoutEvent(), self.__onMouse, [Sprite.MouseWithout]) self.__beastDebug = ConfigVariableBool('beast-debug', False).getValue() self.__mouseInside = False self.__disabled = False #- Setup state configuration self.__lastStateOptions = None self.__state = None self.__states = { 'default': SpriteOptions(), 'hover': SpriteOptions(), 'click': SpriteOptions(), 'focus': SpriteOptions(), 'disabled': SpriteOptions(), } self.updateToState('default')
def loadGUI(self): self.gui = loader.loadModel('phase_13/models/parties/trampolineGUI') self.gui.reparentTo(base.a2dTopLeft) self.gui.setPos(0.115, 0, -1) self.gui.hide() self.toonIndicator = self.gui.find('**/trampolineGUI_MovingBar') jumpLineLocator = self.gui.find('**/jumpLine_locator') guiBean = self.gui.find('**/trampolineGUI_GreenJellyBean') self.gui.find('**/trampolineGUI_GreenJellyBean').stash() self.guiBeans = [ guiBean.instanceUnderNode(jumpLineLocator, self.uniqueName('guiBean%d' % i)) for i in xrange(self.numJellyBeans) ] self.guiBeans[-1].setScale(1.5) heightTextNode = TextNode(self.uniqueName('TrampolineActivity.heightTextNode')) heightTextNode.setFont(ToontownGlobals.getSignFont()) heightTextNode.setAlign(TextNode.ALeft) heightTextNode.setText('0.0') heightTextNode.setShadow(0.05, 0.05) heightTextNode.setShadowColor(0.0, 0.0, 0.0, 1.0) heightTextNode.setTextColor(1.0, 1.0, 1.0, 1.0) self.heightText = jumpLineLocator.attachNewNode(heightTextNode) self.heightText.setX(0.15) self.heightText.setScale(0.1) self.heightText.setAlphaScale(0.0) self.quitEarlyButtonModels = loader.loadModel('phase_3.5/models/gui/inventory_gui') quitEarlyUp = self.quitEarlyButtonModels.find('**//InventoryButtonUp') quitEarlyDown = self.quitEarlyButtonModels.find('**/InventoryButtonDown') quitEarlyRollover = self.quitEarlyButtonModels.find('**/InventoryButtonRollover') self.quitEarlyButton = DirectButton(parent=base.a2dTopRight, relief=None, text=TTLocalizer.PartyTrampolineQuitEarlyButton, text_fg=(1, 1, 0.65, 1), text_pos=(0, -0.23), text_scale=0.7, image=(quitEarlyUp, quitEarlyDown, quitEarlyRollover), image_color=(1, 0, 0, 1), image_scale=(20, 1, 11), pos=(-0.183, 0, -0.4), scale=0.09, command=self.leaveTrampoline) self.quitEarlyButton.stash() self.flashText = OnscreenText(text='', pos=(0.0, -0.45), scale=0.2, fg=(1.0, 1.0, 0.65, 1.0), align=TextNode.ACenter, font=ToontownGlobals.getSignFont(), mayChange=True) self.timer = PartyUtils.getNewToontownTimer() self.timer.posInTopRightCorner() return
def traverse(self, nodePath, dnaStorage): root = NodePath('signroot') head_root = NodePath('root') wantDecalTest = base.config.GetBool('want-sign-decal-test', False) x = 0 for i in range(len(self.text)): tn = TextNode('text') tn.setText(self.text[i]) tn.setTextColor(self.color) font = dnaStorage.findFont(self.code) if font == None: raise DNAError.DNAError('Font code %s not found.' % self.code) tn.setFont(font) if i == 0 and 'b' in self.flags: tn.setTextScale(1.5) np = root.attachNewNode(tn) np.setScale(self.scale) np.setDepthWrite(0) if i % 2: np.setPos(x + self.stumble, 0, self.stomp) np.setR(-self.wiggle) else: np.setPos(x - self.stumble, 0, self.stomp) np.setR(self.wiggle) x += tn.getWidth() * np.getSx() + self.kern for i in range(root.getNumChildren()): c = root.getChild(i) c.setX(c.getX() - x / 2.0) if self.width and self.height: for i in range(root.getNumChildren()): node = root.getChild(i) A = node.getX() / (self.height / 2.0) B = self.indent * math.pi / 180.0 theta = A + B d = node.getY() x = math.sin(theta) * (self.height / 2.0) y = (math.cos(theta) - 1) * (self.height / 2.0) radius = math.hypot(x, y) if radius != 0: j = (radius + d) / radius x *= j y *= j node.setPos(x, 0, y) node.setR(node, theta * 180.0 / math.pi) collection = root.findAllMatches('**/+TextNode') for i in range(collection.getNumPaths()): xnp = collection.getPath(i) np2 = xnp.getParent().attachNewNode(xnp.node().generate()) np2.setTransform(xnp.getTransform()) xnp.removeNode() _np = nodePath.attachNewNode(root.node()) _np.setPosHpr(self.pos, self.hpr) if wantDecalTest: root.setEffect(DecalEffect.make()) else: _np.setDepthOffset(50) self.traverseChildren(_np, dnaStorage) _np.flattenStrong()
class Avatar(Actor, ShadowCaster): notify = DirectNotifyGlobal.directNotify.newCategory('Avatar') def __init__(self, other=None): Actor.__init__(self, None, None, other, flattenable=0, setFinal=1) ShadowCaster.__init__(self) self.collTube = None self.scale = 1.0 self.height = 0.0 self.style = None self.hpText = None self.hpTextGenerator = TextNode('HpTextGenerator') def delete(self): try: self.Avatar_deleted except: Actor.cleanup(self) self.Avatar_deleted = 1 self.style = None self.collTube = None self.hpText = None self.hpTextGenerator = None ShadowCaster.delete(self) Actor.delete(self) def uniqueName(self, name): return 'Avatar-{0}-{1}'.format(id(self), name) def getCollisionId(self): return self.uniqueName('bodyColl') def getAvatarScale(self): return self.scale def setAvatarScale(self, scale): if self.scale != scale: self.scale = scale self.getGeomNode().setScale(scale) self.setHeight(self.height) def getHeight(self): return self.height def setHeight(self, height): self.height = height if not self.collTube: self.initializeBodyCollisions() self.collTube.setPointB(0, 0, height - self.getRadius()) if self.collNodePath: self.collNodePath.forceRecomputeBounds() def getRadius(self): return GameGlobals.AvatarDefaultRadius def getStyle(self): return self.style def setStyle(self, style): self.style = style def getAirborneHeight(self): height = self.getPos(self.shadowPlacer.shadowNodePath) return height.getZ() + 0.025 def initializeBodyCollisions(self): self.collTube = CollisionTube(0, 0, 0.5, 0, 0, self.height - self.getRadius(), self.getRadius()) self.collNode = CollisionNode(self.getCollisionId()) self.collNode.addSolid(self.collTube) self.collNodePath = self.attachNewNode(self.collNode) self.collNode.setCollideMask(BitmaskGlobals.WallBitmask) def showNodePathColl(self): self.collNodePath.show() def stashBodyCollisions(self): if hasattr(self, 'collNodePath'): self.collNodePath.stash() def unstashBodyCollisions(self): if hasattr(self, 'collNodePath'): self.collNodePath.unstash() def disableBodyCollisions(self): if hasattr(self, 'collNodePath'): self.collNodePath.removeNode() del self.collNodePath self.collTube = None def showHpText(self, number, bonus=0, scale=1.75): if number == 0: return if self.hpText: self.hideHpText() self.hpTextGenerator.setFont(GameGlobals.getSignFont()) if number < 0: text = str(number) if random.randrange(0, 100) < SILLY_SURGE_CHANCE: text += '\n' text += random.choice(GameLocalizer.SillySurgeTerms) else: text = '+' + str(number) self.hpTextGenerator.setText(text) self.hpTextGenerator.clearShadow() self.hpTextGenerator.setAlign(TextNode.ACenter) if bonus == 1: color = [1, 1, 0, 1] elif bonus == 2: color = [1, 0.5, 0, 1] elif number < 0: color = [0.9, 0, 0, 1] else: color = [0, 0.9, 0, 1] self.hpTextGenerator.setTextColor(*color) self.hpTextNode = self.hpTextGenerator.generate() self.hpText = self.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(0, 0, self.height / 2) color[3] = 0 Sequence( self.hpText.posInterval(1.0, (0, 0, self.height + 0.75), blendType='easeOut'), Wait(0.85), self.hpText.colorInterval(0.1, Vec4(*color), 0.1), Func(self.hideHpText)).start() def hideHpText(self): if self.hpText: taskMgr.remove(self.uniqueName('hpText')) self.hpText.removeNode() self.hpText = None
def attachHostNameToSign(self, locator): if self.hostName == '': return nameText = TextNode('nameText') nameText.setCardAsMargin(0.1, 0.1, 0.1, 0.1) nameText.setCardDecal(True) nameText.setCardColor(1.0, 1.0, 1.0, 0.0) r = 232.0 / 255.0 g = 169.0 / 255.0 b = 23.0 / 255.0 nameText.setTextColor(r, g, b, 1) nameText.setAlign(nameText.ACenter) nameText.setFont(ToontownGlobals.getBuildingNametagFont()) nameText.setShadowColor(0, 0, 0, 1) nameText.setBin('fixed') if TTLocalizer.BuildingNametagShadow: nameText.setShadow(*TTLocalizer.BuildingNametagShadow) nameWordWrap = 11.0 nameText.setWordwrap(nameWordWrap) scaleMult = 0.48 houseName = self.hostName nameText.setText(houseName) textWidth = nameText.getWidth() xScale = 1.0 * scaleMult if textWidth > nameWordWrap: xScale = nameWordWrap / textWidth * scaleMult sign_origin = locator namePlate = sign_origin.attachNewNode(nameText) namePlate.setDepthWrite(0) namePlate.setPos(0, 0, 0) namePlate.setScale(xScale)
class PartyPlanner(DirectFrame, FSM): notify = DirectNotifyGlobal.directNotify.newCategory('PartyPlanner') def __init__(self, doneEvent=None): FSM.__init__(self, 'PartyPlannerFSM') DirectFrame.__init__(self) self.doneEvent = doneEvent self.stateArray = [ 'Off', 'Welcome', 'PartyEditor', 'Date', 'Time', 'Invitation', 'Farewell' ] self.partyTime = base.cr.toontownTimeManager.getCurServerDateTime() self.partyNowTime = base.cr.toontownTimeManager.getCurServerDateTime() minutesToNextFifteen = 15 - self.partyTime.minute % 15 self.cleanPartyTime = self.partyTime + timedelta( minutes=minutesToNextFifteen, seconds=-self.partyTime.second) self.partyTime = self.cleanPartyTime self.guests = [] self.isPrivate = False self.selectedCalendarGuiDay = None self.gui = loader.loadModel('phase_4/models/parties/partyPlannerGUI') self.partyDuration = timedelta(hours=PartyGlobals.DefaultPartyDuration) self.timeTypeToMaxValue = {'hour': 23, 'minute': 59} self.timeTypeToChangeAmount = { 'hour': (1, -1), 'minute': (15, -15), 'ampm': (1, -1) } self.partyInfo = None self.asapMinuteRounding = config.GetInt( 'party-asap-minute-rounding', PartyGlobals.PartyPlannerAsapMinuteRounding) self.load() self.request('Welcome') return def enterWelcome(self, *args): self.prevButton['state'] = DirectGuiGlobals.DISABLED self.prevButton.hide() self.nextButton['state'] = DirectGuiGlobals.NORMAL self.welcomePage.show() self.partyPlannerHead.reparentTo(self.welcomePage) self.partyPlannerHead.startBlink() self.partyPlannerHead.startLookAround() self.nametagNP.reparentTo(self.welcomePage) self.chatNP.reparentTo(self.welcomePage) def exitWelcome(self): self.welcomePage.hide() self.prevButton.show() self.partyPlannerHead.stopBlink() self.partyPlannerHead.stopLookAround() def enterPartyEditor(self, *args): self.prevButton['state'] = DirectGuiGlobals.NORMAL self.nextButton['state'] = DirectGuiGlobals.DISABLED self.nextButton.hide() self.partyEditorPage.show() self.okWithGroundsGui.doneStatus = '' self.partyEditor.request('Idle') def exitPartyEditor(self): self.partyEditor.request('Hidden') self.partyEditorPage.hide() def enterGuests(self, *args): self.prevButton['state'] = DirectGuiGlobals.NORMAL self.nextButton['state'] = DirectGuiGlobals.NORMAL self.nextButton.show() self.guestPage.show() def exitGuests(self): self.guests = [] for friendCheckBox in self.friendList['items']: if friendCheckBox['indicatorValue']: self.guests.append(friendCheckBox.getPythonTag('id')) self.guestPage.hide() def enterDate(self, *args): self.prevButton.show() self.prevButton['state'] = DirectGuiGlobals.NORMAL if self.selectedCalendarGuiDay is None: self.nextButton['state'] = DirectGuiGlobals.DISABLED self.nextButton.hide() self.makePartyNowButton.show() self.datePage.show() return def exitDate(self): self.datePage.hide() self.nextButton.show() if self.selectedCalendarGuiDay is not None: self.partyTime = self.cleanPartyTime self.alterPartyTime(year=self.selectedCalendarGuiDay.myDate.year, month=self.selectedCalendarGuiDay.myDate.month, day=self.selectedCalendarGuiDay.myDate.day) else: self.partyNowTime = self.calcAsapTime() self.partyTime = self.partyNowTime return def calcAsapTime(self): curServerTime = base.cr.toontownTimeManager.getCurServerDateTime() baseTime = curServerTime baseTime = baseTime.replace(baseTime.year, baseTime.month, baseTime.day, baseTime.hour, baseTime.minute, second=0, microsecond=0) minute = curServerTime.minute remainder = minute % self.asapMinuteRounding if remainder: baseTime += timedelta(minutes=self.asapMinuteRounding - remainder) else: baseTime += timedelta(minutes=self.asapMinuteRounding) return baseTime def enterTime(self, *args): self.prevButton.show() self.prevButton['state'] = DirectGuiGlobals.NORMAL self.nextButton.show() self.timePage.show() self.timePageRecapToontownTimeLabel2[ 'text'] = '%s' % PartyUtils.formatDateTime(self.partyTime) self.timePageRecapLocalTimeLabel['text'] = '%s%s' % ( TTLocalizer.PartyPlannerTimeLocalTime, PartyUtils.formatDateTime(self.partyTime, inLocalTime=True)) def exitTime(self): self.timePage.hide() self.nextButton.show() def enterInvitation(self, *args): self.prevButton['state'] = DirectGuiGlobals.NORMAL self.nextButton.hide() defaultInviteTheme = PartyGlobals.InviteTheme.GenericMale if hasattr(base.cr, 'newsManager') and base.cr.newsManager: if ToontownGlobals.VICTORY_PARTY_HOLIDAY in base.cr.newsManager.getHolidayIdList( ): defaultInviteTheme = PartyGlobals.InviteTheme.VictoryParty elif ToontownGlobals.KARTING_TICKETS_HOLIDAY in base.cr.newsManager.getHolidayIdList( ) or ToontownGlobals.CIRCUIT_RACING_EVENT in base.cr.newsManager.getHolidayIdList( ): defaultInviteTheme = PartyGlobals.InviteTheme.Racing elif ToontownGlobals.VALENTINES_DAY in base.cr.newsManager.getHolidayIdList( ): defaultInviteTheme = PartyGlobals.InviteTheme.Valentoons if self.partyInfo is not None: del self.partyInfo activityList = self.partyEditor.partyEditorGrid.getActivitiesOnGrid() decorationList = self.partyEditor.partyEditorGrid.getDecorationsOnGrid( ) endTime = self.partyTime + self.partyDuration self.partyInfo = PartyInfo(0, 0, self.partyTime.year, self.partyTime.month, self.partyTime.day, self.partyTime.hour, self.partyTime.minute, endTime.year, endTime.month, endTime.day, endTime.hour, endTime.minute, self.isPrivate, defaultInviteTheme, activityList, decorationList, 0) if self.noFriends or len(self.getInvitees()) == 0: self.inviteVisual.setNoFriends(True) self.invitationTitleLabel[ 'text'] = TTLocalizer.PartyPlannerConfirmTitleNoFriends self.inviteButton[ 'text'] = TTLocalizer.PartyPlannerInviteButtonNoFriends self.selectedInviteThemeLabel.stash() self.nextThemeButton.stash() self.prevThemeButton.stash() self.setInviteTheme(defaultInviteTheme) else: self.inviteVisual.setNoFriends(False) self.invitationTitleLabel[ 'text'] = TTLocalizer.PartyPlannerConfirmTitle self.inviteButton['text'] = TTLocalizer.PartyPlannerInviteButton self.selectedInviteThemeLabel.unstash() self.nextThemeButton.unstash() self.prevThemeButton.unstash() self.setInviteTheme(defaultInviteTheme) self.inviteVisual.updateInvitation(base.localAvatar.getName(), self.partyInfo) self.invitationPage.show() return def __prevTheme(self): self.nextThemeButton.show() prevTheme = self.currentInvitationTheme - 1 while prevTheme not in self.inviteThemes: prevTheme -= 1 if prevTheme == self.currentInvitationTheme: self.notify.warning('No previous invite theme found.') break elif prevTheme < 0: prevTheme = len(self.inviteVisual.inviteThemesIdToInfo) - 1 self.setInviteTheme(prevTheme) def __nextTheme(self): self.prevThemeButton.show() nextTheme = self.currentInvitationTheme + 1 while nextTheme not in self.inviteThemes: nextTheme += 1 if nextTheme == self.currentInvitationTheme: self.notify.warning('No next invite theme found.') break elif nextTheme >= len(self.inviteVisual.inviteThemesIdToInfo): nextTheme = 0 self.setInviteTheme(nextTheme) def setInviteTheme(self, themeNumber): self.currentInvitationTheme = themeNumber self.selectedInviteThemeLabel['text'] = '%s %s (%d/%d)' % ( self.inviteVisual.inviteThemesIdToInfo[self.currentInvitationTheme] [1], TTLocalizer.PartyPlannerInvitationTheme, self.inviteThemes.index(self.currentInvitationTheme) + 1, len(self.inviteThemes)) self.partyInfo.inviteTheme = self.currentInvitationTheme self.inviteVisual.updateInvitation(base.localAvatar.getName(), self.partyInfo) def exitInvitation(self): self.invitationPage.hide() self.nextButton.show() def enterFarewell(self, goingBackAllowed): self.farewellPage.show() if goingBackAllowed: self.prevButton.show() else: self.prevButton.hide() self.nextButton.hide() self.partyPlannerHead.reparentTo(self.farewellPage) self.partyPlannerHead.startBlink() self.partyPlannerHead.startLookAround() self.nametagNP.reparentTo(self.farewellPage) self.chatNP.reparentTo(self.farewellPage) def exitFarewell(self): self.farewellPage.hide() self.nextButton.show() self.prevButton.show() self.partyPlannerHead.stopBlink() self.partyPlannerHead.stopLookAround() def load(self): self.frame = DirectFrame(parent=aspect2d, geom=self.gui.find('**/background'), relief=None, scale=0.85, pos=(0.05, 0.0, 0.1)) self.titleScale = TTLocalizer.PPtitleScale self._createNavButtons() self.welcomePage = self._createWelcomePage() self.welcomePage.hide() self.datePage = self._createDatePage() self.datePage.hide() self.timePage = self._createTimePage() self.timePage.hide() self.guestPage = self._createGuestPage() self.guestPage.hide() self.partyEditorPage = self._createPartyEditorPage() self.partyEditorPage.hide() self.invitationPage = self._createInvitationPage() self.invitationPage.hide() self.farewellPage = self._createFarewellPage() self.farewellPage.hide() return def _createNavButtons(self): self.quitButton = DirectButton( parent=self.frame, relief=None, geom=(self.gui.find('**/cancelButton_up'), self.gui.find('**/cancelButton_down'), self.gui.find('**/cancelButton_rollover')), command=self.__acceptExit) self.nextButton = DirectButton( parent=self.frame, relief=None, geom=(self.gui.find('**/bottomNext_button/nextButton_up'), self.gui.find('**/bottomNext_button/nextButton_down'), self.gui.find('**/bottomNext_button/nextButton_rollover')), command=self.__nextItem, state=DirectGuiGlobals.DISABLED) self.prevButton = DirectButton( parent=self.frame, relief=None, geom=( self.gui.find('**/bottomPrevious_button/previousButton_up'), self.gui.find('**/bottomPrevious_button/previousButton_down'), self.gui.find( '**/bottomPrevious_button/previousButton_rollover')), command=self.__prevItem, state=DirectGuiGlobals.DISABLED) self.currentItem = None return def __createNametag(self, parent): if self.nametagGroup == None: self.nametagGroup = NametagGroup() self.nametagGroup.setFont(ToontownGlobals.getToonFont()) self.nametagGroup.setSpeechFont(ToontownGlobals.getToonFont()) self.nametagGroup.setActive(0) self.nametagGroup.setAvatar(self.partyPlannerHead) self.nametagGroup.manage(base.marginManager) self.nametagGroup.setColorCode(self.nametagGroup.CCNonPlayer) self.nametagGroup.getNametag2d().setContents(0) self.nametagNode = NametagFloat2d() self.nametagNode.setContents(Nametag.CName) self.nametagGroup.addNametag(self.nametagNode) self.nametagGroup.setName( base.cr.partyManager.getPartyPlannerName()) self.nametagNP = parent.attachNewNode(self.nametagNode) nametagPos = self.gui.find( '**/step_01_partymanPeteNametag_locator').getPos() self.nametagNP.setPosHprScale(nametagPos[0], 0, nametagPos[2], 0, 0, 0, 0.1, 1, 0.1) self.chatNode = NametagFloat2d() self.chatNode.setContents(Nametag.CSpeech | Nametag.CThought) self.nametagGroup.addNametag(self.chatNode) self.nametagGroup.setChat(TTLocalizer.PartyPlannerInstructions, CFSpeech) self.chatNP = parent.attachNewNode(self.chatNode) chatPos = self.gui.find( '**/step_01_partymanPeteText_locator').getPos() self.chatNP.setPosHprScale(chatPos[0], 0, chatPos[2], 0, 0, 0, 0.08, 1, 0.08) return def clearNametag(self): if self.nametagGroup != None: self.nametagGroup.unmanage(base.marginManager) self.nametagGroup.removeNametag(self.nametagNode) self.nametagGroup.removeNametag(self.chatNode) self.nametagNP.removeNode() self.chatNP.removeNode() del self.nametagNP del self.chatNP del self.nametagNode del self.chatNode self.nametagGroup.setAvatar(NodePath()) self.nametagGroup.destroy() self.nametagGroup = None return def _createWelcomePage(self): self.nametagGroup = None page = DirectFrame(self.frame) page.setName('PartyPlannerWelcomePage') self.welcomeTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerWelcomeTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale) self.partyPlannerHead = ToonHead.ToonHead() partyPlannerStyle = base.cr.partyManager.getPartyPlannerStyle() self.partyPlannerHead.setupHead(partyPlannerStyle, forGui=True) self.partyPlannerHead.setPos( self.gui.find('**/step_01_partymanPete_locator').getPos()) animal = partyPlannerStyle.getAnimal() if animal == 'cat' or animal == 'pig': headScale = 0.4 else: if animal == 'dog' or animal == 'bear': headScale = 0.45 else: if animal == 'rabbit': headScale = 0.35 else: headScale = 0.3 self.partyPlannerHead.setScale(headScale) self.partyPlannerHead.setH(180.0) self.partyPlannerHead.reparentTo(page) self.__createNametag(page) return page def _createDatePage(self): page = DirectFrame(self.frame) page.setName('PartyPlannerDatePage') self.createDateTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerDateTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale) pos = self.gui.find('**/step_06_sendInvitation_locator').getPos() self.makePartyNowButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/send_up'), self.gui.find('**/send_down'), self.gui.find('**/send_rollover')), text=TTLocalizer.PartyPlannerPartyNow, text_pos=(pos[0], pos[2]), text_scale=0.05, command=self.__doMakePartyNow) curServerDate = base.cr.toontownTimeManager.getCurServerDateTime() self.calendarGuiMonth = CalendarGuiMonth( page, curServerDate, scale=0.95, pos=(-0.05, 0.0, -0.33), dayClickCallback=self._dayClickCallback, onlyFutureDaysClickable=True) return page def __doMakePartyNow(self): self.request('Invitation') def _dayClickCallback(self, calendarGuiDay): self.selectedCalendarGuiDay = calendarGuiDay self.nextButton['state'] = DirectGuiGlobals.NORMAL self.makePartyNowButton.hide() self.nextButton.show() def alterPartyTime(self, year=None, month=None, day=None, hour=None, minute=None): self.partyTime = datetime(year=self.positiveTime('year', year), month=self.positiveTime('month', month), day=self.positiveTime('day', day), hour=self.positiveTime('hour', hour), minute=self.positiveTime('minute', minute), tzinfo=self.partyTime.tzinfo) def positiveTime(self, type, amount): if amount is None: return getattr(self.partyTime, type) if type == 'hour' or type == 'minute': if amount < 0: return self.timeTypeToMaxValue[ type] + 1 + self.timeTypeToChangeAmount[type][1] if amount > self.timeTypeToMaxValue[type]: return 0 return amount def _createTimePage(self): page = DirectFrame(self.frame) page.setName('PartyPlannerTimePage') self.createTimeTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale) self.clockImage = DirectFrame( parent=page, relief=None, geom=self.gui.find('**/toontownTime_background')) self.timePageToontownLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeToontown, pos=self.gui.find('**/step_03_toontown_locator').getPos(), scale=0.15, text_fg=(1.0, 0.0, 0.0, 1.0), text_font=ToontownGlobals.getSignFont()) self.timePageTimeLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeTime, pos=self.gui.find('**/step_03_time_locator').getPos(), scale=0.15, text_fg=(1.0, 0.0, 0.0, 1.0), text_font=ToontownGlobals.getSignFont()) self.timePageRecapLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeRecap, pos=self.gui.find('**/step_03_partyDateAndTime_locator').getPos(), scale=0.09) self.timePageRecapToontownTimeLabel1 = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeToontownTime, pos=self.gui.find('**/step_03_toontownTime_locator').getPos(), scale=0.06) self.timePageRecapToontownTimeLabel2 = DirectLabel( parent=page, relief=None, text='%s' % PartyUtils.formatDateTime(self.partyTime), pos=self.gui.find( '**/step_03_toontownDateAndTime_loactor').getPos(), textMayChange=True, scale=0.06) self.timePageRecapLocalTimeLabel = DirectLabel( parent=page, relief=None, text='%s%s' % (TTLocalizer.PartyPlannerTimeLocalTime, PartyUtils.formatDateTime(self.partyTime, inLocalTime=True)), pos=self.gui.find('**/step_03_localDateAndTime_loactor').getPos(), textMayChange=True, scale=0.06, text_fg=(1.0, 0.0, 0.0, 1.0)) self.timeInputHourLabel, self.timeInputHourUpButton, self.timeInputHourDownButton = self.getTimeWidgets( page, 'hour') self.timeInputMinuteLabel, self.timeInputMinuteUpButton, self.timeInputMinuteDownButton = self.getTimeWidgets( page, 'minute') self.timeInputAmPmLabel, self.timeInputAmPmUpButton, self.timeInputAmPmDownButton = self.getTimeWidgets( page, 'ampm') self.timePagecolonLabel = DirectLabel( parent=page, relief=None, text=':', pos=self.gui.find('**/step_03_colon_locator').getPos(), scale=0.15) return page def getTimeWidgets(self, page, type): if type == 'ampm': data = self.getCurrentAmPm() else: data = getattr(self.partyTime, type) if data == 0 and type == 'minute': data = '00' else: if type == 'hour': data = data % 12 if data == 0: data = 12 data = '%d' % data label = DirectLabel(parent=page, relief=None, text='%s' % data, textMayChange=True, pos=self.gui.find('**/step_03_%s_locator' % type).getPos(), scale=0.12) def changeValue(self, amount): if type == 'ampm': self.alterPartyTime(hour=(self.partyTime.hour + 12) % 24) newAmount = self.getCurrentAmPm() label['text'] = newAmount else: if type == 'hour': newAmount = getattr(self.partyTime, type) + amount newAmount = newAmount % 12 if self.timeInputAmPmLabel[ 'text'] == TTLocalizer.PartyTimeFormatMeridiemPM: newAmount = newAmount % 12 + 12 self.alterPartyTime(hour=newAmount) else: if type == 'minute': newAmount = getattr(self.partyTime, type) + amount self.alterPartyTime(minute=newAmount) else: PartyPlanner.notify.error( 'Invalid type for changeValue in PartyPlanner: %s' % type) newAmount = getattr(self.partyTime, type) if newAmount < 10 and type == 'minute': label['text'] = '0%d' % newAmount else: if type == 'hour': newAmount = newAmount % 12 if newAmount == 0: newAmount = 12 label['text'] = '%d' % newAmount self.timePageRecapToontownTimeLabel2[ 'text'] = '%s' % PartyUtils.formatDateTime(self.partyTime) self.timePageRecapLocalTimeLabel['text'] = '%s%s' % ( TTLocalizer.PartyPlannerTimeLocalTime, PartyUtils.formatDateTime(self.partyTime, inLocalTime=True)) upButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/%sButtonUp_up' % type), self.gui.find('**/%sButtonUp_down' % type), self.gui.find('**/%sButtonUp_rollover' % type)), command=changeValue, extraArgs=[self, self.timeTypeToChangeAmount[type][0]]) downButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/%sButtonDown_up' % type), self.gui.find('**/%sButtonDown_down' % type), self.gui.find('**/%sButtonDown_rollover' % type)), command=changeValue, extraArgs=[self, self.timeTypeToChangeAmount[type][1]]) return (label, upButton, downButton) def getCurrentAmPm(self): if self.partyTime.hour < 12: return TTLocalizer.PartyTimeFormatMeridiemAM return TTLocalizer.PartyTimeFormatMeridiemPM def _createGuestPage(self): page = DirectFrame(self.frame) page.setName('PartyPlannerGuestPage') self.guestTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerGuestTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale) self.guestBackgroundLabel = DirectLabel( parent=page, relief=None, image=self.gui.find('**/guestListBackground_flat'), scale=(1.2, 1.0, 1.0)) self.friendList = ScrolledFriendList(page, self.gui, makeItemsCheckBoxes=True) if len(base.localAvatar.friendsList) == 0: self.noFriends = True else: self.noFriends = False for friendPair in base.localAvatar.friendsList: self.friendList.addFriend(determineFriendName(friendPair), friendPair[0]) self.friendList.scrollTo(0) pos = self.gui.find('**/step_04_partyWillBe_locator').getPos() self.publicPrivateLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerPublicPrivateLabel, text_align=TextNode.ACenter, text_scale=0.065, pos=pos) self.publicDescriptionLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerPublicDescription, text_align=TextNode.ACenter, text_scale=TTLocalizer.PPpbulicDescriptionLabel, pos=(pos[0] - 0.52, pos[1], pos[2])) self.publicDescriptionLabel.stash() self.privateDescriptionLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerPrivateDescription, text_align=TextNode.ACenter, text_scale=TTLocalizer.PPprivateDescriptionLabel, pos=(pos[0] + 0.55, pos[1], pos[2])) self.privateDescriptionLabel.stash() pos = self.gui.find('**/step_04_public_locator').getPos() self.publicButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/publicButton_up'), self.gui.find('**/publicButton_down'), self.gui.find('**/publicButton_rollover'), self.gui.find('**/publicButton_inactive')), text=TTLocalizer.PartyPlannerPublic, text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPpublicButton, command=self.__doTogglePublicPrivate) self.publicButton['state'] = DirectGuiGlobals.DISABLED self.publicButton.bind(DirectGuiGlobals.ENTER, self.__enterPublic) self.publicButton.bind(DirectGuiGlobals.EXIT, self.__exitPublic) pos = self.gui.find('**/step_04_private_locator').getPos() self.privateButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/privateButton_up'), self.gui.find('**/privateButton_down'), self.gui.find('**/privateButton_rollover'), self.gui.find('**/privateButton_inactive')), text=TTLocalizer.PartyPlannerPrivate, text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPprivateButton, command=self.__doTogglePublicPrivate) self.privateButton.bind(DirectGuiGlobals.ENTER, self.__enterPrivate) self.privateButton.bind(DirectGuiGlobals.EXIT, self.__exitPrivate) self.checkAllButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/checkAllButton_up'), self.gui.find('**/checkAllButton_down'), self.gui.find('**/checkAllButton_rollover')), command=self.__doCheckAll) self.uncheckAllButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/uncheckAllButton_up'), self.gui.find('**/uncheckAllButton_down'), self.gui.find('**/uncheckAllButton_rollover')), command=self.__doUncheckAll) return page def __doCheckAll(self): for friendBox in self.friendList['items']: friendBox['indicatorValue'] = True def __doUncheckAll(self): for friendBox in self.friendList['items']: friendBox['indicatorValue'] = False def __enterPrivate(self, mouseEvent): self.privateDescriptionLabel.unstash() def __exitPrivate(self, mouseEvent): self.privateDescriptionLabel.stash() def __enterPublic(self, mouseEvent): self.publicDescriptionLabel.unstash() def __exitPublic(self, mouseEvent): self.publicDescriptionLabel.stash() def __doTogglePublicPrivate(self): if self.isPrivate: self.isPrivate = False self.privateButton['state'] = DirectGuiGlobals.NORMAL self.publicButton['state'] = DirectGuiGlobals.DISABLED else: self.isPrivate = True self.privateButton['state'] = DirectGuiGlobals.DISABLED self.publicButton['state'] = DirectGuiGlobals.NORMAL def _createPartyEditorPage(self): page = DirectFrame(self.frame) page.setName('PartyPlannerEditorPage') self.LayoutTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerEditorTitle, pos=self.gui.find('**/title_locator').getPos() + Point3(0.0, 0.0, 0.075), scale=self.titleScale) self.costLabel = DirectLabel(parent=page, pos=(-0.74, 0.0, 0.17), relief=None, text=TTLocalizer.PartyPlannerTotalCost % 0, text_align=TextNode.ACenter, scale=TTLocalizer.PPcostLabel, textMayChange=True) self.partyGridBackground = DirectFrame( parent=page, relief=None, geom=self.gui.find('**/partyGrid_flat')) self.partyGroundsLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerPartyGrounds, text_font=ToontownGlobals.getSignFont(), text_fg=VBase4(1.0, 0.0, 0.0, 1.0), text_scale=TTLocalizer.PPpartyGroundsLabel, pos=self.gui.find('**/step_05_partyGrounds_text_locator').getPos(), scale=0.1) self.activityBackground = DirectFrame( parent=page, relief=None, geom=self.gui.find('**/activitiesDecorations_flat1'), pos=(0.0, 0.0, 0.04)) pos = self.gui.find('**/step_05_instructions_locator').getPos() self.instructionLabel = DirectLabel( parent=page, relief=None, text=' ', text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPinstructionLabel, textMayChange=True, geom=self.gui.find('**/instructions_flat')) self.elementTitleLabel = DirectLabel( parent=page, relief=None, text=' ', pos=self.gui.find( '**/step_05_activitiesName_text_locator').getPos() + Point3(0.0, 0.0, 0.04), text_scale=TTLocalizer.PPelementTitleLabel, textMayChange=True) self.elementPriceNode = TextNode('ElementPrice') self.elementPriceNode.setAlign(TextNode.ALeft) self.elementPriceNode.setTextColor(0.0, 0.0, 0.0, 1.0) self.elementPriceNode.setFont(ToontownGlobals.getToonFont()) self.elementPrice = page.attachNewNode(self.elementPriceNode) self.elementPrice.setScale(TTLocalizer.PPelementPriceNode) self.elementPrice.setPos( self.gui.find('**/step_05_activityPrice_text_locator').getPos() + Point3(-0.02, 0.0, 0.04)) self.elementDescriptionNode = TextNode('ElementDescription') self.elementDescriptionNode.setAlign(TextNode.ACenter) self.elementDescriptionNode.setWordwrap(8) self.elementDescriptionNode.setFont(ToontownGlobals.getToonFont()) self.elementDescriptionNode.setTextColor(0.0, 0.0, 0.0, 1.0) self.elementDescription = page.attachNewNode( self.elementDescriptionNode) self.elementDescription.setScale(TTLocalizer.PPelementDescription) self.elementDescription.setPos( self.gui.find( '**/step_05_activityDescription_text_locator').getPos() + Point3(0.0, 0.0, 0.04)) self.totalMoney = base.localAvatar.getTotalMoney() catalogGui = loader.loadModel('phase_5.5/models/gui/catalog_gui') self.beanBank = DirectLabel(parent=page, relief=None, text=str(self.totalMoney), text_align=TextNode.ARight, text_scale=0.075, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_pos=(0.495, -0.53), text_font=ToontownGlobals.getSignFont(), textMayChange=True, image=catalogGui.find('**/bean_bank'), image_scale=(0.65, 0.65, 0.65), scale=0.9, pos=(-0.75, 0.0, 0.6)) catalogGui.removeNode() del catalogGui self.accept(localAvatar.uniqueName('moneyChange'), self.__moneyChange) self.accept(localAvatar.uniqueName('bankMoneyChange'), self.__moneyChange) self.partyEditor = PartyEditor(self, page) self.partyEditor.request('Hidden') pos = self.gui.find('**/step_05_add_text_locator').getPos() self.elementBuyButton = DirectButton( parent=page, relief=None, text=TTLocalizer.PartyPlannerBuy, text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPelementBuyButton, geom=(self.gui.find('**/add_up'), self.gui.find('**/add_down'), self.gui.find('**/add_rollover')), geom3_color=VBase4(0.5, 0.5, 0.5, 1.0), textMayChange=True, pos=(0.0, 0.0, 0.04), command=self.partyEditor.buyCurrentElement) self.okWithPartyGroundsLayoutEvent = 'okWithPartyGroundsLayoutEvent' self.accept(self.okWithPartyGroundsLayoutEvent, self.okWithPartyGroundsLayout) self.okWithGroundsGui = TTDialog.TTGlobalDialog( dialogName=self.uniqueName('PartyEditorOkGui'), doneEvent=self.okWithPartyGroundsLayoutEvent, message=TTLocalizer.PartyPlannerOkWithGroundsLayout, style=TTDialog.YesNo, okButtonText=OTPLocalizer.DialogYes, cancelButtonText=OTPLocalizer.DialogNo) self.okWithGroundsGui.doneStatus = '' self.okWithGroundsGui.hide() return page def okWithPartyGroundsLayout(self): self.okWithGroundsGui.hide() if self.okWithGroundsGui.doneStatus == 'ok': self.__nextItem() def setNextButtonState(self, enabled): if enabled: self.nextButton['state'] = DirectGuiGlobals.NORMAL self.nextButton.show() else: self.nextButton['state'] = DirectGuiGlobals.DISABLED self.nextButton.hide() def _createInvitationPage(self): self.__handleHolidays() page = DirectFrame(self.frame) page.setName('PartyPlannerInvitationPage') self.invitationTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerConfirmTitle, textMayChange=True, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale) self.invitationBackground = DirectFrame( parent=page, relief=None, geom=self.gui.find('**/invitationBackground')) self.inviteVisual = InviteVisual(page) self.selectedInviteThemeLabel = DirectLabel( parent=page, relief=None, pos=self.gui.find('**/step_06_theme_locator').getPos(), text='', text_scale=0.06, textMayChange=True) self.nextThemeButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/topNext_button/nextButton_up'), self.gui.find('**/topNext_button/nextButton_down'), self.gui.find('**/topNext_button/nextButton_rollover')), command=self.__nextTheme) self.prevThemeButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/topPrevious_button/previousButton_up'), self.gui.find('**/topPrevious_button/previousButton_down'), self.gui.find( '**/topPrevious_button/previousButton_rollover')), command=self.__prevTheme) pos = self.gui.find('**/step_06_sendInvitation_locator').getPos() self.inviteButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/send_up'), self.gui.find('**/send_down'), self.gui.find('**/send_rollover')), text=TTLocalizer.PartyPlannerInviteButton, textMayChange=True, text_scale=0.05, text_pos=(pos[0], pos[2]), command=self.__handleComplete) return page def __handleHolidays(self): self.inviteThemes = range(len(PartyGlobals.InviteTheme)) if hasattr(base.cr, 'newsManager') and base.cr.newsManager: holidayIds = base.cr.newsManager.getHolidayIdList() if ToontownGlobals.VALENTINES_DAY not in holidayIds: self.inviteThemes.remove(PartyGlobals.InviteTheme.Valentoons) if ToontownGlobals.VICTORY_PARTY_HOLIDAY not in holidayIds: self.inviteThemes.remove(PartyGlobals.InviteTheme.VictoryParty) if ToontownGlobals.WINTER_DECORATIONS not in holidayIds and ToontownGlobals.WACKY_WINTER_DECORATIONS not in holidayIds: self.inviteThemes.remove(PartyGlobals.InviteTheme.Winter) def _createFarewellPage(self): page = DirectFrame(self.frame) page.setName('PartyPlannerFarewellPage') self.confirmTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerConfirmationAllOkTitle, textMayChange=True, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale) pos = self.gui.find('**/step_07_close_text_locator').getPos() self.closePlannerButton = DirectButton( parent=page, relief=None, geom=(self.gui.find('**/close_up'), self.gui.find('**/close_down'), self.gui.find('**/close_rollover')), text=TTLocalizer.PartyPlannerClosePlanner, text_scale=0.055, text_pos=(pos[0], pos[2]), command=self.__acceptExit) return page def close(self): self.ignore('addPartyResponseReceived') self.ignore(localAvatar.uniqueName('moneyChange')) self.ignore(localAvatar.uniqueName('bankMoneyChange')) self.timeInputHourUpButton.destroy() self.timeInputHourDownButton.destroy() self.timeInputMinuteUpButton.destroy() self.timeInputMinuteDownButton.destroy() self.timeInputAmPmUpButton.destroy() self.timeInputAmPmDownButton.destroy() self.privateButton.destroy() self.publicButton.destroy() self.makePartyNowButton.destroy() self.checkAllButton.destroy() self.uncheckAllButton.destroy() self.elementBuyButton.destroy() self.nextThemeButton.destroy() self.prevThemeButton.destroy() self.inviteButton.destroy() self.closePlannerButton.destroy() self.ignore(self.okWithPartyGroundsLayoutEvent) if hasattr(self, 'okWithGroundsGui'): self.okWithGroundsGui.cleanup() del self.okWithGroundsGui if hasattr(self, 'frame') and not self.frame.isEmpty(): messenger.send(self.doneEvent) self.hide() self.cleanup() self.friendList.removeAndDestroyAllItems() self.friendList.destroy() self.calendarGuiMonth.destroy() self.frame.destroy() self.partyPlannerHead.delete() self.partyPlannerHead.removeNode() self.clearNametag() self.partyEditor.request('Cleanup') self.partyEditor = None self.destroy() del self return def __handleComplete(self): self.inviteButton['state'] = DirectGuiGlobals.DISABLED self.prevButton['state'] = DirectGuiGlobals.DISABLED endTime = self.partyTime + self.partyDuration hostId = base.localAvatar.doId self.partyActivities = self.partyEditor.partyEditorGrid.getActivitiesOnGrid( ) decorations = self.partyEditor.partyEditorGrid.getDecorationsOnGrid() invitees = self.getInvitees() self.accept('addPartyResponseReceived', self.processAddPartyResponse) base.cr.partyManager.sendAddParty( hostId, self.partyTime.strftime('%Y-%m-%d %H:%M:%S'), endTime.strftime('%Y-%m-%d %H:%M:%S'), self.isPrivate, self.currentInvitationTheme, self.partyActivities, decorations, invitees) def getInvitees(self): invitees = [] for friendBox in self.friendList['items']: if friendBox['indicatorValue']: invitees.append(friendBox.getPythonTag('id')) return invitees def processAddPartyResponse(self, hostId, errorCode): PartyPlanner.notify.debug( 'processAddPartyResponse : hostId=%d errorCode=%s' % (hostId, PartyGlobals.AddPartyErrorCode.getString(errorCode))) goingBackAllowed = False if errorCode == PartyGlobals.AddPartyErrorCode.AllOk: goingBackAllowed = False self.confirmTitleLabel[ 'text'] = TTLocalizer.PartyPlannerConfirmationAllOkTitle if self.noFriends or len(self.getInvitees()) == 0: confirmRecapText = TTLocalizer.PartyPlannerConfirmationAllOkTextNoFriends else: confirmRecapText = TTLocalizer.PartyPlannerConfirmationAllOkText else: if errorCode == PartyGlobals.AddPartyErrorCode.ValidationError: self.confirmTitleLabel[ 'text'] = TTLocalizer.PartyPlannerConfirmationErrorTitle confirmRecapText = TTLocalizer.PartyPlannerConfirmationValidationErrorText else: if errorCode == PartyGlobals.AddPartyErrorCode.DatabaseError: self.confirmTitleLabel[ 'text'] = TTLocalizer.PartyPlannerConfirmationErrorTitle confirmRecapText = TTLocalizer.PartyPlannerConfirmationDatabaseErrorText else: if errorCode == PartyGlobals.AddPartyErrorCode.TooManyHostedParties: goingBackAllowed = False self.confirmTitleLabel[ 'text'] = TTLocalizer.PartyPlannerConfirmationErrorTitle confirmRecapText = TTLocalizer.PartyPlannerConfirmationTooManyText self.nametagGroup.setChat(confirmRecapText, CFSpeech) self.request('Farewell', goingBackAllowed) def __acceptExit(self): PartyPlanner.notify.debug('__acceptExit') if hasattr(self, 'frame'): self.hide() messenger.send(self.doneEvent) def __nextItem(self): messenger.send('wakeup') if self.state == 'PartyEditor' and self.okWithGroundsGui.doneStatus != 'ok': self.okWithGroundsGui.show() return if self.state == 'PartyEditor' and self.noFriends: self.request('Date') self.selectedCalendarGuiDay = None self.calendarGuiMonth.clearSelectedDay() return if self.state == 'Guests': self.selectedCalendarGuiDay = None self.calendarGuiMonth.clearSelectedDay() if self.state == 'Time': if self.partyTime < base.cr.toontownTimeManager.getCurServerDateTime( ): self.okChooseFutureTimeEvent = 'okChooseFutureTimeEvent' self.acceptOnce(self.okChooseFutureTimeEvent, self.okChooseFutureTime) self.chooseFutureTimeDialog = TTDialog.TTGlobalDialog( dialogName=self.uniqueName('chooseFutureTimeDialog'), doneEvent=self.okChooseFutureTimeEvent, message=TTLocalizer.PartyPlannerChooseFutureTime, style=TTDialog.Acknowledge) self.chooseFutureTimeDialog.show() return self.requestNext() return def okChooseFutureTime(self): if hasattr(self, 'chooseFutureTimeDialog'): self.chooseFutureTimeDialog.cleanup() del self.chooseFutureTimeDialog if hasattr(self, 'okChooseFutureTimeEvent'): self.ignore(self.okChooseFutureTimeEvent) def __prevItem(self): messenger.send('wakeup') if self.state == 'Date' and self.noFriends: self.request('PartyEditor') return if self.state == 'Invitation' and self.selectedCalendarGuiDay is None: self.request('Guests') return self.requestPrev() return def __moneyChange(self, newMoney): if hasattr(self, 'totalMoney'): self.totalMoney = base.localAvatar.getTotalMoney() if hasattr(self, 'beanBank'): self.beanBank['text'] = str(int(self.totalMoney))
flag.reparent_to(OSSteerManager.get_global_ptr().get_reference_node_path()) flagWave = app.loader.load_model("flag_oga-wave.egg") flagWave.reparent_to(flag) auto_bind(flag.node(), flagAnims) flagAnims.get_anim(0).loop(True) return flag if __name__ == '__main__': msg = "'capture_the_flag'" app = startFramework(msg) # # here is room for your own code # print some help to screen text = TextNode("Help") text.set_text( msg + "\n\n" "- press \"d\" to toggle debug drawing\n" "- press \"a\"/\"e\" to add a seeker/enemy\n" "- press \"h\" to set home base center\n" "- press \"s\"/\"shift-s\" to increase/decrease last inserted vehicle's max speed\n" "- press \"f\"/\"shift-f\" to increase/decrease last inserted vehicle's max force\n" "- press \"o\"/\"shift-o\" to add/remove obstacle\n") textNodePath = app.aspect2d.attach_new_node(text) textNodePath.set_pos(-1.25, 0.0, 0.8) textNodePath.set_scale(0.035) # create a steer manager; set root and mask to manage 'kinematic' vehicles steerMgr = OSSteerManager(app.render, mask)
class Cog(DirectObject): def __init__(self, name, dept, suit, head, handColor, height, minLevel, maxLevel): self.name = name self.dept = dept self.head = head self.headObj = None self.headAccessory = head.getAccessory() self.suit = suit self.handColor = handColor self.height = height self.level = random.randint(minLevel, maxLevel) self.minLevel = minLevel self.maxLevel = maxLevel self.version = 1 self.hit = False self.isDefeated = False self.healthBar = None self.healthCondition = 0 def generate(self, isSkeleton=False, isWaiter=False): self.isSkeleton = isSkeleton self.isWaiter = isWaiter self.suit.setupSuit(self.dept.getDept(), self.handColor, isSkeleton, isWaiter) self.suit.generate() self.cog = self.suit.getActor() self.cog.setPythonTag('Cog', self) self.cog.setName(self.name) self.cog.flattenStrong() if (self.level % 12 != 0): self.hp = (self.level + 1) * (self.level + 2) else: self.hp = (self.level / 12) * 200 self.maxHp = self.hp if not isSkeleton: self.headObj = self.head.generate(self.headAccessory) self.head.getHead().reparentTo(self.cog.find('**/joint_head')) self.corpMedallion = self.cog.find('**/Medallion') self.generateHealthBar() self.createNameTag() if not self.isSkeleton: if (self.headObj.getChildren().size() == 0 and self.head.hasAccessory()): self.head.attemptAccessoryFix() def createNameTag(self): try: if (self.nameTag): self.nameTagPath.removeNode() except: pass self.nameTag = TextNode("NameTag") dept = self.dept.getGameDept() name = self.name if self.isSkeleton: name = "Skelecog" if (self.version == 1): self.nameTag.setText('%s\n%s\nLevel %s' % (name, dept, self.level)) else: self.nameTag.setText('%s\n%s\nLevel %s v%s.0' % (name, dept, self.level, self.version)) cogFont = Globals.getFont('vtRemingtonPortable.ttf') self.nameTag.setFont(cogFont) self.nameTagPath = render.attachNewNode(self.nameTag) self.nameTagPath.reparentTo(self.cog.find('**/joint_nameTag')) self.nameTagPath.setBillboardPointEye(0) head = self.head.getHead() jointPos = self.cog.find('**/joint_head').getPos(render) if (head != None): min, max = head.getTightBounds() size = max - min zPos = head.getPos(render).getZ() - size.getZ() pos = head.getPos(render).getZ() + size.getZ() + 2.4 else: pos = jointPos.getZ() + 2.4 self.nameTagPath.setZ(pos) self.nameTag.setAlign(TextNode.ACenter) self.nameTag.setCardColor(0.8, 0.8, 0.8, 0.5) self.nameTag.setCardAsMargin(0, 0, 0, -0.2) self.nameTag.setCardDecal(True) self.nameTag.setTextColor(0.2, 0.2, 0.2, 1.0) self.nameTagPath.setScale(0.35) def playAnim(self, anim, playRate, loop): if (loop): ActorInterval(self.cog, anim, playRate=playRate).loop() else: ActorInterval(self.cog, anim, playRate=playRate) def updateHealthBar(self): health = float(float(self.hp) / float(self.maxHp)) if health < 1: self.corpMedallion.hide() self.healthBar.show() if health > 0.95: condition = 0 elif health > 0.7: condition = 1 elif health > 0.3: condition = 2 elif health > 0.05: condition = 3 elif health > 0: condition = 4 else: condition = 5 if (self.healthCondition != condition): if (condition == 4): blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) base.taskMgr.add(blinkTask, 'blink-task') elif (condition == 5): if (self.healthCondition == 4): base.taskMgr.remove('blink-task') if (self.isDefeated == False): blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) base.taskMgr.add(blinkTask, 'blink-task') self.isDefeated = True if not self.cog.hasPythonTag("Support"): roundInstance = render.getPythonTag('Round') wave = roundInstance.getCurrentWave() wave.setCogsDefeated(wave.getCogsDefeated() + 1) base.taskMgr.doMethodLater(1.5, self.setDefeated, 'Set Cog Defeated') else: self.healthBar.setColor(healthColors[condition], 1) self.healthBarGlow.setColor(healthGlowColors[condition], 1) self.healthCondition = condition def __blinkRed(self, task): self.healthBar.setColor(healthColors[3], 1) self.healthBarGlow.setColor(healthGlowColors[3], 1) return Task.done def __blinkGray(self, task): if not self.healthBar: return self.healthBar.setColor(healthColors[4], 1) self.healthBarGlow.setColor(healthGlowColors[4], 1) return Task.done def generateHealthBar(self): self.removeHealthBar() model = loader.loadModel('phase_3.5/models/gui/matching_game_gui.bam') meter = model.find("**/minnieCircle") meter.setScale(3) meter.setH(180) meter.setColor(healthColors[0]) joint = self.cog.find('**/joint_attachMeter') meter.reparentTo(joint) self.healthBar = meter glow = loader.loadModel('phase_3.5/models/props/glow.bam') glow.reparentTo(self.healthBar) glow.setScale(0.28) glow.setPos(-0.005, 0.01, 0.015) glow.setColor(healthGlowColors[0]) meter.flattenLight() self.healthBarGlow = glow self.healthCondition = 0 self.healthBar.hide() if (self.isSkeleton): self.healthBar.setPos(0, 0.1, 0) def removeHealthBar(self): if self.healthBar: self.healthBar.removeNode() self.healthBar = None if self.healthCondition == 4 or self.healthCondition == 5: taskMgr.remove(self.uniqueName('blink-task')) self.healthCondition = 0 return def setVersion(self, version): self.version = version def getVersion(self): return self.version def destroyCog(self): self.suit.getShadow().deleteDropShadow() self.cog.cleanup() self.cog.removeNode() def setDefeated(self, task): def playSound(sound): SoundBank.getSound(sound).play() def generateReward(pos, hpr): reward = random.choice([True, False]) if (reward): dropMgr = render.getPythonTag('DropManager') drop = dropMgr.generateRandomDrop() drop.reparentTo(render) drop.setPos(pos.getX(), pos.getY(), pos.getZ() + 0.8) if self.cog.isEmpty(): return pos = self.cog.getPos() hpr = self.cog.getHpr() head = copy.copy(self.cog.find('**/Head')) self.destroyCog() self.suit.setupLoseSuit(self.dept.getDept(), self.handColor, self.isSkeleton, self.isWaiter) self.suit.generate() render.getPythonTag('WorldCollisions').addCogGroundCollision( ent=self.suit.getActor()) self.cog = self.suit.getActor() if not self.isSkeleton: head.reparentTo(self.cog.find("**/joint_head")) self.cog.setPos(pos) self.cog.setHpr(hpr) self.cog.reparentTo(render) self.cog.play('lose') Sequence( Wait(1.5), Func(playSound, 'cog_laugh'), Wait(3.5), Func(playSound, 'cog_explode'), Func(generateReward, pos, hpr), Wait(8), Func(self.destroyCog), ).start() return Task.done def setLevel(self, level): self.level = level self.hp = (level + 1) * (level + 2) self.maxHp = self.hp def setHealth(self, hp): self.hp = hp self.updateHealthBar() def getHealth(self): return self.hp def setHit(self, flag): self.hit = flag def wasHit(self): return self.hit def stopAnim(self, anim): self.cog.stop() def cleanUp(self): self.cog.cleanup() self.cog.removeNode() del self def getName(self): return self.name def getDept(self): return self.dept def getHead(self): return self.headObj def isDefeated(self): return self.isDefeated def getHeight(self): return self.height def getLevelCurve(self): return [self.minLevel, self.maxLevel] def getLevel(self): return self.level def getCog(self): return self.cog
def __init__(self, name='NONAME', id=None): NetEnt.__init__(self, id) self.node = NetNodePath(PandaNode('A Character')) self.node.setTag('ID', str(self.id)) if not id: self.spawn() self.node.reparentTo(render) CharacterPool.add(self) self.xVelocity = 0 self.yVelocity = 0 self.vertVelocity = None self.duck = False self.deltaT = 0 self.sprite = Sprite2d('resources/origsprite.png', rows=3, cols=8, rowPerFace=(0, 1, 2, 1)) self.sprite.createAnim('walk', (1, 0, 2, 0)) self.sprite.createAnim('kick', (5, 6, 7, 6, 5)) self.sprite.node.reparentTo(self.node) # set up character's name label self.nameNode = NodePath(TextNode('Char Name')) self.nameNode.node().setText(name) self.nameNode.node().setAlign(TextNode.ACenter) self.nameNode.node().setCardColor(0.2, 0.2, 0.2, 0.5) self.nameNode.node().setCardAsMargin(0, 0, 0, 0) self.nameNode.node().setCardDecal(True) self.nameNode.setZ(1.7) self.nameNode.setScale(0.2) self.nameNode.setBillboardAxis() self.nameNode.reparentTo(self.node) # collision self.collisionHandler = CollisionHandlerQueue() # set up 'from' collision - for detecting char hitting things self.fromCollider = self.node.attachNewNode( CollisionNode('fromCollider')) self.fromCollider.node().addSolid(CollisionRay(0, 0, 2, 0, 0, -1)) self.fromCollider.node().setIntoCollideMask(BITMASK_EMPTY) self.fromCollider.node().setFromCollideMask(BITMASK_TERRAIN) if SHOW_COLLISIONS: self.fromCollider.show() Character.collisionTraverser.addCollider(self.fromCollider, self.collisionHandler) # set up 'into' collision - for detecting things hitting char self.intoCollider = self.node.attachNewNode( CollisionNode('intoCollider')) self.intoCollider.node().addSolid( CollisionTube(0, 0, 0.5, 0, 0, 1, 0.5)) self.intoCollider.node().setIntoCollideMask(BITMASK_CHARACTER) self.intoCollider.node().setFromCollideMask(BITMASK_EMPTY) if SHOW_COLLISIONS: self.intoCollider.show() self.oldPosition = self.node.getPos() self.collisionZ = self.node.getZ() # set up weapons self.sinceShoot = 10 # speculated client history - used for input prediction self.posHistory = []
class PandaVis(ShowBase): """Base class for all visualizations with panda3d""" def __init__(self, rendering: bool): """ Constructor :param rendering: boolean indicating whether to use RenderPipeline or default Panda3d as visualization-module. """ super().__init__(self) self.dir = Filename.fromOsSpecific( pyrado.PANDA_ASSETS_DIR).getFullpath() # Initialize RenderPipeline if rendering: sys.path.insert(0, pyrado.RENDER_PIPELINE_DIR) from rpcore import RenderPipeline self.render_pipeline = RenderPipeline() self.render_pipeline.pre_showbase_init() self.render_pipeline.set_loading_screen_image( osp.join(self.dir, "logo.png")) self.render_pipeline.settings["pipeline.display_debugger"] = False self.render_pipeline.create(self) self.render_pipeline.daytime_mgr.time = "17:00" else: self.render_pipeline = None # Activate antialiasing self.render.setAntialias(AntialiasAttrib.MAuto) # Set window properties self.windowProperties = WindowProperties() self.windowProperties.setForeground(True) self.windowProperties.setTitle("Experiment") # Set background color self.setBackgroundColor(1, 1, 1) # Configuration of the lighting self.directionalLight1 = DirectionalLight("directionalLight") self.directionalLightNP1 = self.render.attachNewNode( self.directionalLight1) self.directionalLightNP1.setHpr(0, -8, 0) self.render.setLight(self.directionalLightNP1) self.directionalLight2 = DirectionalLight("directionalLight") self.directionalLightNP2 = self.render.attachNewNode( self.directionalLight2) self.directionalLightNP2.setHpr(180, -20, 0) self.render.setLight(self.directionalLightNP2) self.ambientLight = AmbientLight("ambientLight") self.ambientLightNP = self.render.attachNewNode(self.ambientLight) self.ambientLight.setColor((0.1, 0.1, 0.1, 1)) self.render.setLight(self.ambientLightNP) # Create a text node displaying the physic parameters on the top left of the screen self.text = TextNode("parameters") self.textNodePath = aspect2d.attachNewNode(self.text) self.text.setTextColor(0, 0, 0, 1) # black self.textNodePath.setScale(0.07) self.textNodePath.setPos(-1.9, 0, 0.9) # Configure trace self.trace = LineSegs() self.trace.setThickness(3) self.trace.setColor(0.8, 0.8, 0.8) # light grey self.lines = self.render.attachNewNode("Lines") self.last_pos = None # Adds one instance of the update function to the task-manager, thus initializes the animation self.taskMgr.add(self.update, "update") def update(self, task: Task): """ Updates the visualization with every call. :param task: Needed by panda3d task manager. :return Task.cont: indicates that task should be called again next frame. """ return Task.cont def reset(self): """ Resets the the visualization to a certain state, so that in can be run again. Removes the trace. """ self.lines.getChildren().detach() self.last_pos = None def draw_trace(self, point): """ Draws a line from the last point to the current point :param point: Current position of pen. Needs 3 value vector. """ # Check if trace initialized if self.last_pos: # Set starting point of new line self.trace.moveTo(self.last_pos) # Draw line to that point self.trace.drawTo(point) # Save last position of pen self.last_pos = point # Show drawing self.trace_np = NodePath(self.trace.create()) self.trace_np.reparentTo(self.lines)
def loadSign(self): actNameForSign = self.activityName if self.activityId == PartyGlobals.ActivityIds.PartyJukebox40: actNameForSign = PartyGlobals.ActivityIds.getString( PartyGlobals.ActivityIds.PartyJukebox) elif self.activityId == PartyGlobals.ActivityIds.PartyDance20: actNameForSign = PartyGlobals.ActivityIds.getString( PartyGlobals.ActivityIds.PartyDance) self.sign = self.root.attachNewNode('%sSign' % self.activityName) self.signModel = self.party.defaultSignModel.copyTo(self.sign) self.signFlat = self.signModel.find('**/sign_flat') self.signFlatWithNote = self.signModel.find('**/sign_withNote') self.signTextLocator = self.signModel.find('**/signText_locator') textureNodePath = getPartyActivityIcon(self.party.activityIconsModel, actNameForSign) textureNodePath.setPos(0.0, -0.02, 2.2) textureNodePath.setScale(2.35) textureNodePath.copyTo(self.signFlat) textureNodePath.copyTo(self.signFlatWithNote) text = TextNode('noteText') text.setTextColor(0.2, 0.1, 0.7, 1.0) text.setAlign(TextNode.ACenter) text.setFont(OTPGlobals.getInterfaceFont()) text.setWordwrap(10.0) text.setText('') self.noteText = self.signFlatWithNote.attachNewNode(text) self.noteText.setPosHpr(self.signTextLocator, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0) self.noteText.setScale(0.2) self.signFlatWithNote.stash() self.signTextLocator.stash()
def text(self, text): self.raw_text = text # clear stuff for img in self.images: destroy(img) self.images.clear() for tn in self.text_nodes: tn.remove_node() self.text_nodes.clear() # check if using tags if (not self.use_tags or self.text == self.start_tag or self.text == self.end_tag or not self.start_tag in text or not self.end_tag in text): self.create_text_section(text) self.align() return # parse tags text = self.start_tag + self.end_tag + str( text) # start with empty tag for alignemnt to work? sections = list() section = '' tag = self.start_tag + 'default' + self.end_tag temp_text_node = TextNode('temp_text_node') temp_text_node.setFont(self.font) x = 0 y = 0 i = 0 while i < len(text): char = text[i] if char == '\n': sections.append([section, tag, x, y]) section = '' y -= 1 x = 0 i += 1 elif char == self.start_tag: # find tag sections.append([section, tag, x, y]) x += temp_text_node.calcWidth(section) section = '' tag = '' for j in range(len(text) - i): tag += text[i + j] if text[i + j] == self.end_tag and len(tag) > 0: i += j + 1 break else: section += char i += 1 sections.append([section, tag, x, y]) for i, s in enumerate(sections): tag = s[1] # move the text after image one space right if tag.startswith(self.start_tag + 'image:'): for f in sections: if f[3] == s[3] and f[2] > s[2]: f[2] += .5 s[2] += .5 self.create_text_section(text=s[0], tag=s[1], x=s[2], y=s[3]) self.align()
class InteractiveAnimatedProp(GenericAnimatedProp.GenericAnimatedProp, FSM.FSM): ZoneToIdles = {} ZoneToIdleIntoFightAnims = {} ZoneToFightAnims = {} ZoneToVictoryAnims = {} ZoneToSadAnims = {} IdlePauseTime = base.config.GetFloat('prop-idle-pause-time', 0.0) HpTextGenerator = TextNode('HpTextGenerator') BattleCheerText = '+' def __init__(self, node, holidayId = -1): FSM.FSM.__init__(self, 'InteractiveProp-%s' % str(node)) self.holidayId = holidayId self.numIdles = 0 self.numFightAnims = 0 self.idleInterval = None self.battleCheerInterval = None self.sadInterval = None self.victoryInterval = None self.lastIdleAnimName = '' self.lastIdleTime = 0 self.curIval = None self.okToStartNextAnim = False cellIndexStr = node.getTag('DNACellIndex') self.cellIndex = ord(cellIndexStr) self.origAnimNameToSound = {} self.lastPlayingAnimPhase = 0 self.buildingsMakingMeSad = set() GenericAnimatedProp.GenericAnimatedProp.__init__(self, node) return def delete(self): self.exit() GenericAnimatedProp.GenericAnimatedProp.delete(self) self.idleInterval = None self.battleCheerInterval = None self.sadInterval = None self.victoryInterval = None return def getCellIndex(self): return self.cellIndex def playBattleCheerAnim(self): self.node.loop('battleCheer') def setupActor(self, node): if self.hoodId in self.ZoneToIdles: self.numIdles = len(self.ZoneToIdles[self.hoodId]) if self.hoodId in self.ZoneToFightAnims: self.numFightAnims = len(self.ZoneToFightAnims[self.hoodId]) self.idleInterval = None anim = node.getTag('DNAAnim') self.trashcan = Actor.Actor(node, copy=0) self.trashcan.reparentTo(node) self.soundPos = node.getPos() animDict = {} animDict['anim'] = '%s/%s' % (self.path, anim) for i in range(self.numIdles): baseAnim = self.ZoneToIdles[self.hoodId][i] if isinstance(baseAnim, tuple): baseAnim = baseAnim[0] animStr = self.path + '/' + baseAnim animKey = 'idle%d' % i animDict[animKey] = animStr settleName = self.getSettleName(i) if settleName: settleStr = self.path + '/' + settleName settleKey = 'settle%d' % i animDict[settleKey] = settleStr for i in range(self.numFightAnims): animStr = self.path + '/' + self.ZoneToFightAnims[self.hoodId][i] animKey = 'fight%d' % i animDict[animKey] = animStr if self.hoodId in self.ZoneToIdleIntoFightAnims: animStr = self.path + '/' + self.ZoneToIdleIntoFightAnims[self.hoodId] animKey = 'idleIntoFight' animDict[animKey] = animStr if self.hoodId in self.ZoneToIdleIntoFightAnims: animStr = self.path + '/' + self.ZoneToVictoryAnims[self.hoodId] animKey = 'victory' animDict[animKey] = animStr if self.hoodId in self.ZoneToSadAnims: animStr = self.path + '/' + self.ZoneToSadAnims[self.hoodId] animKey = 'sad' animDict[animKey] = animStr self.trashcan.loadAnims(animDict) self.trashcan.pose('anim', 0) self.node = self.trashcan self.idleInterval = self.createIdleInterval() self.battleCheerInterval = self.createBattleCheerInterval() self.victoryInterval = self.createVictoryInterval() self.sadInterval = self.createSadInterval() return def createIdleInterval(self): result = Sequence() if self.numIdles >= 3: numberOfAnimsAbove2 = self.numIdles - 2 for rareIdle in range(2, self.numIdles): for i in range(2): result.append(ActorInterval(self.node, 'idle0')) result.append(Wait(self.IdlePauseTime)) result.append(ActorInterval(self.node, 'idle1')) result.append(Wait(self.IdlePauseTime)) result.append(ActorInterval(self.node, 'idle%d' % rareIdle)) result.append(Wait(self.IdlePauseTime)) else: for i in range(self.numIdles): result.append(ActorInterval(self.node, 'idle%d' % i)) self.notify.debug('idle interval=%s' % result) return result def createBattleCheerText(self): self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) self.HpTextGenerator.setText(self.BattleCheerText) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = 0 g = 0 b = 1 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = self.node.attachNewNode(self.hpTextNode) self.hpText.setScale(1) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(0, 0, 4) self.hpText.hide() def createBattleCheerInterval(self): result = Sequence() for i in range(self.numFightAnims): animKey = 'fight%d' % i animAndSoundIval = self.createAnimAndSoundIval(animKey) origAnimName = self.node.getAnimFilename(animKey).split('/')[-1] if self.hasOverrideIval(origAnimName): result.append(self.getOverrideIval(origAnimName)) elif self.hasSpecialIval(origAnimName): result.append(Parallel(animAndSoundIval, self.getSpecialIval(origAnimName))) else: result.append(animAndSoundIval) self.createBattleCheerText() battleCheerTextIval = Sequence(Func(self.hpText.show), self.hpText.posInterval(duration=4.0, pos=Vec3(0, 0, 7), startPos=(0, 0, 3)), Func(self.hpText.hide)) ivalWithText = Parallel(battleCheerTextIval, result) return ivalWithText def createSadInterval(self): result = Sequence() if self.hoodId in self.ZoneToSadAnims: result = self.createAnimAndSoundIval('sad') return result def hasSpecialIval(self, origAnimName): return False def getSpecialIval(self, origAnimName): return Sequence() def hasOverrideIval(self, origAnimName): return False def getOverrideIval(self, origAnimName): return Sequence() def createVictoryInterval(self): result = Sequence() if self.hoodId in self.ZoneToVictoryAnims: animAndSoundIval = self.createAnimAndSoundIval('victory') result.append(animAndSoundIval) return result def enter(self): GenericAnimatedProp.GenericAnimatedProp.enter(self) if base.config.GetBool('props-buff-battles', True): self.notify.debug('props buff battles is true') if base.cr.newsManager.isHolidayRunning(self.holidayId): self.notify.debug('holiday is running, doing idle interval') self.node.stop() self.node.pose('idle0', 0) if base.config.GetBool('interactive-prop-random-idles', 1): self.requestIdleOrSad() else: self.idleInterval.loop() else: self.notify.debug('holiday is NOT running, doing nothing') self.node.stop() self.node.pose('idle0', 0) else: self.notify.debug('props do not buff battles') self.node.stop() self.node.pose('idle0', 0) def exit(self): self.okToStartNextAnim = False self.notify.debug('%s %d okToStartNextAnim=%s' % (self, self.visId, self.okToStartNextAnim)) GenericAnimatedProp.GenericAnimatedProp.exit(self) self.request('Off') def requestIdleOrSad(self): if not hasattr(self, 'node') or not self.node: self.notify.warning("requestIdleOrSad returning hasattr(self,'node')=%s" % hasattr(self, 'node')) return if self.buildingsMakingMeSad: self.request('Sad') else: self.request('DoIdleAnim') def enterDoIdleAnim(self): self.notify.debug('enterDoIdleAnim numIdels=%d' % self.numIdles) self.okToStartNextAnim = True self.notify.debug('%s %d okToStartNextAnim=%s' % (self, self.visId, self.okToStartNextAnim)) self.startNextIdleAnim() def exitDoIdleAnim(self): self.notify.debug('exitDoIdlesAnim numIdles=%d' % self.numIdles) self.okToStartNextAnim = False self.notify.debug('%s %d okToStartNextAnim=%s' % (self, self.visId, self.okToStartNextAnim)) self.calcLastIdleFrame() self.clearCurIval() def calcLastIdleFrame(self): if self.curIval and self.curIval.ivals: firstIval = self.curIval.ivals[0] if isinstance(firstIval, ActorInterval): self.lastIdleFrame = firstIval.getCurrentFrame() self.lastIdleAnimName = firstIval.animName elif isinstance(firstIval, Parallel): for testIval in firstIval.ivals: if isinstance(firstIval, ActorInterval): self.lastIdleTime = testIval.getT() self.lastIdleAnimName = testIval.animName break def chooseIdleAnimToRun(self): result = self.numIdles - 1 if base.config.GetBool('randomize-interactive-idles', True): pairs = [] for i in range(self.numIdles): reversedChance = self.numIdles - i - 1 pairs.append((math.pow(2, reversedChance), i)) else: result = self.lastPlayingAnimPhase + 1 if result >= len(self.ZoneToIdles[self.hoodId]): result = 0 return result def startNextIdleAnim(self): self.notify.debug('startNextAnim self.okToStartNextAnim=%s' % self.okToStartNextAnim) if not hasattr(self, 'node') or not self.node: self.notify.warning("startNextIdleAnim returning hasattr(self,'node')=%s" % hasattr(self, 'node')) return self.curIval = None if self.okToStartNextAnim: self.notify.debug('got pass okToStartNextAnim') whichAnim = self.chooseIdleAnimToRun() if self.visId == localAvatar.zoneId: self.notify.debug('whichAnim=%s' % whichAnim) if __dev__: self.notify.info('whichAnim=%s %s' % (whichAnim, self.getOrigIdleAnimName(whichAnim))) self.lastPlayingAnimPhase = whichAnim self.curIval = self.createIdleAnimSequence(whichAnim) self.notify.debug('starting curIval of length %s' % self.curIval.getDuration()) self.curIval.start() else: self.curIval = Wait(10) self.notify.debug('false self.okToStartNextAnim=%s' % self.okToStartNextAnim) return def createIdleAnimAndSoundInterval(self, whichIdleAnim, startingTime = 0): animIval = self.node.actorInterval('idle%d' % whichIdleAnim, startTime=startingTime) animIvalDuration = animIval.getDuration() origAnimName = self.ZoneToIdles[self.hoodId][whichIdleAnim] if isinstance(origAnimName, tuple): origAnimName = origAnimName[0] soundIval = self.createSoundInterval(origAnimName, animIvalDuration) soundIvalDuration = soundIval.getDuration() if self.hasSpecialIval(origAnimName): specialIval = self.getSpecialIval(origAnimName) idleAnimAndSound = Parallel(animIval, soundIval, specialIval) else: idleAnimAndSound = Parallel(animIval, soundIval) return idleAnimAndSound def createIdleAnimSequence(self, whichIdleAnim): dummyResult = Sequence(Wait(self.IdlePauseTime)) if not hasattr(self, 'node') or not self.node: self.notify.warning("createIdleAnimSequence returning dummyResult hasattr(self,'node')=%s" % hasattr(self, 'node')) return dummyResult idleAnimAndSound = self.createIdleAnimAndSoundInterval(whichIdleAnim) result = Sequence(idleAnimAndSound, Wait(self.IdlePauseTime), Func(self.startNextIdleAnim)) if isinstance(self.ZoneToIdles[self.hoodId][whichIdleAnim], tuple) and len(self.ZoneToIdles[self.hoodId][whichIdleAnim]) > 2: info = self.ZoneToIdles[self.hoodId][whichIdleAnim] origAnimName = info[0] minLoop = info[1] maxLoop = info[2] settleAnim = info[3] minPauseTime = info[4] maxPauseTime = info[5] numberOfLoops = random.randrange(minLoop, maxLoop + 1) pauseTime = random.randrange(minPauseTime, maxPauseTime + 1) result = Sequence() for i in range(numberOfLoops): result.append(idleAnimAndSound) if self.getSettleName(whichIdleAnim): result.append(self.node.actorInterval('settle%d' % whichIdleAnim)) result.append(Wait(pauseTime)) result.append(Func(self.startNextIdleAnim)) return result def gotoFaceoff(self): self.notify.debugStateCall(self) if base.cr.newsManager.isHolidayRunning(self.holidayId): self.request('Faceoff') else: self.notify.debug('not going to faceoff because holiday %d is not running' % self.holidayId) def gotoBattleCheer(self): self.notify.debugStateCall(self) if base.cr.newsManager.isHolidayRunning(self.holidayId): self.request('BattleCheer') else: self.notify.debug('not going to battleCheer because holiday %d is not running' % self.holidayId) def gotoIdle(self): self.notify.debugStateCall(self) if base.cr.newsManager.isHolidayRunning(self.holidayId): self.request('DoIdleAnim') else: self.notify.debug('not going to idle because holiday %d is not running' % self.holidayId) def gotoVictory(self): self.notify.debugStateCall(self) if base.cr.newsManager.isHolidayRunning(self.holidayId): self.request('Victory') else: self.notify.debug('not going to victory because holiday %d is not running' % self.holidayId) def gotoSad(self, buildingDoId): self.notify.debugStateCall(self) self.buildingsMakingMeSad.add(buildingDoId) if base.cr.newsManager.isHolidayRunning(self.holidayId): self.request('Sad') else: self.notify.debug('not going to sad because holiday %d is not running' % self.holidayId) def buildingLiberated(self, buildingDoId): self.buildingsMakingMeSad.discard(buildingDoId) if not self.buildingsMakingMeSad: self.gotoIdle() def enterFaceoff(self): self.notify.debugStateCall(self) self.curIval = self.createFaceoffInterval() self.curIval.start() def exitFaceoff(self): self.notify.debugStateCall(self) self.curIval.pause() self.curIval = None return def calcWhichIdleAnim(self, animName): result = 0 info = self.ZoneToIdles[self.hoodId] for index, curInfo in enumerate(info): if isinstance(curInfo, tuple): if curInfo[0] == animName: result = index break elif isinstance(curInfo, str): if curInfo == animName: result = index breal return result def createFaceoffInterval(self): result = Sequence() if self.lastIdleAnimName: whichIdleAnim = self.calcWhichIdleAnim(self.lastIdleAnimName) animAndSound = self.createIdleAnimAndSoundInterval(whichIdleAnim, self.lastIdleTime) result.append(animAndSound) idleIntoFightIval = self.createAnimAndSoundIval('idleIntoFight') result.append(idleIntoFightIval) result.append(Func(self.gotoBattleCheer)) return result def enterBattleCheer(self): self.notify.debugStateCall(self) self.curIval = self.battleCheerInterval if self.curIval: self.curIval.loop() def exitBattleCheer(self): self.notify.debugStateCall(self) if self.curIval: self.curIval.finish() self.curIval = None return def enterVictory(self): self.notify.debugStateCall(self) self.curIval = self.victoryInterval if self.curIval: self.curIval.loop() def exitVictory(self): self.notify.debugStateCall(self) if self.curIval: self.curIval.finish() self.curIval = None return def enterSad(self): self.notify.debugStateCall(self) self.curIval = self.sadInterval if self.curIval: self.curIval.loop() def exitSad(self): self.notify.debugStateCall(self) if self.curIval: self.curIval.finish() self.curIval = None return def getSettleName(self, whichIdleAnim): result = None if isinstance(self.ZoneToIdles[self.hoodId][whichIdleAnim], tuple) and len(self.ZoneToIdles[self.hoodId][whichIdleAnim]) > 3: result = self.ZoneToIdles[self.hoodId][whichIdleAnim][3] return result def getOrigIdleAnimName(self, whichIdleAnim): result = None if isinstance(self.ZoneToIdles[self.hoodId][whichIdleAnim], tuple): result = self.ZoneToIdles[self.hoodId][whichIdleAnim][0] else: result = self.ZoneToIdles[self.hoodId][whichIdleAnim] return result def createAnimAndSoundIval(self, animKey): animIval = self.node.actorInterval(animKey) animIvalDuration = animIval.getDuration() origAnimName = self.node.getAnimFilename(animKey) soundIval = self.createSoundInterval(origAnimName, animIvalDuration) soundIvalDuration = soundIval.getDuration() printFunc = Func(self.printAnimIfClose, animKey) if self.hasSpecialIval(origAnimName): specialIval = self.getSpecialIval(origAnimName) idleAnimAndSound = Parallel(animIval, soundIval, specialIval) if base.config.GetBool('interactive-prop-info', False): idleAnimAndSound.append(printFunc) else: idleAnimAndSound = Parallel(animIval, soundIval) if base.config.GetBool('interactive-prop-info', False): idleAnimAndSound.append(printFunc) return idleAnimAndSound def printAnimIfClose(self, animKey): if base.config.GetBool('interactive-prop-info', False): try: animName = self.node.getAnimFilename(animKey) baseAnimName = animName.split('/')[-1] if localAvatar.zoneId == self.visId: self.notify.info('playing %s' % baseAnimName) except Exception as e: self.notify.warning('Unknown error in printAnimIfClose, giving up:\n%s' % str(e)) def clearCurIval(self): if self.curIval: self.curIval.finish() clearPythonIvals(self.curIval) self.curIval = None return
class Text(Entity): size = .025 default_font = 'OpenSans-Regular.ttf' default_resolution = 1080 * size * 2 start_tag = '<' end_tag = '>' def __init__(self, text='', start_tag=start_tag, end_tag=end_tag, ignore=True, **kwargs): super().__init__(ignore=ignore) self.size = Text.size self.parent = camera.ui self.setColorScaleOff() self.text_nodes = list() self.images = list() self.origin = (-.5, .5) self.font = Text.default_font self.resolution = Text.default_resolution self.line_height = 1 self.use_tags = True self.start_tag = start_tag self.end_tag = end_tag self.text_colors = {'default': color.text_color} for color_name in color.color_names: self.text_colors[color_name] = color.colors[color_name] self.tag = Text.start_tag + 'default' + Text.end_tag self.current_color = self.text_colors['default'] self.scale_override = 1 self._background = None self.appear_sequence = None # gets created when calling appear() if text != '': self.text = text for key, value in kwargs.items(): setattr(self, key, value) @property def text(self): # set this to update the text. t = '' y = 0 if self.text_nodes: # y = self.text_nodes[0].getZ() y = self.text_nodes[0].getY() for tn in self.text_nodes: # if y != tn.getZ(): if y != tn.getY(): t += '\n' # y = tn.getZ() y = tn.getY() t += tn.node().text return t @text.setter def text(self, text): self.raw_text = text # clear stuff for img in self.images: destroy(img) self.images.clear() for tn in self.text_nodes: tn.remove_node() self.text_nodes.clear() # check if using tags if (not self.use_tags or self.text == self.start_tag or self.text == self.end_tag or not self.start_tag in text or not self.end_tag in text): self.create_text_section(text) self.align() return # parse tags text = self.start_tag + self.end_tag + str( text) # start with empty tag for alignemnt to work? sections = list() section = '' tag = self.start_tag + 'default' + self.end_tag temp_text_node = TextNode('temp_text_node') temp_text_node.setFont(self.font) x = 0 y = 0 i = 0 while i < len(text): char = text[i] if char == '\n': sections.append([section, tag, x, y]) section = '' y -= 1 x = 0 i += 1 elif char == self.start_tag: # find tag sections.append([section, tag, x, y]) x += temp_text_node.calcWidth(section) section = '' tag = '' for j in range(len(text) - i): tag += text[i + j] if text[i + j] == self.end_tag and len(tag) > 0: i += j + 1 break else: section += char i += 1 sections.append([section, tag, x, y]) for i, s in enumerate(sections): tag = s[1] # move the text after image one space right if tag.startswith(self.start_tag + 'image:'): for f in sections: if f[3] == s[3] and f[2] > s[2]: f[2] += .5 s[2] += .5 self.create_text_section(text=s[0], tag=s[1], x=s[2], y=s[3]) self.align() def create_text_section(self, text, tag='', x=0, y=0): # print(text, tag) self.text_node = TextNode('t') self.text_node_path = self.attachNewNode(self.text_node) try: self.text_node.setFont(self._font) except: pass # default font if tag != '<>': tag = tag[1:-1] if tag.startswith('hsb('): # set color based on numbers tag = tag[4:-1] hsb_values = tuple(float(e.strip()) for e in tag.split(',')) self.current_color = color.color(*hsb_values) elif tag.startswith('rgb('): # set color based on numbers tag = tag[4:-1] rgb_values = (float(e.strip()) for e in tag.split(',')) self.current_color = color.rgba(*rgb_values) if tag.startswith('scale:'): scale = tag.split(':')[1] self.scale_override = float(scale) elif tag.startswith('image:'): texture_name = tag.split(':')[1] image = Entity( parent=self.text_node_path, name='inline_image', model='quad', texture=texture_name, color=self.current_color, scale=1, # position=(x*self.size*self.scale_override, y*self.size*self.line_height), origin=(.0, -.25), add_to_scene_entities=False, ) if not image.texture: destroy(image) else: self.images.append(image) # self.text_node.remove_node() # self.text_node = image else: if tag in self.text_colors: self.current_color = self.text_colors[tag] self.text_node_path.setScale(self.scale_override * self.size) self.text_node.setText(text) self.text_node.setTextColor(self.current_color) self.text_node.setPreserveTrailingWhitespace(True) # self.text_node_path.setPos( # x * self.size * self.scale_override, # 0, # (y * self.size * self.line_height) - .75 * self.size) self.text_node_path.setPos(x * self.size * self.scale_override, (y * self.size * self.line_height) - .75 * self.size, 0) self.text_nodes.append(self.text_node_path) return self.text_node @property def font(self): return self._font @font.setter def font(self, value): font = loader.loadFont(value) if font: self._font = font self._font.clear() # remove assertion warning self._font.setPixelsPerUnit(self.resolution) self.text = self.raw_text # update tex @property def color(self): # sets the default color. return self._color @color.setter def color(self, value): self._color = value self.current_color = value self.text_colors['default'] = value for tn in self.text_nodes: tn.node().setTextColor(value) @property def line_height(self): try: return self._line_height except: return 1 @line_height.setter def line_height(self, value): self._line_height = value self.text = self.raw_text @property def width(self): # gets the width of the widest line. if not hasattr(self, 'text'): return 0 temp_text_node = TextNode('temp') temp_text_node.setFont(self._font) longest_line_length = 0 for line in self.text.split('\n'): longest_line_length = max(longest_line_length, temp_text_node.calcWidth(line)) return longest_line_length * self.scale_x * self.size @property def height(self): # gets the height of the text return (len(self.lines) * self.line_height * self.scale_y * self.size) @property def lines(self): return self.text.splitlines() @property def resolution(self): return self._font.getPixelsPerUnit() @resolution.setter def resolution(self, value): self._font.setPixelsPerUnit(value) @property def wordwrap( self ): # set this to make the text wrap after a certain number of characters. if hasattr(self, '_wordwrap'): return self._wordwrap else: return 0 @wordwrap.setter def wordwrap(self, value): self._wordwrap = value new_text = '' is_in_tag = False i = 0 for word in self.raw_text.replace('\n', ' ').replace( self.end_tag, self.end_tag + ' ').split(' '): if word.startswith(self.start_tag) and new_text: new_text = new_text[:-1] if not word.startswith(self.start_tag): i += len(word) if i >= value: new_text += '\n' i = 0 new_text += word + ' ' # print('--------------------\n', new_text) self.text = new_text @property def origin(self): return self._origin @origin.setter def origin(self, value): self._origin = value if self.text: self.text = self.raw_text @property def background(self): return self._background @background.setter def background(self, value): if value == True: self.create_background() elif self._background: destroy(self._background) def align(self): value = self.origin linewidths = [ self.text_nodes[0].node().calcWidth(line) for line in self.lines ] # print('.........', linewidths) for tn in self.text_nodes: # center text horizontally # linenumber = abs(int(tn.getZ() / self.size / self.line_height)) linenumber = abs(int(tn.getY() / self.size / self.line_height)) tn.setX(tn.getX() - (linewidths[linenumber] / 2 * self.size * tn.getScale()[0] / self.size)) # tn.setX(tn.getX() - (linewidths[linenumber] / 2 * self.size)) # add offset based on origin/value # x -= half line width * text node scale tn.setX(tn.getX() - (linewidths[linenumber] / 2 * value[0] * 2 * self.size) * tn.getScale()[0] / self.size) # center text vertically halfheight = len(linewidths) * self.line_height / 2 # tn.setZ(tn.getZ() + (halfheight * self.size)) tn.setY(tn.getY() + (halfheight * self.size)) # add offset # tn.setZ(tn.getZ() - (halfheight * value[1] * 2 * self.size)) tn.setY(tn.getY() - (halfheight * value[1] * 2 * self.size)) def create_background(self, padding=size * 2, radius=size, color=ursina.color.black66): from ursina import Quad, destroy if self._background: destroy(self._background) self._background = Entity(parent=self, z=.01) if isinstance(padding, (int, float, complex)): padding = (padding, padding) w, h = self.width + padding[0], self.height + padding[1] self._background.x -= self.origin_x * self.width self._background.y -= self.origin_y * self.height self._background.model = Quad(radius=radius, scale=(w / self.scale_x, h / self.scale_y)) self._background.color = color def appear(self, speed=.025, delay=0): from ursina.ursinastuff import invoke self.enabled = True # self.visible = True # setting visible seems to reset the colors if self.appear_sequence: self.appear_sequence.finish() x = 0 self.appear_sequence = Sequence() for i, tn in enumerate(self.text_nodes): target_text = tn.node().getText() tn.node().setText('') new_text = '' for j, char in enumerate(target_text): new_text += char self.appear_sequence.append(Wait(speed)) self.appear_sequence.append(Func(tn.node().setText, new_text)) self.appear_sequence.start() return self.appear_sequence def get_width(string, font=None): t = Text(string) if font: t.font = font w = t.width from ursina import destroy destroy(t) return w
class DistributedPartyCatchActivity(DistributedPartyActivity, DistributedPartyCatchActivityBase): notify = DirectNotifyGlobal.directNotify.newCategory( 'DistributedPartyCatchActivity') DropTaskName = 'dropSomething' DropObjectPlurals = { 'apple': TTLocalizer.PartyCatchActivityApples, 'orange': TTLocalizer.PartyCatchActivityOranges, 'pear': TTLocalizer.PartyCatchActivityPears, 'coconut': TTLocalizer.PartyCatchActivityCoconuts, 'watermelon': TTLocalizer.PartyCatchActivityWatermelons, 'pineapple': TTLocalizer.PartyCatchActivityPineapples, 'anvil': TTLocalizer.PartyCatchActivityAnvils } class Generation: def __init__(self, generation, startTime, startNetworkTime, numPlayers): self.generation = generation self.startTime = startTime self.startNetworkTime = startNetworkTime self.numPlayers = numPlayers self.hasBeenScheduled = False self.droppedObjNames = [] self.dropSchedule = [] self.numItemsDropped = 0 self.droppedObjCaught = {} def __init__(self, cr): DistributedPartyActivity.__init__( self, cr, PartyGlobals.ActivityIds.PartyCatch, PartyGlobals.ActivityTypes.HostInitiated, wantRewardGui=True) self.setUsesSmoothing() self.setUsesLookAround() self._sNumGen = SerialNumGen() def getTitle(self): return TTLocalizer.PartyCatchActivityTitle def getInstructions(self): return TTLocalizer.PartyCatchActivityInstructions % { 'badThing': self.DropObjectPlurals['anvil'] } def generate(self): DistributedPartyActivity.generate(self) self.notify.info('localAvatar doId: %s' % base.localAvatar.doId) self.notify.info('generate()') self._generateFrame = globalClock.getFrameCount() self._id2gen = {} self._orderedGenerations = [] self._orderedGenerationIndex = None rng = RandomNumGen(self.doId) self._generationSeedBase = rng.randrange(1000) self._lastDropTime = 0.0 return def getCurGeneration(self): if self._orderedGenerationIndex is None: return return self._orderedGenerations[self._orderedGenerationIndex] def _addGeneration(self, generation, startTime, startNetworkTime, numPlayers): self._id2gen[generation] = self.Generation(generation, startTime, startNetworkTime, numPlayers) i = 0 while 1: if i >= len(self._orderedGenerations): break gen = self._orderedGenerations[i] startNetT = self._id2gen[gen].startTime genId = self._id2gen[gen].generation if startNetT > startNetworkTime: break if startNetT == startNetworkTime and genId > generation: break i += 1 self._orderedGenerations = self._orderedGenerations[:i] + [ generation ] + self._orderedGenerations[i:] if self._orderedGenerationIndex is not None: if self._orderedGenerationIndex >= i: self._orderedGenerationIndex += 1 return def _removeGeneration(self, generation): del self._id2gen[generation] i = self._orderedGenerations.index(generation) self._orderedGenerations = self._orderedGenerations[: i] + self._orderedGenerations[ i + 1:] if self._orderedGenerationIndex is not None: if len(self._orderedGenerations): if self._orderedGenerationIndex >= i: self._orderedGenerationIndex -= 1 else: self._orderedGenerationIndex = None return def announceGenerate(self): self.notify.info('announceGenerate()') self.catchTreeZoneEvent = 'fence_floor' DistributedPartyActivity.announceGenerate(self) def load(self, loadModels=1, arenaModel='partyCatchTree'): self.notify.info('load()') DistributedPartyCatchActivity.notify.debug('PartyCatch: load') self.activityFSM = CatchActivityFSM(self) if __dev__: for o in xrange(3): print { 0: 'SPOTS PER PLAYER', 1: 'DROPS PER MINUTE PER SPOT DURING NORMAL DROP PERIOD', 2: 'DROPS PER MINUTE PER PLAYER DURING NORMAL DROP PERIOD' }[o] for i in xrange(1, self.FallRateCap_Players + 10): self.defineConstants(forceNumPlayers=i) numDropLocations = self.DropRows * self.DropColumns numDropsPerMin = 60.0 / self.DropPeriod if o == 0: spotsPerPlayer = numDropLocations / float(i) print '%2d PLAYERS: %s' % (i, spotsPerPlayer) elif o == 1: numDropsPerMinPerSpot = numDropsPerMin / numDropLocations print '%2d PLAYERS: %s' % (i, numDropsPerMinPerSpot) elif i > 0: numDropsPerMinPerPlayer = numDropsPerMin / i print '%2d PLAYERS: %s' % (i, numDropsPerMinPerPlayer) self.defineConstants() self.treesAndFence = loader.loadModel('phase_13/models/parties/%s' % arenaModel) self.treesAndFence.setScale(0.9) self.treesAndFence.find('**/fence_floor').setPos(0.0, 0.0, 0.1) self.treesAndFence.reparentTo(self.root) ground = self.treesAndFence.find('**/groundPlane') ground.setBin('ground', 1) DistributedPartyActivity.load(self) exitText = TextNode('PartyCatchExitText') exitText.setCardAsMargin(0.1, 0.1, 0.1, 0.1) exitText.setCardDecal(True) exitText.setCardColor(1.0, 1.0, 1.0, 0.0) exitText.setText(TTLocalizer.PartyCatchActivityExit) exitText.setTextColor(0.0, 8.0, 0.0, 0.9) exitText.setAlign(exitText.ACenter) exitText.setFont(ToontownGlobals.getBuildingNametagFont()) exitText.setShadowColor(0, 0, 0, 1) exitText.setBin('fixed') if TTLocalizer.BuildingNametagShadow: exitText.setShadow(*TTLocalizer.BuildingNametagShadow) exitTextLoc = self.treesAndFence.find('**/loc_exitSignText') exitTextNp = exitTextLoc.attachNewNode(exitText) exitTextNp.setDepthWrite(0) exitTextNp.setScale(4) exitTextNp.setZ(-0.5) self.sign.reparentTo(self.treesAndFence.find('**/loc_eventSign')) self.sign.wrtReparentTo(self.root) self.avatarNodePath = NodePath('PartyCatchAvatarNodePath') self.avatarNodePath.reparentTo(self.root) self._avatarNodePathParentToken = 3 base.cr.parentMgr.registerParent(self._avatarNodePathParentToken, self.avatarNodePath) self.toonSDs = {} self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow') self.dropObjModels = {} if loadModels: self.__loadDropModels() self.sndGoodCatch = base.loader.loadSfx( 'phase_4/audio/sfx/SZ_DD_treasure.ogg') self.sndOof = base.loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.sndAnvilLand = base.loader.loadSfx( 'phase_4/audio/sfx/AA_drop_anvil_miss.ogg') self.sndPerfect = base.loader.loadSfx( 'phase_4/audio/sfx/ring_perfect.ogg') self.__textGen = TextNode('partyCatchActivity') self.__textGen.setFont(ToontownGlobals.getSignFont()) self.__textGen.setAlign(TextNode.ACenter) self.activityFSM.request('Idle') def __loadDropModels(self): for objType in PartyGlobals.DropObjectTypes: model = loader.loadModel(objType.modelPath) self.dropObjModels[objType.name] = model modelScales = { 'apple': 0.7, 'orange': 0.7, 'pear': 0.5, 'coconut': 0.7, 'watermelon': 0.6, 'pineapple': 0.45 } if modelScales.has_key(objType.name): model.setScale(modelScales[objType.name]) if objType == PartyGlobals.Name2DropObjectType['pear']: model.setZ(-0.6) if objType == PartyGlobals.Name2DropObjectType['coconut']: model.setP(180) if objType == PartyGlobals.Name2DropObjectType['watermelon']: model.setH(135) model.setZ(-0.5) if objType == PartyGlobals.Name2DropObjectType['pineapple']: model.setZ(-1.7) if objType == PartyGlobals.Name2DropObjectType['anvil']: model.setZ(-self.ObjRadius) model.flattenStrong() def unload(self): DistributedPartyCatchActivity.notify.debug('unload') self.finishAllDropIntervals() self.destroyOrthoWalk() DistributedPartyActivity.unload(self) self.stopDropTask() del self.activityFSM del self.__textGen for avId in self.toonSDs.keys(): if self.toonSDs.has_key(avId): toonSD = self.toonSDs[avId] toonSD.unload() del self.toonSDs self.treesAndFence.removeNode() del self.treesAndFence self.dropShadow.removeNode() del self.dropShadow base.cr.parentMgr.unregisterParent(self._avatarNodePathParentToken) for model in self.dropObjModels.values(): model.removeNode() del self.dropObjModels del self.sndGoodCatch del self.sndOof del self.sndAnvilLand del self.sndPerfect def setStartTimestamp(self, timestamp32): self.notify.info('setStartTimestamp(%s)' % (timestamp32, )) self._startTimestamp = globalClockDelta.networkToLocalTime(timestamp32, bits=32) def getCurrentCatchActivityTime(self): return globalClock.getFrameTime() - self._startTimestamp def getObjModel(self, objName): return self.dropObjModels[objName].copyTo(hidden) def joinRequestDenied(self, reason): DistributedPartyActivity.joinRequestDenied(self, reason) base.cr.playGame.getPlace().fsm.request('walk') def handleToonJoined(self, toonId): if not self.toonSDs.has_key(toonId): toonSD = PartyCatchActivityToonSD(toonId, self) self.toonSDs[toonId] = toonSD toonSD.load() self.notify.debug('handleToonJoined : currentState = %s' % self.activityFSM.state) if config.GetBool('always-max-lod', False): self.cr.doId2do[toonId].useLOD(1000) else: self.cr.doId2do[toonId].useLOD(500) if self.activityFSM.state == 'Active': if self.toonSDs.has_key(toonId): self.toonSDs[toonId].enter() if base.localAvatar.doId == toonId: base.localAvatar.b_setParent(self._avatarNodePathParentToken) self.putLocalAvatarInActivity() if self.toonSDs.has_key(toonId): self.toonSDs[toonId].fsm.request('rules') def handleToonExited(self, toonId): self.notify.debug('handleToonExited( toonId=%s )' % toonId) if self.cr.doId2do.has_key(toonId): self.cr.doId2do[toonId].resetLOD() if self.toonSDs.has_key(toonId): self.toonSDs[toonId].fsm.request('notPlaying') self.toonSDs[toonId].exit() self.toonSDs[toonId].unload() del self.toonSDs[toonId] if base.localAvatar.doId == toonId: base.localAvatar.b_setParent(ToontownGlobals.SPRender) def takeLocalAvatarOutOfActivity(self): self.notify.debug('localToon has left the circle') camera.reparentTo(base.localAvatar) base.localAvatar.startUpdateSmartCamera() base.localAvatar.enableSmartCameraViews() base.localAvatar.setCameraPositionByIndex(base.localAvatar.cameraIndex) DistributedSmoothNode.activateSmoothing(1, 0) def _enableCollisions(self): DistributedPartyActivity._enableCollisions(self) self._enteredTree = False self.accept('enter' + self.catchTreeZoneEvent, self._toonMayHaveEnteredTree) self.accept('again' + self.catchTreeZoneEvent, self._toonMayHaveEnteredTree) self.accept('exit' + self.catchTreeZoneEvent, self._toonExitedTree) self.accept(DistributedPartyCannonActivity.LOCAL_TOON_LANDED_EVENT, self._handleCannonLanded) def _disableCollisions(self): self.ignore(DistributedPartyCannonActivity.LOCAL_TOON_LANDED_EVENT) self.ignore('enter' + self.catchTreeZoneEvent) self.ignore('again' + self.catchTreeZoneEvent) self.ignore('exit' + self.catchTreeZoneEvent) DistributedPartyActivity._disableCollisions(self) def _handleCannonLanded(self): x = base.localAvatar.getX() y = base.localAvatar.getY() if x > self.x - self.StageHalfWidth and x < self.x + self.StageHalfWidth and y > self.y - self.StageHalfHeight and y < self.y + self.StageHalfHeight: self._toonEnteredTree(None) return def _toonMayHaveEnteredTree(self, collEntry): if self._enteredTree: return if base.localAvatar.controlManager.currentControls.getIsAirborne(): return self._toonEnteredTree(collEntry) def _toonEnteredTree(self, collEntry): self.notify.debug('_toonEnteredTree : avid = %s' % base.localAvatar.doId) self.notify.debug('_toonEnteredTree : currentState = %s' % self.activityFSM.state) if self.isLocalToonInActivity(): return if self.activityFSM.state == 'Active': base.cr.playGame.getPlace().fsm.request('activity') self.d_toonJoinRequest() else: if self.activityFSM.state == 'Idle': base.cr.playGame.getPlace().fsm.request('activity') self.d_toonJoinRequest() self._enteredTree = True def _toonExitedTree(self, collEntry): self.notify.debug('_toonExitedTree : avid = %s' % base.localAvatar.doId) self._enteredTree = False if hasattr( base.cr.playGame.getPlace(), 'fsm' ) and self.activityFSM.state == 'Active' and self.isLocalToonInActivity( ): if self.toonSDs.has_key(base.localAvatar.doId): self.takeLocalAvatarOutOfActivity() self.toonSDs[base.localAvatar.doId].fsm.request('notPlaying') self.d_toonExitDemand() def setToonsPlaying(self, toonIds): self.notify.info('setToonsPlaying(%s)' % (toonIds, )) DistributedPartyActivity.setToonsPlaying(self, toonIds) if self.isLocalToonInActivity( ) and base.localAvatar.doId not in toonIds: if self.toonSDs.has_key(base.localAvatar.doId): self.takeLocalAvatarOutOfActivity() self.toonSDs[base.localAvatar.doId].fsm.request('notPlaying') def __genText(self, text): self.__textGen.setText(text) return self.__textGen.generate() def getNumPlayers(self): return len(self.toonIds) def defineConstants(self, forceNumPlayers=None): DistributedPartyCatchActivity.notify.debug('defineConstants') self.ShowObjSpheres = 0 self.ShowToonSpheres = 0 self.useGravity = True self.trickShadows = True if forceNumPlayers is None: numPlayers = self.getNumPlayers() else: numPlayers = forceNumPlayers self.calcDifficultyConstants(numPlayers) DistributedPartyCatchActivity.notify.debug('ToonSpeed: %s' % self.ToonSpeed) DistributedPartyCatchActivity.notify.debug('total drops: %s' % self.totalDrops) DistributedPartyCatchActivity.notify.debug('numFruits: %s' % self.numFruits) DistributedPartyCatchActivity.notify.debug('numAnvils: %s' % self.numAnvils) self.ObjRadius = 1.0 dropRegionTable = PartyRegionDropPlacer.getDropRegionTable(numPlayers) self.DropRows, self.DropColumns = len(dropRegionTable), len( dropRegionTable[0]) for objType in PartyGlobals.DropObjectTypes: DistributedPartyCatchActivity.notify.debug('*** Object Type: %s' % objType.name) objType.onscreenDuration = objType.onscreenDurMult * self.BaselineOnscreenDropDuration DistributedPartyCatchActivity.notify.debug( 'onscreenDuration=%s' % objType.onscreenDuration) v_0 = 0.0 t = objType.onscreenDuration x_0 = self.MinOffscreenHeight x = 0.0 g = 2.0 * (x - x_0 - v_0 * t) / (t * t) DistributedPartyCatchActivity.notify.debug('gravity=%s' % g) objType.trajectory = Trajectory(0, Vec3(0, 0, x_0), Vec3(0, 0, v_0), gravMult=abs(g / Trajectory.gravity)) objType.fallDuration = objType.onscreenDuration + self.OffscreenTime return def grid2world(self, column, row): x = column / float(self.DropColumns - 1) y = row / float(self.DropRows - 1) x = x * 2.0 - 1.0 y = y * 2.0 - 1.0 x *= self.StageHalfWidth y *= self.StageHalfHeight return (x, y) def showPosts(self): self.hidePosts() self.posts = [Toon.Toon(), Toon.Toon(), Toon.Toon(), Toon.Toon()] for i in range(len(self.posts)): tree = self.posts[i] tree.reparentTo(render) x = self.StageHalfWidth y = self.StageHalfHeight if i > 1: x = -x if i % 2: y = -y tree.setPos(x + self.x, y + self.y, 0) def hidePosts(self): if hasattr(self, 'posts'): for tree in self.posts: tree.removeNode() del self.posts def showDropGrid(self): self.hideDropGrid() self.dropMarkers = [] for row in range(self.DropRows): self.dropMarkers.append([]) rowList = self.dropMarkers[row] for column in range(self.DropColumns): toon = Toon.Toon() toon.setDNA(base.localAvatar.getStyle()) toon.reparentTo(self.root) toon.setScale(1.0 / 3) x, y = self.grid2world(column, row) toon.setPos(x, y, 0) rowList.append(toon) def hideDropGrid(self): if hasattr(self, 'dropMarkers'): for row in self.dropMarkers: for marker in row: marker.removeNode() del self.dropMarkers def handleToonDisabled(self, avId): DistributedPartyCatchActivity.notify.debug('handleToonDisabled') DistributedPartyCatchActivity.notify.debug('avatar ' + str(avId) + ' disabled') if self.toonSDs.has_key(avId): self.toonSDs[avId].exit(unexpectedExit=True) del self.toonSDs[avId] def turnOffSmoothingOnGuests(self): pass def setState(self, newState, timestamp): self.notify.info('setState(%s, %s)' % (newState, timestamp)) DistributedPartyCatchActivity.notify.debug( 'setState( newState=%s, ... )' % newState) DistributedPartyActivity.setState(self, newState, timestamp) self.activityFSM.request(newState) if newState == 'Active': if base.localAvatar.doId != self.party.partyInfo.hostId: if globalClock.getFrameCount() > self._generateFrame: if base.localAvatar.getX( ) > self.x - self.StageHalfWidth and base.localAvatar.getX( ) < self.x + self.StageHalfWidth and base.localAvatar.getY( ) > self.y - self.StageHalfHeight and base.localAvatar.getY( ) < self.y + self.StageHalfHeight: self._toonEnteredTree(None) return def putLocalAvatarInActivity(self): if base.cr.playGame.getPlace() and hasattr(base.cr.playGame.getPlace(), 'fsm'): base.cr.playGame.getPlace().fsm.request('activity', [False]) else: self.notify.info( "Avoided crash: toontown.parties.DistributedPartyCatchActivity:632, toontown.parties.DistributedPartyCatchActivity:1198, toontown.parties.activityFSMMixins:49, direct.fsm.FSM:423, AttributeError: 'NoneType' object has no attribute 'fsm'" ) base.localAvatar.stopUpdateSmartCamera() camera.reparentTo(self.treesAndFence) camera.setPosHpr(0.0, -63.0, 30.0, 0.0, -20.0, 0.0) if not hasattr(self, 'ltLegsCollNode'): self.createCatchCollisions() def createCatchCollisions(self): radius = 0.7 handler = CollisionHandlerEvent() handler.setInPattern('ltCatch%in') self.ltLegsCollNode = CollisionNode('catchLegsCollNode') self.ltLegsCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltHeadCollNode = CollisionNode('catchHeadCollNode') self.ltHeadCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltLHandCollNode = CollisionNode('catchLHandCollNode') self.ltLHandCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) self.ltRHandCollNode = CollisionNode('catchRHandCollNode') self.ltRHandCollNode.setCollideMask(PartyGlobals.CatchActivityBitmask) legsCollNodepath = base.localAvatar.attachNewNode(self.ltLegsCollNode) legsCollNodepath.hide() head = base.localAvatar.getHeadParts().getPath(2) headCollNodepath = head.attachNewNode(self.ltHeadCollNode) headCollNodepath.hide() lHand = base.localAvatar.getLeftHands()[0] lHandCollNodepath = lHand.attachNewNode(self.ltLHandCollNode) lHandCollNodepath.hide() rHand = base.localAvatar.getRightHands()[0] rHandCollNodepath = rHand.attachNewNode(self.ltRHandCollNode) rHandCollNodepath.hide() base.localAvatar.cTrav.addCollider(legsCollNodepath, handler) base.localAvatar.cTrav.addCollider(headCollNodepath, handler) base.localAvatar.cTrav.addCollider(lHandCollNodepath, handler) base.localAvatar.cTrav.addCollider(lHandCollNodepath, handler) if self.ShowToonSpheres: legsCollNodepath.show() headCollNodepath.show() lHandCollNodepath.show() rHandCollNodepath.show() self.ltLegsCollNode.addSolid(CollisionSphere(0, 0, radius, radius)) self.ltHeadCollNode.addSolid(CollisionSphere(0, 0, 0, radius)) self.ltLHandCollNode.addSolid( CollisionSphere(0, 0, 0, 2 * radius / 3.0)) self.ltRHandCollNode.addSolid( CollisionSphere(0, 0, 0, 2 * radius / 3.0)) self.toonCollNodes = [ legsCollNodepath, headCollNodepath, lHandCollNodepath, rHandCollNodepath ] def destroyCatchCollisions(self): if not hasattr(self, 'ltLegsCollNode'): return for collNode in self.toonCollNodes: while collNode.node().getNumSolids(): collNode.node().removeSolid(0) base.localAvatar.cTrav.removeCollider(collNode) del self.toonCollNodes del self.ltLegsCollNode del self.ltHeadCollNode del self.ltLHandCollNode del self.ltRHandCollNode def timerExpired(self): pass def __handleCatch(self, generation, objNum): DistributedPartyCatchActivity.notify.debug('catch: %s' % [generation, objNum]) if base.localAvatar.doId not in self.toonIds: return self.showCatch(base.localAvatar.doId, generation, objNum) objName = self._id2gen[generation].droppedObjNames[objNum] objTypeId = PartyGlobals.Name2DOTypeId[objName] self.sendUpdate('claimCatch', [generation, objNum, objTypeId]) self.finishDropInterval(generation, objNum) def showCatch(self, avId, generation, objNum): if not self.toonSDs.has_key(avId): return isLocal = avId == base.localAvatar.doId if generation not in self._id2gen: return if not self._id2gen[generation].hasBeenScheduled: return objName = self._id2gen[generation].droppedObjNames[objNum] objType = PartyGlobals.Name2DropObjectType[objName] if objType.good: if not self._id2gen[generation].droppedObjCaught.has_key(objNum): if isLocal: base.playSfx(self.sndGoodCatch) fruit = self.getObjModel(objName) toon = self.getAvatar(avId) rHand = toon.getRightHands()[1] self.toonSDs[avId].eatFruit(fruit, rHand) else: self.toonSDs[avId].fsm.request('fallForward') self._id2gen[generation].droppedObjCaught[objNum] = 1 def setObjectCaught(self, avId, generation, objNum): self.notify.info('setObjectCaught(%s, %s, %s)' % (avId, generation, objNum)) if self.activityFSM.state != 'Active': DistributedPartyCatchActivity.notify.warning( 'ignoring msg: object %s caught by %s' % (objNum, avId)) return isLocal = avId == base.localAvatar.doId if not isLocal: DistributedPartyCatchActivity.notify.debug( 'AI: avatar %s caught %s' % (avId, objNum)) self.finishDropInterval(generation, objNum) self.showCatch(avId, generation, objNum) self._scheduleGenerations() gen = self._id2gen[generation] if gen.hasBeenScheduled: objName = gen.droppedObjNames[objNum] if PartyGlobals.Name2DropObjectType[objName].good: if hasattr(self, 'fruitsCaught'): self.fruitsCaught += 1 def finishDropInterval(self, generation, objNum): if hasattr(self, 'dropIntervals'): if self.dropIntervals.has_key((generation, objNum)): self.dropIntervals[(generation, objNum)].finish() def finishAllDropIntervals(self): if hasattr(self, 'dropIntervals'): for dropInterval in self.dropIntervals.values(): dropInterval.finish() def setGenerations(self, generations): self.notify.info('setGenerations(%s)' % (generations, )) gen2t = {} gen2nt = {} gen2np = {} for id, timestamp32, numPlayers in generations: gen2t[id] = globalClockDelta.networkToLocalTime( timestamp32, bits=32) - self._startTimestamp gen2nt[id] = timestamp32 gen2np[id] = numPlayers ids = self._id2gen.keys() for id in ids: if id not in gen2t: self._removeGeneration(id) for id in gen2t: if id not in self._id2gen: self._addGeneration(id, gen2t[id], gen2nt[id], gen2np[id]) def scheduleDrops(self, genId=None): if genId is None: genId = self.getCurGeneration() gen = self._id2gen[genId] if gen.hasBeenScheduled: return fruitIndex = int((gen.startTime + 0.5 * self.DropPeriod) / PartyGlobals.CatchActivityDuration) fruitNames = [ 'apple', 'orange', 'pear', 'coconut', 'watermelon', 'pineapple' ] fruitName = fruitNames[(fruitIndex % len(fruitNames))] rng = RandomNumGen(genId + self._generationSeedBase) gen.droppedObjNames = [fruitName ] * self.numFruits + ['anvil'] * self.numAnvils rng.shuffle(gen.droppedObjNames) dropPlacer = PartyRegionDropPlacer(self, gen.numPlayers, genId, gen.droppedObjNames, startTime=gen.startTime) gen.numItemsDropped = 0 tIndex = gen.startTime % PartyGlobals.CatchActivityDuration tPercent = float(tIndex) / PartyGlobals.CatchActivityDuration gen.numItemsDropped += dropPlacer.skipPercent(tPercent) while not dropPlacer.doneDropping(continuous=True): nextDrop = dropPlacer.getNextDrop() gen.dropSchedule.append(nextDrop) gen.hasBeenScheduled = True return def startDropTask(self): taskMgr.add(self.dropTask, self.DropTaskName) def stopDropTask(self): taskMgr.remove(self.DropTaskName) def _scheduleGenerations(self): curT = self.getCurrentCatchActivityTime() genIndex = self._orderedGenerationIndex newGenIndex = genIndex while genIndex is None or genIndex < len(self._orderedGenerations) - 1: if genIndex is None: nextGenIndex = 0 else: nextGenIndex = genIndex + 1 nextGenId = self._orderedGenerations[nextGenIndex] nextGen = self._id2gen[nextGenId] startT = nextGen.startTime if curT >= startT: newGenIndex = nextGenIndex if not nextGen.hasBeenScheduled: self.defineConstants(forceNumPlayers=nextGen.numPlayers) self.scheduleDrops( genId=self._orderedGenerations[nextGenIndex]) genIndex = nextGenIndex self._orderedGenerationIndex = newGenIndex return def dropTask(self, task): self._scheduleGenerations() curT = self.getCurrentCatchActivityTime() if self._orderedGenerationIndex is not None: i = self._orderedGenerationIndex genIndex = self._orderedGenerations[i] gen = self._id2gen[genIndex] while len(gen.dropSchedule) > 0 and gen.dropSchedule[0][0] < curT: drop = gen.dropSchedule[0] gen.dropSchedule = gen.dropSchedule[1:] dropTime, objName, dropCoords = drop objNum = gen.numItemsDropped x, y = self.grid2world(*dropCoords) dropIval = self.getDropIval(x, y, objName, genIndex, objNum) def cleanup(generation, objNum, self=self): del self.dropIntervals[(generation, objNum)] dropIval.append(Func(Functor(cleanup, genIndex, objNum))) self.dropIntervals[(genIndex, objNum)] = dropIval gen.numItemsDropped += 1 dropIval.start(curT - dropTime) self._lastDropTime = dropTime return Task.cont def getDropIval(self, x, y, dropObjName, generation, num): objType = PartyGlobals.Name2DropObjectType[dropObjName] id = (generation, num) dropNode = hidden.attachNewNode('catchDropNode%s' % (id, )) dropNode.setPos(x, y, 0) shadow = self.dropShadow.copyTo(dropNode) shadow.setZ(PartyGlobals.CatchDropShadowHeight) shadow.setColor(1, 1, 1, 1) object = self.getObjModel(dropObjName) object.reparentTo(hidden) if dropObjName in ('watermelon', 'anvil'): objH = object.getH() absDelta = {'watermelon': 12, 'anvil': 15}[dropObjName] delta = (self.randomNumGen.random() * 2.0 - 1.0) * absDelta newH = objH + delta else: newH = self.randomNumGen.random() * 360.0 object.setH(newH) sphereName = 'FallObj%s' % (id, ) radius = self.ObjRadius if objType.good: radius *= lerp(1.0, 1.3, 0.5) collSphere = CollisionSphere(0, 0, 0, radius) collSphere.setTangible(0) collNode = CollisionNode(sphereName) collNode.setCollideMask(PartyGlobals.CatchActivityBitmask) collNode.addSolid(collSphere) collNodePath = object.attachNewNode(collNode) collNodePath.hide() if self.ShowObjSpheres: collNodePath.show() catchEventName = 'ltCatch' + sphereName def eatCollEntry(forward, collEntry): forward() self.accept( catchEventName, Functor(eatCollEntry, Functor(self.__handleCatch, id[0], id[1]))) def cleanup(self=self, dropNode=dropNode, id=id, event=catchEventName): self.ignore(event) dropNode.removeNode() duration = objType.fallDuration onscreenDuration = objType.onscreenDuration targetShadowScale = 0.3 if self.trickShadows: intermedScale = targetShadowScale * (self.OffscreenTime / self.BaselineDropDuration) shadowScaleIval = Sequence( LerpScaleInterval(shadow, self.OffscreenTime, intermedScale, startScale=0)) shadowScaleIval.append( LerpScaleInterval(shadow, duration - self.OffscreenTime, targetShadowScale, startScale=intermedScale)) else: shadowScaleIval = LerpScaleInterval(shadow, duration, targetShadowScale, startScale=0) targetShadowAlpha = 0.4 shadowAlphaIval = LerpColorScaleInterval( shadow, self.OffscreenTime, Point4(1, 1, 1, targetShadowAlpha), startColorScale=Point4(1, 1, 1, 0)) shadowIval = Parallel(shadowScaleIval, shadowAlphaIval) if self.useGravity: def setObjPos(t, objType=objType, object=object): z = objType.trajectory.calcZ(t) object.setZ(z) setObjPos(0) dropIval = LerpFunctionInterval(setObjPos, fromData=0, toData=onscreenDuration, duration=onscreenDuration) else: startPos = Point3(0, 0, self.MinOffscreenHeight) object.setPos(startPos) dropIval = LerpPosInterval(object, onscreenDuration, Point3(0, 0, 0), startPos=startPos, blendType='easeIn') ival = Sequence(Func(Functor(dropNode.reparentTo, self.root)), Parallel( Sequence( WaitInterval(self.OffscreenTime), Func(Functor(object.reparentTo, dropNode)), dropIval), shadowIval), Func(cleanup), name='drop%s' % (id, )) if objType == PartyGlobals.Name2DropObjectType['anvil']: ival.append(Func(self.playAnvil)) return ival def playAnvil(self): if base.localAvatar.doId in self.toonIds: base.playSfx(self.sndAnvilLand) def initOrthoWalk(self): DistributedPartyCatchActivity.notify.debug('startOrthoWalk') def doCollisions(oldPos, newPos, self=self): x = bound(newPos[0], self.StageHalfWidth, -self.StageHalfWidth) y = bound(newPos[1], self.StageHalfHeight, -self.StageHalfHeight) newPos.setX(x) newPos.setY(y) return newPos orthoDrive = OrthoDrive(self.ToonSpeed, instantTurn=True) self.orthoWalk = OrthoWalk(orthoDrive, broadcast=True) def destroyOrthoWalk(self): DistributedPartyCatchActivity.notify.debug('destroyOrthoWalk') if hasattr(self, 'orthoWalk'): self.orthoWalk.stop() self.orthoWalk.destroy() del self.orthoWalk def startIdle(self): DistributedPartyCatchActivity.notify.debug('startIdle') def finishIdle(self): DistributedPartyCatchActivity.notify.debug('finishIdle') def startActive(self): DistributedPartyCatchActivity.notify.debug('startActive') for avId in self.toonIds: if self.toonSDs.has_key(avId): toonSD = self.toonSDs[avId] toonSD.enter() toonSD.fsm.request('normal') self.fruitsCaught = 0 self.dropIntervals = {} self.startDropTask() if base.localAvatar.doId in self.toonIds: self.putLocalAvatarInActivity() def finishActive(self): DistributedPartyCatchActivity.notify.debug('finishActive') self.stopDropTask() if hasattr(self, 'finishIval'): self.finishIval.pause() del self.finishIval if base.localAvatar.doId in self.toonIds: self.takeLocalAvatarOutOfActivity() for ival in self.dropIntervals.values(): ival.finish() del self.dropIntervals def startConclusion(self): DistributedPartyCatchActivity.notify.debug('startConclusion') for avId in self.toonIds: if self.toonSDs.has_key(avId): toonSD = self.toonSDs[avId] toonSD.fsm.request('notPlaying') self.destroyCatchCollisions() if base.localAvatar.doId not in self.toonIds: return self.localToonExiting() if self.fruitsCaught >= self.numFruits: finishText = TTLocalizer.PartyCatchActivityFinishPerfect else: finishText = TTLocalizer.PartyCatchActivityFinish perfectTextSubnode = hidden.attachNewNode(self.__genText(finishText)) perfectText = hidden.attachNewNode('perfectText') perfectTextSubnode.reparentTo(perfectText) frame = self.__textGen.getCardActual() offsetY = -abs(frame[2] + frame[3]) / 2.0 perfectTextSubnode.setPos(0, 0, offsetY) perfectText.setColor(1, 0.1, 0.1, 1) def fadeFunc(t, text=perfectText): text.setColorScale(1, 1, 1, t) def destroyText(text=perfectText): text.removeNode() textTrack = Sequence( Func(perfectText.reparentTo, aspect2d), Parallel( LerpScaleInterval(perfectText, duration=0.5, scale=0.3, startScale=0.0), LerpFunctionInterval(fadeFunc, fromData=0.0, toData=1.0, duration=0.5)), Wait(2.0), Parallel( LerpScaleInterval(perfectText, duration=0.5, scale=1.0), LerpFunctionInterval(fadeFunc, fromData=1.0, toData=0.0, duration=0.5, blendType='easeIn')), Func(destroyText), WaitInterval(0.5)) soundTrack = SoundInterval(self.sndPerfect) self.finishIval = Parallel(textTrack, soundTrack) self.finishIval.start() def finishConclusion(self): DistributedPartyCatchActivity.notify.debug('finishConclusion') if base.localAvatar.doId in self.toonIds: self.takeLocalAvatarOutOfActivity() base.cr.playGame.getPlace().fsm.request('walk') def showJellybeanReward(self, earnedAmount, jarAmount, message): if earnedAmount > 0: DistributedPartyActivity.showJellybeanReward( self, earnedAmount, jarAmount, message) else: base.cr.playGame.getPlace().fsm.request('walk')
def create_text_section(self, text, tag='', x=0, y=0): # print(text, tag) self.text_node = TextNode('t') self.text_node_path = self.attachNewNode(self.text_node) try: self.text_node.setFont(self._font) except: pass # default font if tag != '<>': tag = tag[1:-1] if tag.startswith('hsb('): # set color based on numbers tag = tag[4:-1] hsb_values = tuple(float(e.strip()) for e in tag.split(',')) self.current_color = color.color(*hsb_values) elif tag.startswith('rgb('): # set color based on numbers tag = tag[4:-1] rgb_values = (float(e.strip()) for e in tag.split(',')) self.current_color = color.rgba(*rgb_values) if tag.startswith('scale:'): scale = tag.split(':')[1] self.scale_override = float(scale) elif tag.startswith('image:'): texture_name = tag.split(':')[1] image = Entity( parent=self.text_node_path, name='inline_image', model='quad', texture=texture_name, color=self.current_color, scale=1, # position=(x*self.size*self.scale_override, y*self.size*self.line_height), origin=(.0, -.25), add_to_scene_entities=False, ) if not image.texture: destroy(image) else: self.images.append(image) # self.text_node.remove_node() # self.text_node = image else: if tag in self.text_colors: self.current_color = self.text_colors[tag] self.text_node_path.setScale(self.scale_override * self.size) self.text_node.setText(text) self.text_node.setTextColor(self.current_color) self.text_node.setPreserveTrailingWhitespace(True) # self.text_node_path.setPos( # x * self.size * self.scale_override, # 0, # (y * self.size * self.line_height) - .75 * self.size) self.text_node_path.setPos(x * self.size * self.scale_override, (y * self.size * self.line_height) - .75 * self.size, 0) self.text_nodes.append(self.text_node_path) return self.text_node
def load(self, loadModels=1, arenaModel='partyCatchTree'): self.notify.info('load()') DistributedPartyCatchActivity.notify.debug('PartyCatch: load') self.activityFSM = CatchActivityFSM(self) if __dev__: for o in xrange(3): print { 0: 'SPOTS PER PLAYER', 1: 'DROPS PER MINUTE PER SPOT DURING NORMAL DROP PERIOD', 2: 'DROPS PER MINUTE PER PLAYER DURING NORMAL DROP PERIOD' }[o] for i in xrange(1, self.FallRateCap_Players + 10): self.defineConstants(forceNumPlayers=i) numDropLocations = self.DropRows * self.DropColumns numDropsPerMin = 60.0 / self.DropPeriod if o == 0: spotsPerPlayer = numDropLocations / float(i) print '%2d PLAYERS: %s' % (i, spotsPerPlayer) elif o == 1: numDropsPerMinPerSpot = numDropsPerMin / numDropLocations print '%2d PLAYERS: %s' % (i, numDropsPerMinPerSpot) elif i > 0: numDropsPerMinPerPlayer = numDropsPerMin / i print '%2d PLAYERS: %s' % (i, numDropsPerMinPerPlayer) self.defineConstants() self.treesAndFence = loader.loadModel('phase_13/models/parties/%s' % arenaModel) self.treesAndFence.setScale(0.9) self.treesAndFence.find('**/fence_floor').setPos(0.0, 0.0, 0.1) self.treesAndFence.reparentTo(self.root) ground = self.treesAndFence.find('**/groundPlane') ground.setBin('ground', 1) DistributedPartyActivity.load(self) exitText = TextNode('PartyCatchExitText') exitText.setCardAsMargin(0.1, 0.1, 0.1, 0.1) exitText.setCardDecal(True) exitText.setCardColor(1.0, 1.0, 1.0, 0.0) exitText.setText(TTLocalizer.PartyCatchActivityExit) exitText.setTextColor(0.0, 8.0, 0.0, 0.9) exitText.setAlign(exitText.ACenter) exitText.setFont(ToontownGlobals.getBuildingNametagFont()) exitText.setShadowColor(0, 0, 0, 1) exitText.setBin('fixed') if TTLocalizer.BuildingNametagShadow: exitText.setShadow(*TTLocalizer.BuildingNametagShadow) exitTextLoc = self.treesAndFence.find('**/loc_exitSignText') exitTextNp = exitTextLoc.attachNewNode(exitText) exitTextNp.setDepthWrite(0) exitTextNp.setScale(4) exitTextNp.setZ(-0.5) self.sign.reparentTo(self.treesAndFence.find('**/loc_eventSign')) self.sign.wrtReparentTo(self.root) self.avatarNodePath = NodePath('PartyCatchAvatarNodePath') self.avatarNodePath.reparentTo(self.root) self._avatarNodePathParentToken = 3 base.cr.parentMgr.registerParent(self._avatarNodePathParentToken, self.avatarNodePath) self.toonSDs = {} self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow') self.dropObjModels = {} if loadModels: self.__loadDropModels() self.sndGoodCatch = base.loader.loadSfx( 'phase_4/audio/sfx/SZ_DD_treasure.ogg') self.sndOof = base.loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.sndAnvilLand = base.loader.loadSfx( 'phase_4/audio/sfx/AA_drop_anvil_miss.ogg') self.sndPerfect = base.loader.loadSfx( 'phase_4/audio/sfx/ring_perfect.ogg') self.__textGen = TextNode('partyCatchActivity') self.__textGen.setFont(ToontownGlobals.getSignFont()) self.__textGen.setAlign(TextNode.ACenter) self.activityFSM.request('Idle')
def _createPartyEditorPage(self): page = DirectFrame(self.frame) page.setName('PartyPlannerEditorPage') self.LayoutTitleLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerEditorTitle, pos=self.gui.find('**/title_locator').getPos() + Point3(0.0, 0.0, 0.075), scale=self.titleScale) self.costLabel = DirectLabel(parent=page, pos=(-0.74, 0.0, 0.17), relief=None, text=TTLocalizer.PartyPlannerTotalCost % 0, text_align=TextNode.ACenter, scale=TTLocalizer.PPcostLabel, textMayChange=True) self.partyGridBackground = DirectFrame( parent=page, relief=None, geom=self.gui.find('**/partyGrid_flat')) self.partyGroundsLabel = DirectLabel( parent=page, relief=None, text=TTLocalizer.PartyPlannerPartyGrounds, text_font=ToontownGlobals.getSignFont(), text_fg=VBase4(1.0, 0.0, 0.0, 1.0), text_scale=TTLocalizer.PPpartyGroundsLabel, pos=self.gui.find('**/step_05_partyGrounds_text_locator').getPos(), scale=0.1) self.activityBackground = DirectFrame( parent=page, relief=None, geom=self.gui.find('**/activitiesDecorations_flat1'), pos=(0.0, 0.0, 0.04)) pos = self.gui.find('**/step_05_instructions_locator').getPos() self.instructionLabel = DirectLabel( parent=page, relief=None, text=' ', text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPinstructionLabel, textMayChange=True, geom=self.gui.find('**/instructions_flat')) self.elementTitleLabel = DirectLabel( parent=page, relief=None, text=' ', pos=self.gui.find( '**/step_05_activitiesName_text_locator').getPos() + Point3(0.0, 0.0, 0.04), text_scale=TTLocalizer.PPelementTitleLabel, textMayChange=True) self.elementPriceNode = TextNode('ElementPrice') self.elementPriceNode.setAlign(TextNode.ALeft) self.elementPriceNode.setTextColor(0.0, 0.0, 0.0, 1.0) self.elementPriceNode.setFont(ToontownGlobals.getToonFont()) self.elementPrice = page.attachNewNode(self.elementPriceNode) self.elementPrice.setScale(TTLocalizer.PPelementPriceNode) self.elementPrice.setPos( self.gui.find('**/step_05_activityPrice_text_locator').getPos() + Point3(-0.02, 0.0, 0.04)) self.elementDescriptionNode = TextNode('ElementDescription') self.elementDescriptionNode.setAlign(TextNode.ACenter) self.elementDescriptionNode.setWordwrap(8) self.elementDescriptionNode.setFont(ToontownGlobals.getToonFont()) self.elementDescriptionNode.setTextColor(0.0, 0.0, 0.0, 1.0) self.elementDescription = page.attachNewNode( self.elementDescriptionNode) self.elementDescription.setScale(TTLocalizer.PPelementDescription) self.elementDescription.setPos( self.gui.find( '**/step_05_activityDescription_text_locator').getPos() + Point3(0.0, 0.0, 0.04)) self.totalMoney = base.localAvatar.getTotalMoney() catalogGui = loader.loadModel('phase_5.5/models/gui/catalog_gui') self.beanBank = DirectLabel(parent=page, relief=None, text=str(self.totalMoney), text_align=TextNode.ARight, text_scale=0.075, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_pos=(0.495, -0.53), text_font=ToontownGlobals.getSignFont(), textMayChange=True, image=catalogGui.find('**/bean_bank'), image_scale=(0.65, 0.65, 0.65), scale=0.9, pos=(-0.75, 0.0, 0.6)) catalogGui.removeNode() del catalogGui self.accept(localAvatar.uniqueName('moneyChange'), self.__moneyChange) self.accept(localAvatar.uniqueName('bankMoneyChange'), self.__moneyChange) self.partyEditor = PartyEditor(self, page) self.partyEditor.request('Hidden') pos = self.gui.find('**/step_05_add_text_locator').getPos() self.elementBuyButton = DirectButton( parent=page, relief=None, text=TTLocalizer.PartyPlannerBuy, text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPelementBuyButton, geom=(self.gui.find('**/add_up'), self.gui.find('**/add_down'), self.gui.find('**/add_rollover')), geom3_color=VBase4(0.5, 0.5, 0.5, 1.0), textMayChange=True, pos=(0.0, 0.0, 0.04), command=self.partyEditor.buyCurrentElement) self.okWithPartyGroundsLayoutEvent = 'okWithPartyGroundsLayoutEvent' self.accept(self.okWithPartyGroundsLayoutEvent, self.okWithPartyGroundsLayout) self.okWithGroundsGui = TTDialog.TTGlobalDialog( dialogName=self.uniqueName('PartyEditorOkGui'), doneEvent=self.okWithPartyGroundsLayoutEvent, message=TTLocalizer.PartyPlannerOkWithGroundsLayout, style=TTDialog.YesNo, okButtonText=OTPLocalizer.DialogYes, cancelButtonText=OTPLocalizer.DialogNo) self.okWithGroundsGui.doneStatus = '' self.okWithGroundsGui.hide() return page
class Sprite(NodePath, DirectObject): #- Just constant identifiers MouseLeftDown = 'left-down' MouseLeftUp = 'left-up' MouseLeftClick = 'left-click' MouseCenterDown = 'center-down' MouseCenterUp = 'center-up' MouseCenterClick = 'center-click' MouseRightDown = 'right-down' MouseRightUp = 'right-up' MouseRightClick = 'right-click' MouseFourDown = 'four-down' MouseFourUp = 'four-up' MouseFourClick = 'four-click' MouseFiveDown = 'five-down' MouseFiveUp = 'five-up' MouseFiveClick = 'five-click' MouseScrollUp = 'scroll-up' MouseScrollDown = 'scroll-down' MouseEnter = 'enter' MouseExit = 'exit' MouseWithin = 'within' MouseWithout = 'without' StateDefault = 'state-default' StateHover = 'state-hover' StateClick = 'state-click' StateFocus = 'state-focus' StateDisabled = 'state-disabled' def __init__(self, name): NodePath.__init__(self, name) DirectObject.__init__(self) self.setPythonTag('Sprite', self) global SpriteCounter SpriteCounter += 1 self.__id = int(SpriteCounter) #- Use PGItem to detect mouse and keyboard input via PGTop (eg, aspect2d, pixel2d, etc) self.__pgItem = PGItem(name) self.__pgItem.setActive(True) self.__pgItemNp = self.attachNewNode(self.__pgItem) #- Use TextNode to generate both text and cards for displaying background images self.__textNode = TextNode(name) self.__textNodeNp = None #self.__textNodeNp = self.attachNewNode(self.__textNode) #self.__textNode.setCardDecal(True) #- This is what we would do, should Sprite support being non-under PGTop self.accept(self.__pgItem.getPressEvent(MouseButton.one()), self.__onMouse, [Sprite.MouseLeftDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.two()), self.__onMouse, [Sprite.MouseCenterDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.three()), self.__onMouse, [Sprite.MouseRightDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.four()), self.__onMouse, [Sprite.MouseFourDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.five()), self.__onMouse, [Sprite.MouseFiveDown]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.one()), self.__onMouse, [Sprite.MouseLeftUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.two()), self.__onMouse, [Sprite.MouseCenterUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.three()), self.__onMouse, [Sprite.MouseRightUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.four()), self.__onMouse, [Sprite.MouseFourUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.five()), self.__onMouse, [Sprite.MouseFiveUp]) self.accept(self.__pgItem.getPressEvent(MouseButton.wheelDown()), self.__onMouse, [Sprite.MouseScrollDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.wheelUp()), self.__onMouse, [Sprite.MouseScrollUp]) self.accept(self.__pgItem.getEnterEvent(), self.__onMouse, [Sprite.MouseEnter]) self.accept(self.__pgItem.getExitEvent(), self.__onMouse, [Sprite.MouseExit]) self.accept(self.__pgItem.getWithinEvent(), self.__onMouse, [Sprite.MouseWithin]) self.accept(self.__pgItem.getWithoutEvent(), self.__onMouse, [Sprite.MouseWithout]) self.__beastDebug = ConfigVariableBool('beast-debug', False).getValue() self.__mouseInside = False self.__disabled = False #- Setup state configuration self.__lastStateOptions = None self.__state = None self.__states = { 'default': SpriteOptions(), 'hover': SpriteOptions(), 'click': SpriteOptions(), 'focus': SpriteOptions(), 'disabled': SpriteOptions(), } self.updateToState('default') def setDirty(self, dirty=True): if dirty: self.setTag('dirty', '') else: self.clearTag('dirty') def setDisabled(self, disabled): self.__disabled = disabled if self.__disabled: self.updateToState('disabled') else: #- FIXME! Account for focus? self.updateToState('default') def isDisabled(self): return self.__disabled def bind(self, event, method, extraArgs=[], onlyOnce=False): actualEvent = self.getEvent(event) if onlyOnce: self.acceptOnce(event, method, extraArgs=extraArgs) else: self.accept(event, method, extraArgs=extraArgs) def unbind(self, event): actualEvent = self.getEvent(event) self.ignore(actualEvent) def getEvent(self, event): return 'Sprite-' + str(self.__id) + '-' + self.getName() + '-' + event def __onMouse(self, event, mwr): if event == Sprite.MouseEnter: self.__mouseInside = True elif event == Sprite.MouseExit: self.__mouseInside = False actualEvents = [] actualEvents.append(event) if self.__mouseInside: if event == Sprite.MouseLeftUp: actualEvents.append(Sprite.MouseLeftClick) elif event == Sprite.MouseCenterUp: actualEvents.append(Sprite.MouseCenterClick) elif event == Sprite.MouseRightUp: actualEvents.append(Sprite.MouseRightClick) elif event == Sprite.MouseFourUp: actualEvents.append(Sprite.MouseFourClick) elif event == Sprite.MouseFiveUp: actualEvents.append(Sprite.MouseFiveClick) #- Handle state changing for event in actualEvents: if self.__state == 'default': if event == Sprite.MouseEnter: self.updateToState('hover') elif self.__state == 'hover': if event == Sprite.MouseExit: self.updateToState('default') if event == Sprite.MouseLeftDown: self.updateToState('click') elif self.__state == 'click': if event == Sprite.MouseLeftClick: # self.updateToState('focus') self.updateToState('hover') if event == Sprite.MouseLeftUp and self.__mouseInside == False: # self.updateToState('focus') self.updateToState('default') #- Finally, we can send out user events for event in actualEvents: messenger.send(self.getEvent(event)) def updateToState(self, newState=None): if newState == self.__state: return if newState: self.__state = newState if self.__beastDebug: print self.__state, globalClock.getFrameCount() messenger.send(self.getEvent('state-' + self.__state)) defaultOptions = self.__states['default'] hoverOptions = self.__states['hover'] clickOptions = self.__states['click'] focusOptions = self.__states['focus'] disabledOptions = self.__states['disabled'] if self.__state == 'default': self._applySpriteOptions(SpriteOptions.combine(defaultOptions)) elif self.__state == 'hover': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, hoverOptions)) elif self.__state == 'click': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, hoverOptions, clickOptions)) elif self.__state == 'focus': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, focusOptions)) elif self.__state == 'disabled': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, disabledOptions)) def _applySpriteOptions(self, options): dirty = False if options.options.values() == self.__lastStateOptions: return else: self.__lastStateOptions = options.options.values() self.setDirty() dirty = True #- First we do checks for size if options.hasSize(): self.__pgItem.setActive(True) #- It has a size, so it's active x, y = options.getSize() self.__pgItem.setFrame(0, x, -y, 0) #- Set both the card and frame bounds to match the size specified self.__textNode.setCardActual(0, x, -y, 0) if options.hasBorderColor(): #- They want a border, no matter what self.__textNode.setFrameActual(0, x, -y, 0) if options.hasBorderWidth(): self.__textNode.setFrameLineWidth(options.getBorderWidth()) else: self.__textNode.setFrameLineWidth(1) else: #- They want no border self.__textNode.clearFrame() self.__textNode.setFrameLineWidth(0) #- Unimportant I think else: self.__pgItem.setActive(False) #- It has no size, it's un active self.__pgItem.setFrame(0, 0, 0, 0) self.__textNode.clearCard() self.__textNode.clearFrame() if options.hasFont(): self.__textNode.setFont(options.getFont()) else: self.__textNode.clearFont() if options.hasFontSize(): #- FIXME! change for point2d later textNodeScale = 1.0 / options.getFontSize() #- Applied later # #self.__textNodeNp.setScale(1.0 / options.getFontSize()) # FIXME? Make sure it's 4 spaces self.__textNode.setTabWidth(options.getFontSize() * 4.0) else: textNodeScale = 1.0 # #self.__textNodeNp.setScale(1.0) if options.hasBackgroundColor(): color = options.getBackgroundColor().getAsFloat() self.__textNode.setCardColor(*color) else: if options.hasSize(): self.__textNode.setCardColor(1, 1, 1, 1) #- White else: self.__textNode.setCardColor(0, 0, 0, 0) #- Clear if options.hasBorderColor(): color = options.getBorderColor().getAsFloat() self.__textNode.setFrameColor(*color) else: self.__textNode.setFrameColor(0, 0, 0, 0) #- Clear if options.hasText(): text = options.getText() self.__textNode.setWtext(options.getText()) if options.hasTextPadding(): px, py = options.getTextPadding() else: px, py = (0, 0) #- Set sizes, even if they have no color self.__textNode.setCardAsMargin(px, px, py, py) self.__textNode.setFrameAsMargin(px, px, py, py) l, r, b, t = self.__textNode.getCardActual() #- Offset the TextNode so it only extends right and down #- FIXME! change for point2d later? (Does scale apply there even haha?) s = textNodeScale l, r, b, t = l * s, r * s, b * s, t * s textNodeX = -l #- Applied later textNodeZ = -t #- Applied later #self.__textNodeNp.setX(-l) #self.__textNodeNp.setZ(-t) self.__pgItem.setActive(True) #- It has a size now, it's active self.__pgItem.setFrame(0, -l + r, -t + b, 0) else: self.__textNode.setWtext( u' ' ) #- It's important to have a space, otherwise no card is rendered! textNodeX = 0 #- Applied later textNodeZ = 0 #- Applied later #self.__textNodeNp.setX(0) #self.__textNodeNp.setZ(0) if not options.hasSize(): self.__pgItem.setFrame(0, 0, 0, 0) if options.hasTextAlign(): align = options.getTextAlign() if align == 'left': self.__textNode.setAlign(TextNode.ALeft) elif align == 'center': self.__textNode.setAlign(TextNode.ACenter) elif align == 'right': self.__textNode.setAlign(TextNode.ARight) else: self.__textNode.clearAlign() if options.hasTextColor(): color = options.getTextColor().getAsFloat() self.__textNode.setTextColor(*color) #self.__textNodeNp.setColor(*color) #else: self.__textNode.setTextColor(0, 0, 0, 1) #- Black # self.__textNodeNp.clearColor() if options.hasTextSmallCaps(): self.__textNode.setSmallCaps(options.getTextSmallCaps()) else: self.__textNode.clearSmallCaps() if options.hasTextSmallCapsScale(): self.__textNode.setSmallCapsScale(options.getTextSmallCapsScale()) else: self.__textNode.clearSmallCapsScale() if options.hasTextSlant(): self.__textNode.setSlant(options.getTextSlant()) else: self.__textNode.clearSlant() if options.hasTextUnderline(): self.__textNode.setUnderscore(options.getTextUnderline()) else: self.__textNode.clearUnderscore() if options.hasTextShadow(): self.__textNode.setShadow(*options.getTextShadow()) else: self.__textNode.clearShadow() if options.hasTextShadowColor(): color = options.getTextShadowColor().getAsFloat() self.__textNode.setShadowColor(*color) else: self.__textNode.clearShadowColor() if self.__textNodeNp: self.__textNodeNp.remove() self.__textNodeNp = self.attachNewNode(self.__textNode.generate()) self.__textNodeNp.setScale(textNodeScale) self.__textNodeNp.setX(textNodeX) self.__textNodeNp.setZ(textNodeZ) ''' def setup(self, textNodeScale, textNodeX, textNodeZ): print 'getting lock...' base.textThreadLock.acquire() print 'Got lock' if self.__textNodeNp: self.__textNodeNp.remove() self.__textNodeNp = self.attachNewNode('foobar') #textNode.generate() print 'yes, it generated' base.textThreadLock.release() ''' #self.__textNodeNp = self.attachNewNode(self.__textNode.generate()) #self.__textNodeNp.setScale(textNodeScale) #self.__textNodeNp.setX(textNodeX) #self.__textNodeNp.setZ(textNodeZ) ''' import direct.stdpy.threading t = threading.Thread(target=setup, args=(self, textNodeScale, textNodeX, textNodeZ)) t.start() ''' if dirty: messenger.send('beastCollectionUpdate') def getOptions(self, state): return self.__states[state] def getCurrentOptions(self): return self.__states[self.__state] def getCurrentState(self): return self.__state def getPgItem(self): return self.__pgItem def getPgItemNp(self): return self.__pgItemNp def getTextNode(self): return self.__textNode def getTextNodeNp(self): return self.__textNodeNp @staticmethod def destroyChildren(np): for child in np.getChildren(): if child.hasPythonTag('Sprite'): sprite = child.getPythonTag('Sprite') sprite.destroy() def destroy(self): self.clearPythonTag('Sprite') self.ignoreAll() Sprite.destroyChildren(self) self.remove()
class GUI(object): """ Handles the gui elements like showing the current stage """ def __init__(self, control): self.control = control self.gui_node = pixel2d.attach_new_node("GUI") self.gui_node.hide() self.gui_node.set_transparency(True) roboto_light = loader.loadFont("res/Roboto-Light.ttf") roboto_light.set_scale_factor(1) roboto_light.set_pixels_per_unit(120) self.text_stage = TextNode("TextStage") self.text_stage.set_text("Stage 1") self.text_stage.set_align(TextNode.A_left) self.text_stage.set_text_color(1, 1, 1, 1) self.text_stage.set_font(roboto_light) self.text_stage_np = self.gui_node.attach_new_node(self.text_stage) self.text_stage_np.set_scale(80.0) self.text_stage_np.set_pos(60, 0, -120) self.anim = None def show(self): self.gui_node.show() if self.anim is not None: self.anim.finish() self.anim = Sequence( LerpColorScaleInterval(self.gui_node, 0.2, Vec4(1), Vec4(1, 1, 1, 0), blendType="easeInOut")) self.anim.start() def hide(self): self.gui_node.hide() if self.anim is not None: self.anim.finish() self.anim = Sequence( LerpColorScaleInterval(self.gui_node, 0.2, Vec4(1, 1, 1, 0), Vec4(1), blendType="easeInOut")) self.anim.start() def set_stage(self, stage_nr): print("Setting stage", stage_nr) Sequence( LerpColorScaleInterval(self.text_stage_np, 0.4, Vec4(1, 1, 1, 0), Vec4(1), blendType="easeInOut"), Func(lambda *args: self.text_stage.set_text("Stage " + str(stage_nr ))), LerpColorScaleInterval(self.text_stage_np, 0.4, Vec4(1), Vec4(1, 1, 1, 0), blendType="easeInOut"), ).start()
def __init__(self, rendering: bool): """ Constructor :param rendering: boolean indicating whether to use RenderPipeline or default Panda3d as visualization-module. """ super().__init__(self) self.dir = Filename.fromOsSpecific( pyrado.PANDA_ASSETS_DIR).getFullpath() # Initialize RenderPipeline if rendering: sys.path.insert(0, pyrado.RENDER_PIPELINE_DIR) from rpcore import RenderPipeline self.render_pipeline = RenderPipeline() self.render_pipeline.pre_showbase_init() self.render_pipeline.set_loading_screen_image( osp.join(self.dir, "logo.png")) self.render_pipeline.settings["pipeline.display_debugger"] = False self.render_pipeline.create(self) self.render_pipeline.daytime_mgr.time = "17:00" else: self.render_pipeline = None # Activate antialiasing self.render.setAntialias(AntialiasAttrib.MAuto) # Set window properties self.windowProperties = WindowProperties() self.windowProperties.setForeground(True) self.windowProperties.setTitle("Experiment") # Set background color self.setBackgroundColor(1, 1, 1) # Configuration of the lighting self.directionalLight1 = DirectionalLight("directionalLight") self.directionalLightNP1 = self.render.attachNewNode( self.directionalLight1) self.directionalLightNP1.setHpr(0, -8, 0) self.render.setLight(self.directionalLightNP1) self.directionalLight2 = DirectionalLight("directionalLight") self.directionalLightNP2 = self.render.attachNewNode( self.directionalLight2) self.directionalLightNP2.setHpr(180, -20, 0) self.render.setLight(self.directionalLightNP2) self.ambientLight = AmbientLight("ambientLight") self.ambientLightNP = self.render.attachNewNode(self.ambientLight) self.ambientLight.setColor((0.1, 0.1, 0.1, 1)) self.render.setLight(self.ambientLightNP) # Create a text node displaying the physic parameters on the top left of the screen self.text = TextNode("parameters") self.textNodePath = aspect2d.attachNewNode(self.text) self.text.setTextColor(0, 0, 0, 1) # black self.textNodePath.setScale(0.07) self.textNodePath.setPos(-1.9, 0, 0.9) # Configure trace self.trace = LineSegs() self.trace.setThickness(3) self.trace.setColor(0.8, 0.8, 0.8) # light grey self.lines = self.render.attachNewNode("Lines") self.last_pos = None # Adds one instance of the update function to the task-manager, thus initializes the animation self.taskMgr.add(self.update, "update")
class PartyCog(FSM): notify = directNotify.newCategory('PartyCog') HpTextGenerator = TextNode('HpTextGenerator') hpText = None height = 7 def __init__(self, parentNode, id, bounceSpeed=3, bounceHeight=1, rotateSpeed=1, heightShift=1, xMoveSpeed=0, xMoveDistance=0, bounceOffset=0): self.id = id FSM.__init__(self, 'PartyCogFSM-%d' % self.id) self.showFacingStatus = False self.xMoveSpeed = xMoveSpeed self.xMoveDistance = xMoveDistance self.heightShift = heightShift self.bounceSpeed = bounceSpeed self.bounceHeight = bounceHeight self.rotateSpeed = rotateSpeed self.parentNode = parentNode self.bounceOffset = bounceOffset self.hitInterval = None self.kaboomTrack = None self.resetRollIval = None self.netTimeSentToStartByHit = 0 self.load() self.request('Down') return def load(self): self.root = NodePath('PartyCog-%d' % self.id) self.root.reparentTo(self.parentNode) path = 'phase_13/models/parties/cogPinata_' self.actor = Actor( path + 'actor', { 'idle': path + 'idle_anim', 'down': path + 'down_anim', 'up': path + 'up_anim', 'bodyHitBack': path + 'bodyHitBack_anim', 'bodyHitFront': path + 'bodyHitFront_anim', 'headHitBack': path + 'headHitBack_anim', 'headHitFront': path + 'headHitFront_anim' }) self.actor.reparentTo(self.root) self.temp_transform = Mat4() self.head_locator = self.actor.attachNewNode('temphead') self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75) self.bodyColl.setTangible(1) self.bodyCollNode = CollisionNode('PartyCog-%d-Body-Collision' % self.id) self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.bodyCollNode.addSolid(self.bodyColl) self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode) self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5) self.headColl.setTangible(1) self.headCollNode = CollisionNode('PartyCog-%d-Head-Collision' % self.id) self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.headCollNode.addSolid(self.headColl) self.headCollNodePath = self.root.attachNewNode(self.headCollNode) self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0) self.arm1Coll.setTangible(1) self.arm1CollNode = CollisionNode('PartyCog-%d-Arm1-Collision' % self.id) self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm1CollNode.addSolid(self.arm1Coll) self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode) self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0) self.arm2Coll.setTangible(1) self.arm2CollNode = CollisionNode('PartyCog-%d-Arm2-Collision' % self.id) self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm2CollNode.addSolid(self.arm2Coll) self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode) splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splatType = globalPropPool.getPropType(splatName) self.pieHitSound = globalBattleSoundCache.getSound( 'AA_wholepie_only.ogg') self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.ogg') self.hole = loader.loadModel('phase_13/models/parties/cogPinataHole') self.hole.setTransparency(True) self.hole.setP(-90.0) self.hole.setScale(3) self.hole.setBin('ground', 3) self.hole.reparentTo(self.parentNode) def unload(self): self.request('Off') self.clearHitInterval() if self.hole is not None: self.hole.removeNode() self.hole = None if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None if self.root is not None: self.root.removeNode() self.root = None if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.kaboomTrack = None if self.resetRollIval is not None and self.resetRollIval.isPlaying(): self.resetRollIval.finish() self.resetRollIval = None if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.finish() self.hitInterval = None del self.upSound del self.pieHitSound return def enterStatic(self): pass def exitStatic(self): pass def enterActive(self, startTime): self.root.setR(0.0) updateTask = Task.Task(self.updateTask) updateTask.startTime = startTime taskMgr.add(updateTask, 'PartyCog.update-%d' % self.id) def exitActive(self): taskMgr.remove('PartyCog.update-%d' % self.id) taskMgr.remove('PartyCog.bounceTask-%d' % self.id) self.clearHitInterval() self.resetRollIval = self.root.hprInterval(0.5, Point3( self.root.getH(), 0.0, 0.0), blendType='easeInOut') self.resetRollIval.start() self.actor.stop() def enterDown(self): if self.oldState == 'Off': downAnimControl = self.actor.getAnimControl('down') self.actor.pose('down', downAnimControl.getNumFrames() - 1) return self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpFunc(self.setAlongSpline, duration=1.0, fromData=self.currentT, toData=0.0), LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'down', loop=0)), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def exitDown(self): self.root.setR(0.0) self.root.setH(0.0) self.targetDistance = 0.0 self.targetFacing = 0.0 self.currentT = 0.0 self.setAlongSpline(0.0) self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'up', loop=0)), Func(self.actor.loop, 'idle'), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def filterDown(self, request, args): if request == 'Down': return None else: return self.defaultFilter(request, args) return None def setEndPoints(self, start, end, amplitude=1.7): self.sinAmplitude = amplitude self.sinPeriod = (end.getX() - start.getX()) / 2 self.sinDisplacement = start.getY() self.startPoint = start self.endPoint = end self.currentT = 0.0 self.targetDistance = 0.0 self.currentFacing = 0.0 self.targetFacing = 0.0 self.setAlongSpline(self.currentT) self.hole.setPos(self.root.getPos()) self.hole.setZ(0.02) def rockBackAndForth(self, task): t = task.startTime + task.time angle = math.sin(t) * 20.0 self.root.setR(angle) return task.cont def updateDistance(self, distance): self.targetDistance = clamp(distance, -1.0, 1.0) def updateTask(self, task): self.rockBackAndForth(task) if self.targetDistance > self.currentT: self.currentT += min(0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) elif self.targetDistance < self.currentT: self.currentT += max(-0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) if self.currentT < 0.0: self.targetFacing = -90.0 elif self.currentT > 0.0: self.targetFacing = 90.0 else: self.targetFacing = 0.0 if self.targetFacing > self.currentFacing: self.currentFacing += min(10, self.targetFacing - self.currentFacing) elif self.targetFacing < self.currentFacing: self.currentFacing += max(-10, self.targetFacing - self.currentFacing) self.root.setH(self.currentFacing) return task.cont def setAlongSpline(self, t): t = t + 1.0 dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0 x = self.startPoint.getX() + t * dist y = self.startPoint.getY() - math.sin( t * 2 * math.pi) * self.sinAmplitude self.root.setPos(x, y, 0) def startBounce(self): taskMgr.add(self.bounce, 'PartyCog.bounceTask-%d' % self.id) def bounce(self, task): self.root.setZ( math.sin((self.bounceOffset + task.time) * self.bounceSpeed) * self.bounceHeight + self.heightShift) return task.cont def setPos(self, position): self.root.setPos(position) def respondToPieHit(self, timestamp, position, hot=False, direction=1.0): if self.netTimeSentToStartByHit < timestamp: self.__showSplat(position, direction, hot) if self.netTimeSentToStartByHit < timestamp: self.netTimeSentToStartByHit = timestamp else: self.notify.debug( 'respondToPieHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit) def clearHitInterval(self): if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.clearToInitial() return def __showSplat(self, position, direction, hot=False): if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.clearHitInterval() splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splat.reparentTo(render) self.splat.setPos(self.root, position) self.splat.setAlphaScale(1.0) if not direction == 1.0: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0]) if self.currentFacing > 0.0: facing = 'HitFront' else: facing = 'HitBack' else: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1]) if self.currentFacing > 0.0: facing = 'HitBack' else: facing = 'HitFront' if hot: targetscale = 0.75 part = 'head' else: targetscale = 0.5 part = 'body' def setSplatAlpha(amount): self.splat.setAlphaScale(amount) self.hitInterval = Sequence( ActorInterval(self.actor, part + facing, loop=0), Func(self.actor.loop, 'idle')) self.hitInterval.start() self.kaboomTrack = Parallel( SoundInterval(self.pieHitSound, volume=1.0, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence( Func(self.splat.showThrough), Parallel( Sequence( LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType='easeOut'), Wait(0.175)), Sequence( Wait(0.1), LerpFunc(setSplatAlpha, duration=1.0, fromData=1.0, toData=0.0, blendType='easeOut'))), Func(self.splat.cleanup), Func(self.splat.removeNode))) self.kaboomTrack.start() return def showHitScore(self, number, scale=1): if number <= 0: return if self.hpText: self.hideHitScore() self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText('+' + str(number)) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = 1 g = 1 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = render.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(self.root, 0, 0, self.height / 2) seq = Sequence( self.hpText.posInterval( 0.25, Point3(self.root.getX(render), self.root.getY(render), self.root.getZ(render) + self.height + 1.0), blendType='easeOut'), Wait(0.25), self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)), Func(self.__hideHitScore)) seq.start() def hideHitScore(self): if self.hpText: taskMgr.remove('PartyCogHpText' + str(self.id)) self.hpText.removeNode() self.hpText = None return def getHeadLocation(self): self.actor.getJoints(jointName='head')[0].getNetTransform( self.temp_transform) self.head_locator.setMat(self.temp_transform) return self.head_locator.getZ(self.root)