def __makeTrack(self, trackName): gui = loader.loadModel('phase_3.5/models/gui/inventory_gui.bam') color = GagGlobals.TrackColorByName[trackName] track = gui.find('**/InventoryRow') track.setColor(*color) frame = DirectFrame(parent=self) frame.setZ(TrackZValueByName[trackName]) frame['image'] = track trackTitle = OnscreenText(text=trackName, parent=frame, pos=(-0.63, -0.01, 0), scale=0.06) self.trackByName[trackName] = frame
class UnoGameCardDeck(DirectFrame): def __init__(self, ug): DirectFrame.__init__(self, relief=None, sortOrder=50, parent=base.a2dBottomCenter) self.initialiseoptions(UnoGameCardDeck) self.container = DirectFrame(parent=self, relief=None) self.title = None self.cards = [] self.cardBtns = [] self.numCards = 0 self.unoGame = ug self.deck = None self.cardToFollowGui = None self.holiday = base.cr.holidayManager.getHoliday() self.gui = None self.loadCards() return def loadCards(self): self.gui = loader.loadModel( "phase_4/models/minigames/mg_uno_game_cards.egg") if self.holiday == HolidayType.CHRISTMAS: cards = self.gui.find( '**/mg_uno_numcards_green_7').getParent().getChildren() for child in cards: child.setTexture( loader.loadTexture('winter/maps/uno/%s.png' % (child.getName())), 1) def updateCardToFollowGui(self): self.deleteCardToFollowGui() if self.unoGame.cardToFollow[-2:] == str(UGG.CARD_BLUE): self.cardToFollowGui = OnscreenImage( image=self.getCard('mg_uno_numcards_blue_blank'), parent=base.a2dRightCenter) elif self.unoGame.cardToFollow[-2:] == str(UGG.CARD_RED): self.cardToFollowGui = OnscreenImage( image=self.getCard('mg_uno_numcards_red_blank'), parent=base.a2dRightCenter) elif self.unoGame.cardToFollow[-2:] == str(UGG.CARD_GREEN): self.cardToFollowGui = OnscreenImage( image=self.getCard('mg_uno_numcards_green_blank'), parent=base.a2dRightCenter) elif self.unoGame.cardToFollow[-2:] == str(UGG.CARD_YELLOW): self.cardToFollowGui = OnscreenImage( image=self.getCard('mg_uno_numcards_yellow_blank'), parent=base.a2dRightCenter) if self.cardToFollowGui: self.cardToFollowGui.setScale(0.25, 0.3, 0.3) self.cardToFollowGui.setPos(-0.175, 0, -0.75) def deleteCardToFollowGui(self): if self.cardToFollowGui: self.cardToFollowGui.destroy() self.cardToFollowGui = None def getCard(self, cardType): cards = loader.loadModel( "phase_4/models/minigames/mg_uno_game_cards.egg") card = cards.find('**/' + cardType) if self.holiday == HolidayType.CHRISTMAS: holidayTexture = loader.loadTexture('winter/maps/uno/%s.png' % (card.getName())) card.setTexture(holidayTexture, 1) return card def generate(self): self.container["image"] = "phase_4/maps/mg_uno_card_deck.png" self.container.setTransparency(True) self.container.setZ(-0.456) self.container.setSx(2) self.container.setSz(1) gui = loader.loadModel("phase_3.5/models/gui/friendslist_gui.bam") numItemsVisible = 5 itemHeight = -0.25 self.deck = DirectScrolledList( itemFrame_relief=DGG.SUNKEN, decButton_pos=(0.35, 0, -0.02), decButton_geom=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'), gui.find('**/Horiz_Arrow_Rllvr'), gui.find('**/Horiz_Arrow_UP')), decButton_relief=None, decButton_hpr=(0, 0, 90), incButton_pos=(0.35, 0, 1.95), incButton_geom=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'), gui.find('**/Horiz_Arrow_Rllvr'), gui.find('**/Horiz_Arrow_UP')), incButton_hpr=(0, 0, -90), incButton_relief=None, pos=(-0.936, 0, -0.41), hpr=(0, 0, 90), scale=0.97, numItemsVisible=numItemsVisible, forceHeight=itemHeight, itemFrame_frameSize=(-0.2, 0.2, -0.37, 1.5), itemFrame_pos=(0.35, 0, 0.4), itemFrame_borderWidth=(0.02, 0.02), ) def disable(self): if self.deck: self.deck.destroy() self.deck = None for btn in self.cardBtns: btn.destroy() del btn self.deleteCardToFollowGui() return def delete(self): DirectFrame.destroy(self) self.disable() self.gui.removeNode() self.gui = None self.cards = None self.title = None self.container = None self.cardBtns = None self.numCards = None self.unoGame = None self.deck = None return def drawCard(self, id): card = self.getCard(UGG.cardId2cardTex[id]) card.setScale(0.225, 0.3, 0.3) card.setR(-90) cardBtn = DirectButton(geom=card, relief=None, scale=(0.3, 0.3, 0.23), command=self.placeCard) cardBtn.setPythonTag('id', id) cardBtn['extraArgs'] = [id, cardBtn] cardBtn['state'] = DGG.DISABLED if not self.deck: self.generate() self.deck.addItem(cardBtn) self.cardBtns.append(cardBtn) self.enableAll(self.unoGame.cardToFollow) # Scroll to the card we just added to the deck. self.deck.scrollTo(len(self.cardBtns)) card.removeNode() del card def enableAll(self, cardToFollow=None): for btn in self.cardBtns: if cardToFollow != None: if (cardToFollow == btn.getPythonTag('id') or cardToFollow[:2] == btn.getPythonTag('id')[:2] or cardToFollow[-2:] == btn.getPythonTag('id')[-2:] or btn.getPythonTag('id') == str(UGG.CARD_WILD) or btn.getPythonTag('id') == str( UGG.CARD_WILD_DRAW_FOUR)): btn['state'] = DGG.NORMAL else: btn['state'] = DGG.DISABLED else: btn['state'] = DGG.NORMAL def disableAll(self): for btn in self.cardBtns: btn['state'] = DGG.DISABLED def placeCard(self, id, btn): self.deck.removeItem(btn) self.cardBtns.remove(btn) self.disableAll() self.unoGame.d_requestPlaceCard(id)
class GagSelectionGui(DirectFrame, FSM): InactivityTime = 5.0 AmmoZSelect = -0.15 AmmoZIdle = 0.035 def __init__(self): DirectFrame.__init__(self, parent=aspect2d, pos=(0, 0, 0.93), scale=0.7) FSM.__init__(self, 'GagSelectionGui') self.setTransparency(TransparencyAttrib.MDual) self.tracks = [] self.currentTrack = 0 self.currentGag = None self.fwdShakeIval = None self.revShakeIval = None self.newTrackSound = None self.keyScrollSound = None self.selectSound = None self.selectDenySound = None self.lastActivityTime = 0.0 self.activityTask = None self.midpoint = 0.0 self.ammoFrame = DirectFrame(parent=self, pos=(0, 0, -0.2), image='phase_14/maps/status_bar.png', image_scale=(0.461 * 0.7, 0, 0.098), relief=None) self.ammoFrame.hide() self.ammoTitle = OnscreenText(parent=self.ammoFrame, text='SUPPLY', fg=(0, 0, 0, 0.65), align=TextNode.ALeft, pos=(-0.37 * 0.7, -0.015, 0)) self.ammoText = OnscreenText(parent=self.ammoFrame, text='', fg=(1, 1, 1, 1), shadow=(0, 0, 0, 1), align=TextNode.ARight, pos=(0.37 * 0.7, -0.015, 0)) def update(self): plyr = base.localAvatar if not base.localAvatar.hasAttacks(): return gagId = -1 if self.getCurrentOrNextState() == 'Idle': gagId = plyr.getEquippedAttack() elif self.getCurrentOrNextState() == 'Select' and self.currentGag: gagId = self.currentGag.gagId if gagId != -1: self.ammoFrame.showThrough() if plyr.hasAttackId(gagId): self.ammoText.setText( '%i/%i' % (plyr.getAttackAmmo(gagId), plyr.getAttackMaxAmmo(gagId))) else: self.ammoText.setText('') col = GagGlobals.TrackColorByName[GagGlobals.getTrackOfGag(gagId)] self.ammoFrame['image_color'] = (col[0], col[1], col[2], 1.0) else: self.ammoFrame.hide() def enterOff(self): pass def exitOff(self): pass def hide(self): showAmmo = False if not self.ammoFrame.isHidden(): showAmmo = True DirectFrame.hide(self) if showAmmo: self.ammoFrame.showThrough() def enterSelect(self): base.localAvatar.disableGagKeys() self.ammoFrame.setZ(self.AmmoZSelect) self.show() self.update() self.acceptSelectionClick() self.resetTimeout() self.activityTask = taskMgr.add(self.__activityTask, "activityTask") def acceptSelectionClick(self): self.accept('mouse1-up', self.selectCurrentGag) def ignoreSelectionClick(self): self.ignore('mouse1-up') def resetTimeout(self): self.lastActivityTime = globalClock.getFrameTime() def __activityTask(self, task): time = globalClock.getFrameTime() if time - self.lastActivityTime >= self.InactivityTime: self.request('Idle') return task.done return task.cont def exitSelect(self): self.activityTask.remove() self.activityTask = None self.hide() self.ignoreSelectionClick() def enterIdle(self): self.ammoFrame.setZ(self.AmmoZIdle) self.hide() self.update() if base.localAvatar.avatarMovementEnabled: base.localAvatar.enableGagKeys() def exitIdle(self): pass def disable(self): self.disableControls() self.hide() def enable(self): self.enableControls() self.show() def cleanup(self): self.request('Off') self.disableControls() self.newTrackSound = None self.keyScrollSound = None self.selectSound = None self.selectDenySound = None if self.fwdShakeIval: self.fwdShakeIval.finish() self.fwdShakeIval = None if self.revShakeIval: self.revShakeIval.finish() self.revShakeIval = None self.currentTrack = None self.currentGag = None if self.tracks: for track in self.tracks: track.cleanup() self.tracks = None self.destroy() def __accumulateTracks(self): tracks = [] for gagId in base.localAvatar.attacks.keys(): trackId = GagGlobals.getTrackOfGag(gagId, getId=True) if trackId not in tracks: tracks.append(trackId) tracks.sort() return tracks def load(self): tracks = self.__accumulateTracks() for i in xrange(len(tracks)): track = GagTrack(self, tracks[i]) track.load() track.reparentTo(self) track.setX(FRAME_OFFSET * i) self.tracks.append(track) self.midpoint = (len(self.tracks) / 2.0) * -FRAME_OFFSET # Center the gui horizontally self.setX(self.midpoint) self.ammoFrame.setX(-self.midpoint) if base.config.GetBool('gsg-want-hlsounds', False): self.newTrackSound = base.loadSfx( "phase_14/audio/sfx/wpn_hudon.ogg") self.keyScrollSound = base.loadSfx( 'phase_14/audio/sfx/wpn_moveselect.ogg') self.selectSound = base.loadSfx( 'phase_14/audio/sfx/wpn_select.ogg') self.selectDenySound = base.loadSfx( 'phase_14/audio/sfx/wpn_denyselect.ogg') else: self.newTrackSound = base.loadSfx( "phase_3/audio/sfx/GUI_create_toon_back.ogg") self.keyScrollSound = base.loadSfx( 'phase_3/audio/sfx/GUI_rollover.ogg') self.selectSound = base.loadSfx( 'phase_3/audio/sfx/GUI_create_toon_fwd.ogg') self.selectDenySound = base.loadSfx( 'phase_4/audio/sfx/ring_miss.ogg') self.fwdShakeIval = Effects.createXBounce(self, 1, Vec3(self.midpoint, 0, 0.93), 0.05, 0.05) self.revShakeIval = Effects.createXBounce(self, 1, Vec3(self.midpoint, 0, 0.93), 0.05, -0.05) if base.localAvatar.hasAttacks(): self.updateCurrentTrack(0) def enableControls(self): self.accept('wheel_up', self.__handleScrollUp) self.accept('wheel_down', self.__handleScrollDown) for i in xrange(len(self.tracks)): self.accept(str(i + 1), self.__handleTrackChoose, [i]) self.request('Idle') def selectCurrentGag(self): selected = False self.newTrackSound.stop() self.keyScrollSound.stop() if self.currentGag is not None: if base.localAvatar.getEquippedAttack() == self.currentGag.gagId: selected = True elif (not self.currentGag.locked and self.currentGag.hasAmmo()): gagId = self.currentGag.gagId base.localAvatar.needsToSwitchToGag = gagId if base.localAvatar.gagsTimedOut == False: base.localAvatar.selectGag(gagId) selected = True if not selected: # Denied! self.selectDenySound.play() self.resetTimeout() else: self.selectSound.play() self.request('Idle') def disableControls(self): self.ignore('wheel_up') self.ignore('wheel_down') for i in xrange(len(self.tracks)): self.ignore(str(i + 1)) self.request('Idle') def __maybeDoSelect(self): if self.getCurrentOrNextState() == 'Idle': self.request('Select') def __handleTrackChoose(self, idx): if not base.localAvatar.hasAttacks(): return self.__maybeDoSelect() self.resetTimeout() if self.currentTrack == idx: # Scroll through the current track. self.tracks[self.currentTrack].selectNextGag() self.newTrackSound.stop() self.keyScrollSound.play() else: # Always start from the beginning when using the keys to choose a track. self.updateCurrentTrack(idx, 0) self.newTrackSound.play() def __handleScrollUp(self): if not base.localAvatar.hasAttacks(): return self.__maybeDoSelect() self.resetTimeout() track = self.tracks[self.currentTrack] if track.isOnFirstGag(): self.prevTrack() else: track.selectPrevGag() self.newTrackSound.stop() self.keyScrollSound.play() def __handleScrollDown(self): if not base.localAvatar.hasAttacks(): return self.__maybeDoSelect() self.resetTimeout() track = self.tracks[self.currentTrack] if track.isOnLastGag(): self.nextTrack() else: track.selectNextGag() self.newTrackSound.stop() self.keyScrollSound.play() def nextTrack(self): newIdx = self.currentTrack + 1 if newIdx > len(self.tracks) - 1: newIdx = 0 self.updateCurrentTrack(newIdx) def prevTrack(self): newIdx = self.currentTrack - 1 if newIdx < 0: newIdx = len(self.tracks) - 1 self.updateCurrentTrack(newIdx) def updateCurrentTrack(self, idx, startLoc=None): oldTrack = self.tracks[self.currentTrack] oldTrack.deselectAll() oldTrack.stashContents() if idx - self.currentTrack < 0: direction = 1 else: direction = 0 if startLoc is None: startLoc = direction if direction == 0: self.fwdShakeIval.start() else: self.revShakeIval.start() self.currentTrack = idx # Resort the tracks numTracks = len(self.tracks) maxTrack = numTracks - 1 for i in xrange(len(self.tracks)): track = self.tracks[i] if i == idx: sort = FRAME_FRONT_SORT elif i > idx: sort = FRAME_SORT_BEGIN + (maxTrack - i) * FRAME_SORT_DISTANCE elif i < idx: sort = FRAME_SORT_BEGIN + (i * FRAME_SORT_DISTANCE) track.setBin('gsg-popup', sort) if i == idx: track.unstashContents() if startLoc == 0: track.selectFirstGag() else: track.selectLastGag() else: track.stashContents()
class OptionsPage(BookPage): notify = directNotify.newCategory("OptionsPage") # Keys are categories and values are x-positions for the text. Categories = OrderedDict() Categories[AboutCategory] = 0.09 Categories[GeneralCategory] = 0.07 Categories[ControlsCategory] = 0.05 Categories[SoundCategory] = 0.0825 Categories[DisplayCategory] = 0.07 Categories[AdvancedDisplayCategory] = 0.05 def __init__(self, book): BookPage.__init__(self, book, "Options") self.currentCategory = None self.tabs = [] def load(self): BookPage.load(self) icons = loader.loadModel('phase_3.5/models/gui/sos_textures.bam') self.icon = icons.find('**/switch') icons.detachNode() def enter(self): BookPage.enter(self) self.tabScaleFrame = DirectFrame(parent=self.book) self.tabScaleFrame.setZ(0.7683) self.tabsFrame = DirectFrame(parent=self.tabScaleFrame) tabWidth = 0.379136800766 spacing = 0.075 totalWidth = 0.0 bookWidth = 2.0 for i in xrange(len(self.Categories.keys())): if i > 0: totalWidth += spacing totalWidth += tabWidth cl = self.Categories.keys()[i] tab = CategoryTab(self, cl.Name, [cl], ((tabWidth + spacing) * i, 0, 0), self.Categories.values()[i]) self.tabs.append(tab) self.tabsFrame.setX(totalWidth / -2.0) self.tabScaleFrame.setScale(min(1.0, 1.0 / (totalWidth / bookWidth))) self.pickCategory(AboutCategory) def closeWindow(self): if self.currentCategory: self.currentCategory.cleanup() self.currentCategory = None def pickCategory(self, cat): if self.currentCategory: self.currentCategory.cleanup() self.currentCategory = None self.currentCategory = cat(self) for tab in self.tabs: if tab['extraArgs'][0] is cat: tab['state'] = DGG.DISABLED else: tab['state'] = DGG.NORMAL #self.currentCategory.show() def exit(self): if self.currentCategory: self.currentCategory.cleanup() self.currentCategory = None for tab in self.tabs: tab.destroy() self.tabsFrame.destroy() del self.tabsFrame self.tabScaleFrame.destroy() del self.tabScaleFrame self.tabs = [] BookPage.exit(self)
class MainGUI(DirectObject.DirectObject): def __init__(self): self.scaling = Scaling() self.layer = 0 self.regen = False self.showMenu = True self.showPause = False self.showMap = False self.pauseBar = DirectFrame( frameColor=(0.22/2, 0.24/2, 0.32/2, 1), frameSize=(0, base.win.getXSize(), 0, self.scaling.getVerticalDisplayRatio(25)), pos=(0, -1, -self.scaling.getVerticalDisplayRatio(25)), parent=pixel2d ) header = TextNode('paused') header.setText('Paused') header.setTextColor(1, 1, 1, 1) header.setAlign(TextNode.ACenter) header.setTextScale(30) self.pauseTextNodePath = self.pauseBar.attachNewNode(header) self.pauseTextNodePath.setPos(base.win.getXSize()/2, 0, -5) self.footer = DirectFrame( frameSize=(0, base.win.getXSize(), 0, 24), pos=(0, -1, -base.win.getYSize()), parent=pixel2d ) #findMethods(self.footer, 'set') self.pauseBar.hide() self.coords = TextNode('coords') self.coords.setText('coords: _x _y _z') self.coords.setTextColor(0, 0, 0, 1) self.coords.setAlign(TextNode.ARight) self.coords.setTextScale(15) self.coordsTextNodePath = self.footer.attachNewNode(self.coords) self.coordsTextNodePath.setPos(base.win.getXSize() - 10, 0, 5) self.time = TextNode('time') self.time.setText('time: _x _y _z') self.time.setTextColor(0, 0, 0, 1) self.time.setAlign(TextNode.ALeft) self.time.setTextScale(15) self.timeTextNodePath = self.footer.attachNewNode(self.time) self.timeTextNodePath.setPos(10, 0, 5) pixel2d.setAntialias(AntialiasAttrib.MMultisample) self.menubar = MenuBar() self.mapView = MapView() self.registerEvents() self.registerMouseClickEvents() def registerEvents(self): self.accept('window-event', self.onWindowEvent) self.accept('escape', self.exitProgram) self.accept('q', self.toggleMenu) self.accept('m', self.toggleMap) self.accept('l', self.cycleLayers) self.accept('space', self.togglePause) self.accept('w', self.shiftMapUp) self.accept('s', self.shiftMapDown) self.accept('a', self.shiftMapLeft) self.accept('d', self.shiftMapRight) def registerMouseClickEvents(self): findMethods(self.menubar.btnQuit, 'func') self.menubar.btnQuit['command'] = self.exitProgram self.mapView.btnLayers['command'] = self.cycleLayers self.menubar.btnMaps['command'] = self.setRegen def shiftMapUp(self): if self.mapView.origin[1] > 0: self.mapView.origin[1] -= 1 print(self.mapView.origin) def shiftMapDown(self): if self.mapView.origin[1] >= 0: self.mapView.origin[1] += 1 print(self.mapView.origin) def shiftMapLeft(self): if self.mapView.origin[0] > 0: self.mapView.origin[0] -= 1 print(self.mapView.origin) def shiftMapRight(self): if self.mapView.origin[0] >= 0: self.mapView.origin[0] += 1 print(self.mapView.origin) def setRegen(self): self.regen = True def toggleMenu(self): self.showMenu = not self.showMenu if self.showMenu: self.menubar.menubar.show() else: self.menubar.menubar.hide() def togglePause(self): self.showPause = not self.showPause if self.showPause: self.pauseBar.show() else: self.pauseBar.hide() def toggleMap(self): self.showMap = not self.showMap if self.showMap: self.mapView.mapView.show() else: self.mapView.mapView.hide() def onWindowEvent(self, window): self.pauseBar['frameSize'] = (0, window.size[0], 0, self.scaling.getVerticalDisplayRatio(25)) self.footer['frameSize'] = (0, window.size[0], 0, self.scaling.getVerticalDisplayRatio(25)) self.footer.setZ(-window.size[1]) self.pauseTextNodePath.setPos(base.win.getXSize()/2, 0, -5) self.coordsTextNodePath.setPos(base.win.getXSize() - 10, 0, 5) self.mapView.mapView.setPos( base.win.getXSize() - self.mapView.xDim - 1, -1, -base.win.getYSize() + self.mapView.vOffset ) def exitProgram(self): sys.exit() def cycleLayers(self): self.layer += 1 if self.layer >= 4: self.layer = 0 def prepare_font(self): pass
class DistributedInspectionSite(DistributedNode): def __init__(self, cr): DistributedNode.__init__(self, cr) ####################################################### # The below attributes are required at generation time. ####################################################### # The site id is the unique id associated with the data # for the inspection site. ####################################################### self.siteId = -1 self.zoneId = -1 ####################################################### self.siteData = None self.distanceTask = None self.interactCollSphereNP = None self.interactCollSphere = None self.identifierIcon = None self.floorMarker = None self.iconSequence = None self.fadeSequence = None self.text = None def setSiteId(self, _id): self.siteId = _id def getSiteId(self): return self.siteId def setZoneId(self, _id): self.zoneId = _id def getZoneId(self): return self.zoneId def announceGenerate(self): DistributedNode.announceGenerate(self) self.setName('InspectionSite-%d' % self.siteId) self.notify = directNotify.newCategory('DistributedInspectionSite[%d]' % self.siteId) self.siteData = InspectionSites.getSiteById(self.zoneId, self.siteId) if self.siteData: interactKey = base.inputStore.Interact.upper() self.text = OnscreenText( text = 'Press \'%s\' to %s' % (interactKey, self.siteData.type), pos = (0, -0.75), font = CIGlobals.getToonFont(), fg = (1, 1, 1, 1), shadow = (0, 0, 0, 1) ) self.text.hide() self.distanceTask = base.taskMgr.add(self.__calculateDistance, self.uniqueName('calculateAvDistance')) self.generateCollision() self.generateIconAndMarker() self.accept('enter' + self.interactCollSphereNP.getName(), self.onEnter) self.accept('exit' + self.interactCollSphereNP.getName(), self.onExit) self.reparentTo(render) def __calculateDistance(self, task): dist = float(base.localAvatar.getPos(self).length()) fullAlphaDist = 15.0 noAlphaDist = 105.0 alpha = 1.0 if 10 < dist < noAlphaDist: alpha = float(fullAlphaDist / dist) if alpha < 0.0: alpha = 0.0 elif dist >= noAlphaDist: alpha = 0.0 self.identifierIcon.setColorScale(1.0, 1.0, 1.0, alpha) self.floorMarker.setColorScale(1.0, 1.0, 1.0, alpha) return task.cont def generateCollision(self): self.interactCollSphere = CollisionSphere(0, 0, 0, 4) self.interactCollSphere.setTangible(0) ss = CollisionNode('inspectionSensor') ss.addSolid(self.interactCollSphere) self.interactCollSphereNP = self.attachNewNode(ss) self.interactCollSphereNP.setCollideMask(CIGlobals.EventBitmask) def generateIconAndMarker(self): icon = 'phase_5/maps/inspect_location.mat' self.identifierIcon = DirectFrame(parent = self, image = icon, frameColor = (0, 0, 0, 0)) self.identifierIcon.setTransparency(TransparencyAttrib.MAlpha) self.identifierIcon.setTwoSided(1) self.identifierIcon.setBillboardPointEye() self.identifierIcon.setZ(2.0) self.iconSequence = Sequence( LerpPosInterval(self.identifierIcon, 1.0, pos = (0, 0, 6.0), startPos = (0, 0, 3.0), blendType = 'easeInOut', name = ('inspSite%d-in' % self.siteId)), LerpPosInterval(self.identifierIcon, 1.0, pos = (0, 0, 3.0), startPos = (0, 0, 6.0), blendType = 'easeInOut', name = ('inspSite%d-out' % self.siteId)) ) self.iconSequence.loop() cm = CardMaker('marker') self.floorMarker = self.attachNewNode(cm.generate()) self.floorMarker.setBSPMaterial(icon, 1) self.floorMarker.setTransparency(TransparencyAttrib.MAlpha) self.floorMarker.setTwoSided(1) self.floorMarker.setPosHpr(-2.50, 2.53, -0.01, 0.0, 90.0, 0.0) self.floorMarker.setScale(5.0) def requestEnter(self): pass def canEnter(self): place = base.cr.playGame.getPlace() return place and place.fsm.getCurrentState().getName() == 'walk' def onEnter(self, _): self.text.show() self.acceptOnce(base.inputStore.Interact, self.requestEnter) def onExit(self, _): self.text.hide() self.ignore(base.inputStore.Interact) def disable(self): DistributedNode.disable(self) base.taskMgr.remove(self.distanceTask) if self.iconSequence: self.iconSequence.finish() self.iconSequence = None if self.fadeSequence: self.fadeSequence.finish() self.fadeSequence = None if self.text: self.text.hide() self.ignoreAll() def delete(self): if self.siteData: self.siteData = None if self.identifierIcon: self.identifierIcon.destroy() self.identifierIcon = None if self.distanceTask: self.distanceTask = None if self.interactCollSphereNP: self.interactCollSphereNP.removeNode() self.interactCollSphereNP = None self.interactCollSphere = None if self.floorMarker: self.floorMarker.removeNode() self.floorMarker = None if self.text: self.text.hide() self.text.destroy() self.text = None del self.siteData del self.identifierIcon del self.distanceTask del self.interactCollSphereNP del self.interactCollSphere del self.floorMarker del self.text DistributedNode.delete(self)