def createToon(self): fields = { "ACCOUNT": self.accountId, "setDNAStrand": (str(self.choice[0]), ), "setName": (str(self.choice[2]), ), "setHealth": (100, ), "setMaxHealth": (100, ), "setMoney": (5000, ), "setBackpackAmmo": (GagGlobals.getDefaultBackpackNetString(True), ), "setLoadout": (GagGlobals.InitLoadout, ), # Start with cupcake and squirting flower. "setTrackExperience": (GagGlobals.trackExperienceToNetString( GagGlobals.DefaultTrackExperiences), ), "setAccessLevel": (AdminCommands.NoAccess, ), "setQuests": ("", ), "setQuestHistory": ([], ), "setTier": (13, ), "setFriendsList": ([], ), "setTutorialCompleted": (1, ), #self.choice[3],), "setHoodsDiscovered": ([ZoneUtil.ToontownCentralId], ), "setTeleportAccess": ([], ), "setLastHood": (ZoneUtil.ToontownCentralId, ), "setDefaultShard": (0, ) } self.notify.info("Creating new toon!") self.avList = self.accFields["AVATAR_IDS"] self.avList = self.avList[:6] self.avList += [0] * (6 - len(self.avList)) self.air.dbInterface.createObject( self.air.dbId, self.air.dclassesByName['DistributedPlayerToonUD'], fields, self.createDone)
def setTrackExperience(self, netString): self.trackExperience = GagGlobals.getTrackExperienceFromNetString( netString) if GagGlobals.processTrackData( self.trackExperience, self.backpack) and self == base.localAvatar: if base.localAvatar.invGui: base.localAvatar.reloadInvGui()
def addGag(self, gagId, curSupply=None, maxSupply=None): if isinstance(gagId, str): gagId = self.avatar.getAttackMgr().getAttackIDByName(gagId) gagName = self.avatar.getAttackMgr().getAttackName(gagId) # Make sure the gag is actually a registered attack and we # don't already have it in our backpack if not self.hasGag(gagId) and gagId in self.avatar.getAttackMgr( ).AttackClasses.keys(): if maxSupply is None: # Sets the max supply if one is not specified. maxSupply = GagGlobals.calculateMaxSupply( self.avatar, gagName, GagGlobals.getGagData(gagName)) # Sets the current supply to the max supply if current supply isn't # specified. if curSupply is None: curSupply = maxSupply gagData = GagGlobals.getGagData(gagName) attackCls = self.avatar.getAttackMgr().getAttackClassByID(gagId) if attackCls: attack = attackCls() attack.setAvatar(self.avatar) attack.setMaxAmmo(maxSupply) attack.setAmmo(curSupply) # ============================================================ # # Horrible hack until we start determining damage # based on the Gag's level. import types baseDamage = GagGlobals.calcBaseDamage( self.avatar, self.avatar.getAttackMgr().getAttackName(gagId), gagData) def getBaseDamage(self): return baseDamage attack.getBaseDamage = types.MethodType(getBaseDamage, attack) damageMaxDistance = float(gagData.get('distance', 10)) def getDamageMaxDistance(self): return damageMaxDistance attack.getDamageMaxDistance = types.MethodType( getDamageMaxDistance, attack) # ============================================================ # attack.load() self.avatar.attacks[gagId] = attack return True return False
def __getGagEffectOnMe(self, avId, gagName, gagData, damageInfo, isPlayer): """ Returns the base damage and the damage offset a specified gag name used by "avId" has on this Cog """ weaknessFactor = self.suitPlan.getGagWeaknesses().get(gagName, 1.0) classWeakness = self.suitPlan.getCogClassAttrs().getGagDmgRamp(GagGlobals.getTrackOfGag(gagName, isAI = True)) if isPlayer: baseDmg = GagGlobals.calculateDamage(avId, gagName, gagData) else: baseDmg = damageInfo.damageAmount dmgOffset = int(math.ceil(baseDmg * weaknessFactor * classWeakness)) - baseDmg return baseDmg, dmgOffset
class Sandbag(LightDropGag): name = GagGlobals.Sandbag model = GagGlobals.getProp('5', 'sandbag-mod') anim = GagGlobals.getProp('5', 'sandbag-chan') hitSfxPath = GagGlobals.BAG_DROP_SFX missSfxPath = GagGlobals.BAG_MISS_SFX def __init__(self): LightDropGag.__init__(self) self.setImage('phase_3.5/maps/sandbag.png') self.colliderRadius = 0.75
def handleHitByToon(self, player, gagId, distance): if self.isDead(): return gagName = base.cr.attackMgr.getAttackName(gagId) data = dict(GagGlobals.getGagData(gagName)) data['distance'] = distance baseDmg = GagGlobals.calculateDamage(player, gagName, data) hp = self.health - baseDmg self.setHealth(hp) self.announceHealth(0, baseDmg, -1) self.doDamageFade() if self.isDead(): self.doRagdollMode()
def buildFlower(self): if self.flower: self.flower.removeNode() self.flower = None self.flower = loader.loadModel( GagGlobals.getProp(3.5, 'squirting-flower')) self.flower.setScale(GagGlobals.PNT3NEAR0)
def getBackpackAmmo(self): if self.backpack: netString = self.backpack.toNetString() return netString else: defaultBackpack = GagGlobals.getDefaultBackpack(isAI=True) return defaultBackpack.toNetString()
def __init__(self): __metaclass__ = ABCMeta DirectObject.__init__(self) BaseAttack.__init__(self) self.avatar = None self.gag = None self.target = None self.splat = None self.splatPos = None self.state = GagState.LOADED self.woosh = None self.handJoint = None self.equipped = False self.index = None self.id = GagGlobals.getIDByName(self.name) self.timeout = 5 self.animTrack = None self.holdGag = True # Handles the new recharging for certain gags. # The time it takes (in seconds) to recharge this gag. self.rechargeTime = 0 # The elapsed time of the current recharge. Should be a float self.rechargeElapsedTime = 0 if metadata.PROCESS == 'client': if self.gagType == GagType.THROW: self.woosh = base.audio3d.loadSfx(GagGlobals.PIE_WOOSH_SFX) self.hitSfx = base.audio3d.loadSfx(self.hitSfxPath) self.drawSfx = base.audio3d.loadSfx(GagGlobals.DEFAULT_DRAW_SFX)
def getDefaultMaxSupply(self, gagId): data = GagGlobals.getGagData(gagId) if 'minMaxSupply' in data.keys(): return data.get('minMaxSupply') else: return data.get('maxSupply')
def __accumulateTracks(self): tracks = [] for gagId in base.localAvatar.attacks.keys(): trackId = GagGlobals.getTrackOfGag(gagId, getId=True) if trackId not in tracks: tracks.append(trackId) tracks.sort() return tracks
class FlowerPot(LightDropGag): name = GagGlobals.FlowerPot model = GagGlobals.getProp('5', 'flowerpot-mod') anim = GagGlobals.getProp('5', 'flowerpot-chan') hitSfxPath = GagGlobals.POT_DROP_SFX missSfxPath = GagGlobals.POT_MISS_SFX def __init__(self): LightDropGag.__init__(self) self.setImage('phase_3.5/maps/flowerpot.png') self.colliderRadius = 0.75 self.colliderOfs = Point3(0, 0, -3.5) def startDrop(self, entity): if self.dropLoc: self.dropLoc.setZ(self.dropLoc.getZ() + 3.5) LightDropGag.startDrop(self, entity)
def incrementExp(self, trackIndex, track, newValue): bar = self.trackBars[trackIndex] nextExp = GagGlobals.getMaxExperienceValue(newValue, track.name) oldValue = bar['value'] color = GagGlobals.TrackColorByName.get(track.name) bar['text'] = '%d/%d' % (newValue, nextExp) bar['range'] = nextExp if not nextExp == -1 else newValue bar['value'] = newValue bar['barColor'] = (color[0], color[1], color[2], 1)
def buildEntity(self): cloud = Actor(self.model, {'chan': GagGlobals.getProp(4, 'stormcloud-chan')}) trickleFx = GagUtils.loadParticle(5, 'trickleLiquidate') rainFx01 = GagUtils.loadParticle(5, 'liquidate') rainFx02 = GagUtils.loadParticle(5, 'liquidate') rainFx03 = GagUtils.loadParticle(5, 'liquidate') rainEffects = [rainFx01, rainFx02, rainFx03] entity = [cloud, [trickleFx, rainEffects]] self.entities.append(entity) return cloud, trickleFx, rainEffects, entity
def hitByGag(self, gagId, distance): if self.isDead(): return avId = self.air.getAvatarIdFromSender() player = self.air.doId2do.get(avId, None) if not player: return gagName = self.air.attackMgr.getAttackName(gagId) data = dict(GagGlobals.getGagData(gagName)) data['distance'] = distance baseDmg = GagGlobals.calculateDamage(player, gagName, data) hp = self.health - baseDmg self.b_setHealth(hp) self.d_announceHealth(0, baseDmg, -1) if self.isDead(): self.dispatchOutput("OnDie") self.brain.stop() self.d_doRagdollMode()
def toonHitByPie(self, avId, gagId): obj = self.air.doId2do.get(avId, None) hp = GagGlobals.getGagData(gagId).get('health', 0) if obj: if obj.getHealth() < obj.getMaxHealth() and not obj.isDead(): if obj.__class__.__name__ == 'DistributedToonAI': obj.toonUp(hp) else: if obj.getHealth() + hp > obj.getMaxHealth(): hp = obj.getMaxHealth() - obj.getHealth() obj.b_setHealth(obj.getHealth() + hp) obj.d_announceHealth(1, hp)
def loadEntityValues(self): self.track = self.getEntityValueInt("track") if self.track == -1: # random track self.track = random.choice(GagGlobals.TrackIdByName.values()) trackName = GagGlobals.getTrackName(self.track) self.gagId = self.getEntityValueInt("gag") if self.gagId != -1: self.gagId = GagGlobals.gagIdByName[ GagGlobals.TrackGagNamesByTrackName[trackName][self.gagId]]
def onHit(self, pos, intoNP): BaseProjectile.onHit(self, pos, intoNP) WATER_SPRAY_COLOR = Point4(0.3, 0.7, 0.9, 0.7) CIGlobals.makeSplat(pos, WATER_SPRAY_COLOR, 0.3) if self.local: avNP = intoNP.getParent() for obj in base.avatars: if CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey(): gid = GagGlobals.getIDByName(GagGlobals.WaterGun) obj.handleHitByToon(base.localAvatar, gid, (self.getPos(render) - self.initialPos).length()) self.removeNode()
def d_setGrab(self, avId): DistributedRestockBarrelAI.d_setGrab(self, avId) avatar = self.air.doId2do.get(avId) backpack = avatar.backpack trackName = GagGlobals.getTrackName(self.track) availableGags = [] restockGags = {} trackGags = GagGlobals.TrackGagNamesByTrackName.get(trackName) if self.gagId == -1: # Gets the gag ids of gags in this gag track. for trackGag in trackGags: gagId = self.air.attackMgr.getAttackIDByName(trackGag) if backpack.hasGag(gagId): availableGags.append(gagId) # The strongest gags should be first. availableGags.reverse() else: # this barrel restocks a specific gag if backpack.hasGag(self.gagId): availableGags.append(self.gagId) restockLeft = int(self.maxRestock) for gagId in availableGags: if restockLeft <= 0: break supply = backpack.getSupply(gagId) maxAmount = backpack.getMaxSupply(gagId) if supply < maxAmount: giveAmount = maxAmount - backpack.getSupply(gagId) if restockLeft < giveAmount: giveAmount = restockLeft restockGags[gagId] = supply + giveAmount restockLeft -= giveAmount self.notify.info( 'Requesting to give %s %ss.' % (str(giveAmount), self.air.attackMgr.getAttackName(gagId))) for gagId in restockGags.keys(): attack = avatar.getAttack(gagId) avatar.b_updateAttackAmmo(gagId, restockGags.get(gagId), *attack.getAmmoValues()[1:])
def __init__(self, avatar): self.avatar = avatar self.avatarName = None if not self.avatar else avatar.getName() self.notify = directNotify.newCategory( 'RPToonData[%s]' % self.avatarName if self.avatarName else 'Undefined') self.favoriteGag = GagGlobals.Cupcake # All the gag tracks self.tracks = OrderedDict() if not self.avatar: for track in GagGlobals.TrackNameById.values(): self.tracks[track] = Track(track, 0, 0, 0) else: for track, exp in self.avatar.trackExperience.iteritems(): self.tracks[track] = Track( track, exp, GagGlobals.getMaxExperienceValue(exp, track), 0)
def setBackpackAmmo(self, netString): data = self.backpack.fromNetString(netString) for gagId in data.keys(): supply = data[gagId] if not gagId in self.getAttackMgr().AttackClasses.keys(): # This is like an integrity check making sure that the avatar # only has access to attacks we want them to have access to. # This also is an automatic way to correct old backpack data # that could be lingering in our database. This integrity check # isn't supposed to remain in the code for a long time. self.b_setBackpackAmmo( GagGlobals.getDefaultBackpackNetString(True)) break if not self.backpack.hasGag(gagId): self.backpack.addGag(gagId, curSupply=supply) else: self.backpack.setSupply(gagId, supply, updateEnabled=False)
def __makeGagButton(self, gagName, trackName): gui = loader.loadModel('phase_3.5/models/gui/inventory_gui.bam') icons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam') icon = icons.find(GagGlobals.InventoryIconByName[gagName]) index = GagGlobals.TrackGagNamesByTrackName[trackName].index(gagName) xValue = GagButtonXValues[index] gagId = GagGlobals.getIDByName(gagName) button = DirectButton( relief=None, image=(gui.find('**/InventoryButtonUp'), gui.find('**/InventoryButtonDown'), gui.find('**/InventoryButtonRollover'), gui.find('**/InventoryButtonFlat')), geom=icon, geom_scale=0.6, parent=self.trackByName[trackName], text=str(base.localAvatar.getBackpack().getSupply(gagId)), text_align=TextNode.ARight, text_scale=0.04, text_fg=Vec4(1, 1, 1, 1), text_pos=(0.07, -0.04)) button.setX(xValue) self.gagButtonByName[gagName] = button
def update(self): plyr = base.localAvatar if not base.localAvatar.hasAttacks(): return gagId = -1 if self.getCurrentOrNextState() == 'Idle': gagId = plyr.getEquippedAttack() elif self.getCurrentOrNextState() == 'Select' and self.currentGag: gagId = self.currentGag.gagId if gagId != -1: self.ammoFrame.showThrough() if plyr.hasAttackId(gagId): self.ammoText.setText( '%i/%i' % (plyr.getAttackAmmo(gagId), plyr.getAttackMaxAmmo(gagId))) else: self.ammoText.setText('') col = GagGlobals.TrackColorByName[GagGlobals.getTrackOfGag(gagId)] self.ammoFrame['image_color'] = (col[0], col[1], col[2], 1.0) else: self.ammoFrame.hide()
def buildLips(self): self.cleanupLips() self.lips = GagGlobals.loadProp(5, 'lips')
def getTrackExperience(self): return GagGlobals.trackExperienceToNetString(self.trackExperience)
def setTrackExperience(self, netString): self.trackExperience = GagGlobals.getTrackExperienceFromNetString( netString) GagGlobals.processTrackData(self.trackExperience, self.backpack, isAI=True)
def reqUnlockAllGags(self): if self.__requesterAuthorized(): self.b_setTrackExperience( GagGlobals.trackExperienceToNetString( GagGlobals.MaxedTrackExperiences)) self.backpack.refillSupply()
def parseToonData(self): blobs = [] for avId, data in self.avatarData.iteritems(): avatar = base.air.doId2do.get(avId, None) deadCogData = data[1] favGagId = 0 # Make it whole cream pie by default favGagUses = 0 gagUnlocked = False if avatar: rpData = RPToonData(avatar) trackIncrements = {} for track in avatar.trackExperience.keys(): trackIncrements[track] = 0 for gagId, uses in data[0].iteritems(): gagName = self.air.attackMgr.getAttackName(gagId) gagData = GagGlobals.gagData.get(gagName) track = gagData['track'] if uses > favGagUses: favGagId = gagId trackGags = GagGlobals.TrackGagNamesByTrackName.get(track) incr = (trackGags.index(gagName) + 1) * uses if track in trackIncrements.keys(): incr = incr + trackIncrements[track] trackIncrements[track] = incr rpData.favoriteGag = self.air.attackMgr.getAttackName(favGagId) for track, exp in avatar.trackExperience.iteritems(): rpDataTrack = rpData.getTrackByName(track) increment = trackIncrements.get(track) maxExp = GagGlobals.getMaxExperienceValue(exp, track) incrMaxExp = GagGlobals.getMaxExperienceValue( exp + increment, track) rpDataTrack.exp = exp rpDataTrack.maxExp = maxExp rpDataTrack.increment = increment avatar.trackExperience[track] = (exp + rpDataTrack.increment) if incrMaxExp != maxExp: # We've unlocked a gag. maxExpIndex = GagGlobals.TrackExperienceAmounts.get( track).index(incrMaxExp) newGagName = GagGlobals.TrackGagNamesByTrackName.get( track)[maxExpIndex] gagId = self.air.attackMgr.getAttackIDByName( newGagName) avatar.backpack.addGag(gagId, 1) gagUnlocked = True avatar.b_setTrackExperience( GagGlobals.trackExperienceToNetString( avatar.trackExperience)) if gagUnlocked: netString = avatar.getBackpackAmmo() avatar.d_setBackpackAmmo(netString) # Let's update quest stuff for this avatar. questManager = avatar.questManager objectiveProgresses = [] for quest in questManager.quests.values(): objectiveProgress = [] for i, objective in enumerate(quest.accessibleObjectives): objectiveProgress.append(objective.progress) if objective.type == DefeatCog: progress = objective.progress for killData in deadCogData: if not ( progress == objective.goal ) and objective.isNeededCogFromDeadCogData( killData): progress += 1 elif (progress == objective.goal): break objectiveProgress[i] = progress elif objective.type == DefeatCogBuilding and self.isCogOffice( ) and objective.isAcceptable(self.hood, self.dept, self.numFloors): objectiveProgress[i] = objectiveProgress[i] + 1 elif objective.type == RecoverItem: for killData in deadCogData: objective.handleProgressFromDeadCogData( killData) objectiveProgresses.append(objectiveProgress) questManager.updateQuestData( objectiveProgresses=objectiveProgresses) blobs.append(rpData.toNetString(avId)) return blobs
def takeDamage(self, damageInfo): #, gagId, distance): gagId = damageInfo.attackID distance = damageInfo.damageDistance avId = damageInfo.damager.doId avatar = damageInfo.damager gagName = self.air.attackMgr.getAttackName(gagId) dataRef = GagGlobals.getGagData(gagName) if dataRef: data = dict(dataRef) else: data = {} data['distance'] = distance track = GagGlobals.getTrackOfGag(gagId, getId=True, isAI=True) isPlayer = hasattr(avatar, "trackExperience") if self.canGetHit(): damage = self.__handleTacticalAttacks(avatar.doId, gagName, data, damageInfo, isPlayer) self.setDamageConditions(damage) if isPlayer and self.battleZone: # We only want to award credit when Toons use gags that are less than or at the level of the Cog # they're using them on. gagLevel = GagGlobals.TrackGagNamesByTrackName.get( data.get('track')).index(gagName) if gagLevel <= self.level: self.battleZone.handleGagUse(gagId, avId) if isPlayer and not avId in self.damagers: self.damagers.append(avId) if self.isDead(): self.stopStun() #if self.firstTimeDead: # self.sendUpdate('doStunEffect') deathAnim = self.__getAnimForGag(track, gagName) #self.b_setAnimState(deathAnim, 0) #self.stopAI() # Let's give everyone credit who damaged me. if self.battleZone: for damager in self.damagers: self.battleZone.handleCogDeath(self, damager) self.firstTimeDead = False elif gagName in GagGlobals.Stunnables and not self.stunned: # We have been stunned. self.clearTrack() animName = self.__getAnimForGag(track, gagName) animB4Stun = SuitGlobals.getAnimIdByName(animName) self.sendUpdate('stun', [animB4Stun]) baseStunTime = 6.0 stunTime = (baseStunTime / self.suitPlan.getCogClassAttrs().dmgMod) * ( damage / 95.0) taskMgr.doMethodLater(stunTime, self.__stunTask, self.taskName('stunTask')) self.stunned = True else: # Sound will wake me up. if self.stunned and track == GagType.SOUND: self.stopStun(restart=True) # Do appropriate gag effects. flags = 0 if gagName == GagGlobals.TNT: flags |= GagEffects.GEAsh if flags != 0: self.sendUpdate('doGagEffect', [flags])
def getBackpackAmmo(self): if self.backpack: return self.backpack.netString return GagGlobals.getDefaultBackpack().toNetString()