class Suit(Avatar.Avatar): healthColors = (Vec4(0, 1, 0, 1), Vec4(1, 1, 0, 1), Vec4(1, 0.5, 0, 1), Vec4(1, 0, 0, 1), Vec4(0.3, 0.3, 0.3, 1)) healthGlowColors = (Vec4(0.25, 1, 0.25, 0.5), Vec4(1, 1, 0.25, 0.5), Vec4(1, 0.5, 0.25, 0.5), Vec4(1, 0.25, 0.25, 0.5), Vec4(0.3, 0.3, 0.3, 0)) medallionColors = {'c': Vec4(0.863, 0.776, 0.769, 1.0), 's': Vec4(0.843, 0.745, 0.745, 1.0), 'l': Vec4(0.749, 0.776, 0.824, 1.0), 'm': Vec4(0.749, 0.769, 0.749, 1.0)} health2DmgMultiplier = 2.5 def __init__(self): try: self.Suit_initialized return except: self.Suit_initialized = 1 Avatar.Avatar.__init__(self) self.avatarType = CIGlobals.Suit self.name = '' self.chat = '' self.suit = None self.suitHeads = None self.suitHead = None self.loserSuit = None self.healthMeterGlow = None self.healthMeter = None self.weapon = None self.weapon_sfx = None self.anim = None self.suit_dial = None self.shadow = None self.balloon_sfx = None self.add_sfx = None self.explosion = None self.largeExp = None self.smallExp = None self.death_sfx = None self.attack = None self.wtrajectory = None self.throwObjectId = None self.hasSpawned = False self.condition = 0 self.type = "" self.head = "" self.team = "" self.isSkele = 0 self.animFSM = ClassicFSM('Suit', [State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('walk', self.enterWalk, self.exitWalk), State('die', self.enterDie, self.exitDie), State('attack', self.enterAttack, self.exitAttack), State('flydown', self.enterFlyDown, self.exitFlyDown), State('pie', self.enterPie, self.exitPie), State('win', self.enterWin, self.exitWin), State('flyaway', self.enterFlyAway, self.exitFlyAway), State('rollodex', self.enterRollodex, self.exitRollodex)], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() self.initializeBodyCollisions() def delete(self): try: self.Suit_deleted except: self.Suit_deleted = 1 if self.suit: self.cleanupSuit() if self.loserSuit: self.cleanupLoserSuit() if self.suitHeads: self.suitHeads.remove() self.suitHeads = None if self.suitHead: self.suitHead.remove() self.suitHead = None if self.healthMeterGlow: self.healthMeterGlow.remove() self.healthMeterGlow = None if self.healthMeter: self.healthMeter.remove() self.healthMeter = None if self.shadow: self.shadow.remove() self.shadow = None self.weapon = None self.weapon_sfx = None self.suit_dial = None del self.shadowPlacer def generateSuit(self, suitType, suitHead, suitTeam, suitHealth, skeleton): self.health = suitHealth self.maxHealth = suitHealth self.generateBody(suitType, suitTeam, suitHead, skeleton) self.generateHealthMeter() self.generateHead(suitType, suitHead) self.setupNameTag() Avatar.Avatar.initShadow(self) def generateBody(self, suitType, suitTeam, suitHead, skeleton): if self.suit: self.cleanupSuit() self.team = suitTeam self.type = suitType self.head = suitHead self.isSkele = skeleton if suitType == "A": if skeleton: self.suit = Actor("phase_5/models/char/cogA_robot-zero.bam") else: self.suit = Actor("phase_3.5/models/char/suitA-mod.bam") self.suit.loadAnims({"neutral": "phase_4/models/char/suitA-neutral.bam", "walk": "phase_4/models/char/suitA-walk.bam", "pie": "phase_4/models/char/suitA-pie-small.bam", "land": "phase_5/models/char/suitA-landing.bam", "throw-object": "phase_5/models/char/suitA-throw-object.bam", "throw-paper": "phase_5/models/char/suitA-throw-paper.bam", "glower": "phase_5/models/char/suitA-glower.bam", "win": "phase_4/models/char/suitA-victory.bam", "rollodex": "phase_5/models/char/suitA-roll-o-dex.bam"}) if suitType == "B": if skeleton: self.suit = Actor("phase_5/models/char/cogB_robot-zero.bam") else: self.suit = Actor("phase_3.5/models/char/suitB-mod.bam") self.suit.loadAnims({"neutral": "phase_4/models/char/suitB-neutral.bam", "walk": "phase_4/models/char/suitB-walk.bam", "pie": "phase_4/models/char/suitB-pie-small.bam", "land": "phase_5/models/char/suitB-landing.bam", "throw-object": "phase_5/models/char/suitB-throw-object.bam", "throw-paper": "phase_5/models/char/suitB-throw-paper.bam", "glower": "phase_5/models/char/suitB-magic1.bam", "win": "phase_4/models/char/suitB-victory.bam", "rollodex": "phase_5/models/char/suitB-roll-o-dex.bam"}) if suitType == "C": if skeleton: self.suit = Actor("phase_5/models/char/cogC_robot-zero.bam") else: self.suit = Actor("phase_3.5/models/char/suitC-mod.bam") self.suit.loadAnims({"neutral": "phase_3.5/models/char/suitC-neutral.bam", "walk": "phase_3.5/models/char/suitC-walk.bam", "pie": "phase_3.5/models/char/suitC-pie-small.bam", "land": "phase_5/models/char/suitC-landing.bam", "throw-object": "phase_3.5/models/char/suitC-throw-paper.bam", "throw-paper": "phase_3.5/models/char/suitC-throw-paper.bam", "glower": "phase_5/models/char/suitC-glower.bam", "win": "phase_4/models/char/suitC-victory.bam"}) if skeleton: self.suit.setTwoSided(1) self.suit.getGeomNode().setScale(CIGlobals.SuitScales[suitHead] / CIGlobals.SuitScaleFactors[suitType]) if skeleton: if suitTeam == "s": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_sales.jpg") elif suitTeam == "m": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_money.jpg") elif suitTeam == "l": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_legal.jpg") elif suitTeam == "c": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_boss.jpg") self.suit.find('**/tie').setTexture(self.suit_tie, 1) else: self.suit_blazer = loader.loadTexture("phase_3.5/maps/" + suitTeam + "_blazer.jpg") self.suit_leg = loader.loadTexture("phase_3.5/maps/" + suitTeam + "_leg.jpg") self.suit_sleeve = loader.loadTexture("phase_3.5/maps/" + suitTeam + "_sleeve.jpg") self.suit.find('**/legs').setTexture(self.suit_leg, 1) self.suit.find('**/arms').setTexture(self.suit_sleeve, 1) self.suit.find('**/torso').setTexture(self.suit_blazer, 1) if suitHead == "coldcaller": self.suit.find('**/hands').setColor(0.55, 0.65, 1.0, 1.0) elif suitHead == "corporateraider": self.suit.find('**/hands').setColor(0.85, 0.55, 0.55, 1.0) elif suitHead == "bigcheese": self.suit.find('**/hands').setColor(0.75, 0.95, 0.75, 1.0) elif suitHead == "bloodsucker": self.suit.find('**/hands').setColor(0.95, 0.95, 1.0, 1.0) elif suitHead == "spindoctor": self.suit.find('**/hands').setColor(0.5, 0.8, 0.75, 1.0) elif suitHead == "legaleagle": self.suit.find('**/hands').setColor(0.25, 0.25, 0.5, 1.0) elif suitHead == "pennypincher": self.suit.find('**/hands').setColor(1.0, 0.5, 0.6, 1.0) elif suitHead == "loanshark": self.suit.find('**/hands').setColor(0.5, 0.85, 0.75, 1.0) else: self.suit.find('**/hands').setColor(CIGlobals.SuitHandColors[suitTeam]) self.suit.reparentTo(self) def generateHead(self, suitType, suitHead): if self.suitHead: self.cleanupSuitHead() self.type = suitType self.head = suitHead if suitHead == "vp": self.suitHead = Actor("phase_9/models/char/sellbotBoss-head-zero.bam", {"neutral": "phase_9/models/char/bossCog-head-Ff_neutral.bam"}) self.suitHead.setTwoSided(True) self.suitHead.loop("neutral") self.suitHead.setScale(0.35) self.suitHead.setHpr(270, 0, 270) self.suitHead.setZ(-0.10) else: if suitType == "A" or suitType == "B": self.suitHeads = loader.loadModel("phase_4/models/char/suit" + suitType + "-heads.bam") else: self.suitHeads = loader.loadModel("phase_3.5/models/char/suit" + suitType + "-heads.bam") self.suitHead = self.suitHeads.find('**/' + CIGlobals.SuitHeads[suitHead]) if suitHead == "flunky": glasses = self.suitHeads.find('**/glasses') glasses.reparentTo(self.suitHead) glasses.setTwoSided(True) if suitHead in CIGlobals.SuitSharedHeads: if suitHead == "coldcaller": self.suitHead.setColor(0.25, 0.35, 1.0, 1.0) else: headTexture = loader.loadTexture("phase_3.5/maps/" + suitHead + ".jpg") self.suitHead.setTexture(headTexture, 1) if not self.isSkele: self.suitHead.reparentTo(self.suit.find('**/joint_head')) def cleanupSuit(self): if self.shadow: self.shadow.remove() self.shadow = None self.removeHealthBar() self.suit.cleanup() self.suit = None def cleanupSuitHead(self): if self.suitHeads: self.suitHeads.remove() self.suitHeads = None if self.suitHead: self.suitHead.remove() self.suitHead = None def cleanupLoserSuit(self): if self.explosion: self.explosion.remove() self.explosion = None if self.smallExp: self.smallExp = None if self.largeExp: self.largeExp.cleanup() self.largeExp = None if self.loserSuit: self.loserSuit.cleanup() self.loserSuit = None def setName(self, nameString, charName): Avatar.Avatar.setName(self, nameString, avatarType=self.avatarType, charName=charName) def setChat(self, chatString): self.chat = chatString if self.isSkele: if "?" in chatString: self.suit_dial = audio3d.loadSfx("phase_5/audio/sfx/Skel_COG_VO_question.ogg") elif "!" in chatString: self.suit_dial = audio3d.loadSfx("phase_5/audio/sfx/Skel_COG_VO_grunt.ogg") else: self.suit_dial = audio3d.loadSfx("phase_5/audio/sfx/Skel_COG_VO_statement.ogg") elif self.head == "vp": if "?" in chatString: self.suit_dial = audio3d.loadSfx("phase_9/audio/sfx/Boss_COG_VO_question.ogg") elif "!" in chatString: self.suit_dial = audio3d.loadSfx("phase_9/audio/sfx/Boss_COG_VO_grunt.ogg") else: self.suit_dial = audio3d.loadSfx("phase_9/audio/sfx/Boss_COG_VO_statement.ogg") else: if "?" in chatString: self.suit_dial = audio3d.loadSfx("phase_3.5/audio/dial/COG_VO_question.ogg") elif "!" in chatString: self.suit_dial = audio3d.loadSfx("phase_3.5/audio/dial/COG_VO_grunt.ogg") else: self.suit_dial = audio3d.loadSfx("phase_3.5/audio/dial/COG_VO_statement.ogg") if self.isSkele: audio3d.attachSoundToObject(self.suit_dial, self.suit) else: audio3d.attachSoundToObject(self.suit_dial, self.suitHead) self.suit_dial.play() Avatar.Avatar.setChat(self, chatString) def generateHealthMeter(self): self.removeHealthBar() model = loader.loadModel("phase_3.5/models/gui/matching_game_gui.bam") button = model.find('**/minnieCircle') button.setScale(3.0) button.setH(180) button.setColor(self.healthColors[0]) chestNull = self.suit.find('**/def_joint_attachMeter') if chestNull.isEmpty(): chestNull = self.suit.find('**/joint_attachMeter') button.reparentTo(chestNull) self.healthBar = button glow = loader.loadModel("phase_3.5/models/props/glow.bam") glow.reparentTo(self.healthBar) glow.setScale(0.28) glow.setPos(-0.005, 0.01, 0.015) glow.setColor(self.healthGlowColors[0]) button.flattenLight() self.healthBarGlow = glow self.condition = 0 def updateHealthBar(self, hp): if hp > self.hp: self.hp = hp self.hp -= hp health = float(self.health) / float(self.maxHP) if health > 0.95: condition = 0 elif health > 0.7: condition = 1 elif health > 0.3: condition = 2 elif health > 0.05: condition = 3 elif health > 0.0: condition = 4 else: condition = 5 if self.condition != condition: if condition == 4: blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) elif condition == 5: if self.condition == 4: taskMgr.remove(self.taskName('blink-task')) blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) else: self.healthBar.setColor(self.healthColors[condition], 1) self.healthBarGlow.setColor(self.healthGlowColors[condition], 1) self.condition = condition def __blinkRed(self, task): self.healthBar.setColor(self.healthColors[3], 1) self.healthBarGlow.setColor(self.healthGlowColors[3], 1) if self.condition == 5: self.healthBar.setScale(1.17) return Task.done def __blinkGray(self, task): if not self.healthBar: return self.healthBar.setColor(self.healthColors[4], 1) self.healthBarGlow.setColor(self.healthGlowColors[4], 1) if self.condition == 5: self.healthBar.setScale(1.0) return Task.done def removeHealthBar(self): if self.healthMeter: self.healthBar.removeNode() self.healthBar = None if self.condition == 4 or self.condition == 5: taskMgr.remove(self.taskName('blink-task')) self.healthCondition = 0 return def enterOff(self): self.anim = None return def exitOff(self): pass def exitGeneral(self): self.suit.stop() def enterNeutral(self): self.suit.loop("neutral") def exitNeutral(self): self.exitGeneral() def enterRollodex(self): self.suit.play("rollodex") def exitRollodex(self): self.exitGeneral() def enterWalk(self): self.suit.loop("walk") def exitWalk(self): self.exitGeneral() def generateLoserSuit(self): self.cleanupLoserSuit() if self.type == "A": if self.isSkele: self.loserSuit = Actor("phase_5/models/char/cogA_robot-lose-mod.bam") else: self.loserSuit = Actor("phase_4/models/char/suitA-lose-mod.bam") self.loserSuit.loadAnims({"lose": "phase_4/models/char/suitA-lose.bam"}) if self.type == "B": if self.isSkele: self.loserSuit = Actor("phase_5/models/char/cogB_robot-lose-mod.bam") else: self.loserSuit = Actor("phase_4/models/char/suitB-lose-mod.bam") self.loserSuit.loadAnims({"lose": "phase_4/models/char/suitB-lose.bam"}) if self.type == "C": if self.isSkele: self.loserSuit = Actor("phase_5/models/char/cogC_robot-lose-mod.bam") else: self.loserSuit = Actor("phase_3.5/models/char/suitC-lose-mod.bam") self.loserSuit.loadAnims({"lose": "phase_3.5/models/char/suitC-lose.bam"}) if self.isSkele: self.loserSuit.find('**/tie').setTexture(self.suit_tie, 1) self.loserSuit.setTwoSided(1) else: self.loserSuit.find('**/hands').setColor(self.suit.find('**/hands').getColor()) self.loserSuit.find('**/legs').setTexture(self.suit_leg, 1) self.loserSuit.find('**/arms').setTexture(self.suit_sleeve, 1) self.loserSuit.find('**/torso').setTexture(self.suit_blazer, 1) self.loserSuit.getGeomNode().setScale(self.suit.getScale()) self.loserSuit.reparentTo(self) if not self.isSkele: self.suitHead.reparentTo(self.loserSuit.find('**/joint_head')) self.loserSuit.setPos(self.suit.getPos(render)) self.loserSuit.setHpr(self.suit.getHpr(render)) self.cleanupSuit() Avatar.Avatar.initShadow(self, self.avatarType) self.loserSuit.reparentTo(render) def enterDie(self): self.generateLoserSuit() self.state = "dead" self.loserSuit.play("lose") spinningSound = base.loadSfx("phase_3.5/audio/sfx/Cog_Death.ogg") deathSound = base.loadSfx("phase_3.5/audio/sfx/ENC_cogfall_apart.ogg") #audio3d.attachSoundToObject(spinningSound, self.loserSuit) #audio3d.attachSoundToObject(deathSound, self.loserSuit) Sequence(Wait(0.8), SoundInterval(spinningSound, duration=1.2, startTime=1.5, volume=0.4, node=self.loserSuit), SoundInterval(spinningSound, duration=3.0, startTime=0.6, volume=2.0, node=self.loserSuit), SoundInterval(deathSound, volume=0.32, node=self.loserSuit)).start() Sequence(Wait(0.8), Func(self.smallDeathParticles), Wait(4.2), Func(self.suitExplode), Wait(1.0), Func(self.delSuit)).start() def smallDeathParticles(self): self.smallExp = ParticleLoader.loadParticleEffect("phase_3.5/etc/gearExplosionSmall.ptf") self.smallExp.start(self.loserSuit) def suitExplode(self): self.smallExp.cleanup() self.largeExp = ParticleLoader.loadParticleEffect("phase_3.5/etc/gearExplosion.ptf") self.largeExp.start(self.loserSuit) self.explosion = loader.loadModel("phase_3.5/models/props/explosion.bam") self.explosion.setScale(0.5) self.explosion.reparentTo(render) self.explosion.setBillboardPointEye() if self.isSkele: self.explosion.setPos(self.loserSuit.find('**/joint_head').getPos(render) + (0, 0, 2)) else: self.explosion.setPos(self.suitHead.getPos(render) + (0,0,2)) def delSuit(self): self.cleanupLoserSuit() self.disableBodyCollisions() def exitDie(self): pass def enterFlyDown(self): self.fd_sfx = audio3d.loadSfx("phase_5/audio/sfx/ENC_propeller_in.ogg") self.prop = Actor("phase_4/models/props/propeller-mod.bam", {"chan": "phase_4/models/props/propeller-chan.bam"}) audio3d.attachSoundToObject(self.fd_sfx, self.prop) self.fd_sfx.play() self.prop.reparentTo(self.suit.find('**/joint_head')) propTrack = Sequence(Func(self.prop.loop, 'chan', fromFrame=0, toFrame=3), Wait(1.75), Func(self.prop.play, 'chan', fromFrame=3)) propTrack.start() if not self.hasSpawned: showSuit = Task.sequence(Task(self.hideSuit), Task.pause(0.3), Task(self.showSuit)) taskMgr.add(showSuit, "showsuit") self.hasSpawned = True dur = self.suit.getDuration('land') suitTrack = Sequence(Func(self.suit.pose, 'land', 0), Wait(1.9), ActorInterval(self.suit, 'land', duration=dur)) suitTrack.start() def hideSuit(self, task): self.hide() return Task.done def showSuit(self, task): self.show() fadeIn = Sequence(Func(self.setTransparency, 1), self.colorScaleInterval(0.6, colorScale=Vec4(1,1,1,1), startColorScale=Vec4(1,1,1,0)), Func(self.clearColorScale), Func(self.clearTransparency), Func(self.reparentTo, render)) fadeIn.start() return Task.done def initializeLocalCollisions(self, name): Avatar.Avatar.initializeLocalCollisions(self, 1, 3, name) def initializeBodyCollisions(self): Avatar.Avatar.initializeBodyCollisions(self, self.avatarType, 2.25, 1, 4, 2) self.initializeRay(self.avatarType) self.collTube.setTangible(0) def deleteBean(self): if self.bean: self.bean.remove_node() self.bean = None def createJellyBean(self): self.deleteBean() money = int(self.maxHP / CIGlobals.SuitAttackDamageFactors['clipontie']) if money == 1: self.bean = loader.loadModel("phase_5.5/models/estate/jellyBean.bam") self.bean.set_two_sided(True) random_r = random.uniform(0, 1) random_g = random.uniform(0, 1) random_b = random.uniform(0, 1) self.bean.set_color(random_r, random_g, random_b, 1) else: self.bean = loader.loadModel("phase_5.5/models/estate/jellybeanJar.bam") self.bean.reparent_to(render) self.bean.set_pos(self.get_pos(render) + (0, 0, 1)) bean_int = self.bean.hprInterval(1, Point3(360, 0, 0), startHpr=(0, 0, 0)) bean_int.loop() def exitFlyDown(self): audio3d.detachSound(self.fd_sfx) self.prop.cleanup() self.prop = None def enterFlyAway(self): self.fa_sfx = audio3d.loadSfx("phase_5/audio/sfx/ENC_propeller_out.ogg") self.prop = Actor("phase_4/models/props/propeller-mod.bam", {"chan": "phase_4/models/props/propeller-chan.bam"}) audio3d.attachSoundToObject(self.fa_sfx, self.prop) self.fa_sfx.play() self.prop.reparentTo(self.suit.find('**/joint_head')) self.prop.setPlayRate(-1.0, "chan") propTrack = Sequence(Func(self.prop.play, 'chan', fromFrame=3), Wait(1.75), Func(self.prop.play, 'chan', fromFrame=0, toFrame=3)) propTrack.start() self.suit.setPlayRate(-1.0, 'land') self.suit.play('land') def exitFlyAway(self): audio3d.detachSound(self.fa_sfx) self.prop.cleanup() self.prop = None def enterAttack(self, attack): self.attack = attack self.weapon_state = 'start' if attack == "canned": self.weapon = loader.loadModel("phase_5/models/props/can.bam") self.weapon.setScale(15) self.weapon.setR(180) self.wss = CollisionSphere(0,0,0,0.05) elif attack == "clipontie": self.weapon = loader.loadModel("phase_5/models/props/power-tie.bam") self.weapon.setScale(4) self.weapon.setR(180) self.wss = CollisionSphere(0,0,0,0.2) elif attack == "sacked": self.weapon = loader.loadModel("phase_5/models/props/sandbag-mod.bam") self.weapon.setScale(2) self.weapon.setR(180) self.weapon.setP(90) self.weapon.setY(-2.8) self.weapon.setZ(-0.3) self.wss = CollisionSphere(0,0,0,1) elif attack == "playhardball": self.weapon = loader.loadModel("phase_5/models/props/baseball.bam") self.weapon.setScale(10) self.wss = CollisionSphere(0,0,0,0.1) self.weapon.setZ(-0.5) elif attack == "marketcrash": self.weapon = loader.loadModel("phase_5/models/props/newspaper.bam") self.weapon.setScale(3) self.weapon.setPos(0.41, -0.06, -0.06) self.weapon.setHpr(90, 0, 270) self.wss = CollisionSphere(0,0,0,0.35) elif attack == "glowerpower": self.weapon = loader.loadModel("phase_5/models/props/dagger.bam") self.wss = CollisionSphere(0,0,0,1) else: notify.warning("unknown attack!") self.throwObjectId = random.uniform(0, 101010101010) if attack == "canned" or attack == "playhardball": self.weapon.reparentTo(self.suit.find('**/joint_Rhold')) if self.type == "C": taskMgr.doMethodLater(2.2, self.throwObject, "throwObject" + str(self.throwObjectId)) else: taskMgr.doMethodLater(3, self.throwObject, "throwObject" + str(self.throwObjectId)) self.suit.play("throw-object") elif attack == "clipontie" or attack == "marketcrash" or attack == "sacked": self.weapon.reparentTo(self.suit.find('**/joint_Rhold')) if self.type == "C": taskMgr.doMethodLater(2.2, self.throwObject, "throwObject" + str(self.throwObjectId)) else: taskMgr.doMethodLater(3, self.throwObject, "throwObject" + str(self.throwObjectId)) self.suit.play("throw-paper") elif attack == "glowerpower": taskMgr.doMethodLater(1, self.throwObject, "throwObject" + str(self.throwObjectId)) self.suit.play("glower") self.weaponSensorId = random.uniform(0, 1010101010101001) wsnode = CollisionNode('weaponSensor' + str(self.weaponSensorId)) wsnode.addSolid(self.wss) self.wsnp = self.weapon.attachNewNode(wsnode) if attack == "sacked": self.wsnp.setZ(1) elif attack == "marketcrash": self.wsnp.setPos(-0.25, 0.3, 0) def delWeapon(self, task): if self.weapon: self.weapon.removeNode() self.weapon = None return task.done def interruptAttack(self): if self.wtrajectory: if self.wtrajectory.isStopped(): if self.weapon: self.weapon.removeNode() self.weapon = None if self.throwObjectId: taskMgr.remove("throwObject" + str(self.throwObjectId)) def handleWeaponTouch(self): if not self.attack == "glowerpower" or not self.attack == "clipontie": if self.weapon_sfx: self.weapon_sfx.stop() try: self.wtrajectory.pause() except: pass if self.weapon: self.weapon.removeNode() self.weapon = None def weaponCollisions(self): self.wsnp.setCollideMask(BitMask32(0)) self.wsnp.node().setFromCollideMask(CIGlobals.EventBitmask) event = CollisionHandlerEvent() event.setInPattern("%fn-into") event.setOutPattern("%fn-out") base.cTrav.addCollider(self.wsnp, event) def throwObject(self, task): self.playWeaponSound() self.weaponNP = NodePath("weaponNP") self.weaponNP.setScale(render, 1) try: self.weaponNP.reparentTo(self.find('**/joint_nameTag')) except: return task.done self.weaponNP.setPos(0, 50, 0) self.weaponNP.setHpr(0, 0, 0) if self.weapon: self.weapon.setScale(self.weapon.getScale(render)) try: self.weapon.reparentTo(render) except: return task.done self.weapon.setPos(0,0,0) self.weapon.setHpr(0,0,0) if self.attack == "glowerpower": self.weapon.setH(self.weaponNP.getH(render)) self.wtrajectory = self.weapon.posInterval(0.5, Point3(self.weaponNP.getPos(render)), startPos=(self.getX(render), self.getY(render) + 3, self.find('**/joint_head').getZ(render))) self.wtrajectory.start() else: self.wtrajectory = ProjectileInterval(self.weapon, startPos = (self.suit.find('**/joint_Rhold').getPos(render)), endPos = self.weaponNP.getPos(render), gravityMult = 0.7, duration = 1) self.wtrajectory.start() if self.attack == "glowerpower": taskMgr.doMethodLater(0.5, self.delWeapon, "delWeapon") else: taskMgr.doMethodLater(1, self.delWeapon, "delWeapon") self.weapon_state = 'released' def playWeaponSound(self): if self.attack == "glowerpower": self.weapon_sfx = audio3d.loadSfx("phase_5/audio/sfx/SA_glower_power.ogg") elif self.attack == "canned": self.weapon_sfx = audio3d.loadSfx("phase_5/audio/sfx/SA_canned_tossup_only.ogg") elif self.attack == "clipontie": self.weapon_sfx = audio3d.loadSfx("phase_5/audio/sfx/SA_powertie_throw.ogg") elif self.attack == "sacked": self.weapon_sfx = audio3d.loadSfx("phase_5/audio/sfx/SA_canned_tossup_only.ogg") elif self.attack == "playhardball": self.weapon_sfx = audio3d.loadSfx("phase_5/audio/sfx/SA_canned_tossup_only.ogg") elif self.attack == "marketcrash": self.weapon_sfx = audio3d.loadSfx("phase_5/audio/sfx/SA_canned_tossup_only.ogg") if self.weapon: audio3d.attachSoundToObject(self.weapon_sfx, self.weapon) self.weapon_sfx.play() def exitAttack(self): pass def enterPie(self): self.suit.play("pie") def exitPie(self): self.exitGeneral() def enterWin(self): self.suit.play("win") def exitWin(self): self.exitGeneral()
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 DistributedSuit(Suit, DistributedAvatar, DistributedSmoothNode, DelayDeletable): notify = directNotify.newCategory("DistributedSuit") def __init__(self, cr): try: self.DistributedSuit_initialized return except: self.DistributedSuit_initialized = 1 Suit.__init__(self) DistributedAvatar.__init__(self, cr) DistributedSmoothNode.__init__(self, cr) self.suitFSM = ClassicFSM('DistributedSuit', [ State('off', self.enterSuitOff, self.exitSuitOff), State('walking', self.enterWalking, self.exitWalking), State('flyingDown', self.enterFlyingDown, self.exitFlyingDown), State('flyingUp', self.enterFlyingUp, self.exitFlyingUp), State('bossFlying', self.enterBossFlying, self.exitBossFlying) ], 'off', 'off' ) self.suitFSM.enterInitialState() self.makeStateDict() self.makeAnimStateDict() # These are just default values, we'll set them later on. self.anim = None self.state = "alive" self.health = None self.type = None self.team = None self.head = None self.skeleton = 0 self.battle = None self.suitState = None self.startPoint = None self.endPoint = None self.moveIval = None self.walkPaused = None self.animIval = None self.level = None return def d_disableMovement(self, wantRay = False): self.sendUpdate('disableMovement', []) self.interruptAttack() if not wantRay: Suit.disableRay(self) def d_enableMovement(self): self.sendUpdate('enableMovement', []) Suit.initializeRay(self, self.avatarType, 2) def startRay(self): Suit.initializeRay(self, self.avatarType, 2) def setLevel(self, level): self.level = level def getLevel(self): return self.level def makeStateDict(self): self.suitState2stateIndex = {} for state in self.suitFSM.getStates(): self.suitState2stateIndex[state.getName()] = self.suitFSM.getStates().index(state) self.stateIndex2suitState = {v: k for k, v in self.suitState2stateIndex.items()} def makeAnimStateDict(self): self.animState2animId = {} for index in range(len(self.animFSM.getStates())): self.animState2animId[self.animFSM.getStates()[index].getName()] = index self.animId2animState = {v: k for k, v in self.animState2animId.items()} def setLatePos(self, x, y): self.setX(x) self.setY(y) def enterAttack(self, attack, target, ts = 0): Suit.enterAttack(self, attack, target, ts) if target: self.headsUp(target) def setSuitState(self, index, startPoint, endPoint, timestamp = None): if timestamp != None: ts = globalClockDelta.localElapsedTime(timestamp) else: ts = 0.0 self.suitState = self.stateIndex2suitState[index] self.startPoint = startPoint self.endPoint = endPoint self.suitFSM.request(self.suitState, [startPoint, endPoint, ts]) def getSuitState(self): return self.suitState def enterWalking(self, startIndex, endIndex, ts = 0.0): durationFactor = 0.2 if startIndex > -1: startPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[startIndex] startPos = CIGlobals.SuitSpawnPoints[self.getHood()][startPoint] else: startPos = self.getPos(render) endPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[endIndex] endPos = CIGlobals.SuitSpawnPoints[self.getHood()][endPoint] if self.moveIval: self.moveIval.pause() self.moveIval = None self.moveIval = NPCWalkInterval(self, endPos, durationFactor, startPos, fluid = 1) self.moveIval.start(ts) self.animFSM.request('walk') def exitWalking(self): if self.moveIval: self.moveIval.pause() self.moveIval = None if not self.isDead(): self.animFSM.request('off') def enterFlyingDown(self, startIndex, endIndex, ts = 0.0): duration = 3 startPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[startIndex] startPos = CIGlobals.SuitSpawnPoints[self.getHood()][startPoint] + (0, 0, 50) endPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[endIndex] endPos = CIGlobals.SuitSpawnPoints[self.getHood()][endPoint] if self.moveIval: self.moveIval.finish() self.moveIval = None self.moveIval = LerpPosInterval(self, duration = duration, pos = endPos, startPos = startPos, fluid = 1) self.moveIval.start(ts) self.animFSM.request('flydown', [ts]) yaw = random.uniform(0.0, 360.0) self.setH(yaw) def exitFlyingDown(self): if self.moveIval: self.moveIval.finish() self.moveIval = None self.animFSM.request('off') def enterFlyingUp(self, startIndex, endIndex, ts = 0.0): duration = 3 startPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[startIndex] endPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[endIndex] startPos = CIGlobals.SuitSpawnPoints[self.getHood()][startPoint] endPos = CIGlobals.SuitSpawnPoints[self.getHood()][endPoint] + (0, 0, 50) if self.moveIval: self.moveIval.finish() self.moveIval = None self.moveIval = LerpPosInterval(self, duration = duration, pos = endPos, startPos = startPos, fluid = 1) self.moveIval.start(ts) self.animFSM.request('flyaway', [ts]) def exitFlyingUp(self): if self.moveIval: self.moveIval.finish() self.moveIval = None self.animFSM.request('off') def enterBossFlying(self, startIndex, endIndex, ts = 0.0): duration = 3.5 startPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[startIndex] endPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[endIndex] startPos = CIGlobals.SuitSpawnPoints[self.getHood()][startPoint] endPos = CIGlobals.SuitSpawnPoints[self.getHood()][endPoint] if self.moveIval: self.moveIval.finish() self.moveIval = None self.animIval = Sequence( Func(self.animFSM.request, 'flyaway', [ts]), Wait(1.0), Func(self.animFSM.request, 'flydown', [ts]) ) self.moveIval = Sequence( Wait(0.5), Func(self.headsUp, endPos), ProjectileInterval( self, startPos = startPos, endPos = endPos, gravityMult = 0.25, duration = duration ) ) self.moveIval.start(ts) self.animIval.start(ts) def exitBossFlying(self): if self.animIval: self.animIval.finish() self.animIval = None if self.moveIval: self.moveIval.finish() self.moveIval = None self.animFSM.request('off') def enterSuitOff(self, foo1 = None, foo2 = None, foo3 = None): pass def exitSuitOff(self): pass #def setWalking(self, value, startPos, endPath, timestamp = None): # # # self.value = value # self.startPath = startPath # self.endPath = endPath # # if self.walkIval: # self.walkIval.finish() # self.walkIval = None # # if value: # durationFactor = 0.2 # path = CIGlobals.SuitSpawnPoints.values()[endPath] # self.walkIval = NPCWalkInterval(self, path, startPos = self.getPos(render), name = pathName, durationFactor = durationFactor, fluid = 1) def setBattle(self, battle): self.battle = battle def getBattle(self): return self.battle def printPos(self, task): print self.getPos(render) print self.getHpr(render) return task.cont def announceHealth(self, level, hp): DistributedAvatar.announceHealth(self, level, hp) if level == 1: healthSfx = base.audio3d.loadSfx("phase_3/audio/sfx/health.mp3") base.audio3d.attachSoundToObject(healthSfx, self) SoundInterval(healthSfx).start() del healthSfx def setSuit(self, suitType, head, team, skeleton): for obj in self.cr.doId2do.values(): if obj.zoneId == self.zoneId: if obj.__class__.__name__ == "DistributedCogBattle": # This has to be the Cog Battle we're in because it's in the same zone. self.setBattle(obj) hp = CIGlobals.SuitHealthAmounts[head] Suit.generateSuit(self, suitType, head, team, hp, skeleton) def getSuit(self): return tuple((self.type, self.head, self.team, self.skeleton)) def setName(self, name): Suit.setName(self, name, self.head) def setHealth(self, health): DistributedAvatar.setHealth(self, health) self.updateHealthBar(health) def setAnimState(self, anim, timestamp = None): self.anim = anim if timestamp == None: ts = 0.0 else: ts = globalClockDelta.localElapsedTime(timestamp) if type(anim) == types.IntType: anim = self.animId2animState[anim] if self.animFSM.getStateNamed(anim): self.animFSM.request(anim, [ts]) def doAttack(self, attackId, avId, timestamp = None): if timestamp == None: ts = 0.0 else: ts = globalClockDelta.localElapsedTime(timestamp) attackName = SuitAttacks.SuitAttackLengths.keys()[attackId] avatar = self.cr.doId2do.get(avId) self.animFSM.request('attack', [attackName, avatar, ts]) def throwObject(self): self.acceptOnce("enter" + self.wsnp.node().getName(), self.__handleWeaponCollision) Suit.throwObject(self) def __handleWeaponCollision(self, entry): self.sendUpdate('toonHitByWeapon', [self.attack, base.localAvatar.doId]) base.localAvatar.handleHitByWeapon(self.attack, self) self.b_handleWeaponTouch() def b_handleWeaponTouch(self): self.sendUpdate('handleWeaponTouch', []) self.handleWeaponTouch() def announceGenerate(self): DistributedAvatar.announceGenerate(self) if self.animFSM.getCurrentState().getName() == 'off': self.setAnimState('neutral') def generate(self): DistributedAvatar.generate(self) DistributedSmoothNode.generate(self) self.startSmooth() def disable(self): if self.suitTrack != None: self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.stopSmooth() self.suitFSM.requestFinalState() self.suitFSM = None self.suitState2stateIndex = None self.stateIndex2suitState = None self.anim = None self.state = None self.health = None self.type = None self.team = None self.head = None self.skeleton = None self.battle = None Suit.disable(self) DistributedAvatar.disable(self) def delete(self): Suit.delete(self) DistributedAvatar.delete(self) DistributedSmoothNode.delete(self)
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 Suit(Avatar.Avatar): healthColors = (Vec4(0, 1, 0, 1), Vec4(1, 1, 0, 1), Vec4(1, 0.5, 0, 1), Vec4(1, 0, 0, 1), Vec4(0.3, 0.3, 0.3, 1)) healthGlowColors = (Vec4(0.25, 1, 0.25, 0.5), Vec4(1, 1, 0.25, 0.5), Vec4(1, 0.5, 0.25, 0.5), Vec4(1, 0.25, 0.25, 0.5), Vec4(0.3, 0.3, 0.3, 0)) medallionColors = {'c': Vec4(0.863, 0.776, 0.769, 1.0), 's': Vec4(0.843, 0.745, 0.745, 1.0), 'l': Vec4(0.749, 0.776, 0.824, 1.0), 'm': Vec4(0.749, 0.769, 0.749, 1.0)} health2DmgMultiplier = 2.5 def __init__(self): try: self.Suit_initialized return except: self.Suit_initialized = 1 Avatar.Avatar.__init__(self) self.avatarType = CIGlobals.Suit self.name = '' self.chat = '' self.suit = None self.suitHeads = None self.suitHead = None self.loserSuit = None self.healthBarGlow = None self.healthBar = None self.weapon = None self.weapon_sfx = None self.anim = None self.suit_dial = None self.shadow = None self.balloon_sfx = None self.add_sfx = None self.explosion = None self.largeExp = None self.smallExp = None self.death_sfx = None self.attack = None self.wtrajectory = None self.throwObjectId = None self.hasSpawned = False self.suitTrack = None self.headModel = None self.condition = 0 self.type = "" self.head = "" self.team = "" self.isSkele = 0 self.timestampAnimTrack = None self.animFSM = ClassicFSM('Suit', [State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('walk', self.enterWalk, self.exitWalk), State('die', self.enterDie, self.exitDie), State('attack', self.enterAttack, self.exitAttack), State('flydown', self.enterFlyDown, self.exitFlyDown), State('pie', self.enterPie, self.exitPie), State('win', self.enterWin, self.exitWin), State('flyaway', self.enterFlyAway, self.exitFlyAway), State('rollodex', self.enterRollodex, self.exitRollodex), State('flyNeutral', self.enterFlyNeutral, self.exitFlyNeutral), State('flail', self.enterFlail, self.exitFlail), State('drop', self.enterDrop, self.exitDrop), State('drop-react', self.enterDropReact, self.exitDropReact), State('squirt-large', self.enterLSquirt, self.exitLSquirt), State('squirt-small', self.enterSSquirt, self.exitSSquirt), State('soak', self.enterSoak, self.exitSoak)], 'off', 'off') animStateList = self.animFSM.getStates() self.animFSM.enterInitialState() self.initializeBodyCollisions() def delete(self): try: self.Suit_deleted except: self.Suit_deleted = 1 Avatar.Avatar.delete(self) self.weapon = None self.weapon_sfx = None self.suit_dial = None del self.shadowPlacer def disable(self): if self.suitTrack: self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.animFSM.requestFinalState() self.cleanupSuit() self.animFSM = None self.avatarType = None self.name = None self.chat = None self.suit = None self.state = None self.weapon_state = None self.suitHeads = None self.suitHead = None self.loserSuit = None self.healthMeterGlow = None self.healthMeter = None self.weapon = None self.weapon_sfx = None self.anim = None self.suit_dial = None self.shadow = None self.balloon_sfx = None self.add_sfx = None self.explosion = None self.largeExp = None self.smallExp = None self.death_sfx = None self.attack = None self.wtrajectory = None self.throwObjectId = None self.hasSpawned = None self.suitTrack = None self.headModel = None self.condition = None self.type = None self.head = None self.team = None self.isSkele = None self.timestampAnimTrack = None Avatar.Avatar.disable(self) def generateSuit(self, suitType, suitHead, suitTeam, suitHealth, skeleton, hideFirst = True): self.type = suitType self.head = suitHead self.isSkele = skeleton self.team = suitTeam self.health = suitHealth self.maxHealth = suitHealth self.cleanupSuit() self.generateBody(suitType, suitTeam, suitHead, skeleton) self.generateHealthMeter() self.generateHead(suitType, suitHead) #self.setupNameTag() self.parentSuitParts() self.rescaleSuit() Avatar.Avatar.initShadow(self) if hideFirst: self.hide() def rescaleSuit(self): self.setAvatarScale(CIGlobals.SuitScales[self.head] / CIGlobals.SuitScaleFactors[self.type]) def parentSuitParts(self): if not self.isSkele: self.headModel.reparentTo(self.find('**/joint_head')) def unparentSuitParts(self): self.getPart('body').reparentTo(self.getGeomNode()) if not self.isSkele: self.headModel.reparentTo(self.getGeomNode()) def generateBody(self, suitType, suitTeam, suitHead, skeleton): self.team = suitTeam self.type = suitType self.head = suitHead self.isSkele = skeleton if suitType == "A": if skeleton: self.loadModel("phase_5/models/char/cogA_robot-zero.bam", "body") else: self.loadModel("phase_3.5/models/char/suitA-mod.bam", "body") self.loadAnims({"neutral": "phase_4/models/char/suitA-neutral.bam", "walk": "phase_4/models/char/suitA-walk.bam", "pie": "phase_4/models/char/suitA-pie-small.bam", "land": "phase_5/models/char/suitA-landing.bam", "throw-object": "phase_5/models/char/suitA-throw-object.bam", "throw-paper": "phase_5/models/char/suitA-throw-paper.bam", "glower": "phase_5/models/char/suitA-glower.bam", "win": "phase_4/models/char/suitA-victory.bam", "rollodex": "phase_5/models/char/suitA-roll-o-dex.bam", "pickpocket": "phase_5/models/char/suitA-pickpocket.bam", "fountainpen": "phase_7/models/char/suitA-fountain-pen.bam", "phone": "phase_5/models/char/suitA-phone.bam", "flail": "phase_4/models/char/suitA-flailing.bam", "drop" : "phase_5/models/char/suitA-drop.bam", "drop-react" : "phase_5/models/char/suitA-anvil-drop.bam", "squirt-large" : "phase_5/models/char/suitA-squirt-large.bam", "squirt-small" : "phase_4/models/char/suitA-squirt-small.bam", "slip-forward" : "phase_4/models/char/suitA-slip-forward.bam", "slip-backward" : "phase_4/models/char/suitA-slip-backward.bam", "sit": "phase_12/models/char/suitA-sit.bam", "speak": "phase_5/models/char/suitA-speak.bam", "fingerwag": "phase_5/models/char/suitA-fingerwag.bam", "soak" : "phase_5/models/char/suitA-soak.bam"}, "body") if suitType == "B": if skeleton: self.loadModel("phase_5/models/char/cogB_robot-zero.bam", "body") else: self.loadModel("phase_3.5/models/char/suitB-mod.bam", "body") self.loadAnims({"neutral": "phase_4/models/char/suitB-neutral.bam", "walk": "phase_4/models/char/suitB-walk.bam", "pie": "phase_4/models/char/suitB-pie-small.bam", "land": "phase_5/models/char/suitB-landing.bam", "throw-object": "phase_5/models/char/suitB-throw-object.bam", "throw-paper": "phase_5/models/char/suitB-throw-paper.bam", "glower": "phase_5/models/char/suitB-magic1.bam", "win": "phase_4/models/char/suitB-victory.bam", "rollodex": "phase_5/models/char/suitB-roll-o-dex.bam", "pickpocket": "phase_5/models/char/suitB-pickpocket.bam", "fountainpen": "phase_5/models/char/suitB-pen-squirt.bam", "phone": "phase_5/models/char/suitB-phone.bam", "flail": "phase_4/models/char/suitB-flailing.bam", "drop" : "phase_5/models/char/suitB-drop.bam", "drop-react" : "phase_5/models/char/suitB-anvil-drop.bam", "squirt-large" : "phase_5/models/char/suitB-squirt-large.bam", "squirt-small" : "phase_4/models/char/suitB-squirt-small.bam", "slip-forward" : "phase_4/models/char/suitB-slip-forward.bam", "slip-backward" : "phase_4/models/char/suitB-slip-backward.bam", "speak": "phase_5/models/char/suitB-speak.bam", "fingerwag": "phase_5/models/char/suitB-finger-wag.bam", "soak" : "phase_5/models/char/suitB-soak.bam"}, "body") if suitType == "C": if skeleton: self.loadModel("phase_5/models/char/cogC_robot-zero.bam", "body") else: self.loadModel("phase_3.5/models/char/suitC-mod.bam", "body") self.loadAnims({"neutral": "phase_3.5/models/char/suitC-neutral.bam", "walk": "phase_3.5/models/char/suitC-walk.bam", "pie": "phase_3.5/models/char/suitC-pie-small.bam", "land": "phase_5/models/char/suitC-landing.bam", "throw-object": "phase_3.5/models/char/suitC-throw-paper.bam", "throw-paper": "phase_3.5/models/char/suitC-throw-paper.bam", "glower": "phase_5/models/char/suitC-glower.bam", "win": "phase_4/models/char/suitC-victory.bam", "pickpocket": "phase_5/models/char/suitC-pickpocket.bam", "fountainpen": "phase_5/models/char/suitC-fountain-pen.bam", "phone": "phase_3.5/models/char/suitC-phone.bam", "flail": "phase_4/models/char/suitC-flailing.bam", "drop" : "phase_5/models/char/suitC-drop.bam", "drop-react" : "phase_5/models/char/suitC-anvil-drop.bam", "squirt-large" : "phase_5/models/char/suitC-squirt-large.bam", "squirt-small" : "phase_3.5/models/char/suitC-squirt-small.bam", "slip-forward" : "phase_4/models/char/suitC-slip-forward.bam", "slip-backward" : "phase_4/models/char/suitC-slip-backward.bam", "sit": "phase_12/models/char/suitC-sit.bam", "speak": "phase_5/models/char/suitC-speak.bam", "fingerwag": "phase_5/models/char/suitC-finger-wag.bam", "soak" : "phase_5/models/char/suitC-soak.bam"}, "body") if skeleton: self.setTwoSided(1) if skeleton: if suitTeam == "s": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_sales.jpg") elif suitTeam == "m": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_money.jpg") elif suitTeam == "l": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_legal.jpg") elif suitTeam == "c": self.suit_tie = loader.loadTexture("phase_5/maps/cog_robot_tie_boss.jpg") self.find('**/tie').setTexture(self.suit_tie, 1) else: if hasattr(self, 'getBattle') and self.getBattle() != None: if self.getBattle().getHoodIndex() == CogBattleGlobals.WaiterHoodIndex: self.suit_blazer = loader.loadTexture("phase_3.5/maps/waiter_m_blazer.jpg") self.suit_leg = loader.loadTexture("phase_3.5/maps/waiter_m_leg.jpg") self.suit_sleeve = loader.loadTexture("phase_3.5/maps/waiter_m_sleeve.jpg") if not hasattr(self, 'getBattle') or self.getBattle() == None or self.getBattle().getHoodIndex() != CogBattleGlobals.WaiterHoodIndex: self.suit_blazer = loader.loadTexture("phase_3.5/maps/" + suitTeam + "_blazer.jpg") self.suit_leg = loader.loadTexture("phase_3.5/maps/" + suitTeam + "_leg.jpg") self.suit_sleeve = loader.loadTexture("phase_3.5/maps/" + suitTeam + "_sleeve.jpg") self.find('**/legs').setTexture(self.suit_leg, 1) self.find('**/arms').setTexture(self.suit_sleeve, 1) self.find('**/torso').setTexture(self.suit_blazer, 1) if suitHead == "coldcaller": self.find('**/hands').setColor(0.55, 0.65, 1.0, 1.0) elif suitHead == "corporateraider": self.find('**/hands').setColor(0.85, 0.55, 0.55, 1.0) elif suitHead == "bigcheese": self.find('**/hands').setColor(0.75, 0.95, 0.75, 1.0) elif suitHead == "bloodsucker": self.find('**/hands').setColor(0.95, 0.95, 1.0, 1.0) elif suitHead == "spindoctor": self.find('**/hands').setColor(0.5, 0.8, 0.75, 1.0) elif suitHead == "legaleagle": self.find('**/hands').setColor(0.25, 0.25, 0.5, 1.0) elif suitHead == "pennypincher": self.find('**/hands').setColor(1.0, 0.5, 0.6, 1.0) elif suitHead == "loanshark": self.find('**/hands').setColor(0.5, 0.85, 0.75, 1.0) else: self.find('**/hands').setColor(CIGlobals.SuitHandColors[suitTeam]) def generateHead(self, suitType, suitHead): self.type = suitType self.head = suitHead if suitHead == "vp": self.headModel = Actor("phase_9/models/char/sellbotBoss-head-zero.bam") self.headModel.loadAnims({"neutral": "phase_9/models/char/bossCog-head-Ff_neutral.bam"}) self.headModel.setTwoSided(True) self.headModel.loop("neutral") self.headModel.setScale(0.35) self.headModel.setHpr(270, 0, 270) self.headModel.setZ(-0.10) else: if suitType == "A" or suitType == "B": heads = loader.loadModel("phase_4/models/char/suit" + suitType + "-heads.bam") else: heads = loader.loadModel("phase_3.5/models/char/suit" + suitType + "-heads.bam") self.headModel = heads.find('**/' + CIGlobals.SuitHeads[suitHead]) if suitHead == "flunky": glasses = heads.find('**/glasses') glasses.reparentTo(self.headModel) glasses.setTwoSided(True) if suitHead in CIGlobals.SuitSharedHeads: if suitHead == "coldcaller": self.headModel.setColor(0.25, 0.35, 1.0, 1.0) else: headTexture = loader.loadTexture("phase_3.5/maps/" + suitHead + ".jpg") self.headModel.setTexture(headTexture, 1) def cleanupSuit(self): self.removeHealthBar() if 'body' in self._Actor__commonBundleHandles: del self._Actor__commonBundleHandles['body'] if self.shadow: self.deleteShadow() if self.headModel: self.headModel.removeNode() self.headModel = None if self.getPart('body'): self.removePart('body') def setName(self, nameString, charName): Avatar.Avatar.setName(self, nameString, avatarType=self.avatarType, charName=charName, createNow = 1) def setupNameTag(self): Avatar.Avatar.setupNameTag(self) self.nameTag.setText(self.nameTag.getText() + "\nLevel %d" % self.level) def setChat(self, chatString): self.chat = chatString if self.isSkele: if "?" in chatString: self.suit_dial = base.audio3d.loadSfx("phase_5/audio/sfx/Skel_COG_VO_question.ogg") elif "!" in chatString: self.suit_dial = base.audio3d.loadSfx("phase_5/audio/sfx/Skel_COG_VO_grunt.ogg") else: self.suit_dial = base.audio3d.loadSfx("phase_5/audio/sfx/Skel_COG_VO_statement.ogg") elif self.head in ["vp"]: if "?" in chatString: self.suit_dial = base.audio3d.loadSfx("phase_9/audio/sfx/Boss_COG_VO_question.ogg") elif "!" in chatString: self.suit_dial = base.audio3d.loadSfx("phase_9/audio/sfx/Boss_COG_VO_grunt.ogg") else: self.suit_dial = base.audio3d.loadSfx("phase_9/audio/sfx/Boss_COG_VO_statement.ogg") else: if "?" in chatString: self.suit_dial = base.audio3d.loadSfx( random.choice( [ "phase_3.5/audio/dial/COG_VO_question.ogg", "phase_3.5/audio/dial/COG_VO_question_2.ogg" ] ) ) elif "!" in chatString: self.suit_dial = base.audio3d.loadSfx("phase_3.5/audio/dial/COG_VO_grunt.ogg") else: self.suit_dial = base.audio3d.loadSfx("phase_3.5/audio/dial/COG_VO_statement.ogg") if self.isSkele: base.audio3d.attachSoundToObject(self.suit_dial, self) else: base.audio3d.attachSoundToObject(self.suit_dial, self.headModel) self.suit_dial.play() Avatar.Avatar.setChat(self, chatString) def generateHealthMeter(self): self.removeHealthBar() model = loader.loadModel("phase_3.5/models/gui/matching_game_gui.bam") button = model.find('**/minnieCircle') button.setScale(3.0) button.setH(180) button.setColor(self.healthColors[0]) chestNull = self.find('**/def_joint_attachMeter') if chestNull.isEmpty(): chestNull = self.find('**/joint_attachMeter') button.reparentTo(chestNull) self.healthBar = button glow = loader.loadModel("phase_3.5/models/props/glow.bam") glow.reparentTo(self.healthBar) glow.setScale(0.28) glow.setPos(-0.005, 0.01, 0.015) glow.setColor(self.healthGlowColors[0]) button.flattenLight() self.healthBarGlow = glow self.condition = 0 if hasattr(self, 'getHealth'): self.updateHealthBar(self.getHealth()) def updateHealthBar(self, hp): if not self.healthBar: return if hp > self.health: self.health = hp #self.health -= hp health = 0.0 try: health = float(hp) / float(self.maxHealth) except: pass if health > 0.95: condition = 0 elif health > 0.7: condition = 1 elif health > 0.3: condition = 2 elif health > 0.05: condition = 3 elif health > 0.0: condition = 4 else: condition = 5 if self.condition != condition: if condition == 4: blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) elif condition == 5: if self.condition == 4: taskMgr.remove(self.taskName('blink-task')) blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) else: self.healthBar.setColor(self.healthColors[condition], 1) self.healthBarGlow.setColor(self.healthGlowColors[condition], 1) self.condition = condition def __blinkRed(self, task): self.healthBar.setColor(self.healthColors[3], 1) self.healthBarGlow.setColor(self.healthGlowColors[3], 1) if self.condition == 5: self.healthBar.setScale(1.17) return Task.done def __blinkGray(self, task): if not self.healthBar: return self.healthBar.setColor(self.healthColors[4], 1) self.healthBarGlow.setColor(self.healthGlowColors[4], 1) if self.condition == 5: self.healthBar.setScale(1.0) return Task.done def removeHealthBar(self): if self.healthBar: self.healthBar.removeNode() self.healthBar = None if self.condition == 4 or self.condition == 5: taskMgr.remove(self.taskName('blink-task')) self.healthCondition = 0 return def enterOff(self, ts = 0): self.anim = None return def exitOff(self): pass def exitGeneral(self): self.stop() def enterFlail(self, ts = 0): self.pingpong("flail", fromFrame = 30, toFrame = 35) def exitFlail(self): self.stop() def enterNeutral(self, ts = 0): self.show() self.timestampAnimTrack = Sequence(Wait(ts), Func(self.loop, "neutral")) self.timestampAnimTrack.start() def exitNeutral(self): self.timestampAnimTrack.pause() self.timestampAnimTrack = None self.exitGeneral() def enterRollodex(self, ts = 0): self.play("rollodex") def exitRollodex(self): self.exitGeneral() def enterWalk(self, ts = 0): self.show() self.timestampAnimTrack = Sequence(Wait(ts), Func(self.loop, "walk")) self.timestampAnimTrack.start() self.disableShadowRay() def exitWalk(self): self.timestampAnimTrack.pause() self.timestampAnimTrack = None self.exitGeneral() self.enableShadowRay() def __moveSuitUpForDropAnim(self): self.getGeomNode().setZ(0.5) def __moveSuitDownToNormal(self): self.getGeomNode().setZ(0) def enterDrop(self, ts = 0): self.suitTrack = Parallel( ActorInterval(self, 'drop')#, #Sequence(Wait(0.1), Func(self.__moveSuitUpForDropAnim), Wait(2.7), Func(self.__moveSuitDownToNormal)) ) self.suitTrack.start() def exitDrop(self): if self.suitTrack: self.suitTrack.finish() self.suitTrack = None def enterDropReact(self, ts = 0): self.play('drop-react') def exitDropReact(self): self.stop() def enterSSquirt(self, ts = 0): self.play('squirt-small') def exitSSquirt(self): self.stop() def enterLSquirt(self, ts = 0): self.play('squirt-large') def exitLSquirt(self): self.stop() def enterSoak(self, ts = 0): self.play('soak') def exitSoak(self): self.stop() def generateLoserSuit(self): if not self.isSkele: handColor = self.find('**/hands').getColor() self.cleanupSuit() if self.type == "A": if self.isSkele: self.loadModel("phase_5/models/char/cogA_robot-lose-mod.bam", 'body') else: self.loadModel("phase_4/models/char/suitA-lose-mod.bam", 'body') self.loadAnims({"lose": "phase_4/models/char/suitA-lose.bam"}, 'body') if self.type == "B": if self.isSkele: self.loadModel("phase_5/models/char/cogB_robot-lose-mod.bam", 'body') else: self.loadModel("phase_4/models/char/suitB-lose-mod.bam", 'body') self.loadAnims({"lose": "phase_4/models/char/suitB-lose.bam"}, 'body') if self.type == "C": if self.isSkele: self.loadModel("phase_5/models/char/cogC_robot-lose-mod.bam", 'body') else: self.loadModel("phase_3.5/models/char/suitC-lose-mod.bam", 'body') self.loadAnims({"lose": "phase_3.5/models/char/suitC-lose.bam"}, 'body') if self.isSkele: self.find('**/tie').setTexture(self.suit_tie, 1) self.setTwoSided(1) else: self.find('**/hands').setColor(handColor) self.find('**/legs').setTexture(self.suit_leg, 1) self.find('**/arms').setTexture(self.suit_sleeve, 1) self.find('**/torso').setTexture(self.suit_blazer, 1) self.generateHead(self.type, self.head) self.rescaleSuit() self.parentSuitParts() self.deleteNameTag() Avatar.Avatar.initShadow(self) def enterDie(self, ts = 0): self.show() self.generateLoserSuit() self.clearChat() self.state = "dead" self.play("lose") deathSound = base.audio3d.loadSfx("phase_3.5/audio/sfx/Cog_Death_Full.ogg") base.audio3d.attachSoundToObject(deathSound, self) trackName = self.uniqueName('enterDie') smallGears = ParticleLoader.loadParticleEffect('phase_3.5/etc/gearExplosionSmall.ptf') smallGears.getParticlesNamed('particles-1').setPoolSize(30) singleGear = ParticleLoader.loadParticleEffect('phase_3.5/etc/gearExplosion.ptf') singleGear.getParticlesNamed('particles-1').setPoolSize(1) smallGearExplosion = ParticleLoader.loadParticleEffect('phase_3.5/etc/gearExplosion.ptf') smallGearExplosion.getParticlesNamed('particles-1').setPoolSize(10) bigGearExplosion = ParticleLoader.loadParticleEffect('phase_3.5/etc/gearExplosionBig.ptf') bigGearExplosion.getParticlesNamed('particles-1').setPoolSize(30) smallGears.setDepthWrite(False) singleGear.setDepthWrite(False) smallGearExplosion.setDepthWrite(False) bigGearExplosion.setDepthWrite(False) self.smallGears = smallGears self.smallGears.setPos(self.find('**/joint_head').getPos() + (0,0, 2)) self.singleGear = singleGear self.smallGearExp = smallGearExplosion self.bigGearExp = bigGearExplosion gearTrack = Sequence(Wait(0.7), Func(self.doSingleGear), Wait(1.5), Func(self.doSmallGears), Wait(3.0), Func(self.doBigExp)) self.suitTrack = Parallel(Sequence(Wait(0.7), Func(self.doSingleGear), Wait(4.3), Func(self.suitExplode), Wait(1.0), Func(self.delSuit)), gearTrack, name = trackName) self.suitTrack.setDoneEvent(self.suitTrack.getName()) Sequence(Wait(0.8), SoundInterval(deathSound)).start() self.acceptOnce(self.suitTrack.getName(), self.exitDie) if "Distributed" in self.__class__.__name__: self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, trackName) self.suitTrack.start(ts) del deathSound def doSingleGear(self): self.singleGear.start(self.getGeomNode()) def doSmallGears(self): self.smallGears.start(self.getGeomNode()) def doSmallExp(self): self.smallGearExp.start(self.getGeomNode()) def doBigExp(self): self.bigGearExp.start(self.getGeomNode()) def suitExplode(self): self.explosion = loader.loadModel("phase_3.5/models/props/explosion.bam") self.explosion.setScale(0.5) self.explosion.reparentTo(render) self.explosion.setBillboardPointEye() self.explosion.setDepthWrite(False) if self.isSkele: self.explosion.setPos(self.getPart("body").find('**/joint_head').getPos(render) + (0, 0, 2)) else: self.explosion.setPos(self.headModel.getPos(render) + (0,0,2)) def delSuit(self): self.disableBodyCollisions() def exitDie(self): if self.suitTrack != None: self.ignore(self.suitTrack.getName()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None if hasattr(self, 'singleGear'): self.singleGear.cleanup() del self.singleGear if hasattr(self, 'smallGears'): self.smallGears.cleanup() del self.smallGears if hasattr(self, 'smallGearExp'): self.smallGearExp.cleanup() del self.smallGearExp if hasattr(self, 'bigGearExp'): self.bigGearExp.cleanup() del self.bigGearExp if self.explosion: self.explosion.removeNode() self.explosion = None def enterFlyNeutral(self, ts = 0): self.disableRay() self.sfx = base.audio3d.loadSfx("phase_4/audio/sfx/TB_propeller.ogg") self.prop = Actor("phase_4/models/props/propeller-mod.bam", {"chan": "phase_4/models/props/propeller-chan.bam"}) base.audio3d.attachSoundToObject(self.sfx, self.prop) self.prop.reparentTo(self.find('**/joint_head')) self.sfx.setLoop(True) self.sfx.play() self.prop.loop('chan', fromFrame = 0, toFrame = 3) self.setPlayRate(0.8, 'land') self.pingpong('land', fromFrame = 0, toFrame = 10) def exitFlyNeutral(self): self.prop.cleanup() del self.prop base.audio3d.detachSound(self.sfx) del self.sfx self.stop() def enterFlyDown(self, ts = 0): self.disableRay() self.fd_sfx = base.audio3d.loadSfx("phase_5/audio/sfx/ENC_propeller_in.ogg") self.prop = Actor("phase_4/models/props/propeller-mod.bam", {"chan": "phase_4/models/props/propeller-chan.bam"}) base.audio3d.attachSoundToObject(self.fd_sfx, self.prop) self.prop.reparentTo(self.find('**/joint_head')) self.fd_sfx.play() dur = self.getDuration('land') if hasattr(self, 'uniqueName'): name = self.uniqueName('enterFlyDown') else: name = 'enterFlyDown' self.suitTrack = Parallel(Sequence(Func(self.pose, 'land', 0), Func(self.prop.loop, 'chan', fromFrame=0, toFrame=3), Wait(1.75), Func(self.prop.play, 'chan', fromFrame=3), Wait(0.15), ActorInterval(self, 'land', duration=dur)), name = name) if not self.hasSpawned: showSuit = Sequence(Func(self.hideSuit), Wait(0.3), Func(self.showSuit)) self.hasSpawned = True self.suitTrack.append(showSuit) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyAway) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name) self.suitTrack.start(ts) def hideSuit(self): self.hide() def showSuit(self): self.show() fadeIn = Sequence(Func(self.setTransparency, 1), self.colorScaleInterval(0.6, colorScale=Vec4(1,1,1,1), startColorScale=Vec4(1,1,1,0)), Func(self.clearColorScale), Func(self.clearTransparency), Func(self.reparentTo, render)) fadeIn.start() def initializeLocalCollisions(self, name): Avatar.Avatar.initializeLocalCollisions(self, 1, 3, name) def initializeBodyCollisions(self): Avatar.Avatar.initializeBodyCollisions(self, self.avatarType, 6, 2) self.initializeRay(self.avatarType, 2) def exitFlyDown(self): self.initializeRay(self.avatarType, 2) if self.suitTrack != None: self.ignore(self.suitTrack.getDoneEvent()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None if hasattr(self, 'fd_sfx'): base.audio3d.detachSound(self.fd_sfx) self.exitGeneral() if self.prop: self.prop.cleanup() self.prop = None def enterFlyAway(self, ts = 0): self.show() self.fa_sfx = base.audio3d.loadSfx("phase_5/audio/sfx/ENC_propeller_out.ogg") self.prop = Actor("phase_4/models/props/propeller-mod.bam", {"chan": "phase_4/models/props/propeller-chan.bam"}) base.audio3d.attachSoundToObject(self.fa_sfx, self.prop) self.fa_sfx.play() self.prop.reparentTo(self.find('**/joint_head')) self.prop.setPlayRate(-1.0, "chan") if hasattr(self, 'uniqueName'): name = self.uniqueName('enterFlyAway') else: name = 'enterFlyAway' self.suitTrack = Sequence(Func(self.prop.play, 'chan', fromFrame=3), Wait(1.75), Func(self.prop.play, 'chan', fromFrame=0, toFrame=3), name = name) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyAway) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name) self.suitTrack.start(ts) self.setPlayRate(-1.0, 'land') self.play('land') def exitFlyAway(self): if self.suitTrack: self.ignore(self.suitTrack.getDoneEvent()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None if hasattr(self, 'fa_sfx'): base.audio3d.detachSound(self.fa_sfx) self.exitGeneral() if self.prop: self.prop.cleanup() self.prop = None def enterAttack(self, attack, target, ts = 0): self.show() if hasattr(self, 'uniqueName'): doneEvent = self.uniqueName('suitAttackDone') else: doneEvent = 'suitAttackDone' self.suitAttackState = SuitAttacks(doneEvent, self, target) self.suitAttackState.load(attack) self.suitAttackState.enter(ts) self.acceptOnce(doneEvent, self.handleSuitAttackDone) def handleSuitAttackDone(self): self.exitAttack() def exitAttack(self): if hasattr(self, 'uniqueName'): self.ignore(self.uniqueName('suitAttackDone')) else: self.ignore('suitAttackDone') if hasattr(self, 'suitAttackState'): self.suitAttackState.exit() if hasattr(self, 'suitAttackState'): self.suitAttackState.unload() if hasattr(self, 'suitAttackState'): del self.suitAttackState def interruptAttack(self): if hasattr(self, 'suitAttackState'): self.suitAttackState.currentAttack.interruptAttack() def handleWeaponTouch(self): if hasattr(self, 'suitAttackState'): self.suitAttackState.currentAttack.handleWeaponTouch() def enterPie(self, ts = 0): self.show() self.play("pie") def exitPie(self): self.exitGeneral() def enterWin(self, ts = 0): self.play("win") def exitWin(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()