from direct.actor.DistributedActor import DistributedActor from direct.distributed import DistributedNode from direct.interval.IntervalGlobal import * from direct.showbase import PythonUtil from direct.task import Task from panda3d.core import * from Avatar import Avatar from otp.ai.MagicWordGlobal import * from otp.otpbase import OTPGlobals from toontown.battle.BattleProps import globalPropPool from otp.nametag.Nametag import Nametag class DistributedAvatar(DistributedActor, Avatar): HpTextGenerator = TextNode('HpTextGenerator') HpTextEnabled = 1 ManagesNametagAmbientLightChanged = True def __init__(self, cr): try: self.DistributedAvatar_initialized return except: self.DistributedAvatar_initialized = 1 Avatar.__init__(self) DistributedActor.__init__(self, cr) self.hpText = None self.hp = None self.maxHp = None return def disable(self): try: del self.DistributedAvatar_announced except: return self.reparentTo(hidden) self.removeActive() self.disableBodyCollisions() self.hideHpText() self.hp = None self.ignore('nameTagShowAvId') self.ignore('nameTagShowName') DistributedActor.disable(self) return def delete(self): try: self.DistributedAvatar_deleted except: self.DistributedAvatar_deleted = 1 Avatar.delete(self) DistributedActor.delete(self) def generate(self): DistributedActor.generate(self) if not self.isLocal(): self.addActive() self.considerUnderstandable() self.setParent(OTPGlobals.SPHidden) self.setTag('avatarDoId', str(self.doId)) self.accept('nameTagShowAvId', self.__nameTagShowAvId) self.accept('nameTagShowName', self.__nameTagShowName) def announceGenerate(self): try: self.DistributedAvatar_announced return except: self.DistributedAvatar_announced = 1 if not self.isLocal(): self.initializeBodyCollisions('distAvatarCollNode-' + str(self.doId)) DistributedActor.announceGenerate(self) def __setTags(self, extra = None): if hasattr(base, 'idTags'): if base.idTags: self.__nameTagShowAvId() else: self.__nameTagShowName() def do_setParent(self, parentToken): if not self.isDisabled(): if parentToken == OTPGlobals.SPHidden: self.nametag2dDist &= ~Nametag.CName else: self.nametag2dDist |= Nametag.CName self.nametag.getNametag2d().setContents(self.nametag2dContents & self.nametag2dDist) DistributedActor.do_setParent(self, parentToken) self.__setTags() def toonUp(self, hpGained): if self.hp == None or hpGained < 0: return oldHp = self.hp if self.hp + hpGained <= 0: self.hp += hpGained else: self.hp = min(max(self.hp, 0) + hpGained, self.maxHp) hpGained = self.hp - max(oldHp, 0) if hpGained > 0: self.showHpText(hpGained) self.hpChange(quietly=0) return def takeDamage(self, hpLost, bonus = 0): if self.hp == None or hpLost < 0: return oldHp = self.hp self.hp = max(self.hp - hpLost, 0) hpLost = oldHp - self.hp if hpLost > 0: self.showHpText(-hpLost, bonus) self.hpChange(quietly=0) if self.hp <= 0 and oldHp > 0: self.died() return def setHp(self, hitPoints): justRanOutOfHp = (hitPoints is not None and self.hp is not None and self.hp - hitPoints > 0) and (hitPoints <= 0) self.hp = hitPoints self.hpChange(quietly=1) if justRanOutOfHp: self.died() return def hpChange(self, quietly = 0): if (not hasattr(self, 'doId')) or self.hp == None: return if self.maxHp != None: messenger.send(self.uniqueName('hpChange'), [self.hp, self.maxHp, quietly]) if self.hp > 0: messenger.send(self.uniqueName('positiveHP')) def died(self): pass def getHp(self): return self.hp def setMaxHp(self, hitPoints): self.maxHp = hitPoints self.hpChange() def getMaxHp(self): return self.maxHp def getName(self): return Avatar.getName(self) def setName(self, name): try: self.node().setName('%s-%d' % (name, self.doId)) self.gotName = 1 except: pass return Avatar.setName(self, name) def showHpText(self, number, bonus = 0, scale = 1): if self.HpTextEnabled and not self.ghostMode: if number != 0: if self.hpText: self.hideHpText() self.HpTextGenerator.setFont(OTPGlobals.getSignFont()) if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText('+' + str(number)) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) if bonus == 1: r = 1.0 g = 1.0 b = 0 a = 1 elif bonus == 2: r = 1.0 g = 0.5 b = 0 a = 1 elif number < 0: r = 0.9 g = 0 b = 0 a = 1 else: r = 0 g = 0.9 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = self.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(0, 0, self.height / 2) seq = Sequence(self.hpText.posInterval(1.0, Point3(0, 0, self.height + 1.5), blendType='easeOut'), Wait(0.85), self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)), Func(self.hideHpText)) seq.start() def showHpString(self, text, duration = 0.85, scale = 0.7): if self.HpTextEnabled and not self.ghostMode: if text != '': if self.hpText: self.hideHpText() self.HpTextGenerator.setFont(OTPGlobals.getSignFont()) self.HpTextGenerator.setText(text) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = a = 1.0 g = b = 0.0 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = self.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardAxis() self.hpText.setPos(0, 0, self.height / 2) seq = Sequence(self.hpText.posInterval(1.0, Point3(0, 0, self.height + 1.5), blendType='easeOut'), Wait(duration), self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)), Func(self.hideHpText)) seq.start() def hideHpText(self): if self.hpText: taskMgr.remove(self.uniqueName('hpText')) self.hpText.removeNode() self.hpText = None return def getStareAtNodeAndOffset(self): return (self, Point3(0, 0, self.height)) def getAvIdName(self): return '%s\n%s' % (self.getName(), self.doId) def __nameTagShowAvId(self, extra = None): self.setDisplayName(self.getAvIdName()) def __nameTagShowName(self, extra = None): self.setDisplayName(self.getName()) def askAvOnShard(self, avId): if base.cr.doId2do.get(avId): messenger.send('AvOnShard%s' % avId, [True]) else: self.sendUpdate('checkAvOnShard', [avId]) def confirmAvOnShard(self, avId, onShard = True): messenger.send('AvOnShard%s' % avId, [onShard]) def getDialogueArray(self): return None @magicWord(category=CATEGORY_COMMUNITY_MANAGER) def warp(): """ warp the target to the invoker's current position, and rotation. """ invoker = spellbook.getInvoker() target = spellbook.getTarget() if invoker.doId == target.doId: return "You can't warp yourself!" target.setPosHpr(invoker.getPos(), invoker.getHpr()) @magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[str]) def loop(anim): """ animate the target using animation [anim] on the entire actor. """ target = spellbook.getTarget() target.loop(anim) @magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[str, int, str]) def pose(anim, frame, part=None): """ freeze the target on frame [frame] of animation [anim] on the entire actor, or optional [part] of the actor. """ target = spellbook.getTarget() target.pose(anim, frame, partName=part) @magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[str, int, int, str]) def pingpong(anim, start=None, end=None, part=None): """ animate the target by bouncing back and forth between the start and end, or the optional frames , and [end] of animation [anim] on the entire actor, or optional of the actor. """ target = spellbook.getTarget() target.pingpong(anim, partName=part, fromFrame=start, toFrame=end) @magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[str]) def rightHand(prop=None): """ parents the optional to the target's right hand node. """ target = spellbook.getTarget() rightHand = target.find('**/rightHand') if prop is None: for child in rightHand.getChildren(): child.removeNode() else: for child in rightHand.getChildren(): child.removeNode() requestedProp = globalPropPool.getProp(prop) requestedProp.reparentTo(rightHand) @magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[str]) def leftHand(prop=None): """ parents the optional to the target's left hand node. """ target = spellbook.getTarget() leftHand = target.find('**/leftHand') if prop is None: for child in leftHand.getChildren(): child.removeNode() else: for child in leftHand.getChildren(): child.removeNode() requestedProp = globalPropPool.getProp(prop) requestedProp.reparentTo(leftHand) @magicWord(category=CATEGORY_PROGRAMMER, types=[]) def getPos(): """ Return your target's position. """ return spellbook.getTarget().getPos() @magicWord(category=CATEGORY_PROGRAMMER, types=[int]) def setFov(fov=OTPGlobals.DefaultCameraFov): """ Set your field of view in-game. """ if fov == 0: return 'Cannot set FOV to 0!' base.camLens.setMinFov(fov/(4./3.)) if fov == OTPGlobals.DefaultCameraFov: return 'Set FOV to the default.' else: return 'Set FOV to %s.' % fov