class Char(Avatar.Avatar): def __init__(self): try: self.Char_initialized return except: self.Char_initialized = 1 Avatar.Avatar.__init__(self) self.avatarType = CIGlobals.CChar self.avatarName = None self.currentAnim = None self.charType = '' self.eyes = loader.loadTexture('phase_3/maps/eyes1.jpg', 'phase_3/maps/eyes1_a.rgb') self.closedEyes = loader.loadTexture('phase_3/maps/mickey_eyes_closed.jpg', 'phase_3/maps/mickey_eyes_closed_a.rgb') self.animFSM = ClassicFSM('Char', [State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('walk', self.enterWalk, self.exitWalk), State('run', self.enterRun, self.exitRun)], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() Avatar.Avatar.initializeBodyCollisions(self, self.avatarType, 3.5, 1) return def getNametagJoints(self): return [] def stopAnimations(self): if hasattr(self, 'animFSM'): if not self.animFSM.isInternalStateInFlux(): self.animFSM.request('off') else: notify.warning('animFSM in flux, state=%s, not requesting off' % self.animFSM.getCurrentState().getName()) else: notify.warning('animFSM has been deleted') def disable(self): self.stopBlink() self.stopAnimations() Avatar.Avatar.disable(self) def delete(self): try: self.Char_deleted except: self.Char_deleted = 1 del self.animFSM Avatar.Avatar.delete(self) def setChat(self, chatString): if self.charType == CIGlobals.Mickey: self.dial = base.audio3d.loadSfx('phase_3/audio/dial/mickey.ogg') else: if self.charType == CIGlobals.Minnie: self.dial = base.audio3d.loadSfx('phase_3/audio/dial/minnie.ogg') else: if self.charType == CIGlobals.Goofy: self.dial = base.audio3d.loadSfx('phase_6/audio/dial/goofy.ogg') base.audio3d.attachSoundToObject(self.dial, self) self.dial.play() Avatar.Avatar.setChat(self, chatString) def setName(self, nameString, charName=None): self.avatarName = nameString Avatar.Avatar.setName(self, nameString, avatarType=self.avatarType, charName=charName) def setupNameTag(self, tempName=None): Avatar.Avatar.setupNameTag(self, tempName) self.nametag.setNametagColor(NametagGlobals.NametagColors[NametagGlobals.CCNPC]) self.nametag.setActive(0) self.nametag.updateAll() def generateChar(self, charType): self.charType = charType if charType == CIGlobals.Mickey or charType == CIGlobals.Minnie: self.loadModel('phase_3/models/char/' + charType.lower() + '-' + str(CIGlobals.ModelDetail(self.avatarType)) + '.bam') self.loadAnims({'neutral': 'phase_3/models/char/' + charType.lower() + '-wait.bam', 'walk': 'phase_3/models/char/' + charType.lower() + '-walk.bam', 'run': 'phase_3/models/char/' + charType.lower() + '-run.bam', 'left-start': 'phase_3.5/models/char/' + charType.lower() + '-left-start.bam', 'left': 'phase_3.5/models/char/' + charType.lower() + '-left.bam', 'right-start': 'phase_3.5/models/char/' + charType.lower() + '-right-start.bam', 'right': 'phase_3.5/models/char/' + charType.lower() + '-right.bam'}) if charType == CIGlobals.Mickey: self.mickeyEye = self.controlJoint(None, 'modelRoot', 'joint_pupilR') self.mickeyEye.setY(0.025) for bundle in self.getPartBundleDict().values(): bundle = bundle['modelRoot'].getBundle() earNull = bundle.findChild('sphere3') if not earNull: earNull = bundle.findChild('*sphere3') earNull.clearNetTransforms() for bundle in self.getPartBundleDict().values(): charNodepath = bundle['modelRoot'].partBundleNP bundle = bundle['modelRoot'].getBundle() earNull = bundle.findChild('sphere3') if not earNull: earNull = bundle.findChild('*sphere3') ears = charNodepath.find('**/sphere3') if ears.isEmpty(): ears = charNodepath.find('**/*sphere3') ears.clearEffect(CharacterJointEffect.getClassType()) earRoot = charNodepath.attachNewNode('earRoot') earPitch = earRoot.attachNewNode('earPitch') earPitch.setP(40.0) ears.reparentTo(earPitch) earNull.addNetTransform(earRoot.node()) ears.clearMat() ears.node().setPreserveTransform(ModelNode.PTNone) ears.setP(-40.0) ears.flattenMedium() ears.setBillboardAxis() self.startBlink() else: if charType == CIGlobals.Pluto: self.loadModel('phase_6/models/char/pluto-1000.bam') self.loadAnims({'walk': 'phase_6/models/char/pluto-walk.bam', 'neutral': 'phase_6/models/char/pluto-neutral.bam', 'sit': 'phase_6/models/char/pluto-sit.bam', 'stand': 'phase_6/models/char/pluto-stand.bam'}) else: if charType == CIGlobals.Goofy: self.loadModel('phase_6/models/char/TT_G-1500.bam') self.loadAnims({'neutral': 'phase_6/models/char/TT_GWait.bam', 'walk': 'phase_6/models/char/TT_GWalk.bam'}) else: raise StandardError('unknown char %s!' % charType) Avatar.Avatar.initShadow(self) return def initializeLocalCollisions(self, name, radius): Avatar.Avatar.initializeLocalCollisions(self, radius, 2, name) def startBlink(self): randomStart = random.uniform(0.5, 5) taskMgr.add(self.blinkTask, 'blinkTask') def stopBlink(self): taskMgr.remove('blinkTask') taskMgr.remove('doBlink') taskMgr.remove('openEyes') def blinkTask(self, task): taskMgr.add(self.doBlink, 'doBlink') delay = random.uniform(0.5, 7) task.delayTime = delay return task.again def doBlink(self, task): self.closeEyes() taskMgr.doMethodLater(0.2, self.openEyes, 'openEyes') return task.done def closeEyes(self): self.find('**/joint_pupilR').hide() self.find('**/joint_pupilL').hide() if self.charType == CIGlobals.Mickey: self.mickeyEye.setY(-0.025) self.mickeyEye.hide() self.find('**/eyes').setTexture(self.closedEyes, 1) def openEyes(self, task): self.find('**/joint_pupilR').show() self.find('**/joint_pupilL').show() if self.charType == CIGlobals.Mickey: self.mickeyEye.setY(0.025) self.mickeyEye.show() self.find('**/eyes').setTexture(self.eyes, 1) return task.done def enterOff(self): self.currentAnim = None return def exitOff(self): pass def enterNeutral(self): self.loop('neutral') def exitNeutral(self): self.stop() def enterWalk(self): self.loop('walk') def exitWalk(self): self.stop() def enterRun(self): self.loop('run') def exitRun(self): self.stop()
class Toon(Avatar.Avatar, ToonHead, ToonDNA.ToonDNA): notify = directNotify.newCategory("Toon") def __init__(self, cr, mat=0): self.cr = cr try: self.Toon_initialized return except: self.Toon_initialized = 1 Avatar.Avatar.__init__(self, mat) ToonDNA.ToonDNA.__init__(self) ToonHead.__init__(self, cr) self.collsSetup = False self.forwardSpeed = 0.0 self.rotateSpeed = 0.0 self.strafeSpeed = 0.0 self.avatarType = CIGlobals.Toon self.track = None self.standWalkRunReverse = None self.playingAnim = None self.playingRate = None self.tag = None self.money = 0 self.lookAtTrack = None self.portal1 = None self.portal2 = None self.spineA = NodePath() self.tokenIcon = None self.tokenIconIval = None self.fallSfx = base.audio3d.loadSfx( "phase_4/audio/sfx/MG_cannon_hit_dirt.ogg") base.audio3d.attachSoundToObject(self.fallSfx, self) self.eyes = loader.loadTexture("phase_3/maps/eyes.jpg", "phase_3/maps/eyes_a.rgb") self.myTaskId = random.uniform(0, 1231231232132131231232) self.closedEyes = loader.loadTexture("phase_3/maps/eyesClosed.jpg", "phase_3/maps/eyesClosed_a.rgb") self.soundChatBubble = loader.loadSfx( "phase_3/audio/sfx/GUI_balloon_popup.ogg") self.shadowCaster = None self.accessories = [] self.chatSoundDict = {} self.backpack = None self.forceRunSpeed = False self.animFSM = ClassicFSM('Toon', [ State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('swim', self.enterSwim, self.exitSwim), State('walk', self.enterWalk, self.exitWalk), State('run', self.enterRun, self.exitRun), State('bow', self.enterBow, self.exitBow), State('openBook', self.enterOpenBook, self.exitOpenBook), State('readBook', self.enterReadBook, self.exitReadBook), State('closeBook', self.enterCloseBook, self.exitCloseBook), State('teleportOut', self.enterTeleportOut, self.exitTeleportOut), State('teleportIn', self.enterTeleportIn, self.exitTeleportIn), State('died', self.enterDied, self.exitDied), State('fallFWD', self.enterFallFWD, self.exitFallFWD), State('fallBCK', self.enterFallBCK, self.exitFallBCK), State('jump', self.enterJump, self.exitJump), State('leap', self.enterLeap, self.exitLeap), State('laugh', self.enterLaugh, self.exitLaugh), State('happy', self.enterHappyJump, self.exitHappyJump), State('shrug', self.enterShrug, self.exitShrug), State('hdance', self.enterHDance, self.exitHDance), State('wave', self.enterWave, self.exitWave), State('scientistEmcee', self.enterScientistEmcee, self.exitScientistEmcee), State('scientistWork', self.enterScientistWork, self.exitScientistWork), State('scientistGame', self.enterScientistGame, self.exitScientistGame), State('scientistJealous', self.enterScientistJealous, self.exitScientistJealous), State('cringe', self.enterCringe, self.exitCringe), State('conked', self.enterConked, self.exitConked), State('win', self.enterWin, self.exitWin), State('walkBack', self.enterWalkBack, self.exitWalkBack), State('deadNeutral', self.enterDeadNeutral, self.exitDeadNeutral), State('deadWalk', self.enterDeadWalk, self.exitDeadWalk), State('squish', self.enterSquish, self.exitSquish), State('Happy', self.enterHappy, self.exitHappy), State('Sad', self.enterSad, self.exitSad), State('Swim', self.enterSwim, self.exitSwim) ], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() if not hasattr(self, 'uniqueName'): self.uniqueName = types.MethodType(uniqueName, self) self.activities = { ACT_DIE: Die(self), ACT_VICTORY_DANCE: VictoryDance(self), ACT_TOON_BOW: Bow(self), ACT_JUMP: Jump(self) } def setActivity(self, act, timestamp=0): Avatar.Avatar.setActivity(self, act, timestamp) if act == ACT_NONE: self.animFSM.request("Happy") def getUpperBodySubpart(self): if self.getAnimal() == "dog": return ["torso-top", "head"] return ["torso-top"] def getLowerBodySubpart(self): return ["legs", "torso-pants"] def getRightHandNode(self): return self.find("**/def_joint_right_hold") def getLeftHandNode(self): return self.find("**/def_joint_left_hold") def getHeadNode(self): return self.getPart('head') def getEyePoint(self): # middle of the head return Point3(0, 0, self.getHeight() - (self.getHeadHeight() / 2.0)) def setForceRunSpeed(self, flag): self.forceRunSpeed = flag def resetTorsoRotation(self): if not self.isEmpty(): spine = self.find("**/def_spineB") if not spine.isEmpty(): spine.setH(0) spine.detachNode() self.getPart("legs").setH(0) self.releaseJoint("torso", "def_spineB") def showAvId(self): pass def showName(self): pass def getNametagJoints(self): joints = [] for lodName in self.getLODNames(): bundle = self.getPartBundle('legs', lodName) joint = bundle.findChild('joint_nameTag') if joint: joints.append(joint) return joints def enterHappy(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = None self.standWalkRunReverse = (('neutral', 1.0), ('walk', 1.0), ('run', 1.0), ('walk', -1.0), ('strafe', 1.0), ('strafe', -1.0)) self.setSpeed(self.forwardSpeed, self.rotateSpeed) def exitHappy(self): self.standWalkRunReverse = None self.stop() def enterSad(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'sad' self.standWalkRunReverse = (('dneutral', 1.0), ('dwalk', 1.2), ('dwalk', 1.2), ('dwalk', -1.0)) self.setSpeed(0, 0) def exitSad(self): self.standWalkRunReverse = None self.stop() #if hasattr(self, 'doId'): # if hasattr(base, 'localAvatar'): # if base.localAvatar.doId == self.doId: # self.controlManager.enableAvatarJump() def setSpeed(self, forwardSpeed, rotateSpeed, strafeSpeed=0.0): if self.forceRunSpeed: forwardSpeed = CIGlobals.RunCutOff self.forwardSpeed = forwardSpeed self.rotateSpeed = rotateSpeed self.strafeSpeed = strafeSpeed action = None if self.standWalkRunReverse != None: rotateCutOff = CIGlobals.RotateCutOff if not self.isLocalAvatar( ) else CIGlobals.WalkCutOff if strafeSpeed < CIGlobals.StrafeCutOff and strafeSpeed > -CIGlobals.StrafeCutOff: self.resetTorsoRotation() if forwardSpeed >= CIGlobals.RunCutOff: action = CIGlobals.RUN_INDEX elif forwardSpeed > CIGlobals.WalkCutOff: action = CIGlobals.WALK_INDEX elif forwardSpeed < -CIGlobals.WalkCutOff: action = CIGlobals.REVERSE_INDEX elif abs(rotateSpeed) > rotateCutOff: action = CIGlobals.WALK_INDEX elif abs(strafeSpeed) > CIGlobals.RunCutOff: action = CIGlobals.RUN_INDEX elif abs(strafeSpeed) > CIGlobals.WalkCutOff: action = CIGlobals.WALK_INDEX else: action = CIGlobals.STAND_INDEX if abs(strafeSpeed) > CIGlobals.WalkCutOff: spine = self.find("**/def_spineB") if spine.isEmpty(): spine = self.controlJoint(None, "torso", "def_spineB") movementVec = Vec3(strafeSpeed, forwardSpeed, 0) movementVec.normalize() movementAngle = rad2Deg( math.atan2(movementVec[1], movementVec[0])) - 90.0 if action == CIGlobals.REVERSE_INDEX: movementAngle -= 180 spine.setH(-movementAngle) self.getPart('legs').setH(movementAngle) anim, rate = self.standWalkRunReverse[action] if anim != self.playingAnim or rate != self.playingRate or self.forcedTorsoAnim != self.lastForcedTorsoAnim: self.playingAnim = anim self.playingRate = rate self.lastForcedTorsoAnim = self.forcedTorsoAnim if self.forcedTorsoAnim is None: self.loop(anim) else: # Whatever happens to the legs should also happen on the pants. self.loop(anim, partName='torso-pants') self.loop(anim, partName='legs') self.setPlayRate(rate, anim) return action def enterSquish(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'squish' sound = loader.loadSfx('phase_9/audio/sfx/toon_decompress.ogg') lerpTime = 0.1 node = self.getGeomNode().getChild(0) origScale = node.getScale() if hasattr(self, 'uniqueName'): name = self.uniqueName('getSquished') else: name = 'getSquished' self.track = Sequence(LerpScaleInterval(node, lerpTime, VBase3(2, 2, 0.025), blendType='easeInOut'), Wait(1.0), Parallel( Sequence( Wait(0.4), LerpScaleInterval(node, lerpTime, VBase3(1.4, 1.4, 1.4), blendType='easeInOut'), LerpScaleInterval(node, lerpTime / 2.0, VBase3(0.8, 0.8, 0.8), blendType='easeInOut'), LerpScaleInterval( node, lerpTime / 3.0, origScale, blendType='easeInOut')), ActorInterval(self, 'happy', startTime=0.2), SoundInterval(sound)), name=name) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.squishDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete(self, name) self.track.start(ts) def squishDone(self, callback=None, extraArgs=[]): self.__doCallback(callback, extraArgs) def exitSquish(self): if self.track: self.ignore(self.track.getName()) DelayDelete.cleanupDelayDeletes(self.track) self.track.finish() self.track = None self.playingAnim = 'neutral' def enterDeadNeutral(self, ts=0, callback=None, extraArgs=[]): self.loop('dneutral') def exitDeadNeutral(self): self.stop() def enterDeadWalk(self, ts=0, callback=None, extraArgs=[]): self.loop('dwalk') def exitDeadWalk(self): self.stop() def setBackpack(self, pack): self.backpack = pack def getGhost(self): return 0 def updateChatSoundDict(self): self.chatSoundDict['exclaim'] = base.audio3d.loadSfx( self.getToonAnimalNoise('exclaim')) self.chatSoundDict['question'] = base.audio3d.loadSfx( self.getToonAnimalNoise('question')) self.chatSoundDict['short'] = base.audio3d.loadSfx( self.getToonAnimalNoise('short')) self.chatSoundDict['medium'] = base.audio3d.loadSfx( self.getToonAnimalNoise('med')) self.chatSoundDict['long'] = base.audio3d.loadSfx( self.getToonAnimalNoise('long')) self.chatSoundDict['howl'] = base.audio3d.loadSfx( self.getToonAnimalNoise('howl')) base.audio3d.attachSoundToObject(self.chatSoundDict['exclaim'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['question'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['short'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['medium'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['long'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['howl'], self.getPart('head')) def __actAsGone(self): if self.nametag3d: self.nametag3d.hide() if self.getShadow(): self.getShadow().hide() if self.tokenIcon: self.tokenIcon.hide() #self.stashBodyCollisions() def __restoreHide(self): if self.tokenIcon: self.tokenIcon.show() if self.getShadow(): self.getShadow().show() if self.nametag3d: self.nametag3d.show() if self.getGeomNode(): self.getGeomNode().setTransparency(False) self.getGeomNode().setAlphaScale(1.0) self.getGeomNode().show() #self.unstashBodyCollisions() def handleGhost(self, flag): alpha = 1.0 if not flag else 0.25 local = self == base.localAvatar if flag: if self.getAccessLevel() >= base.localAvatar.getAccessLevel(): # Other staff members at this access level or higher should # be able to see this avatar still. alpha = 0.25 #self.stashBodyCollisions() elif not local: self.getGeomNode().setTransparency(True) self.getGeomNode().setColorScale(1.0, 1.0, 1.0, 0.0) self.__actAsGone() else: self.__restoreHide() if local: self.getGeomNode().setTransparency(flag) self.getGeomNode().setColorScale(1.0, 1.0, 1.0, alpha) def stopAnimations(self): if hasattr(self, 'animFSM'): if not self.animFSM.isInternalStateInFlux(): self.animFSM.request('off') else: self.notify.warning( "animFSM in flux, state=%s, not requesting off" % self.animFSM.getCurrentState().getName()) else: self.notify.warning("animFSM has been deleted") if self.track != None: self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None return def disable(self): try: self.Toon_disabled except: self.Toon_disabled = 1 self.ignoreAll() self.backpack = None self.collsSetup = False self.stopAnimations() self.removeAdminToken() ToonHead.delete(self) self.deleteCurrentToon() self.chatSoundDict = {} Avatar.Avatar.disable(self) def delete(self): try: self.Toon_deleted except: self.Toon_deleted = 1 del self.animFSM self.forwardSpeed = None self.chatSoundDict = None self.rotateSpeed = None self.avatarType = None self.track = None self.standWalkRunReverse = None self.currentAnim = None self.toon_head = None self.forcedTorsoAnim = None self.lastForcedTorsoAnim = None self.toon_torso = None self.toon_legs = None self.gender = None self.headtype = None self.head = None self.legtype = None self.torsotype = None self.hr = None self.hg = None self.hb = None self.tr = None self.tg = None self.tb = None self.lr = None self.lg = None self.lb = None self.shir = None self.shig = None self.shib = None self.shor = None self.shog = None self.shob = None self.shirt = None self.sleeve = None self.short = None self.tag = None self.money = None self.lookAtTrack = None self.portal1 = None self.portal2 = None self.backpack = None self.fallSfx = None self.eyes = None self.myTaskId = None self.closedEyes = None self.soundChatBubble = None self.lastAction = None self.lastState = None self.playingAnim = None self.playingRate = None self.accessories = None Avatar.Avatar.delete(self) return def initCollisions(self): self.collNodePath.setCollideMask(BitMask32(0)) self.collNodePath.node().setFromCollideMask(CIGlobals.WallBitmask) pusher = CollisionHandlerPusher() pusher.setInPattern("%in") pusher.addCollider(self.collNodePath, self) base.cTrav.addCollider(self.collNodePath, pusher) def deleteCurrentToon(self): if self.shadowCaster: self.shadowCaster.clear() self.shadowCaster = None for accessory in self.accessories: accessory.removeNode() self.accessories = [] self.pupils = [] if 'head' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['head'] if 'torso' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['torso'] if 'legs' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['legs'] self.deleteShadow() self.removePart('head') self.removePart('torso') self.removePart('legs') self.clearPythonData() self.flush() def setAdminToken(self, tokenInstance): if tokenInstance: matPath = tokenInstance.getMaterialPath() self.tokenIcon = loader.loadModel( "phase_3/models/props/staffIcon.bam") self.tokenIcon.reparentTo(self) self.tokenIcon.setScale(0.75) self.tokenIcon.setShaderAuto() # Let's update the material. self.tokenIcon.setBSPMaterial(matPath, 1) # Let's position the icon above the nametag. x, y, z = self.nametag3d.getPos() self.tokenIcon.setPos(Vec3(x, y, z + self.tokenIcon.getSz())) r, g, b, _ = tokenInstance.getColor() # Let's add the glow. glow = loader.loadModel( 'phase_4/models/minigames/particleGlow.bam') glow.reparentTo(self.tokenIcon) glow.setScale(2.50) glow.setColorScale((r, g, b, 0.50), 1) glow.setBSPMaterial('phase_4/maps/particleGlow.mat', 1) glow.setDepthWrite(False, 1) glow.setShaderAuto() glow.setTwoSided(1) self.tokenIconIval = Sequence( LerpHprInterval(self.tokenIcon, duration=3.0, hpr=Vec3(360, 0, 0), startHpr=Vec3(0, 0, 0))) self.tokenIconIval.loop() else: self.removeAdminToken() def removeAdminToken(self): if self.tokenIcon != None and self.tokenIconIval != None: self.tokenIconIval.finish() self.tokenIcon.removeNode() self.tokenIconIval = None self.tokenIcon = None def playChatSfx(self, chatString): if not self.getGhost() or self.doId == base.localAvatar.doId: if "ooo" in chatString.lower(): sfx = self.chatSoundDict['howl'] elif "!" in chatString.lower(): sfx = self.chatSoundDict['exclaim'] elif "?" in chatString.lower(): sfx = self.chatSoundDict['question'] elif len(chatString) <= 9: sfx = self.chatSoundDict['short'] elif 10 <= len(chatString) <= 19: sfx = self.chatSoundDict['medium'] elif len(chatString) >= 20: sfx = self.chatSoundDict['long'] base.playSfx(sfx, node=self) def chatStompComplete(self, chatString): if not self.thoughtInProg and CIGlobals.getSettingsMgr().getSetting( "chs").getValue(): self.playChatSfx(chatString) def setName(self, nameString): Avatar.Avatar.setName(self, nameString) def setDNAStrand(self, dnaStrand, makeTag=1): ToonDNA.ToonDNA.setDNAStrand(self, dnaStrand) self.deleteCurrentToon() self.generateToon(makeTag) def generateMask(self): # No accessories yet. if self.shirt == self.maleTopDNA2maleTop['135'][ 0] or self.shirt == self.maleTopDNA2maleTop['136'][0]: # This toon is wearing the tsa suit, give them some sweet shades. name = 'tsaGlasses' glasses = loader.loadModel( AccessoryGlobals.AccessoryName2Model[name]) glassesNode = self.getPart('head').attachNewNode('glassesNode') glasses.reparentTo(glassesNode) data = AccessoryGlobals.MaskTransExtended[name].get(self.animal) if not data: data = AccessoryGlobals.MaskTrans.get(self.animal) posHprScale = AccessoryGlobals.MaskTrans[self.animal][ self.headLength] else: posHprScale = AccessoryGlobals.MaskTransExtended[name][ self.animal].get(self.headLength) if not posHprScale: posHprScale = AccessoryGlobals.MaskTrans[self.animal][ self.headLength] glasses.setPos(posHprScale[0]) glasses.setHpr(posHprScale[1]) glasses.setScale(posHprScale[2]) self.accessories.append(glassesNode) def generateToon(self, makeTag=1): self.generateLegs() self.generateTorso() self.generateHead() self.setToonColor() self.setClothes() self.setGloves() self.parentToonParts() self.rescaleToon() self.generateMask() # Make torso subparts so we can play a run animation on the pants but another animation on the spine and arms. if self.gender == 'boy': self.makeSubpart("torso-pants", [ "def_left_pant_bottom", "def_left_pant_top", "def_right_pant_bottom", "def_right_pant_top" ], parent="torso") elif self.gender == 'girl': if self.torso == 'dgs_skirt': self.makeSubpart("torso-pants", [ "def_left_skirt_backA", "def_left_skirt_frontA", "def_left_skirt_topA", "def_right_skirt_backA", "def_right_skirt_frontA", "def_right_skirt_topA" ], parent="torso") elif self.torso == 'dgl_skirt': self.makeSubpart("torso-pants", [ "def_left_skirt_bottomA", "def_left_skirt_topA", "def_right_hip" ], parent="torso") else: self.makeSubpart("torso-pants", [ "def_left_skirt_bottomA", "def_left_skirt_topA", "def_right_skirt_bottomA", "def_right_skirt_topA" ], parent="torso") self.makeSubpart("torso-top", ["def_spineB"], parent="torso") Avatar.Avatar.initShadow(self) self.updateChatSoundDict() self.setBlend(frameBlend=True) bodyMat = CIGlobals.getCharacterMaterial(shininess=5, specular=(0.5, 0.5, 0.5, 1)) self.setMaterial(bodyMat, 1) if not hasattr(base, 'localAvatar') or base.localAvatar != self: self.setupPhysics(1.0, self.getHeight()) # We can safely optimize the scene graph and combine nodes since we're done manipulating # the separate pieces. After this point, the separate pieces of the toon are no # longer manipulatable, such as arms, sleeves, shirt, etc. If this needs to be done, # the toon will have to be regenerated. # Don't do it in Make-A-Toon though, as we have to be constantly modifying the pieces. if not self.mat: self.optimize() if makeTag: self.setupNameTag() if self.cr.isShowingPlayerIds: self.showAvId() self.loop('neutral') def optimize(self): self.getPart('legs').flattenStrong() self.postFlatten() def attachTNT(self): self.pies.attachTNT() self.holdTNTAnim() def detachTNT(self): self.pies.detachTNT() self.animFSM.request(self.animFSM.getCurrentState().getName()) def holdTNTAnim(self): self.pose("toss", 22, partName="torso") def parentToonParts(self): self.attach('head', 'torso', 'def_head') self.attach('torso', 'legs', 'joint_hips') def unparentToonParts(self): self.getPart('head').reparentTo(self.getGeomNode()) self.getPart('torso').reparentTo(self.getGeomNode()) self.getPart('legs').reparentTo(self.getGeomNode()) def getHeadHeight(self): animal = self.getAnimal() headScale = ToonGlobals.HeadScales[animal][2] headHeight = ToonGlobals.HeadHeightDict[self.head] * headScale return headHeight def rescaleToon(self): if not self.getHead(): return animal = self.getAnimal() bodyScale = ToonGlobals.BodyScales[animal] headScale = ToonGlobals.HeadScales[animal][2] shoulderHeight = ToonGlobals.LegHeightDict[ self.getLegs()] * bodyScale + ToonGlobals.TorsoHeightDict[ self.getTorso()] * bodyScale height = shoulderHeight + ToonGlobals.HeadHeightDict[ self.getHead()] * headScale bodyScale = ToonGlobals.BodyScales[animal] self.setAvatarScale(bodyScale) self.getPart('head').setScale(headScale) self.setHeight(height) def setGloves(self): color = self.getGloveColor() gloves = self.find('**/hands') gloves.setColor(color) def setClothes(self): shirt, shirtcolor = self.getShirtStyle() short, shortcolor = self.getShortStyle() sleeve, sleevecolor = self.getSleeveStyle() torsot = self.findAllMatches('**/torso-top') torsob = self.findAllMatches('**/torso-bot') sleeves = self.findAllMatches('**/sleeves') torsot.setBSPMaterial(shirt, 1) torsob.setBSPMaterial(short, 1) sleeves.setBSPMaterial(sleeve, 1) torsot.setColor(shirtcolor) sleeves.setColor(sleevecolor) torsob.setColor(shortcolor) def generateLegs(self): ToonGlobals.generateBodyPart(self, 'legs', self.getLegs(), 3, 'shorts') self.find('**/boots_long').stash() self.find('**/boots_short').stash() self.find('**/shoes').stash() def generateTorso(self): ToonGlobals.generateBodyPart(self, 'torso', self.getTorso(), 3, '') def generateHead(self, pat=0): gender = self.getGender() head = self.getAnimal() headtype = self.getHead() ToonHead.generateHead(self, gender, head, headtype) def setToonColor(self): self.setHeadColor() self.setTorsoColor() self.setLegColor() def setLegColor(self): legcolor = self.getLegColor() self.findAllMatches('**/legs').setColor(legcolor) self.findAllMatches('**/feet').setColor(legcolor) def setTorsoColor(self): torsocolor = self.getTorsoColor() self.findAllMatches('**/arms').setColor(torsocolor) self.findAllMatches('**/neck').setColor(torsocolor) self.findAllMatches('**/hands').setColor(1, 1, 1, 1) def enterOff(self, ts=0, callback=None, extraArgs=[]): self.currentAnim = None return def exitOff(self): pass def enterWin(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'win' self.sfx = base.audio3d.loadSfx("phase_3.5/audio/sfx/ENC_Win.ogg") self.sfx.setLoop(True) base.audio3d.attachSoundToObject(self.sfx, self) base.playSfx(self.sfx, node=self, looping=1) self.loop("win") def exitWin(self): self.stop() self.sfx.stop() del self.sfx self.playingAnim = 'neutral' def enterShrug(self, ts=0, callback=None, extraArgs=[]): self.play("shrug") def exitShrug(self): self.exitGeneral() def enterHDance(self, ts=0, callback=None, extraArgs=[]): self.play("hdance") def exitHDance(self): self.exitGeneral() def enterScientistWork(self, ts=0, callback=None, extraArgs=[]): self.loop("scwork") def exitScientistWork(self): self.exitGeneral() def enterScientistEmcee(self, ts=0, callback=None, extraArgs=[]): self.loop("scemcee") def exitScientistEmcee(self): self.exitGeneral() def enterScientistGame(self, ts=0, callback=None, extraArgs=[]): self.loop("scgame") def exitScientistGame(self): self.exitGeneral() def enterScientistJealous(self, ts=0, callback=None, extraArgs=[]): self.loop("scjealous") def exitScientistJealous(self): self.exitGeneral() def enterWave(self, ts=0, callback=None, extraArgs=[]): self.play("wave") def exitWave(self): self.exitGeneral() def enterLaugh(self, ts=0, callback=None, extraArgs=[]): self.setPlayRate(5.0, "neutral") self.loop("neutral") def exitLaugh(self): self.setPlayRate(1.0, "neutral") self.stop() def enterNeutral(self, ts=0, callback=None, extraArgs=[]): if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop("neutral", partName="legs") return self.loop("neutral") self.playingAnim = 'neutral' def exitNeutral(self): self.exitGeneral() self.playingAnim = 'neutral' def exitGeneral(self): self.stop() def enterRun(self, ts=0, callback=None, extraArgs=[]): if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop('run', partName='legs') return self.loop("run") def exitRun(self): self.exitGeneral() def enterWalk(self, ts=0, callback=None, extraArgs=[]): if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop('walk', partName='legs') return self.loop('walk') def exitWalk(self): self.exitGeneral() def enterWalkBack(self, ts=0, callback=None, extraArgs=[]): self.setPlayRate(-1.0, "walk") self.enterWalk() def exitWalkBack(self): self.exitWalk() self.setPlayRate(1.0, "walk") def enterOpenBook(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'book' self.book1 = Actor("phase_3.5/models/props/book-mod.bam", {"chan": "phase_3.5/models/props/book-chan.bam"}) self.book1.reparentTo( self.getPart('torso').find('**/def_joint_right_hold')) self.track = ActorInterval(self, "book", startFrame=CIGlobals.OpenBookFromFrame, endFrame=CIGlobals.OpenBookToFrame, name=self.uniqueName('enterOpenBook')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__doCallback, [callback, extraArgs]) self.track.start(ts) self.book1.play("chan", fromFrame=CIGlobals.OpenBookFromFrame, toFrame=CIGlobals.OpenBookToFrame) def exitOpenBook(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None if self.book1: self.book1.cleanup() self.book1 = None self.playingAnim = 'neutral' def enterReadBook(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'book' self.book2 = Actor("phase_3.5/models/props/book-mod.bam", {"chan": "phase_3.5/models/props/book-chan.bam"}) self.book2.reparentTo( self.getPart('torso').find('**/def_joint_right_hold')) self.pingpong("book", fromFrame=CIGlobals.ReadBookFromFrame, toFrame=CIGlobals.ReadBookToFrame) self.book2.pingpong("chan", fromFrame=CIGlobals.ReadBookFromFrame, toFrame=CIGlobals.ReadBookToFrame) def exitReadBook(self): if self.book2: self.book2.cleanup() self.book2 = None self.playingAnim = 'neutral' def enterCloseBook(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'book' self.book3 = Actor("phase_3.5/models/props/book-mod.bam", {"chan": "phase_3.5/models/props/book-chan.bam"}) self.book3.reparentTo( self.getPart('torso').find('**/def_joint_right_hold')) self.track = ActorInterval(self, "book", startFrame=CIGlobals.CloseBookFromFrame, endFrame=CIGlobals.CloseBookToFrame, name=self.uniqueName('enterCloseBook')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__doCallback, [callback, extraArgs]) self.track.start(ts) self.book3.play("chan", fromFrame=CIGlobals.CloseBookFromFrame, toFrame=CIGlobals.CloseBookToFrame) self.lerpLookAt(self.getPart('head'), (0, 0, 0)) def exitCloseBook(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None if self.book3: self.book3.cleanup() self.book3 = None self.playingAnim = 'neutral' def enterTeleportOut(self, ts=0, callback=None, extraArgs=[]): self.notify.info( str(self.doId) + "-" + str(self.zoneId) + ": enterTeleportOut") self.playingAnim = 'tele' self.portal1 = Actor( "phase_3.5/models/props/portal-mod.bam", {"chan": "phase_3.5/models/props/portal-chan.bam"}) self.portal1.play("chan") self.portal1.reparentTo( self.getPart('legs').find('**/def_joint_right_hold')) self.play("tele") if hasattr(self, 'uniqueName'): name = self.uniqueName('enterTeleportOut') else: name = 'enterTeleportOut' self.track = Sequence(Wait(0.4), Func(self.teleportOutSfx), Wait(1.3), Func(self.throwPortal), Wait(1.1), Func(self.__actAsGone), Wait(1.5), name=name) self.track.delayDelete = DelayDelete.DelayDelete(self, name) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getName(), self.teleportOutDone, [callback, extraArgs]) self.track.start(ts) def doPortalBins(self, portal): portal.setBin('portal', 19) portal.setDepthWrite(0) portal.setDepthTest(0) def teleportOutDone(self, callback, requestStatus): self.notify.info( str(self.doId) + "-" + str(self.zoneId) + ": teleportOutDone") self.__doCallback(callback, requestStatus) self.exitTeleportOut() def teleportOutSfx(self): self.outSfx = base.audio3d.loadSfx( "phase_3.5/audio/sfx/AV_teleport.ogg") base.audio3d.attachSoundToObject(self.outSfx, self.portal1) base.playSfx(self.outSfx, node=self) def throwPortal(self): self.doPortalBins(self.portal1) self.portal1.reparentTo(self.getPart('legs').find('**/joint_nameTag')) self.portal1.setScale(CIGlobals.PortalScale) self.portal1.setY(6.5) self.portal1.setH(180) def exitTeleportOut(self): self.notify.info( str(self.doId) + "-" + str(self.zoneId) + ": exitTeleportOut") if self.track != None: self.ignore(self.track.getName()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None if self.portal1: self.portal1.cleanup() self.portal1 = None if hasattr(self, 'shadow') and self.shadow is not None: self.shadow.show() self.__restoreHide() self.playingAnim = 'neutral' def getTeleportInTrack(self, portal): self.doPortalBins(portal) holeTrack = Sequence() holeTrack.append(Func(portal.reparentTo, self)) pos = Point3(0, -2.4, 0) holeTrack.append(Func(portal.setPos, pos)) holeTrack.append( ActorInterval(portal, 'chan', startTime=3.4, endTime=3.1)) holeTrack.append(Wait(0.6)) holeTrack.append( ActorInterval(portal, 'chan', startTime=3.1, endTime=3.4)) def restorePortal(portal): portal.setPos(0, 0, 0) portal.detachNode() portal.clearBin() portal.clearDepthTest() portal.clearDepthWrite() holeTrack.append(Func(restorePortal, portal)) toonTrack = Sequence(Wait(0.3), Func(self.__restoreHide), ActorInterval(self, 'happy', startTime=0.45)) if hasattr(self, 'uniqueName'): trackName = self.uniqueName('teleportIn') else: trackName = 'teleportIn' return Parallel(toonTrack, holeTrack, name=trackName) def enterTeleportIn(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'happy' self.portal2 = Actor( "phase_3.5/models/props/portal-mod.bam", {"chan": "phase_3.5/models/props/portal-chan.bam"}) self.show() self.getGeomNode().hide() self.nametag3d.hide() self.track = self.getTeleportInTrack(self.portal2) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getName(), self.teleportInDone, [callback, extraArgs]) if hasattr(self, 'acquireDelayDelete'): self.track.delayDelete = DelayDelete.DelayDelete( self, self.track.getName()) self.track.start(ts) def teleportInDone(self, callback, extraArgs): self.exitTeleportIn() self.__doCallback(callback, extraArgs) def exitTeleportIn(self): if self.track != None: self.ignore(self.track.getName()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None if self.portal2: self.portal2.cleanup() self.portal2 = None if self.nametag3d: self.nametag3d.show() self.playingAnim = 'neutral' def enterFallFWD(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'fallf' self.play("fallf") Sequence(Wait(0.5), SoundInterval(self.fallSfx, node=self)).start() def exitFallFWD(self): self.exitGeneral() self.playingAnim = 'neutral' def enterFallBCK(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'fallb' self.play("fallb") Sequence(Wait(0.5), SoundInterval(self.fallSfx, node=self)).start() def exitFallBCK(self): self.playingAnim = 'neutral' self.exitGeneral() def enterHappyJump(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'happy' self.play("happy") def exitHappyJump(self): self.exitGeneral() self.playingAnim = 'neutral' def enterSwim(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'swim' self.loop("swim") self.resetTorsoRotation() toon = self.getGeomNode() toon.setP(-89.0) if self.shadow: self.shadow.hide() self.swimBobTrack = Sequence( LerpPosInterval(toon, duration=1, pos=(0, -3, 3), startPos=(0, -3, 4), blendType='easeInOut'), LerpPosInterval(toon, duration=1, pos=(0, -3, 4), startPos=(0, -3, 3), blendType='easeInOut')) self.swimBobTrack.loop() self.nametag3d.setZ(5.0) def exitSwim(self): self.swimBobTrack.finish() del self.swimBobTrack if self.shadow: self.shadow.show() self.exitGeneral() self.getGeomNode().setPosHpr(0, 0, 0, 0, 0, 0) nt = self.nametag3d nt.setX(0) nt.setY(0) nt.setZ(self.getHeight() + 0.5) self.playingAnim = 'neutral' def enterDied(self, ts=0, callback=None, extraArgs=[]): def shouldDisableGags(): if hasattr(self, 'disableGags'): self.disableGags() if hasattr(self, 'setEquippedAttack'): self.setEquippedAttack(-1) self.playingAnim = 'lose' self.isdying = True self.play("lose") self.track = Sequence(Func(self.clearForcedTorsoAnim), Func(shouldDisableGags), Wait(2.2), Func(self.dieSfx), Wait(2.8), self.getGeomNode().scaleInterval( 2, Point3(0.01), startScale=(self.getGeomNode().getScale())), Func(self.delToon), name=self.uniqueName('enterDied')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.diedDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete( self, 'enterTeleportOut') self.track.start(ts) def diedDone(self, callback, extraArgs): self.__doCallback(callback, extraArgs) self.exitDied() def __doCallback(self, callback, extraArgs): if callback: if extraArgs: callback(*extraArgs) else: callback() def dieSfx(self): self.Losesfx = base.audio3d.loadSfx("phase_5/audio/sfx/ENC_Lose.ogg") base.audio3d.attachSoundToObject(self.Losesfx, self) base.playSfx(self.Losesfx, node=self) def delToon(self): self.isdead = True def exitDied(self): if self.track != None: self.ignore(self.track.getDoneEvent()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None if hasattr(self, 'enableGags'): self.enableGags() self.rescaleToon() self.playingAnim = 'neutral' def enterBow(self, ts=0, callback=None, extraArgs=[]): self.play("bow") self.playingAnim = 'bow' def exitBow(self): self.exitGeneral() self.playingAnim = 'neutral' def enterJump(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'jump' self.loop("jump") def exitJump(self): self.exitGeneral() self.playingAnim = 'neutral' def enterLeap(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'leap' self.loop("leap") def exitLeap(self): self.exitGeneral() self.playingAnim = 'neutral' def enterCringe(self, ts=0, callback=None, extraArgs=[]): self.play("cringe") def exitCringe(self): self.exitGeneral() def enterConked(self, ts=0, callback=None, extraArgs=[]): self.play("conked") def exitConked(self): self.exitGeneral()
class Toon(Avatar.Avatar, ToonHead, ToonDNA.ToonDNA): def __init__(self, cr, mat = 0): self.cr = cr try: self.Toon_initialized return except: self.Toon_initialized = 1 Avatar.Avatar.__init__(self, mat) ToonDNA.ToonDNA.__init__(self) ToonHead.__init__(self, cr) self.forwardSpeed = 0.0 self.rotateSpeed = 0.0 self.avatarType = CIGlobals.Toon self.track = None self.standWalkRunReverse = None self.playingAnim = None self.tag = None self.money = 0 self.lookAtTrack = None self.portal1 = None self.portal2 = None self.gunAttached = False self.gun = None self.tokenIcon = None self.tokenIconIval = None self.backpack = None self.forcedTorsoAnim = None self.fallSfx = base.audio3d.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.mp3') base.audio3d.attachSoundToObject(self.fallSfx, self) self.eyes = loader.loadTexture('phase_3/maps/eyes.jpg', 'phase_3/maps/eyes_a.rgb') self.myTaskId = random.uniform(0, 1231231232132131231232L) self.closedEyes = loader.loadTexture('phase_3/maps/eyesClosed.jpg', 'phase_3/maps/eyesClosed_a.rgb') self.soundChatBubble = loader.loadSfx('phase_3/audio/sfx/GUI_balloon_popup.mp3') self.shadowCaster = None self.chatSoundDict = {} self.animFSM = ClassicFSM('Toon', [State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('swim', self.enterSwim, self.exitSwim), State('walk', self.enterWalk, self.exitWalk), State('run', self.enterRun, self.exitRun), State('openBook', self.enterOpenBook, self.exitOpenBook), State('readBook', self.enterReadBook, self.exitReadBook), State('closeBook', self.enterCloseBook, self.exitCloseBook), State('teleportOut', self.enterTeleportOut, self.exitTeleportOut), State('teleportIn', self.enterTeleportIn, self.exitTeleportIn), State('died', self.enterDied, self.exitDied), State('fallFWD', self.enterFallFWD, self.exitFallFWD), State('fallBCK', self.enterFallBCK, self.exitFallBCK), State('jump', self.enterJump, self.exitJump), State('leap', self.enterLeap, self.exitLeap), State('laugh', self.enterLaugh, self.exitLaugh), State('happy', self.enterHappyJump, self.exitHappyJump), State('shrug', self.enterShrug, self.exitShrug), State('hdance', self.enterHDance, self.exitHDance), State('wave', self.enterWave, self.exitWave), State('scientistEmcee', self.enterScientistEmcee, self.exitScientistEmcee), State('scientistWork', self.enterScientistWork, self.exitScientistWork), State('scientistGame', self.enterScientistGame, self.exitScientistGame), State('scientistJealous', self.enterScientistJealous, self.exitScientistJealous), State('cringe', self.enterCringe, self.exitCringe), State('conked', self.enterConked, self.exitConked), State('win', self.enterWin, self.exitWin), State('walkBack', self.enterWalkBack, self.exitWalkBack), State('deadNeutral', self.enterDeadNeutral, self.exitDeadNeutral), State('deadWalk', self.enterDeadWalk, self.exitDeadWalk), State('squish', self.enterSquish, self.exitSquish), State('Happy', self.enterHappy, self.exitHappy), State('Sad', self.enterSad, self.exitSad)], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() if not hasattr(base, 'localAvatar') or not base.localAvatar == self: Avatar.Avatar.initializeBodyCollisions(self, self.avatarType, 3, 1) return def enterHappy(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = None self.standWalkRunReverse = (('neutral', 1.0), ('walk', 1.0), ('run', 1.0), ('walk', -1.0)) self.setSpeed(self.forwardSpeed, self.rotateSpeed) return def exitHappy(self): self.standWalkRunReverse = None self.stop() return def enterSad(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'sad' self.standWalkRunReverse = (('dneutral', 1.0), ('dwalk', 1.2), ('dwalk', 1.2), ('dwalk', -1.0)) self.setSpeed(0, 0) def exitSad(self): self.standWalkRunReverse = None self.stop() return def setSpeed(self, forwardSpeed, rotateSpeed): self.forwardSpeed = forwardSpeed self.rotateSpeed = rotateSpeed action = None if self.standWalkRunReverse != None: if forwardSpeed >= CIGlobals.RunCutOff: action = CIGlobals.RUN_INDEX elif forwardSpeed > CIGlobals.WalkCutOff: action = CIGlobals.WALK_INDEX elif forwardSpeed < -CIGlobals.WalkCutOff: action = CIGlobals.REVERSE_INDEX elif rotateSpeed != 0.0: action = CIGlobals.WALK_INDEX else: action = CIGlobals.STAND_INDEX anim, rate = self.standWalkRunReverse[action] if anim != self.playingAnim: self.playingAnim = anim self.stop() self.loop(anim) self.setPlayRate(rate, anim) return action def enterSquish(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'squish' sound = loader.loadSfx('phase_9/audio/sfx/toon_decompress.mp3') lerpTime = 0.1 node = self.getGeomNode().getChild(0) origScale = node.getScale() if hasattr(self, 'uniqueName'): name = self.uniqueName('getSquished') else: name = 'getSquished' self.track = Sequence(LerpScaleInterval(node, lerpTime, VBase3(2, 2, 0.025), blendType='easeInOut'), Wait(1.0), Parallel(Sequence(Wait(0.4), LerpScaleInterval(node, lerpTime, VBase3(1.4, 1.4, 1.4), blendType='easeInOut'), LerpScaleInterval(node, lerpTime / 2.0, VBase3(0.8, 0.8, 0.8), blendType='easeInOut'), LerpScaleInterval(node, lerpTime / 3.0, origScale, blendType='easeInOut')), ActorInterval(self, 'happy', startTime=0.2), SoundInterval(sound)), name=name) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.squishDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete(self, name) self.track.start(ts) def squishDone(self, callback = None, extraArgs = []): self.__doCallback(callback, extraArgs) def exitSquish(self): if self.track: self.ignore(self.track.getName()) DelayDelete.cleanupDelayDeletes(self.track) self.track.finish() self.track = None self.playingAnim = 'neutral' return def enterDeadNeutral(self, ts = 0, callback = None, extraArgs = []): self.loop('dneutral') def exitDeadNeutral(self): self.stop() def enterDeadWalk(self, ts = 0, callback = None, extraArgs = []): self.loop('dwalk') def exitDeadWalk(self): self.stop() def setBackpack(self, pack): self.backpack = pack def getGhost(self): return 0 def updateChatSoundDict(self): self.chatSoundDict['exclaim'] = base.audio3d.loadSfx(self.getToonAnimalNoise('exclaim')) self.chatSoundDict['question'] = base.audio3d.loadSfx(self.getToonAnimalNoise('question')) self.chatSoundDict['short'] = base.audio3d.loadSfx(self.getToonAnimalNoise('short')) self.chatSoundDict['medium'] = base.audio3d.loadSfx(self.getToonAnimalNoise('med')) self.chatSoundDict['long'] = base.audio3d.loadSfx(self.getToonAnimalNoise('long')) self.chatSoundDict['howl'] = base.audio3d.loadSfx(self.getToonAnimalNoise('howl')) base.audio3d.attachSoundToObject(self.chatSoundDict['exclaim'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['question'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['short'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['medium'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['long'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['howl'], self.getPart('head')) def ghostOn(self): self.getGeomNode().hide() self.getNameTag().hide() self.getShadow().hide() if self.tokenIcon: self.tokenIcon.hide() self.stashBodyCollisions() def ghostOff(self): self.unstashBodyCollisions() if self.tokenIcon: self.tokenIcon.show() self.getShadow().show() self.getNameTag().show() self.getGeomNode().show() def attachGun(self, gunName): self.detachGun() if gunName == 'pistol': self.gun = loader.loadModel('phase_4/models/props/water-gun.bam') self.gun.reparentTo(self.find('**/def_joint_right_hold')) self.gun.setPos(Point3(0.28, 0.1, 0.08)) self.gun.setHpr(VBase3(85.6, -4.44, 94.43)) self.gunAttached = True elif gunName == 'shotgun': self.gun = loader.loadModel('phase_4/models/props/shotgun.egg') self.gun.setScale(0.75) self.gun.reparentTo(self.find('**/def_joint_right_hold')) self.gun.setPos(Point3(-0.5, -0.2, 0.19)) self.gun.setHpr(Vec3(350, 272.05, 0)) color = random.choice([VBase4(1, 0.25, 0.25, 1), VBase4(0.25, 1, 0.25, 1), VBase4(0.25, 0.25, 1, 1)]) self.gun.setColorScale(color) self.gunAttached = True def detachGun(self): if self.gun and self.gunAttached: self.gun.removeNode() self.gun = None self.gunAttached = False return def stopAnimations(self): if hasattr(self, 'animFSM'): if not self.animFSM.isInternalStateInFlux(): self.animFSM.request('off') else: notify.warning('animFSM in flux, state=%s, not requesting off' % self.animFSM.getCurrentState().getName()) else: notify.warning('animFSM has been deleted') if self.track != None: self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None return def disable(self): try: self.Toon_disabled except: self.Toon_disabled = 1 self.backpack = None self.stopAnimations() self.removeAdminToken() ToonHead.delete(self) self.deleteCurrentToon() self.chatSoundDict = {} return def delete(self): try: self.Toon_deleted except: self.Toon_deleted = 1 del self.animFSM self.forwardSpeed = None self.chatSoundDict = None self.rotateSpeed = None self.avatarType = None self.track = None self.standWalkRunReverse = None self.currentAnim = None self.toon_head = None self.forcedTorsoAnim = None self.toon_torso = None self.toon_legs = None self.gender = None self.headtype = None self.head = None self.legtype = None self.torsotype = None self.hr = None self.hg = None self.hb = None self.tr = None self.tg = None self.tb = None self.lr = None self.lg = None self.lb = None self.shir = None self.shig = None self.shib = None self.shor = None self.shog = None self.shob = None self.shirt = None self.sleeve = None self.short = None self.tag = None self.money = None self.lookAtTrack = None self.portal1 = None self.portal2 = None self.backpack = None self.fallSfx = None self.eyes = None self.myTaskId = None self.closedEyes = None self.soundChatBubble = None self.lastAction = None self.lastState = None self.playingAnim = None Avatar.Avatar.delete(self) return def initCollisions(self): self.collNodePath.setCollideMask(BitMask32(0)) self.collNodePath.node().setFromCollideMask(CIGlobals.WallBitmask) pusher = CollisionHandlerPusher() pusher.setInPattern('%in') pusher.addCollider(self.collNodePath, self) base.cTrav.addCollider(self.collNodePath, pusher) def deleteCurrentToon(self): if self.shadowCaster: self.shadowCaster.clear() self.shadowCaster = None try: self.stopLookAround() self.stopBlink() except: pass self.pupils = [] if 'head' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['head'] if 'torso' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['torso'] if 'legs' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['legs'] self.deleteShadow() self.removePart('head') self.removePart('torso') self.removePart('legs') self.detachGun() return def enterGagShop(self): DirectLabel(text='ENTERED GAG SHOP', relief=None, text_scale=0.08) return def setAdminToken(self, tokenId): tokens = {0: 500} if tokenId in tokens.keys(): icons = loader.loadModel('phase_3/models/props/gm_icons.bam') self.tokenIcon = icons.find('**/access_level_%s' % tokens[tokenId]) self.tokenIcon.reparentTo(self) x = self.getNameTag().getX() y = self.getNameTag().getY() z = self.getNameTag().getZ() self.tokenIcon.setPos(Vec3(x, y, z) + (0, 0, 0.5)) self.tokenIcon.setScale(0.4) self.tokenIconIval = Sequence(LerpHprInterval(self.tokenIcon, duration=3.0, hpr=Vec3(360, 0, 0), startHpr=Vec3(0, 0, 0))) self.tokenIconIval.loop() icons.removeNode() def removeAdminToken(self): if self.tokenIcon != None and self.tokenIconIval != None: self.tokenIconIval.finish() self.tokenIcon.removeNode() self.tokenIconIval = None self.tokenIcon = None return def setChat(self, chatString): if not self.isThought(chatString): if not self.getGhost() or self.doId == base.localAvatar.doId: if 'ooo' in chatString.lower(): sfx = self.chatSoundDict['howl'] elif '!' in chatString.lower(): sfx = self.chatSoundDict['exclaim'] elif '?' in chatString.lower(): sfx = self.chatSoundDict['question'] elif len(chatString) <= 9: sfx = self.chatSoundDict['short'] elif 10 <= len(chatString) <= 19: sfx = self.chatSoundDict['medium'] elif len(chatString) >= 20: sfx = self.chatSoundDict['long'] sfx.play() Avatar.Avatar.setChat(self, chatString) def setName(self, nameString): Avatar.Avatar.setName(self, nameString, avatarType=self.avatarType) def setDNAStrand(self, dnaStrand, makeTag = 1): ToonDNA.ToonDNA.setDNAStrand(self, dnaStrand) self.deleteCurrentToon() self.generateToon(makeTag) def generateToon(self, makeTag = 1): self.generateLegs() self.generateTorso() self.generateHead() self.setToonColor() self.setClothes() self.setGloves() self.parentToonParts() self.rescaleToon() if makeTag: self.setupNameTag() Avatar.Avatar.initShadow(self) if self.cr.isShowingPlayerIds: self.showAvId() self.updateChatSoundDict() def attachTNT(self): self.pies.attachTNT() self.holdTNTAnim() def detachTNT(self): self.pies.detachTNT() self.animFSM.request(self.animFSM.getCurrentState().getName()) def holdTNTAnim(self): self.pose('toss', 22, partName='torso') def parentToonParts(self): self.attach('head', 'torso', 'def_head') self.attach('torso', 'legs', 'joint_hips') def unparentToonParts(self): self.getPart('head').reparentTo(self.getGeomNode()) self.getPart('torso').reparentTo(self.getGeomNode()) self.getPart('legs').reparentTo(self.getGeomNode()) def rescaleToon(self): animal = self.getAnimal() bodyScale = CIGlobals.toonBodyScales[animal] headScale = CIGlobals.toonHeadScales[animal][2] shoulderHeight = CIGlobals.legHeightDict[self.legs] * bodyScale + CIGlobals.torsoHeightDict[self.torso] * bodyScale height = shoulderHeight + CIGlobals.headHeightDict[self.head] * headScale bodyScale = CIGlobals.toonBodyScales[animal] self.setAvatarScale(bodyScale) self.setHeight(height) def setGloves(self): color = self.getGloveColor() gloves = self.find('**/hands') gloves.setColor(color) def setClothes(self): shirt, shirtcolor = self.getShirtStyle() short, shortcolor = self.getShortStyle() sleeve, sleevecolor = self.getSleeveStyle() torsot = self.findAllMatches('**/torso-top') torsob = self.findAllMatches('**/torso-bot') sleeves = self.findAllMatches('**/sleeves') torsot.setTexture(loader.loadTexture(shirt), 1) torsob.setTexture(loader.loadTexture(short), 1) sleeves.setTexture(loader.loadTexture(sleeve), 1) torsot.setColor(shirtcolor) sleeves.setColor(sleevecolor) torsob.setColor(shortcolor) def generateLegs(self): legtype = self.getLegs() self.loadModel('phase_3/models/char/tt_a_chr_' + legtype + '_shorts_legs_' + str(CIGlobals.getModelDetail(self.avatarType)) + '.bam', 'legs') self.loadAnims({'neutral': 'phase_3/models/char/tt_a_chr_' + legtype + '_shorts_legs_neutral.bam', 'run': 'phase_3/models/char/tt_a_chr_' + legtype + '_shorts_legs_run.bam', 'walk': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_walk.bam', 'pie': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_pie-throw.bam', 'fallb': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_slip-backward.bam', 'fallf': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_slip-forward.bam', 'lose': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_lose.bam', 'win': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_victory-dance.bam', 'squirt': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_water-gun.bam', 'zend': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_jump-zend.bam', 'tele': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_teleport.bam', 'book': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_book.bam', 'leap': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_leap_zhang.bam', 'jump': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_jump-zhang.bam', 'happy': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_jump.bam', 'shrug': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_shrug.bam', 'hdance': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_happy-dance.bam', 'wave': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_wave.bam', 'scemcee': 'phase_4/models/char/tt_a_chr_dgm_shorts_legs_scientistEmcee.bam', 'scwork': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_scientistWork.bam', 'scgame': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_scientistGame.bam', 'scjealous': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_scientistJealous.bam', 'swim': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_swim.bam', 'toss': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_toss.bam', 'cringe': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_cringe.bam', 'conked': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_conked.bam', 'catchneutral': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_gameneutral.bam', 'catchrun': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_gamerun.bam', 'hold-bottle': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_hold-bottle.bam', 'push-button': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_press-button.bam', 'happy-dance': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_happy-dance.bam', 'juggle': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_juggle.bam', 'shout': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_shout.bam', 'dneutral': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_sad-neutral.bam', 'dwalk': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_losewalk.bam', 'smooch': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_smooch.bam', 'conked': 'phase_3.5/models/char/tt_a_chr_' + legtype + '_shorts_legs_conked.bam', 'sound': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_shout.bam', 'sprinkle-dust': 'phase_5/models/char/tt_a_chr_' + legtype + '_shorts_legs_sprinkle-dust.bam', 'start-sit': 'phase_4/models/char/tt_a_chr_' + legtype + '_shorts_legs_intoSit.bam', 'sit': 'phase_4/models/char/char/tt_a_chr_' + legtype + '_shorts_legs_sit.bam'}, 'legs') self.findAllMatches('**/boots_long').stash() self.findAllMatches('**/boots_short').stash() self.findAllMatches('**/shoes').stash() def generateTorso(self): torsotype = self.getTorso() self.loadModel('phase_3/models/char/tt_a_chr_' + torsotype + '_torso_' + str(CIGlobals.getModelDetail(self.avatarType)) + '.bam', 'torso') self.loadAnims({'neutral': 'phase_3/models/char/tt_a_chr_' + torsotype + '_torso_neutral.bam', 'run': 'phase_3/models/char/tt_a_chr_' + torsotype + '_torso_run.bam', 'walk': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_walk.bam', 'pie': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_pie-throw.bam', 'fallb': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_slip-backward.bam', 'fallf': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_slip-forward.bam', 'lose': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_lose.bam', 'win': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_victory-dance.bam', 'squirt': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_water-gun.bam', 'zend': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_jump-zend.bam', 'tele': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_teleport.bam', 'book': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_book.bam', 'leap': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_leap_zhang.bam', 'jump': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_jump-zhang.bam', 'happy': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_jump.bam', 'shrug': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_shrug.bam', 'hdance': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_happy-dance.bam', 'wave': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_wave.bam', 'scemcee': 'phase_4/models/char/tt_a_chr_dgm_shorts_torso_scientistEmcee.bam', 'scwork': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_scientistWork.bam', 'scgame': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_scientistGame.bam', 'scjealous': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_scientistJealous.bam', 'swim': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_swim.bam', 'toss': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_toss.bam', 'cringe': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_cringe.bam', 'conked': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_conked.bam', 'catchneutral': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_gameneutral.bam', 'catchrun': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_gamerun.bam', 'hold-bottle': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_hold-bottle.bam', 'push-button': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_press-button.bam', 'happy-dance': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_happy-dance.bam', 'juggle': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_juggle.bam', 'shout': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_shout.bam', 'dneutral': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_sad-neutral.bam', 'dwalk': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_losewalk.bam', 'smooch': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_smooch.bam', 'conked': 'phase_3.5/models/char/tt_a_chr_' + torsotype + '_torso_conked.bam', 'sound': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_shout.bam', 'sprinkle-dust': 'phase_5/models/char/tt_a_chr_' + torsotype + '_torso_sprinkle-dust.bam', 'start-sit': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_intoSit.bam', 'sit': 'phase_4/models/char/tt_a_chr_' + torsotype + '_torso_sit.bam'}, 'torso') def generateHead(self, pat = 0): gender = self.getGender() head = self.getAnimal() headtype = self.getHead() ToonHead.generateHead(self, gender, head, headtype) def setToonColor(self): self.setHeadColor() self.setTorsoColor() self.setLegColor() def setLegColor(self): legcolor = self.getLegColor() self.findAllMatches('**/legs').setColor(legcolor) self.findAllMatches('**/feet').setColor(legcolor) def setTorsoColor(self): torsocolor = self.getTorsoColor() self.findAllMatches('**/arms').setColor(torsocolor) self.findAllMatches('**/neck').setColor(torsocolor) self.findAllMatches('**/hands').setColor(1, 1, 1, 1) def setForcedTorsoAnim(self, string): self.forcedTorsoAnim = string self.loop(string, partName='torso') def clearForcedTorsoAnim(self): self.forcedTorsoAnim = None self.animFSM.request(self.animFSM.getCurrentState().getName()) return def enterOff(self, ts = 0, callback = None, extraArgs = []): self.currentAnim = None return def exitOff(self): pass def enterWin(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'win' self.sfx = base.audio3d.loadSfx('phase_3.5/audio/sfx/ENC_Win.mp3') self.sfx.setLoop(True) base.audio3d.attachSoundToObject(self.sfx, self) base.playSfx(self.sfx) self.loop('win') def exitWin(self): self.stop() self.sfx.stop() del self.sfx self.playingAnim = 'neutral' def enterShrug(self, ts = 0, callback = None, extraArgs = []): self.play('shrug') def exitShrug(self): self.exitGeneral() def enterHDance(self, ts = 0, callback = None, extraArgs = []): self.play('hdance') def exitHDance(self): self.exitGeneral() def enterScientistWork(self, ts = 0, callback = None, extraArgs = []): self.loop('scwork') def exitScientistWork(self): self.exitGeneral() def enterScientistEmcee(self, ts = 0, callback = None, extraArgs = []): self.loop('scemcee') def exitScientistEmcee(self): self.exitGeneral() def enterScientistGame(self, ts = 0, callback = None, extraArgs = []): self.loop('scgame') def exitScientistGame(self): self.exitGeneral() def enterScientistJealous(self, ts = 0, callback = None, extraArgs = []): self.loop('scjealous') def exitScientistJealous(self): self.exitGeneral() def enterWave(self, ts = 0, callback = None, extraArgs = []): self.play('wave') def exitWave(self): self.exitGeneral() def enterLaugh(self, ts = 0, callback = None, extraArgs = []): self.setPlayRate(5.0, 'neutral') self.loop('neutral') def exitLaugh(self): self.setPlayRate(1.0, 'neutral') self.stop() def enterNeutral(self, ts = 0, callback = None, extraArgs = []): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() != GagState.LOADED: self.loop('neutral', partName='legs') if self.animal == 'dog': self.loop('neutral', partName='head') return if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop('neutral', partName='legs') return else: self.loop('neutral') self.playingAnim = 'neutral' return def exitNeutral(self): self.exitGeneral() self.playingAnim = 'neutral' def exitGeneral(self): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() != GagState.LOADED: self.stop(partName='legs') else: self.stop() else: self.stop() else: self.stop() def enterRun(self, ts = 0, callback = None, extraArgs = []): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() != GagState.LOADED: self.loop('run', partName='legs') if self.animal == 'dog': self.loop('run', partName='head') return if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop('run', partName='legs') return else: self.loop('run') return def exitRun(self): self.exitGeneral() def enterWalk(self, ts = 0, callback = None, extraArgs = []): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() != GagState.LOADED: self.loop('walk', partName='legs') if self.animal == 'dog': self.loop('walk', partName='head') return if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop('walk', partName='legs') return else: self.loop('walk') return def exitWalk(self): self.exitGeneral() def enterWalkBack(self, ts = 0, callback = None, extraArgs = []): self.setPlayRate(-1.0, 'walk') self.enterWalk() def exitWalkBack(self): self.exitWalk() self.setPlayRate(1.0, 'walk') def enterOpenBook(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'book' self.book1 = Actor('phase_3.5/models/props/book-mod.bam', {'chan': 'phase_3.5/models/props/book-chan.bam'}) self.book1.reparentTo(self.getPart('torso').find('**/def_joint_right_hold')) self.track = ActorInterval(self, 'book', startFrame=CIGlobals.OpenBookFromFrame, endFrame=CIGlobals.OpenBookToFrame, name=self.uniqueName('enterOpenBook')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__doCallback, [callback, extraArgs]) self.track.start(ts) self.book1.play('chan', fromFrame=CIGlobals.OpenBookFromFrame, toFrame=CIGlobals.OpenBookToFrame) def exitOpenBook(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None if self.book1: self.book1.cleanup() self.book1 = None self.playingAnim = 'neutral' return def enterReadBook(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'book' self.book2 = Actor('phase_3.5/models/props/book-mod.bam', {'chan': 'phase_3.5/models/props/book-chan.bam'}) self.book2.reparentTo(self.getPart('torso').find('**/def_joint_right_hold')) self.pingpong('book', fromFrame=CIGlobals.ReadBookFromFrame, toFrame=CIGlobals.ReadBookToFrame) self.book2.pingpong('chan', fromFrame=CIGlobals.ReadBookFromFrame, toFrame=CIGlobals.ReadBookToFrame) def exitReadBook(self): if self.book2: self.book2.cleanup() self.book2 = None self.playingAnim = 'neutral' return def enterCloseBook(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'book' self.book3 = Actor('phase_3.5/models/props/book-mod.bam', {'chan': 'phase_3.5/models/props/book-chan.bam'}) self.book3.reparentTo(self.getPart('torso').find('**/def_joint_right_hold')) self.track = ActorInterval(self, 'book', startFrame=CIGlobals.CloseBookFromFrame, endFrame=CIGlobals.CloseBookToFrame, name=self.uniqueName('enterCloseBook')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__doCallback, [callback, extraArgs]) self.track.start(ts) self.book3.play('chan', fromFrame=CIGlobals.CloseBookFromFrame, toFrame=CIGlobals.CloseBookToFrame) def exitCloseBook(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None if self.book3: self.book3.cleanup() self.book3 = None self.playingAnim = 'neutral' return def enterTeleportOut(self, ts = 0, callback = None, extraArgs = []): self.notify.info(str(self.doId) + '-' + str(self.zoneId) + ': enterTeleportOut') self.playingAnim = 'tele' self.portal1 = Actor('phase_3.5/models/props/portal-mod.bam', {'chan': 'phase_3.5/models/props/portal-chan.bam'}) self.portal1.play('chan') self.portal1.reparentTo(self.getPart('legs').find('**/def_joint_right_hold')) self.play('tele') if hasattr(self, 'uniqueName'): name = self.uniqueName('enterTeleportOut') else: name = 'enterTeleportOut' self.track = Sequence(Wait(0.4), Func(self.teleportOutSfx), Wait(1.3), Func(self.throwPortal), Wait(3.4), name=name) self.track.delayDelete = DelayDelete.DelayDelete(self, name) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getName(), self.teleportOutDone, [callback, extraArgs]) self.track.start(ts) def doPortalBins(self, portal): portal.setBin('shadow', 0) portal.setDepthWrite(0) portal.setDepthTest(0) def teleportOutDone(self, callback, requestStatus): self.notify.info(str(self.doId) + '-' + str(self.zoneId) + ': teleportOutDone') self.__doCallback(callback, requestStatus) self.exitTeleportOut() def teleportOutSfx(self): self.outSfx = base.audio3d.loadSfx('phase_3.5/audio/sfx/AV_teleport.mp3') base.audio3d.attachSoundToObject(self.outSfx, self.portal1) self.outSfx.play() def throwPortal(self): self.doPortalBins(self.portal1) self.portal1.reparentTo(self.getPart('legs').find('**/joint_nameTag')) self.portal1.setScale(CIGlobals.PortalScale) self.portal1.setY(6.5) self.portal1.setH(180) def exitTeleportOut(self): self.notify.info(str(self.doId) + '-' + str(self.zoneId) + ': exitTeleportOut') if self.track != None: self.ignore(self.track.getName()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None if self.portal1: self.portal1.cleanup() self.portal1 = None self.playingAnim = 'neutral' return def getTeleportInTrack(self, portal): self.doPortalBins(portal) holeTrack = Sequence() holeTrack.append(Func(portal.reparentTo, self)) pos = Point3(0, -2.4, 0) holeTrack.append(Func(portal.setPos, pos)) holeTrack.append(ActorInterval(portal, 'chan', startTime=3.4, endTime=3.1)) holeTrack.append(Wait(0.6)) holeTrack.append(ActorInterval(portal, 'chan', startTime=3.1, endTime=3.4)) def restorePortal(portal): portal.setPos(0, 0, 0) portal.detachNode() portal.clearBin() portal.clearDepthTest() portal.clearDepthWrite() holeTrack.append(Func(restorePortal, portal)) toonTrack = Sequence(Wait(0.3), Func(self.getGeomNode().show), Func(self.getNameTag().show), ActorInterval(self, 'happy', startTime=0.45)) if hasattr(self, 'uniqueName'): trackName = self.uniqueName('teleportIn') else: trackName = 'teleportIn' return Parallel(toonTrack, holeTrack, name=trackName) def enterTeleportIn(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'happy' self.portal2 = Actor('phase_3.5/models/props/portal-mod.bam', {'chan': 'phase_3.5/models/props/portal-chan.bam'}) self.show() self.getGeomNode().hide() self.getNameTag().hide() self.track = self.getTeleportInTrack(self.portal2) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getName(), self.teleportInDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete(self, self.track.getName()) self.track.start(ts) def teleportInDone(self, callback, extraArgs): self.__doCallback(callback, extraArgs) self.exitTeleportIn() def exitTeleportIn(self): if self.track != None: self.ignore(self.track.getName()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None if self.portal2: self.portal2.cleanup() self.portal2 = None if self.getGeomNode(): self.getGeomNode().show() if self.getNameTag(): self.getNameTag().show() self.playingAnim = 'neutral' return def enterFallFWD(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'fallf' self.play('fallf') Sequence(Wait(0.5), Func(self.fallSfx.play)).start() def exitFallFWD(self): self.exitGeneral() self.playingAnim = 'neutral' def enterFallBCK(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'fallb' self.play('fallb') Sequence(Wait(0.5), Func(self.fallSfx.play)).start() def exitFallBCK(self): self.playingAnim = 'neutral' self.exitGeneral() def enterHappyJump(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'happy' self.play('happy') def exitHappyJump(self): self.exitGeneral() self.playingAnim = 'neutral' def enterSwim(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'swim' self.loop('swim') self.getGeomNode().setP(-89.0) self.getGeomNode().setZ(4.0) nt = self.getNameTag() nt.setX(0) nt.setY(-2) nt.setZ(5.0) def exitSwim(self): self.exitGeneral() self.getGeomNode().setP(0.0) self.getGeomNode().setZ(0.0) nt = self.getNameTag() nt.setX(0) nt.setY(0) nt.setZ(self.getHeight() + 0.3) self.playingAnim = 'neutral' def enterDied(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'lose' self.isdying = True self.play('lose') self.track = Sequence(Wait(2.2), Func(self.dieSfx), Wait(2.8), self.getGeomNode().scaleInterval(2, Point3(0.01), startScale=self.getGeomNode().getScale()), Func(self.delToon), name=self.uniqueName('enterDied')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.diedDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete(self, 'enterTeleportOut') self.track.start(ts) def diedDone(self, callback, extraArgs): self.__doCallback(callback, extraArgs) self.exitDied() def __doCallback(self, callback, extraArgs): if callback: if extraArgs: callback(*extraArgs) else: callback() def dieSfx(self): self.Losesfx = base.audio3d.loadSfx('phase_5/audio/sfx/ENC_Lose.mp3') base.audio3d.attachSoundToObject(self.Losesfx, self) self.Losesfx.play() def delToon(self): self.isdead = True def exitDied(self): if self.track != None: self.ignore(self.track.getDoneEvent()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None self.rescaleToon() self.playingAnim = 'neutral' return def enterJump(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'jump' self.loop('jump') def exitJump(self): self.exitGeneral() self.playingAnim = 'neutral' def enterLeap(self, ts = 0, callback = None, extraArgs = []): self.playingAnim = 'leap' self.loop('leap') def exitLeap(self): self.exitGeneral() self.playingAnim = 'neutral' def enterCringe(self, ts = 0, callback = None, extraArgs = []): self.play('cringe') def exitCringe(self): self.exitGeneral() def enterConked(self, ts = 0, callback = None, extraArgs = []): self.play('conked') def exitConked(self): self.exitGeneral()
class Toon(Avatar.Avatar, ToonHead, ToonDNA.ToonDNA): def __init__(self, cr, mat=0): self.cr = cr try: self.Toon_initialized return except: self.Toon_initialized = 1 Avatar.Avatar.__init__(self, mat) ToonDNA.ToonDNA.__init__(self) ToonHead.__init__(self, cr) self.forwardSpeed = 0.0 self.rotateSpeed = 0.0 self.strafeSpeed = 0.0 self.avatarType = CIGlobals.Toon self.track = None self.standWalkRunReverse = None self.playingAnim = None self.playingRate = None self.tag = None self.money = 0 self.lookAtTrack = None self.portal1 = None self.portal2 = None self.gunAttached = False self.gun = None self.tokenIcon = None self.tokenIconIval = None self.forcedTorsoAnim = None self.fallSfx = base.audio3d.loadSfx( "phase_4/audio/sfx/MG_cannon_hit_dirt.ogg") base.audio3d.attachSoundToObject(self.fallSfx, self) self.eyes = loader.loadTexture("phase_3/maps/eyes.jpg", "phase_3/maps/eyes_a.rgb") self.myTaskId = random.uniform(0, 1231231232132131231232) self.closedEyes = loader.loadTexture("phase_3/maps/eyesClosed.jpg", "phase_3/maps/eyesClosed_a.rgb") self.soundChatBubble = loader.loadSfx( "phase_3/audio/sfx/GUI_balloon_popup.ogg") self.shadowCaster = None self.chatSoundDict = {} self.backpack = None self.animFSM = ClassicFSM('Toon', [ State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('swim', self.enterSwim, self.exitSwim), State('walk', self.enterWalk, self.exitWalk), State('run', self.enterRun, self.exitRun), State('openBook', self.enterOpenBook, self.exitOpenBook), State('readBook', self.enterReadBook, self.exitReadBook), State('closeBook', self.enterCloseBook, self.exitCloseBook), State('teleportOut', self.enterTeleportOut, self.exitTeleportOut), State('teleportIn', self.enterTeleportIn, self.exitTeleportIn), State('died', self.enterDied, self.exitDied), State('fallFWD', self.enterFallFWD, self.exitFallFWD), State('fallBCK', self.enterFallBCK, self.exitFallBCK), State('jump', self.enterJump, self.exitJump), State('leap', self.enterLeap, self.exitLeap), State('laugh', self.enterLaugh, self.exitLaugh), State('happy', self.enterHappyJump, self.exitHappyJump), State('shrug', self.enterShrug, self.exitShrug), State('hdance', self.enterHDance, self.exitHDance), State('wave', self.enterWave, self.exitWave), State('scientistEmcee', self.enterScientistEmcee, self.exitScientistEmcee), State('scientistWork', self.enterScientistWork, self.exitScientistWork), State('scientistGame', self.enterScientistGame, self.exitScientistGame), State('scientistJealous', self.enterScientistJealous, self.exitScientistJealous), State('cringe', self.enterCringe, self.exitCringe), State('conked', self.enterConked, self.exitConked), State('win', self.enterWin, self.exitWin), State('walkBack', self.enterWalkBack, self.exitWalkBack), State('deadNeutral', self.enterDeadNeutral, self.exitDeadNeutral), State('deadWalk', self.enterDeadWalk, self.exitDeadWalk), State('squish', self.enterSquish, self.exitSquish), State('Happy', self.enterHappy, self.exitHappy), State('Sad', self.enterSad, self.exitSad) ], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() if not hasattr(base, 'localAvatar') or not base.localAvatar == self: Avatar.Avatar.initializeBodyCollisions(self, self.avatarType, 3, 1) def showAvId(self): pass def showName(self): pass def getNametagJoints(self): joints = [] for lodName in self.getLODNames(): bundle = self.getPartBundle('legs', lodName) joint = bundle.findChild('joint_nameTag') if joint: joints.append(joint) return joints def enterHappy(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = None self.standWalkRunReverse = (('neutral', 1.0), ('walk', 1.0), ('run', 1.0), ('walk', -1.0), ('strafe', 1.0), ('strafe', -1.0)) self.setSpeed(self.forwardSpeed, self.rotateSpeed) def exitHappy(self): self.standWalkRunReverse = None self.stop() def enterSad(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'sad' self.standWalkRunReverse = (('dneutral', 1.0), ('dwalk', 1.2), ('dwalk', 1.2), ('dwalk', -1.0)) self.setSpeed(0, 0) def exitSad(self): self.standWalkRunReverse = None self.stop() #if hasattr(self, 'doId'): # if hasattr(base, 'localAvatar'): # if base.localAvatar.doId == self.doId: # self.controlManager.enableAvatarJump() def setSpeed(self, forwardSpeed, rotateSpeed, strafeSpeed=0.0): self.forwardSpeed = forwardSpeed self.rotateSpeed = rotateSpeed self.strafeSpeed = strafeSpeed action = None if self.standWalkRunReverse != None: if (forwardSpeed >= CIGlobals.RunCutOff and strafeSpeed < CIGlobals.RunCutOff and strafeSpeed > -CIGlobals.RunCutOff): action = CIGlobals.RUN_INDEX elif strafeSpeed >= CIGlobals.RunCutOff or strafeSpeed <= -CIGlobals.RunCutOff: if strafeSpeed > 0: action = CIGlobals.STRAFE_RIGHT_INDEX elif strafeSpeed < 0: action = CIGlobals.STRAFE_LEFT_INDEX elif forwardSpeed > CIGlobals.WalkCutOff: action = CIGlobals.WALK_INDEX elif forwardSpeed < -CIGlobals.WalkCutOff: action = CIGlobals.REVERSE_INDEX elif rotateSpeed != 0.0: action = CIGlobals.WALK_INDEX else: action = CIGlobals.STAND_INDEX anim, rate = self.standWalkRunReverse[action] if anim != self.playingAnim or rate != self.playingRate: self.playingAnim = anim self.playingRate = rate doingGagAnim = False if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() in [ GagState.START, GagState.RELEASED ]: doingGagAnim = True self.loop(anim, partName="legs") if self.animal == "dog": self.loop(anim, partName="head") if not doingGagAnim: if self.forcedTorsoAnim == None: self.loop(anim) else: self.loop(self.forcedTorsoAnim, partName='head') self.loop(self.forcedTorsoAnim, partName='torso') self.loop(anim, partName='legs') self.setPlayRate(rate, anim) return action def enterSquish(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'squish' sound = loader.loadSfx('phase_9/audio/sfx/toon_decompress.ogg') lerpTime = 0.1 node = self.getGeomNode().getChild(0) origScale = node.getScale() if hasattr(self, 'uniqueName'): name = self.uniqueName('getSquished') else: name = 'getSquished' self.track = Sequence(LerpScaleInterval(node, lerpTime, VBase3(2, 2, 0.025), blendType='easeInOut'), Wait(1.0), Parallel( Sequence( Wait(0.4), LerpScaleInterval(node, lerpTime, VBase3(1.4, 1.4, 1.4), blendType='easeInOut'), LerpScaleInterval(node, lerpTime / 2.0, VBase3(0.8, 0.8, 0.8), blendType='easeInOut'), LerpScaleInterval( node, lerpTime / 3.0, origScale, blendType='easeInOut')), ActorInterval(self, 'happy', startTime=0.2), SoundInterval(sound)), name=name) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.squishDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete(self, name) self.track.start(ts) def squishDone(self, callback=None, extraArgs=[]): self.__doCallback(callback, extraArgs) def exitSquish(self): if self.track: self.ignore(self.track.getName()) DelayDelete.cleanupDelayDeletes(self.track) self.track.finish() self.track = None self.playingAnim = 'neutral' def enterDeadNeutral(self, ts=0, callback=None, extraArgs=[]): self.loop('dneutral') def exitDeadNeutral(self): self.stop() def enterDeadWalk(self, ts=0, callback=None, extraArgs=[]): self.loop('dwalk') def exitDeadWalk(self): self.stop() def setBackpack(self, pack): self.backpack = pack def getGhost(self): return 0 def updateChatSoundDict(self): self.chatSoundDict['exclaim'] = base.audio3d.loadSfx( self.getToonAnimalNoise('exclaim')) self.chatSoundDict['question'] = base.audio3d.loadSfx( self.getToonAnimalNoise('question')) self.chatSoundDict['short'] = base.audio3d.loadSfx( self.getToonAnimalNoise('short')) self.chatSoundDict['medium'] = base.audio3d.loadSfx( self.getToonAnimalNoise('med')) self.chatSoundDict['long'] = base.audio3d.loadSfx( self.getToonAnimalNoise('long')) self.chatSoundDict['howl'] = base.audio3d.loadSfx( self.getToonAnimalNoise('howl')) base.audio3d.attachSoundToObject(self.chatSoundDict['exclaim'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['question'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['short'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['medium'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['long'], self.getPart('head')) base.audio3d.attachSoundToObject(self.chatSoundDict['howl'], self.getPart('head')) def ghostOn(self): self.getGeomNode().hide() self.nametag3d.hide() self.getShadow().hide() if self.tokenIcon: self.tokenIcon.hide() self.stashBodyCollisions() def ghostOff(self): self.unstashBodyCollisions() if self.tokenIcon: self.tokenIcon.show() self.getShadow().show() self.nametag3d.show() self.getGeomNode().show() def attachGun(self, gunName): self.detachGun() if gunName == "pistol": self.gun = loader.loadModel("phase_4/models/props/water-gun.bam") self.gun.reparentTo(self.find('**/def_joint_right_hold')) self.gun.setPos(Point3(0.28, 0.1, 0.08)) self.gun.setHpr(VBase3(85.6, -4.44, 94.43)) self.gunAttached = True elif gunName == "shotgun": self.gun = loader.loadModel("phase_4/models/props/shotgun.egg") self.gun.setScale(0.75) self.gun.reparentTo(self.find('**/def_joint_right_hold')) self.gun.setPos(Point3(-0.5, -0.2, 0.19)) self.gun.setHpr(Vec3(350, 272.05, 0)) color = random.choice([ VBase4(1, 0.25, 0.25, 1), VBase4(0.25, 1, 0.25, 1), VBase4(0.25, 0.25, 1, 1) ]) self.gun.setColorScale(color) self.gunAttached = True elif gunName == "sniper": self.gun = loader.loadModel("phase_4/models/props/sniper.egg") self.gun.setScale(0.75) self.gun.reparentTo(self.find('**/def_joint_right_hold')) self.gun.setPos(Point3(-0.5, -0.2, 0.19)) self.gun.setHpr(Vec3(350, 272.05, 0)) color = random.choice([ VBase4(1, 0.25, 0.25, 1), VBase4(0.25, 1, 0.25, 1), VBase4(0.25, 0.25, 1, 1) ]) self.gun.setColorScale(color) self.gunAttached = True def detachGun(self): if self.gun and self.gunAttached: self.gun.removeNode() self.gun = None self.gunAttached = False def stopAnimations(self): if hasattr(self, 'animFSM'): if not self.animFSM.isInternalStateInFlux(): self.animFSM.request('off') else: notify.warning( "animFSM in flux, state=%s, not requesting off" % self.animFSM.getCurrentState().getName()) else: notify.warning("animFSM has been deleted") if self.track != None: self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None return def disable(self): try: self.Toon_disabled except: self.Toon_disabled = 1 self.backpack = None self.stopAnimations() self.removeAdminToken() ToonHead.delete(self) self.deleteCurrentToon() self.chatSoundDict = {} Avatar.Avatar.disable(self) def delete(self): try: self.Toon_deleted except: self.Toon_deleted = 1 del self.animFSM self.forwardSpeed = None self.chatSoundDict = None self.rotateSpeed = None self.avatarType = None self.track = None self.standWalkRunReverse = None self.currentAnim = None self.toon_head = None self.forcedTorsoAnim = None self.toon_torso = None self.toon_legs = None self.gender = None self.headtype = None self.head = None self.legtype = None self.torsotype = None self.hr = None self.hg = None self.hb = None self.tr = None self.tg = None self.tb = None self.lr = None self.lg = None self.lb = None self.shir = None self.shig = None self.shib = None self.shor = None self.shog = None self.shob = None self.shirt = None self.sleeve = None self.short = None self.tag = None self.money = None self.lookAtTrack = None self.portal1 = None self.portal2 = None self.backpack = None self.fallSfx = None self.eyes = None self.myTaskId = None self.closedEyes = None self.soundChatBubble = None self.lastAction = None self.lastState = None self.playingAnim = None self.playingRate = None Avatar.Avatar.delete(self) return def initCollisions(self): self.collNodePath.setCollideMask(BitMask32(0)) self.collNodePath.node().setFromCollideMask(CIGlobals.WallBitmask) pusher = CollisionHandlerPusher() pusher.setInPattern("%in") pusher.addCollider(self.collNodePath, self) base.cTrav.addCollider(self.collNodePath, pusher) def deleteCurrentToon(self): if self.shadowCaster: self.shadowCaster.clear() self.shadowCaster = None try: self.stopLookAround() self.stopBlink() except: pass self.pupils = [] if 'head' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['head'] if 'torso' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['torso'] if 'legs' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['legs'] self.deleteShadow() self.removePart('head') self.removePart('torso') self.removePart('legs') self.detachGun() def setAdminToken(self, tokenId): if tokenId in ToonGlobals.STAFF_TOKENS.keys(): icons = loader.loadModel("phase_3/models/props/gm_icons.bam") self.tokenIcon = icons.find('**/access_level_%s' % (ToonGlobals.STAFF_TOKENS[tokenId])) self.tokenIcon.reparentTo(self) x = self.nametag3d.getX() y = self.nametag3d.getY() z = self.nametag3d.getZ() self.tokenIcon.setPos(Vec3(x, y, z) + (0, 0, 0.5)) self.tokenIcon.setScale(0.4) self.tokenIconIval = Sequence( LerpHprInterval(self.tokenIcon, duration=3.0, hpr=Vec3(360, 0, 0), startHpr=Vec3(0, 0, 0))) self.tokenIconIval.loop() icons.removeNode() def removeAdminToken(self): if self.tokenIcon != None and self.tokenIconIval != None: self.tokenIconIval.finish() self.tokenIcon.removeNode() self.tokenIconIval = None self.tokenIcon = None def setChat(self, chatString): if not self.isThought(chatString): if not self.getGhost() or self.doId == base.localAvatar.doId: if "ooo" in chatString.lower(): sfx = self.chatSoundDict['howl'] elif "!" in chatString.lower(): sfx = self.chatSoundDict['exclaim'] elif "?" in chatString.lower(): sfx = self.chatSoundDict['question'] elif len(chatString) <= 9: sfx = self.chatSoundDict['short'] elif 10 <= len(chatString) <= 19: sfx = self.chatSoundDict['medium'] elif len(chatString) >= 20: sfx = self.chatSoundDict['long'] base.playSfx(sfx, node=self) Avatar.Avatar.setChat(self, chatString) def setName(self, nameString): Avatar.Avatar.setName(self, nameString, avatarType=self.avatarType) def setDNAStrand(self, dnaStrand, makeTag=1): ToonDNA.ToonDNA.setDNAStrand(self, dnaStrand) self.deleteCurrentToon() self.generateToon(makeTag) def generateToon(self, makeTag=1): self.generateLegs() self.generateTorso() self.generateHead() self.setToonColor() self.setClothes() self.setGloves() self.parentToonParts() self.rescaleToon() if makeTag: self.setupNameTag() Avatar.Avatar.initShadow(self) if self.cr.isShowingPlayerIds: self.showAvId() self.updateChatSoundDict() def attachTNT(self): self.pies.attachTNT() self.holdTNTAnim() def detachTNT(self): self.pies.detachTNT() self.animFSM.request(self.animFSM.getCurrentState().getName()) def holdTNTAnim(self): self.pose("toss", 22, partName="torso") def parentToonParts(self): self.attach('head', 'torso', 'def_head') self.attach('torso', 'legs', 'joint_hips') def unparentToonParts(self): self.getPart('head').reparentTo(self.getGeomNode()) self.getPart('torso').reparentTo(self.getGeomNode()) self.getPart('legs').reparentTo(self.getGeomNode()) def rescaleToon(self): animal = self.getAnimal() bodyScale = CIGlobals.toonBodyScales[animal] headScale = CIGlobals.toonHeadScales[animal][2] shoulderHeight = CIGlobals.legHeightDict[ self.legs] * bodyScale + CIGlobals.torsoHeightDict[ self.torso] * bodyScale height = shoulderHeight + CIGlobals.headHeightDict[ self.head] * headScale bodyScale = CIGlobals.toonBodyScales[animal] self.setAvatarScale(bodyScale) self.getPart('head').setScale(headScale) self.setHeight(height) def setGloves(self): color = self.getGloveColor() gloves = self.find('**/hands') gloves.setColor(color) def setClothes(self): shirt, shirtcolor = self.getShirtStyle() short, shortcolor = self.getShortStyle() sleeve, sleevecolor = self.getSleeveStyle() torsot = self.findAllMatches('**/torso-top') torsob = self.findAllMatches('**/torso-bot') sleeves = self.findAllMatches('**/sleeves') torsot.setTexture(loader.loadTexture(shirt), 1) torsob.setTexture(loader.loadTexture(short), 1) sleeves.setTexture(loader.loadTexture(sleeve), 1) torsot.setColor(shirtcolor) sleeves.setColor(sleevecolor) torsob.setColor(shortcolor) def generateLegs(self): ToonGlobals.generateBodyPart(self, 'legs', self.getLegs(), 3, 'shorts') self.find('**/boots_long').stash() self.find('**/boots_short').stash() self.find('**/shoes').stash() def generateTorso(self): ToonGlobals.generateBodyPart(self, 'torso', self.getTorso(), 3, '') def generateHead(self, pat=0): gender = self.getGender() head = self.getAnimal() headtype = self.getHead() ToonHead.generateHead(self, gender, head, headtype) def setToonColor(self): self.setHeadColor() self.setTorsoColor() self.setLegColor() def setLegColor(self): legcolor = self.getLegColor() self.findAllMatches('**/legs').setColor(legcolor) self.findAllMatches('**/feet').setColor(legcolor) def setTorsoColor(self): torsocolor = self.getTorsoColor() self.findAllMatches('**/arms').setColor(torsocolor) self.findAllMatches('**/neck').setColor(torsocolor) self.findAllMatches('**/hands').setColor(1, 1, 1, 1) def setForcedTorsoAnim(self, string): self.forcedTorsoAnim = string self.loop(string, partName="torso") def clearForcedTorsoAnim(self): self.forcedTorsoAnim = None self.animFSM.request(self.animFSM.getCurrentState().getName()) def enterOff(self, ts=0, callback=None, extraArgs=[]): self.currentAnim = None return def exitOff(self): pass def enterWin(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'win' self.sfx = base.audio3d.loadSfx("phase_3.5/audio/sfx/ENC_Win.ogg") self.sfx.setLoop(True) base.audio3d.attachSoundToObject(self.sfx, self) base.playSfx(self.sfx, node=self) self.loop("win") def exitWin(self): self.stop() self.sfx.stop() del self.sfx self.playingAnim = 'neutral' def enterShrug(self, ts=0, callback=None, extraArgs=[]): self.play("shrug") def exitShrug(self): self.exitGeneral() def enterHDance(self, ts=0, callback=None, extraArgs=[]): self.play("hdance") def exitHDance(self): self.exitGeneral() def enterScientistWork(self, ts=0, callback=None, extraArgs=[]): self.loop("scwork") def exitScientistWork(self): self.exitGeneral() def enterScientistEmcee(self, ts=0, callback=None, extraArgs=[]): self.loop("scemcee") def exitScientistEmcee(self): self.exitGeneral() def enterScientistGame(self, ts=0, callback=None, extraArgs=[]): self.loop("scgame") def exitScientistGame(self): self.exitGeneral() def enterScientistJealous(self, ts=0, callback=None, extraArgs=[]): self.loop("scjealous") def exitScientistJealous(self): self.exitGeneral() def enterWave(self, ts=0, callback=None, extraArgs=[]): self.play("wave") def exitWave(self): self.exitGeneral() def enterLaugh(self, ts=0, callback=None, extraArgs=[]): self.setPlayRate(5.0, "neutral") self.loop("neutral") def exitLaugh(self): self.setPlayRate(1.0, "neutral") self.stop() def enterNeutral(self, ts=0, callback=None, extraArgs=[]): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() in [ GagState.START, GagState.RELEASED ]: self.loop("neutral", partName="legs") if self.animal == "dog": self.loop("neutral", partName="head") return if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop("neutral", partName="legs") return self.loop("neutral") self.playingAnim = 'neutral' def exitNeutral(self): self.exitGeneral() self.playingAnim = 'neutral' def exitGeneral(self): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() in [ GagState.START, GagState.RELEASED ]: self.stop(partName='legs') else: self.stop() else: self.stop() else: self.stop() def enterRun(self, ts=0, callback=None, extraArgs=[]): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() in [ GagState.START, GagState.RELEASED ]: self.loop("run", partName="legs") if self.animal == "dog": self.loop("run", partName="head") return if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop("run", partName="legs") return self.loop("run") def exitRun(self): self.exitGeneral() def enterWalk(self, ts=0, callback=None, extraArgs=[]): if self.backpack: if self.backpack.getCurrentGag(): if self.backpack.getCurrentGag().getState() in [ GagState.START, GagState.RELEASED ]: self.loop("walk", partName="legs") if self.animal == "dog": self.loop("walk", partName="head") return if self.forcedTorsoAnim != None: self.loop(self.forcedTorsoAnim, partName='torso') self.loop("walk", partName="legs") return self.loop("walk") def exitWalk(self): self.exitGeneral() def enterWalkBack(self, ts=0, callback=None, extraArgs=[]): self.setPlayRate(-1.0, "walk") self.enterWalk() def exitWalkBack(self): self.exitWalk() self.setPlayRate(1.0, "walk") def enterOpenBook(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'book' self.book1 = Actor("phase_3.5/models/props/book-mod.bam", {"chan": "phase_3.5/models/props/book-chan.bam"}) self.book1.reparentTo( self.getPart('torso').find('**/def_joint_right_hold')) self.track = ActorInterval(self, "book", startFrame=CIGlobals.OpenBookFromFrame, endFrame=CIGlobals.OpenBookToFrame, name=self.uniqueName('enterOpenBook')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__doCallback, [callback, extraArgs]) self.track.start(ts) self.book1.play("chan", fromFrame=CIGlobals.OpenBookFromFrame, toFrame=CIGlobals.OpenBookToFrame) def exitOpenBook(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None if self.book1: self.book1.cleanup() self.book1 = None self.playingAnim = 'neutral' def enterReadBook(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'book' self.book2 = Actor("phase_3.5/models/props/book-mod.bam", {"chan": "phase_3.5/models/props/book-chan.bam"}) self.book2.reparentTo( self.getPart('torso').find('**/def_joint_right_hold')) self.pingpong("book", fromFrame=CIGlobals.ReadBookFromFrame, toFrame=CIGlobals.ReadBookToFrame) self.book2.pingpong("chan", fromFrame=CIGlobals.ReadBookFromFrame, toFrame=CIGlobals.ReadBookToFrame) def exitReadBook(self): if self.book2: self.book2.cleanup() self.book2 = None self.playingAnim = 'neutral' def enterCloseBook(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'book' self.book3 = Actor("phase_3.5/models/props/book-mod.bam", {"chan": "phase_3.5/models/props/book-chan.bam"}) self.book3.reparentTo( self.getPart('torso').find('**/def_joint_right_hold')) self.track = ActorInterval(self, "book", startFrame=CIGlobals.CloseBookFromFrame, endFrame=CIGlobals.CloseBookToFrame, name=self.uniqueName('enterCloseBook')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__doCallback, [callback, extraArgs]) self.track.start(ts) self.book3.play("chan", fromFrame=CIGlobals.CloseBookFromFrame, toFrame=CIGlobals.CloseBookToFrame) def exitCloseBook(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None if self.book3: self.book3.cleanup() self.book3 = None self.playingAnim = 'neutral' def enterTeleportOut(self, ts=0, callback=None, extraArgs=[]): self.notify.info( str(self.doId) + "-" + str(self.zoneId) + ": enterTeleportOut") self.playingAnim = 'tele' self.portal1 = Actor( "phase_3.5/models/props/portal-mod.bam", {"chan": "phase_3.5/models/props/portal-chan.bam"}) self.portal1.play("chan") self.portal1.reparentTo( self.getPart('legs').find('**/def_joint_right_hold')) self.play("tele") if hasattr(self, 'uniqueName'): name = self.uniqueName('enterTeleportOut') else: name = 'enterTeleportOut' self.track = Sequence(Wait(0.4), Func(self.teleportOutSfx), Wait(1.3), Func(self.throwPortal), Wait(3.4), name=name) self.track.delayDelete = DelayDelete.DelayDelete(self, name) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getName(), self.teleportOutDone, [callback, extraArgs]) self.track.start(ts) def doPortalBins(self, portal): portal.setBin('shadow', 0) portal.setDepthWrite(0) portal.setDepthTest(0) def teleportOutDone(self, callback, requestStatus): self.notify.info( str(self.doId) + "-" + str(self.zoneId) + ": teleportOutDone") self.__doCallback(callback, requestStatus) self.exitTeleportOut() def teleportOutSfx(self): self.outSfx = base.audio3d.loadSfx( "phase_3.5/audio/sfx/AV_teleport.ogg") base.audio3d.attachSoundToObject(self.outSfx, self.portal1) base.playSfx(self.outSfx, node=self) def throwPortal(self): self.doPortalBins(self.portal1) self.portal1.reparentTo(self.getPart('legs').find('**/joint_nameTag')) self.portal1.setScale(CIGlobals.PortalScale) self.portal1.setY(6.5) self.portal1.setH(180) def exitTeleportOut(self): self.notify.info( str(self.doId) + "-" + str(self.zoneId) + ": exitTeleportOut") if self.track != None: self.ignore(self.track.getName()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None if self.portal1: self.portal1.cleanup() self.portal1 = None self.playingAnim = 'neutral' def getTeleportInTrack(self, portal): self.doPortalBins(portal) holeTrack = Sequence() holeTrack.append(Func(portal.reparentTo, self)) pos = Point3(0, -2.4, 0) holeTrack.append(Func(portal.setPos, pos)) holeTrack.append( ActorInterval(portal, 'chan', startTime=3.4, endTime=3.1)) holeTrack.append(Wait(0.6)) holeTrack.append( ActorInterval(portal, 'chan', startTime=3.1, endTime=3.4)) def restorePortal(portal): portal.setPos(0, 0, 0) portal.detachNode() portal.clearBin() portal.clearDepthTest() portal.clearDepthWrite() holeTrack.append(Func(restorePortal, portal)) toonTrack = Sequence(Wait(0.3), Func(self.getGeomNode().show), Func(self.nametag3d.show), ActorInterval(self, 'happy', startTime=0.45)) if hasattr(self, 'uniqueName'): trackName = self.uniqueName('teleportIn') else: trackName = 'teleportIn' return Parallel(toonTrack, holeTrack, name=trackName) def enterTeleportIn(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'happy' self.portal2 = Actor( "phase_3.5/models/props/portal-mod.bam", {"chan": "phase_3.5/models/props/portal-chan.bam"}) self.show() self.getGeomNode().hide() self.nametag3d.hide() self.track = self.getTeleportInTrack(self.portal2) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getName(), self.teleportInDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete( self, self.track.getName()) self.track.start(ts) def teleportInDone(self, callback, extraArgs): self.__doCallback(callback, extraArgs) self.exitTeleportIn() def exitTeleportIn(self): if self.track != None: self.ignore(self.track.getName()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None if self.portal2: self.portal2.cleanup() self.portal2 = None if self.getGeomNode(): self.getGeomNode().show() if self.nametag3d: self.nametag3d.show() self.playingAnim = 'neutral' def enterFallFWD(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'fallf' self.play("fallf") Sequence(Wait(0.5), SoundInterval(self.fallSfx, node=self)).start() def exitFallFWD(self): self.exitGeneral() self.playingAnim = 'neutral' def enterFallBCK(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'fallb' self.play("fallb") Sequence(Wait(0.5), SoundInterval(self.fallSfx, node=self)).start() def exitFallBCK(self): self.playingAnim = 'neutral' self.exitGeneral() def enterHappyJump(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'happy' self.play("happy") def exitHappyJump(self): self.exitGeneral() self.playingAnim = 'neutral' def enterSwim(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'swim' self.loop("swim") self.getGeomNode().setP(-89.0) self.getGeomNode().setZ(4.0) nt = self.nametag3d nt.setX(0) nt.setY(-2) nt.setZ(5.0) def exitSwim(self): self.exitGeneral() self.getGeomNode().setP(0.0) self.getGeomNode().setZ(0.0) nt = self.nametag3d nt.setX(0) nt.setY(0) nt.setZ(self.getHeight() + 0.3) self.playingAnim = 'neutral' def enterDied(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'lose' self.isdying = True self.play("lose") self.track = Sequence(Wait(2.2), Func(self.dieSfx), Wait(2.8), self.getGeomNode().scaleInterval( 2, Point3(0.01), startScale=(self.getGeomNode().getScale())), Func(self.delToon), name=self.uniqueName('enterDied')) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.diedDone, [callback, extraArgs]) self.track.delayDelete = DelayDelete.DelayDelete( self, 'enterTeleportOut') self.track.start(ts) def diedDone(self, callback, extraArgs): self.__doCallback(callback, extraArgs) self.exitDied() def __doCallback(self, callback, extraArgs): if callback: if extraArgs: callback(*extraArgs) else: callback() def dieSfx(self): self.Losesfx = base.audio3d.loadSfx("phase_5/audio/sfx/ENC_Lose.ogg") base.audio3d.attachSoundToObject(self.Losesfx, self) base.playSfx(self.Losesfx, node=self) def delToon(self): self.isdead = True def exitDied(self): if self.track != None: self.ignore(self.track.getDoneEvent()) self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None self.rescaleToon() self.playingAnim = 'neutral' def enterJump(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'jump' self.loop("jump") def exitJump(self): self.exitGeneral() self.playingAnim = 'neutral' def enterLeap(self, ts=0, callback=None, extraArgs=[]): self.playingAnim = 'leap' self.loop("leap") def exitLeap(self): self.exitGeneral() self.playingAnim = 'neutral' def enterCringe(self, ts=0, callback=None, extraArgs=[]): self.play("cringe") def exitCringe(self): self.exitGeneral() def enterConked(self, ts=0, callback=None, extraArgs=[]): self.play("conked") def exitConked(self): self.exitGeneral()
class Toon(Avatar.Avatar, ToonHead): notify = DirectNotifyGlobal.directNotify.newCategory('Toon') def __init__(self): Avatar.Avatar.__init__(self) ToonHead.__init__(self) try: self.Toon_initialized return except: self.Toon_initialized = 1 self.avatarType = 'toon' self.soundChatBubble = base.loadSfx( 'phase_3/audio/sfx/GUI_balloon_popup.ogg') self.swimRunSfx = base.loadSfx( 'phase_4/audio/sfx/AV_footstep_runloop_water.ogg') self.swimRunLooping = False self.animFSM = ClassicFSM('Toon', [ State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral) ], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() def stopAnimations(self): if hasattr(self, 'animFSM'): if not self.animFSM.isInternalStateInFlux(): self.animFSM.request('off') else: self.notify.warning( 'animFSM in flux, state=%s, not requesting off' % self.animFSM.getCurrentState().getName()) else: self.notify.warning('animFSM has been deleted') if self.effectTrack != None: self.effectTrack.finish() self.effectTrack = None if self.emoteTrack != None: self.emoteTrack.finish() self.emoteTrack = None if self.stunTrack != None: self.stunTrack.finish() self.stunTrack = None if self.wake: self.wake.stop() self.wake.destroy() self.wake = None self.cleanupPieModel() return def delete(self): try: self.Toon_deleted except: self.Toon_deleted = 1 self.stopAnimations() self.rightHands = None self.rightHand = None self.leftHands = None self.leftHand = None self.headParts = None self.torsoParts = None self.hipsParts = None self.legsParts = None del self.animFSM for bookActor in self.__bookActors: bookActor.cleanup() del self.__bookActors for holeActor in self.__holeActors: holeActor.cleanup() del self.__holeActors self.soundTeleport = None self.motion.delete() self.motion = None self.removeHeadMeter() self.removeGMIcon() self.removePartyHat() Avatar.Avatar.delete(self) ToonHead.delete(self) def updateToonDNA(self, newDNA, fForce=0): self.newDNA = newDNA self.style.gender = newDNA.getGender() oldDNA = self.style if fForce or newDNA.head != oldDNA.head: self.swapToonHead(newDNA.head) if fForce or newDNA.torso != oldDNA.torso: self.swapToonTorso(newDNA.torso, genClothes=0) self.loop('neutral') if fForce or newDNA.legs != oldDNA.legs: self.swapToonLegs(newDNA.legs) self.swapToonColor(newDNA) self.__swapToonClothes(newDNA) def parentToonParts(self): if self.hasLOD(): for lodName in self.getLODNames(): if base.config.GetBool('want-new-anims', 1): if not self.getPart('torso', lodName).find('**/def_head').isEmpty(): self.attach('head', 'torso', 'def_head', lodName) else: self.attach('head', 'torso', 'joint_head', lodName) else: self.attach('head', 'torso', 'joint_head', lodName) self.attach('torso', 'legs', 'joint_hips', lodName) else: self.attach('head', 'torso', 'joint_head') self.attach('torso', 'legs', 'joint_hips') def unparentToonParts(self): if self.hasLOD(): for lodName in self.getLODNames(): self.getPart('head', lodName).reparentTo(self.getLOD(lodName)) self.getPart('torso', lodName).reparentTo(self.getLOD(lodName)) self.getPart('legs', lodName).reparentTo(self.getLOD(lodName)) else: self.getPart('head').reparentTo(self.getGeomNode()) self.getPart('torso').reparentTo(self.getGeomNode()) self.getPart('legs').reparentTo(self.getGeomNode()) def generateToon(self): self.setDNAString() self.generateToonLegs() self.generateToonHead() self.generateToonTorso() self.generateToonColor() self.parentToonParts() #self.rescaleToon() #self.resetHeight() self.setupToonNodes() def setupToonNodes(self): rightHand = NodePath('rightHand') self.rightHand = None self.rightHands = [] leftHand = NodePath('leftHand') self.leftHands = [] self.leftHand = None for lodName in self.getLODNames(): hand = self.getPart('torso', lodName).find('**/joint_Rhold') if base.config.GetBool('want-new-anims', 1): if not self.getPart( 'torso', lodName).find('**/def_joint_right_hold').isEmpty(): hand = self.getPart( 'torso', lodName).find('**/def_joint_right_hold') else: hand = self.getPart('torso', lodName).find('**/joint_Rhold') self.rightHands.append(hand) rightHand = rightHand.instanceTo(hand) if base.config.GetBool('want-new-anims', 1): if not self.getPart( 'torso', lodName).find('**/def_joint_left_hold').isEmpty(): hand = self.getPart('torso', lodName).find('**/def_joint_left_hold') else: hand = self.getPart('torso', lodName).find('**/joint_Lhold') self.leftHands.append(hand) leftHand = leftHand.instanceTo(hand) if self.rightHand == None: self.rightHand = rightHand if self.leftHand == None: self.leftHand = leftHand self.headParts = self.findAllMatches('**/__Actor_head') self.legsParts = self.findAllMatches('**/__Actor_legs') self.hipsParts = self.legsParts.findAllMatches('**/joint_hips') self.torsoParts = self.hipsParts.findAllMatches('**/__Actor_torso') return def initializeBodyCollisions(self, collIdStr): Avatar.Avatar.initializeBodyCollisions(self, collIdStr) if not self.ghostMode: self.collNode.setCollideMask(self.collNode.getIntoCollideMask() | BitmaskGlobals.PieBitmask) def generateToonLegs(self, copy=1): global Preloaded legStyle = self.newDNA.legs filePrefix = LegDict.get(legStyle) if filePrefix is None: self.notify.error('unknown leg style: %s' % legStyle) print(Preloaded[filePrefix + '-1000']) # self.loadModel(Preloaded[filePrefix+'-1000'], 'legs', '1000', True) self.loadModel(Preloaded[filePrefix + '-1000']) if not copy: self.showPart('legs', '1000') self.loadAnims(LegsAnimDict[legStyle], 'legs', '1000') self.findAllMatches('**/boots_short').stash() self.findAllMatches('**/boots_long').stash() self.findAllMatches('**/shoes').stash() return def swapToonLegs(self, legStyle, copy=1): self.unparentToonParts() self.removePart('legs', '1000') # Bugfix: Until upstream Panda3D includes this, we have to do it here. if 'legs' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['legs'] self.style.legs = legStyle self.generateToonLegs(copy) self.generateToonColor() self.parentToonParts() self.rescaleToon() self.resetHeight() del self.shadowJoint self.initializeDropShadow() self.initializeNametag3d() def generateToonTorso(self, copy=1, genClothes=1): global Preloaded torsoStyle = self.style.torso filePrefix = TorsoDict.get(torsoStyle) if filePrefix is None: self.notify.error('unknown torso style: %s' % torsoStyle) self.loadModel(Preloaded[filePrefix + '-1000'], 'torso', '1000', True) if not copy: self.showPart('torso', '1000') self.loadAnims(TorsoAnimDict[torsoStyle], 'torso', '1000') if genClothes == 1 and not len(torsoStyle) == 1: self.generateToonClothes() return def swapToonTorso(self, torsoStyle, copy=1, genClothes=1): self.unparentToonParts() self.removePart('torso', '1000') # Bugfix: Until upstream Panda3D includes this, we have to do it here. if 'torso' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['torso'] self.style.torso = torsoStyle self.generateToonTorso(copy, genClothes) self.generateToonColor() self.parentToonParts() self.rescaleToon() self.resetHeight() self.setupToonNodes() def setDNAString(self): self.newDNA = ToonDNA.ToonDNA() self.setDNA(self.newDNA) def setDNA(self, dna): self.style = dna #self.generateToon() def generateToonHead(self, copy=1): headHeight = ToonHead.generateToonHead(self, copy, self.style, '1000') if self.style.getAnimal() == 'dog': self.loadAnims(HeadAnimDict[self.style.head], 'head', '1000') def swapToonHead(self, headStyle=-1, copy=1): self.stopLookAroundNow() self.eyelids.request('open') self.unparentToonParts() self.removePart('head', '1000') # Bugfix: Until upstream Panda3D includes this, we have to do it here. if 'head' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['head'] if headStyle > -1: self.style.head = headStyle self.generateToonHead(copy) self.generateToonColor() self.parentToonParts() self.rescaleToon() self.resetHeight() self.eyelids.request('open') self.startLookAround() def generateToonColor(self): ToonHead.generateToonColor(self, self.style) armColor = self.style.getArmColor() gloveColor = self.style.getGloveColor() legColor = self.style.getLegColor() for lodName in self.getLODNames(): torso = self.getPart('torso', lodName) if len(self.style.torso) == 1: parts = torso.findAllMatches('**/torso*') parts.setColor(*armColor) for pieceName in ('arms', 'neck'): piece = torso.find('**/' + pieceName) piece.setColor(*armColor) hands = torso.find('**/hands') hands.setColor(*gloveColor) legs = self.getPart('legs', lodName) for pieceName in ('legs', 'feet'): piece = legs.find('**/%s;+s' % pieceName) piece.setColor(*legColor) if self.cheesyEffect == ToontownGlobals.CEGreenToon: self.reapplyCheesyEffect() def swapToonColor(self, dna): self.setStyle(dna) self.generateToonColor() def __swapToonClothes(self, dna): self.setStyle(dna) self.generateToonClothes(fromNet=1) def generateToonClothes(self, fromNet=0): swappedTorso = 0 if self.hasLOD(): if self.style.getGender() == 'f' and fromNet == 0: try: bottomPair = ToonDNA.GirlBottoms[self.style.botTex] except: bottomPair = ToonDNA.GirlBottoms[0] if len(self.style.torso) < 2: self.sendLogSuspiciousEvent( 'nakedToonDNA %s was requested' % self.style.torso) return 0 elif self.style.torso[1] == 's' and bottomPair[ 1] == ToonDNA.SKIRT: self.swapToonTorso(self.style.torso[0] + 'd', genClothes=0) swappedTorso = 1 elif self.style.torso[1] == 'd' and bottomPair[ 1] == ToonDNA.SHORTS: self.swapToonTorso(self.style.torso[0] + 's', genClothes=0) swappedTorso = 1 try: texName = ToonDNA.Shirts[self.style.topTex] except: texName = ToonDNA.Shirts[0] shirtTex = loader.loadTexture(texName, okMissing=True) if shirtTex is None: self.sendLogSuspiciousEvent('failed to load texture %s' % texName) shirtTex = loader.loadTexture(ToonDNA.Shirts[0]) shirtTex.setMinfilter(Texture.FTLinearMipmapLinear) shirtTex.setMagfilter(Texture.FTLinear) try: shirtColor = ToonDNA.ClothesColors[self.style.topTexColor] except: shirtColor = ToonDNA.ClothesColors[0] try: texName = ToonDNA.Sleeves[self.style.sleeveTex] except: texName = ToonDNA.Sleeves[0] sleeveTex = loader.loadTexture(texName, okMissing=True) if sleeveTex is None: self.sendLogSuspiciousEvent('failed to load texture %s' % texName) sleeveTex = loader.loadTexture(ToonDNA.Sleeves[0]) sleeveTex.setMinfilter(Texture.FTLinearMipmapLinear) sleeveTex.setMagfilter(Texture.FTLinear) try: sleeveColor = ToonDNA.ClothesColors[self.style.sleeveTexColor] except: sleeveColor = ToonDNA.ClothesColors[0] if self.style.getGender() == 'm': try: texName = ToonDNA.BoyShorts[self.style.botTex] except: texName = ToonDNA.BoyShorts[0] else: try: texName = ToonDNA.GirlBottoms[self.style.botTex][0] except: texName = ToonDNA.GirlBottoms[0][0] bottomTex = loader.loadTexture(texName, okMissing=True) if bottomTex is None: self.sendLogSuspiciousEvent('failed to load texture %s' % texName) if self.style.getGender() == 'm': bottomTex = loader.loadTexture(ToonDNA.BoyShorts[0]) else: bottomTex = loader.loadTexture(ToonDNA.GirlBottoms[0][0]) bottomTex.setMinfilter(Texture.FTLinearMipmapLinear) bottomTex.setMagfilter(Texture.FTLinear) try: bottomColor = ToonDNA.ClothesColors[self.style.botTexColor] except: bottomColor = ToonDNA.ClothesColors[0] darkBottomColor = bottomColor * 0.5 darkBottomColor.setW(1.0) for lodName in self.getLODNames(): thisPart = self.getPart('torso', lodName) top = thisPart.find('**/torso-top') top.setTexture(shirtTex, 1) top.setColor(shirtColor) sleeves = thisPart.find('**/sleeves') sleeves.setTexture(sleeveTex, 1) sleeves.setColor(sleeveColor) bottoms = thisPart.findAllMatches('**/torso-bot') for bottomNum in xrange(0, bottoms.getNumPaths()): bottom = bottoms.getPath(bottomNum) bottom.setTexture(bottomTex, 1) bottom.setColor(bottomColor) caps = thisPart.findAllMatches('**/torso-bot-cap') caps.setColor(darkBottomColor) return swappedTorso def getDialogueArray(self): animalType = self.style.getType() if animalType == 'dog': dialogueArray = DogDialogueArray elif animalType == 'cat': dialogueArray = CatDialogueArray elif animalType == 'horse': dialogueArray = HorseDialogueArray elif animalType == 'mouse': dialogueArray = MouseDialogueArray elif animalType == 'rabbit': dialogueArray = RabbitDialogueArray elif animalType == 'duck': dialogueArray = DuckDialogueArray elif animalType == 'monkey': dialogueArray = MonkeyDialogueArray elif animalType == 'bear': dialogueArray = BearDialogueArray elif animalType == 'pig': dialogueArray = PigDialogueArray else: dialogueArray = None return dialogueArray def findSomethingToLookAt(self): if self.randGen.random() < 0.1 or not hasattr(self, 'cr'): x = self.randGen.choice((-0.8, -0.5, 0, 0.5, 0.8)) y = self.randGen.choice((-0.5, 0, 0.5, 0.8)) self.lerpLookAt(Point3(x, 1.5, y), blink=1) return nodePathList = [] for id, obj in self.cr.doId2do.items(): if hasattr(obj, 'getStareAtNodeAndOffset') and obj != self: node, offset = obj.getStareAtNodeAndOffset() if node.getY(self) > 0.0: nodePathList.append((node, offset)) if nodePathList: nodePathList.sort(lambda x, y: cmp(x[0].getDistance(self), y[0]. getDistance(self))) if len(nodePathList) >= 2: if self.randGen.random() < 0.9: chosenNodePath = nodePathList[0] else: chosenNodePath = nodePathList[1] else: chosenNodePath = nodePathList[0] self.lerpLookAt(chosenNodePath[0].getPos(self), blink=1) else: ToonHead.findSomethingToLookAt(self) def setupPickTrigger(self): Avatar.Avatar.setupPickTrigger(self) torso = self.getPart('torso', '1000') if torso == None: return 0 self.pickTriggerNp.reparentTo(torso) size = self.style.getTorsoSize() if size == 'short': self.pickTriggerNp.setPosHprScale(0, 0, 0.5, 0, 0, 0, 1.5, 1.5, 2) elif size == 'medium': self.pickTriggerNp.setPosHprScale(0, 0, 0.5, 0, 0, 0, 1, 1, 2) else: self.pickTriggerNp.setPosHprScale(0, 0, 1, 0, 0, 0, 1, 1, 2) return 1 def enterNeutral(self, animMultiplier=1, ts=0, callback=None, extraArgs=[]): anim = 'neutral' self.pose(anim, int(self.getNumFrames(anim) * self.randGen.random())) self.loop(anim, restart=0) self.setPlayRate(animMultiplier, anim) self.playingAnim = anim self.setActiveShadow(1) def exitNeutral(self): self.stop() def enterOff(self, animMultiplier=1, ts=0, callback=None): self.playingAnim = None return def exitOff(self): pass def __returnToLastAnim(self, task): if self.playingAnim: self.loop(self.playingAnim) elif self.hp > 0: self.loop('neutral') else: self.loop('sad-neutral') return Task.done def getPieces(self, *pieces): results = [] for lodName in self.getLODNames(): for partName, pieceNames in pieces: part = self.getPart(partName, lodName) if part: if type(pieceNames) == types.StringType: pieceNames = (pieceNames, ) for pieceName in pieceNames: npc = part.findAllMatches('**/%s;+s' % pieceName) for i in xrange(npc.getNumPaths()): results.append(npc[i]) return results def __doHeadScale(self, scale, lerpTime): if scale == None: scale = ToontownGlobals.toonHeadScales[self.style.getAnimal()] track = Parallel() for hi in xrange(self.headParts.getNumPaths()): head = self.headParts[hi] track.append( LerpScaleInterval(head, lerpTime, scale, blendType='easeInOut')) return track def __doLegsScale(self, scale, lerpTime): if scale == None: scale = 1 invScale = 1 else: invScale = 1.0 / scale track = Parallel() for li in xrange(self.legsParts.getNumPaths()): legs = self.legsParts[li] torso = self.torsoParts[li] track.append( LerpScaleInterval(legs, lerpTime, scale, blendType='easeInOut')) track.append( LerpScaleInterval(torso, lerpTime, invScale, blendType='easeInOut')) return track def __doToonScale(self, scale, lerpTime): if scale == None: scale = 1 node = self.getGeomNode().getChild(0) track = Sequence( Parallel( LerpHprInterval(node, lerpTime, Vec3(0.0, 0.0, 0.0), blendType='easeInOut'), LerpScaleInterval(node, lerpTime, scale, blendType='easeInOut')), Func(self.resetHeight)) return track def doToonColorScale(self, scale, lerpTime, keepDefault=0): if keepDefault: self.defaultColorScale = scale if scale == None: scale = VBase4(1, 1, 1, 1) node = self.getGeomNode() caps = self.getPieces(('torso', 'torso-bot-cap')) track = Sequence() track.append(Func(node.setTransparency, 1)) if scale[3] != 1: for cap in caps: track.append(HideInterval(cap)) track.append( LerpColorScaleInterval(node, lerpTime, scale, blendType='easeInOut')) if scale[3] == 1: track.append(Func(node.clearTransparency)) for cap in caps: track.append(ShowInterval(cap)) elif scale[3] == 0: track.append(Func(node.clearTransparency)) return track def __colorToonSkin(self, color, lerpTime): track = Sequence() colorTrack = Parallel() torsoPieces = self.getPieces(('torso', ('arms', 'neck'))) legPieces = self.getPieces(('legs', ('legs', 'feet'))) headPieces = self.getPieces(('head', '*head*')) if color == None: armColor = self.style.getArmColor() legColor = self.style.getLegColor() headColor = self.style.getHeadColor() else: armColor = color legColor = color headColor = color for piece in torsoPieces: colorTrack.append(Func(piece.setColor, *armColor)) for piece in legPieces: colorTrack.append(Func(piece.setColor, *legColor)) for piece in headPieces: if 'hatNode' not in str(piece) and 'glassesNode' not in str(piece): colorTrack.append(Func(piece.setColor, *headColor)) track.append(colorTrack) return track def __colorToonEars(self, color, colorScale, lerpTime): track = Sequence() earPieces = self.getPieces(('head', '*ear*')) if len(earPieces) == 0: return track colorTrack = Parallel() if earPieces[0].hasColor(): if color == None: headColor = self.style.getHeadColor() else: headColor = color for piece in earPieces: colorTrack.append(Func(piece.setColor, *headColor)) else: if colorScale == None: colorScale = VBase4(1, 1, 1, 1) for piece in earPieces: colorTrack.append(Func(piece.setColorScale, *colorScale)) track.append(colorTrack) return track def __colorScaleToonMuzzle(self, scale, lerpTime): track = Sequence() colorTrack = Parallel() muzzlePieces = self.getPieces(('head', '*muzzle*')) if scale == None: scale = VBase4(1, 1, 1, 1) for piece in muzzlePieces: colorTrack.append(Func(piece.setColorScale, scale)) track.append(colorTrack) return track def __colorToonGloves(self, color, lerpTime): track = Sequence() colorTrack = Parallel() glovePieces = self.getPieces(('torso', '*hands*')) if color == None: for piece in glovePieces: colorTrack.append(Func(piece.clearColor)) else: for piece in glovePieces: colorTrack.append(Func(piece.setColor, color)) track.append(colorTrack) return track def restoreDefaultColorScale(self): node = self.getGeomNode() if node: if self.defaultColorScale: node.setColorScale(self.defaultColorScale) if self.defaultColorScale[3] != 1: node.setTransparency(1) else: node.clearTransparency() else: node.clearColorScale() node.clearTransparency() def __doToonColor(self, color, lerpTime): node = self.getGeomNode() if color == None: return Func(node.clearColor) else: return Func(node.setColor, color, 1) return def __doPartsColorScale(self, scale, lerpTime): if scale == None: scale = VBase4(1, 1, 1, 1) node = self.getGeomNode() pieces = self.getPieces(('torso', ('arms', 'neck')), ('legs', ('legs', 'feet')), ('head', '+GeomNode')) track = Sequence() track.append(Func(node.setTransparency, 1)) for piece in pieces: if piece.getName( )[:7] == 'muzzle-' and piece.getName()[-8:] != '-neutral': continue track.append(ShowInterval(piece)) p1 = Parallel() for piece in pieces: if piece.getName( )[:7] == 'muzzle-' and piece.getName()[-8:] != '-neutral': continue p1.append( LerpColorScaleInterval(piece, lerpTime, scale, blendType='easeInOut')) track.append(p1) if scale[3] == 1: track.append(Func(node.clearTransparency)) elif scale[3] == 0: track.append(Func(node.clearTransparency)) for piece in pieces: if piece.getName( )[:7] == 'muzzle-' and piece.getName()[-8:] != '-neutral': continue track.append(HideInterval(piece)) self.generateHat() self.generateGlasses() return track def putOnSuit(self, suitType, setDisplayName=True, rental=False): if self.isDisguised: self.takeOffSuit() from toontown.suit import Suit deptIndex = suitType suit = Suit.Suit() dna = SuitDNA.SuitDNA() if rental == True: if SuitDNA.suitDepts[deptIndex] == 's': suitType = 'cc' elif SuitDNA.suitDepts[deptIndex] == 'm': suitType = 'sc' elif SuitDNA.suitDepts[deptIndex] == 'l': suitType = 'bf' elif SuitDNA.suitDepts[deptIndex] == 'c': suitType = 'f' else: self.notify.warning( 'Suspicious: Incorrect rental suit department requested') suitType = 'cc' dna.newSuit(suitType) suit.setStyle(dna) suit.isDisguised = 1 suit.generateSuit() suit.initializeDropShadow() suit.setPos(self.getPos()) suit.setHpr(self.getHpr()) for part in suit.getHeadParts(): part.hide() suitHeadNull = suit.find('**/joint_head') toonHead = self.getPart('head', '1000') Emote.globalEmote.disableAll(self) toonGeom = self.getGeomNode() toonGeom.hide() worldScale = toonHead.getScale(render) self.headOrigScale = toonHead.getScale() headPosNode = hidden.attachNewNode('headPos') toonHead.reparentTo(headPosNode) toonHead.setPos(0, 0, 0.2) headPosNode.reparentTo(suitHeadNull) headPosNode.setScale(render, worldScale) suitGeom = suit.getGeomNode() suitGeom.reparentTo(self) if rental == True: suit.makeRentalSuit(SuitDNA.suitDepts[deptIndex]) self.suit = suit self.suitGeom = suitGeom self.setHeight(suit.getHeight()) self.nametag3d.setPos(0, 0, self.height + 1.3) self.suit.loop('neutral') self.isDisguised = 1 self.setFont(ToontownGlobals.getSuitFont()) self.nametag.setSpeechFont(ToontownGlobals.getSuitFont()) if setDisplayName: if hasattr(base, 'idTags') and base.idTags: name = self.getAvIdName() else: name = self.getName() suitDept = SuitDNA.suitDepts.index(SuitDNA.getSuitDept(suitType)) suitName = SuitBattleGlobals.SuitAttributes[suitType]['name'] self.nametag.setDisplayName( TTLocalizer.SuitBaseNameWithLevel % { 'name': name, 'dept': suitName, 'level': self.cogLevels[suitDept] + 1 }) self.nametag.setWordwrap(9.0) def takeOffSuit(self): if not self.isDisguised: return suitType = self.suit.style.name toonHeadNull = self.find('**/1000/**/def_head') if not toonHeadNull: toonHeadNull = self.find('**/1000/**/joint_head') toonHead = self.getPart('head', '1000') toonHead.reparentTo(toonHeadNull) toonHead.setScale(self.headOrigScale) toonHead.setPos(0, 0, 0) headPosNode = self.suitGeom.find('**/headPos') headPosNode.removeNode() self.suitGeom.reparentTo(self.suit) self.resetHeight() self.nametag3d.setPos(0, 0, self.height + 0.5) toonGeom = self.getGeomNode() toonGeom.show() Emote.globalEmote.releaseAll(self) self.isDisguised = 0 self.setFont(ToontownGlobals.getToonFont()) self.nametag.setSpeechFont(ToontownGlobals.getToonFont()) self.nametag.setWordwrap(None) if hasattr(base, 'idTags') and base.idTags: name = self.getAvIdName() else: name = self.getName() self.setDisplayName(name) self.suit.delete() del self.suit del self.suitGeom def makeWaiter(self): if not self.isDisguised: return self.suit.makeWaiter(self.suitGeom)
class Char(Avatar.Avatar): def __init__(self): try: self.Char_initialized return except: self.Char_initialized = 1 Avatar.Avatar.__init__(self) self.avatarType = CIGlobals.CChar self.avatarName = None self.currentAnim = None self.charType = '' self.eyes = loader.loadTexture('phase_3/maps/eyes1.jpg', 'phase_3/maps/eyes1_a.rgb') self.closedEyes = loader.loadTexture('phase_3/maps/mickey_eyes_closed.jpg', 'phase_3/maps/mickey_eyes_closed_a.rgb') self.animFSM = ClassicFSM('Char', [State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('walk', self.enterWalk, self.exitWalk), State('run', self.enterRun, self.exitRun)], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() Avatar.Avatar.initializeBodyCollisions(self, self.avatarType, 3.5, 1) return def stopAnimations(self): if hasattr(self, 'animFSM'): if not self.animFSM.isInternalStateInFlux(): self.animFSM.request('off') else: notify.warning('animFSM in flux, state=%s, not requesting off' % self.animFSM.getCurrentState().getName()) else: notify.warning('animFSM has been deleted') def disable(self): self.stopBlink() self.stopAnimations() Avatar.Avatar.disable(self) def delete(self): try: self.Char_deleted except: self.Char_deleted = 1 del self.animFSM Avatar.Avatar.delete(self) def setChat(self, chatString): if self.charType == CIGlobals.Mickey: self.dial = base.audio3d.loadSfx('phase_3/audio/dial/mickey.wav') elif self.charType == CIGlobals.Minnie: self.dial = base.audio3d.loadSfx('phase_3/audio/dial/minnie.wav') elif self.charType == CIGlobals.Goofy: self.dial = base.audio3d.loadSfx('phase_6/audio/dial/goofy.wav') base.audio3d.attachSoundToObject(self.dial, self) self.dial.play() Avatar.Avatar.setChat(self, chatString) def setName(self, nameString, charName = None): self.avatarName = nameString Avatar.Avatar.setName(self, nameString, avatarType=self.avatarType, charName=charName) def generateChar(self, charType): self.charType = charType if charType == CIGlobals.Mickey or charType == CIGlobals.Minnie: self.loadModel('phase_3/models/char/' + charType.lower() + '-' + str(CIGlobals.ModelDetail(self.avatarType)) + '.bam') self.loadAnims({'neutral': 'phase_3/models/char/' + charType.lower() + '-wait.bam', 'walk': 'phase_3/models/char/' + charType.lower() + '-walk.bam', 'run': 'phase_3/models/char/' + charType.lower() + '-run.bam', 'left-start': 'phase_3.5/models/char/' + charType.lower() + '-left-start.bam', 'left': 'phase_3.5/models/char/' + charType.lower() + '-left.bam', 'right-start': 'phase_3.5/models/char/' + charType.lower() + '-right-start.bam', 'right': 'phase_3.5/models/char/' + charType.lower() + '-right.bam'}) if charType == CIGlobals.Mickey: self.mickeyEye = self.controlJoint(None, 'modelRoot', 'joint_pupilR') self.mickeyEye.setY(0.025) for bundle in self.getPartBundleDict().values(): bundle = bundle['modelRoot'].getBundle() earNull = bundle.findChild('sphere3') if not earNull: earNull = bundle.findChild('*sphere3') earNull.clearNetTransforms() for bundle in self.getPartBundleDict().values(): charNodepath = bundle['modelRoot'].partBundleNP bundle = bundle['modelRoot'].getBundle() earNull = bundle.findChild('sphere3') if not earNull: earNull = bundle.findChild('*sphere3') ears = charNodepath.find('**/sphere3') if ears.isEmpty(): ears = charNodepath.find('**/*sphere3') ears.clearEffect(CharacterJointEffect.getClassType()) earRoot = charNodepath.attachNewNode('earRoot') earPitch = earRoot.attachNewNode('earPitch') earPitch.setP(40.0) ears.reparentTo(earPitch) earNull.addNetTransform(earRoot.node()) ears.clearMat() ears.node().setPreserveTransform(ModelNode.PTNone) ears.setP(-40.0) ears.flattenMedium() ears.setBillboardAxis() self.startBlink() elif charType == CIGlobals.Pluto: self.loadModel('phase_6/models/char/pluto-1000.bam') self.loadAnims({'walk': 'phase_6/models/char/pluto-walk.bam', 'neutral': 'phase_6/models/char/pluto-neutral.bam', 'sit': 'phase_6/models/char/pluto-sit.bam', 'stand': 'phase_6/models/char/pluto-stand.bam'}) elif charType == CIGlobals.Goofy: self.loadModel('phase_6/models/char/TT_G-1500.bam') self.loadAnims({'neutral': 'phase_6/models/char/TT_GWait.bam', 'walk': 'phase_6/models/char/TT_GWalk.bam'}) else: raise StandardError('unknown char %s!' % charType) Avatar.Avatar.initShadow(self) return def initializeLocalCollisions(self, name, radius): Avatar.Avatar.initializeLocalCollisions(self, radius, 2, name) def startBlink(self): randomStart = random.uniform(0.5, 5) taskMgr.add(self.blinkTask, 'blinkTask') def stopBlink(self): taskMgr.remove('blinkTask') taskMgr.remove('doBlink') taskMgr.remove('openEyes') def blinkTask(self, task): taskMgr.add(self.doBlink, 'doBlink') delay = random.uniform(0.5, 7) task.delayTime = delay return task.again def doBlink(self, task): self.closeEyes() taskMgr.doMethodLater(0.2, self.openEyes, 'openEyes') return task.done def closeEyes(self): self.find('**/joint_pupilR').hide() self.find('**/joint_pupilL').hide() if self.charType == CIGlobals.Mickey: self.mickeyEye.setY(-0.025) self.mickeyEye.hide() self.find('**/eyes').setTexture(self.closedEyes, 1) def openEyes(self, task): self.find('**/joint_pupilR').show() self.find('**/joint_pupilL').show() if self.charType == CIGlobals.Mickey: self.mickeyEye.setY(0.025) self.mickeyEye.show() self.find('**/eyes').setTexture(self.eyes, 1) return task.done def enterOff(self): self.currentAnim = None return def exitOff(self): pass def enterNeutral(self): self.loop('neutral') def exitNeutral(self): self.stop() def enterWalk(self): self.loop('walk') def exitWalk(self): self.stop() def enterRun(self): self.loop('run') def exitRun(self): self.stop()