def RepairItem(player, char): if char.dead: player.sendGameText(RPG_MSG_GAME_DENIED, "%s is dead and cannot repair.\\n" % (char.name)) return citem = player.cursorItem if not citem: player.sendGameText(RPG_MSG_GAME_DENIED, r'Please place an item in your cursor.\n') return code, cost, points = DoItemRepair(char, citem) if code == 2: #not enough money ctext = GenMoneyText(cost) player.sendGameText( RPG_MSG_GAME_DENIED, "The repair of <a:Item%s>%s</a> requires %s. %s doesn't have enough money\\n" % (GetTWikiName(citem.itemProto.name), citem.name, ctext, char.name)) return if code == 0: #not enough skill player.sendGameText( RPG_MSG_GAME_DENIED, "%s lacks the skill to repair <a:Item%s>%s</a>.\\n" % (char.name, GetTWikiName(citem.itemProto.name), citem.name)) return if code == 1: player.sendGameText( RPG_MSG_GAME_DENIED, "<a:Item%s>%s</a> requires no repair.\\n" % (GetTWikiName(citem.itemProto.name), citem.name)) return ctext = GenMoneyText(cost) if citem.repair == citem.repairMax: player.sendGameText( RPG_MSG_GAME_BLUE, r'%s completely repairs <a:Item%s>%s</a> for %i points! (%i/%i)\n%s in materials consumed.\n' % (char.name, GetTWikiName(citem.itemProto.name), citem.name, points, citem.repair, citem.repairMax, ctext)) else: player.sendGameText( RPG_MSG_GAME_GAINED, r'%s repairs <a:Item%s>%s</a> for %i points! (%i/%i)\n%s in materials consumed.\n' % (char.name, GetTWikiName(citem.itemProto.name), citem.name, points, citem.repair, citem.repairMax, ctext)) player.mind.callRemote("playSound", "sfx/Hit_MetalPoleImpact2.ogg")
def encyclopediaGetLink(searchvalue): if not searchvalue: return None if not ENCWND: PyExec() formatted = GetTWikiName(searchvalue) link = None if ENCYC.has_key(formatted): link = "<a:%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Item%s" % formatted): link = "<a:Item%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("ItemSet%s" % formatted): link = "<a:ItemSet%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Spell%s" % formatted): link = "<a:Spell%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Recipe%s" % formatted): link = "<a:Recipe%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Skill%s" % formatted): link = "<a:Skill%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Class%s" % formatted): link = "<a:Class%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Spawn%s" % formatted): link = "<a:Spawn%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Quest%s" % formatted): link = "<a:Quest%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Zone%s" % formatted): link = "<a:Zone%s>%s</a>" % (formatted, searchvalue) elif ENCYC.has_key("Faction%s" % formatted): link = "<a:Faction%s>%s</a>" % (formatted, searchvalue) return link
def encyclopediaSearch(searchvalue): if not ENCWND: PyExec() formatted = GetTWikiName(searchvalue) page = None if ENCYC.has_key("Item%s" % formatted): page = "Item%s" % formatted elif ENCYC.has_key("ItemSet%s" % formatted): page = "ItemSet%s" % formatted elif ENCYC.has_key("Spell%s" % formatted): page = "Spell%s" % formatted elif ENCYC.has_key("Recipe%s" % formatted): page = "Recipe%s" % formatted elif ENCYC.has_key("Skill%s" % formatted): page = "Skill%s" % formatted elif ENCYC.has_key("Class%s" % formatted): page = "Class%s" % formatted elif ENCYC.has_key("Spawn%s" % formatted): page = "Spawn%s" % formatted elif ENCYC.has_key("Quest%s" % formatted): page = "Quest%s" % formatted elif ENCYC.has_key("Zone%s" % formatted): page = "Zone%s" % formatted elif ENCYC.has_key("Faction%s" % formatted): page = "Faction%s" % formatted if page: ENCWND.setPage(page) TGEEval("canvas.pushDialog(EncyclopediaWnd);") else: TGECall("MessageBoxOK", "Entry not found", "No entry for %s in encyclopedia." % searchvalue) return
def CheckRepairItem(charname, rskill, rinfo, citem): from mud.client.gui.tomeGui import TomeGui receiveGameText = TomeGui.instance.receiveGameText if not citem: receiveGameText(RPG_MSG_GAME_DENIED, r'Please place an item in your cursor.\n') return ret = GetItemRepairCost(rskill, citem.REPAIR, citem.REPAIRMAX, citem.LEVEL, citem.CLASSES) if not ret: receiveGameText( RPG_MSG_GAME_DENIED, r'%s has insufficient skill to repair <a:Item%s>%s</a>.\n' % (charname, GetTWikiName(citem.PROTONAME), citem.NAME)) return if ret == 1: receiveGameText( RPG_MSG_GAME_DENIED, r'<a:Item%s>%s</a> doesn\'t need repair.\n' % (GetTWikiName(citem.PROTONAME), citem.NAME)) return ctext = GenMoneyText(ret) if rinfo.checkMoney(ret): receiveGameText( RPG_MSG_GAME_GAINED, "The repair of <a:Item%s>%s</a> requires %s.\\n" % (GetTWikiName(citem.PROTONAME), citem.NAME, ctext)) return receiveGameText( RPG_MSG_GAME_DENIED, "The repair of <a:Item%s>%s</a> requires %s. %s doesn't have enough money.\\n" % (GetTWikiName(citem.PROTONAME), citem.NAME, ctext, charname))
def setInfo(self,infoDict): # Store mob id self.mobID = infoDict['TGTID'] # Set target bitmap if infoDict['DEADTGT']: self.bitmap.SetBitmap("~/data/ui/charportraits/death") elif infoDict.has_key('PORTRAIT'): self.bitmap.SetBitmap("~/data/ui/charportraits/%s"%infoDict['PORTRAIT']) else: self.bitmap.SetBitmap("") # Set general target information classesDesc = "<a:gamelinkClass%s>%i %s</a>"%(GetTWikiName(infoDict['PCLASS']),infoDict['PLEVEL'],infoDict['PCLASS']) try: classesDesc += " / <a:gamelinkClass%s>%i %s</a>"%(GetTWikiName(infoDict['SCLASS']),infoDict['SLEVEL'],infoDict['SCLASS']) try: classesDesc += " / <a:gamelinkClass%s>%i %s</a>"%(GetTWikiName(infoDict['TCLASS']),infoDict['TLEVEL'],infoDict['TCLASS']) except KeyError: pass except KeyError: pass self.classesDesc.SetText(classesDesc) self.raceDesc.SetText(infoDict['RACE']) self.realmDesc.SetText(RPG_REALM_TEXT[infoDict['REALM']]) # Set character specific information if infoDict['CHARTGT']: self.nameDesc.SetText("<a:gamelinkcharlink%s>%s %s</a>"%(infoDict['NAME'].replace(' ','_'),infoDict['NAME'],infoDict['VARIANTNAME'])) self.npcInfo.visible = False guildname = infoDict['GUILDNAME'] if guildname == "": self.pcGuildName.SetText("None") else: self.pcGuildName.SetText(guildname) self.pcBirthDate.SetText(infoDict['BIRTHDATE']) setting = infoDict['ENCOUNTERSETTING'] self.pcEncounterSetting.SetText("<color:%s>%s"%(encounterSettingColoring[setting],RPG_ENCOUNTER_SETTING_FORINDEX[setting])) self.pcInfo.visible = True # Set npc specific information else: self.nameDesc.SetText("<a:gamelinkSpawn%s>%s %s</a>"%(GetTWikiName(infoDict['NAME']),infoDict['VARIANTNAME'],infoDict['NAME'])) self.pcInfo.visible = False if infoDict['PET']: self.npcPet.visible = True else: self.npcPet.visible = False self.npcInfo.visible = True # Set target description if infoDict['MYSELF']: # If the description is my own, get the editable version self.tgtScroll.visible = False self.setMyDesc.setActive(False) self.myDesc.SetText(infoDict['DESC']) self.myDescStuff.visible = True else: # Not mine, disable editable version self.myDescStuff.visible = False relation,relationDesc = infoDict['STANDING'] desc = "%s\n\n<color:%s>%s"%(infoDict['DESC'],relationColoring[relation],relationDesc) self.tgtDesc.setText(desc) self.tgtScroll.visible = True # Show the dialog TGEEval("canvas.pushDialog(TgtDescWnd);") if infoDict['MYSELF']: self.myDesc.makeFirstResponder(True)
def CmdCraft(args, charIndex): from mud.client.playermind import formatMLString, GetMoMClientDBConnection from partyWnd import PARTYWND con = GetMoMClientDBConnection() # Check for existance of arguments. if not len(args): receiveGameText(RPG_MSG_GAME_DENIED, "Please specify a recipe name.\\n") return # Join the list with spaces to get the desired recipe name. recipeName = formatMLString(' '.join(args).replace('\\', '\\\\')) # Do a case-insensitive search for the desired recipe name. # Replace ' with '' for SQL apostropha handling..replace("'", "''") result = con.execute( "SELECT id,name,skillname,skill_level,cost_t_p FROM recipe WHERE LOWER(name) = LOWER(\"%s\") LIMIT 1;" % (recipeName)).fetchone() # If the recipe is not found, print message and return. if not result: receiveGameText( RPG_MSG_GAME_DENIED, '%s is not a valid recipe. Please check the recipe name and try again.\\n' % (recipeName)) return # Extract the tuple from the result. recipeID, recipeName, skillname, skill_level, costTP = result # Get current character info if charIndex == None: charIndex = PARTYWND.curIndex cinfo = PARTYWND.charInfos[charIndex] # Check skill requirements charSkillLevel = cinfo.SKILLS.get(skillname, 0) if charSkillLevel < skill_level: receiveGameText( RPG_MSG_GAME_DENIED, "%s requires a %i skill in <a:Skill%s>%s</a>.\\n" % (cinfo.NAME, skill_level, GetTWikiName(skillname), skillname)) return # Check money requirements if PARTYWND.mind.rootInfo.TIN < costTP: receiveGameText( RPG_MSG_GAME_DENIED, "This <a:Skill%s>%s</a> requires %s.\\n" % (GetTWikiName(skillname), skillname, GenMoneyText(costTP))) return # Check for crafting delays. if skillname.upper() in cinfo.SKILLREUSE: TomeGui.receiveGameTextPersonalized( RPG_MSG_GAME_DENIED, "$src is still cleaning $srchis tools,\\n$srche can use the <a:Skill%s>%s</a> skill again in about %i seconds.\\n" % (GetTWikiName(skillname), skillname, cinfo.SKILLREUSE[skillname.upper()]), cinfo) return # Check for the required craft ingredients # (will be done on server again, in case there was a communication issue or hacking attempt) ingredients = dict(( item_proto_id, count ) for item_proto_id, count in con.execute( "SELECT item_proto_id,count FROM recipe_ingredient WHERE recipe_id=%i AND count!=0" % recipeID).fetchall()) for item in cinfo.ITEMS.itervalues(): for item_proto_id, count in ingredients.iteritems(): if item.PROTOID == item_proto_id: sc = item.STACKCOUNT if not sc: sc = 1 ingredients[item_proto_id] -= sc if ingredients[item_proto_id] <= 0: del ingredients[item_proto_id] break # If all required ingredients have been found, send craft command to server. if not len(ingredients): # Schedule sending of actual crafting command. PARTYWND.mind.perspective.callRemote("PlayerAvatar", "onCraft", charIndex, recipeID) return missing = dict( (con.execute("SELECT name FROM item_proto WHERE id=%i LIMIT 1;" % (protoID)).fetchone()[0], count) for protoID, count in ingredients.iteritems()) receiveGameText( RPG_MSG_GAME_DENIED, "%s lacks %s for this craft.\\n" % (cinfo.NAME, ', '.join("%i <a:Item%s>%s</a>" % (count, GetTWikiName(name), name) for name, count in missing.iteritems())))
def DoSkillSpell(mob, skillname): from projectile import Projectile from spell import SpawnSpell player = mob.player mobSkill = mob.mobSkillProfiles[skillname] classSkill = mobSkill.classSkill # Assert that mob knows the skill. skillLevel = mob.skillLevels.get(skillname, 0) if not skillLevel: return False # Modify skill spells strength by skill level. mod = float(skillLevel) / float(classSkill.maxValue) # Clamp mod to produce at least 10% of maximum effect. if mod < .1: mod = .1 proto = classSkill.spellProto # Get the appropriate target for this skill spell. tgt = mob.target if proto.target == RPG_TARGET_SELF: tgt = mob elif proto.target == RPG_TARGET_PARTY: tgt = mob elif proto.target == RPG_TARGET_ALLIANCE: tgt = mob elif proto.target == RPG_TARGET_PET: tgt = mob.pet elif player and proto.spellType & RPG_SPELL_HEALING and proto.target == RPG_TARGET_OTHER: tgt = GetPlayerHealingTarget(mob, tgt, proto) # If no valid target could be found, return in failure. # Here's one last chance to still acquire one. if not tgt: if player: if proto.spellType & RPG_SPELL_HARMFUL: from command import CmdTargetNearest CmdTargetNearest(mob, None, False, True) tgt = mob.target if not tgt: player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:Skill%s>%s</a> skill failed, no target.\\n" % (GetTWikiName(skillname), skillname), mob) else: tgt = mob # Still no target, now definitely abort skill. # If the mob is a player mob, message has already be sent. if not tgt: return False # For harmful skill spells, check if target may # be harmed at all. Abort if not. if proto.spellType & RPG_SPELL_HARMFUL: if not AllowHarmful(mob, tgt) and not proto.aoeRange: if player: player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:Skill%s>%s</a> skill failed, no valid target.\\n" % (GetTWikiName(skillname), skillname), mob) return False if not player and not (mob.master and mob.master.player) and not IsKOS( mob, tgt): return False # If the skill spell isn't harmful and the target is hostile, # retarget self. if not proto.spellType & RPG_SPELL_HARMFUL and mob.target == tgt: if tgt and IsKOS(tgt, mob): tgt = mob # Check for a skill raise. if mob.character: c = 10 if mobSkill.reuseTime > 180: c = 5 if mobSkill.reuseTime > 180 * 2: c = 3 mob.character.checkSkillRaise(skillname, c) # Play animation and trigger particles if available. if proto.animOverride: mob.zone.simAvatar.mind.callRemote("playAnimation", mob.simObject.id, proto.animOverride) if len(proto.particleNodes): mob.zone.simAvatar.mind.callRemote("triggerParticleNodes", mob.simObject.id, proto.particleNodes) # Launch a projectile if necessary, otherwise spawn skill spell. if proto.projectile: p = Projectile(mob, mob.target) p.spellProto = proto p.launch() else: SpawnSpell(proto, mob, tgt, tgt.simObject.position, mod, skillname) # Return True, so skill was used. return True
def DoPickPocket(mob): # Mobs shouldn't pick pocket at all. Could be fun in some # instances, but needs a special implementation. if not mob.player: print "WARNING: Non-player mob attempting to pick pocket" return (False, False) # Check if there is a target to pick pocket. tgt = mob.target if not tgt or tgt == mob: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:SkillPickPocket>pick pocket</a> failed, no target.\\n", mob) return (False, False) # Cannot pick pocket players, maybe in the future for PvP. if tgt.player or (tgt.master and tgt.master.player): mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:SkillPickPocket>pick pocket</a> failed, can't pick pocket other players.\\n", mob) return (False, False) # Store if the target is disabled in a flag for easier query. tgtDisabled = tgt.sleep > 0 or tgt.stun > 0 if tgt.target: # Can't pick pocket mobs that are in combat with someone else. # Prevent grieving. if tgt.target.player != mob.player: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "<a:SkillPickPocket>Pick pocket</a> failed, can't pick pocket targets in combat with other players.\\n", mob) return (False, False) # Can't pick pocket mobs that are attacking the thief. if tgt.target == mob and not tgtDisabled: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "<a:SkillPickPocket>Pick pocket</a> failed, $tgt has a keen eye on $src.\\n", mob) return (False, False) # Can't pick pocket when fighting. if mob.attacking: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$src is too occupied with combat to <a:SkillPickPocket>pick pocket</a>.\\n", mob) return (False, False) # Check if target is in range. if GetRangeMin(mob, tgt) > 2.0: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:SkillPickPocket>pick pocket</a> failed, out of range.\\n", mob) return (False, False) # Get the targets loot table. loot = tgt.loot # Generate loot if necessary, check if there's # anything in it. nothing = True if loot and loot.generateCorpseLoot(): nothing = False # If the loot table is empty, target has nothing to steal. if nothing: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "<a:SkillPickPocket>Pick pocket</a> failed, $tgt has nothing to steal.\\n", mob) return (False, True) # Gather lists of items that can be pick pocketed. pickPocketNormal = [] # Normal pick pocket list. pickPocketSpecial = [] # Items specially flagged for thieves. for item in loot.items: if loot.lootProto.itemDetails.has_key(item.itemProto.name): if loot.lootProto.itemDetails[ item.itemProto.name] & RPG_LOOT_PICKPOCKET: pickPocketSpecial.append(item) # If the item is in the standard loot table but is equipped allow it # as long as it's not soulbound. Soulbound items resist the thiefs # clutches by themselves, not only the owner. elif not item.flags & RPG_ITEM_SOULBOUND and item.slot != -1: # Check if the specific item actually can be pickpocketed # successfully. if item.slot in (RPG_SLOT_SHOULDERS,RPG_SLOT_HANDS,RPG_SLOT_FEET) and \ not tgtDisabled: continue elif item.slot in (RPG_SLOT_CHEST,RPG_SLOT_ARMS,RPG_SLOT_LEGS) and \ tgt.stun <= 0: continue pickPocketNormal.append(item) continue pickPocketNormal.append(item) # Bummer, no items to steal. if not loot.tin and not len(pickPocketNormal) and not len( pickPocketSpecial): mob.player.sendGameText( RPG_MSG_GAME_DENIED, "<a:SkillPickPocket>Pick pocket</a> failed, $tgt has nothing to steal.\\n", mob) return (False, True) # Calculate possibility for a pick pocket success. pplevel = mob.skillLevels.get('Pick Pocket', 0) # Give a base of 500. succ = 500.0 # Start with paranoia, the longer it was since last pick pocket, # the less the mob pays attention until paranoia no longer applies. # Modifier range: 0.0 - 1.0. # Skip paranoia factor if target is asleep or stunned. if not tgtDisabled: succ *= sqrt(1.0 - loot.pickPocketTimer / 270.0) # Now check level difference. Considering pplevel / 10 equal level, # equal level is standard, linearly increase difficulty for higher # level targets and decrease for lower level targets. # Four times as easy for 100 level lower, impossible for 100 level higher. # Modifier range: 0.002 - 3.98. succ *= 2.0 - float(tgt.plevel * 10 - pplevel) / 500.0 # Include targets difficulty modifier in the calculation. # Modifier range: 0.0 - 0.995. mod = tgt.difficultyMod / 100.0 if mod > 1.0: mod = 1.0 succ *= sqrt(1.0 - mod) # It's easier to pick pockets on a stunned or sleeping mob. if tgtDisabled: succ *= 1.5 # Clamp success modifier high to 975 (equals 97.5%) succ = int(succ) if succ > 975: succ = 975 # Give at least 0.5% chance. if succ < 5: succ = 5 # Pick pocket timer doesn't prevent continuous pick pocketing, # but serves as a diminishing difficulty to pick pocket again. loot.pickPocketTimer = 270 # 45 seconds # Initialize the noticed flag to false. noticed = False # Determine if pick pocket was a success or not. if randint(1, 1000) > succ: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$tgt has noticed $src's <a:SkillPickPocket>pick pocketing</a>!\\n", mob) if tgt.sleep > 0: # wake up tgt.cancelSleep() if not tgt.aggro.get(mob, 0): tgt.addAggro(mob, 10) if succ >= 600: mob.character.checkSkillRaise("Pick Pocket", 4, 4) return (False, True) elif tgt.sleep > 0 and randint(0, 1500) > succ: # wake up tgt.cancelSleep() if not tgt.aggro.get(mob, 0): tgt.addAggro(mob, 10) noticed = True if succ <= 750: mob.character.checkSkillRaise("Pick Pocket", 2, 2) # First of all, try to pick pocket items specially flagged for thieves. if len(pickPocketSpecial): # Choose one randomly from the special pick pocket list. x = len(pickPocketSpecial) - 1 if x >= 1: x = randint(0, x) item = pickPocketSpecial[x] # Save item slot here because it will eventually be altered. slot = item.slot # Try to give the item to the thief. if mob.player.giveItemInstance(item): mob.player.sendGameText( RPG_MSG_GAME_GAINED, "%s successfully <a:SkillPickPocket>pick pockets</a> a <a:Item%s>%s</a>!\\n" % (item.character.name, GetTWikiName( item.itemProto.name), item.name)) # Remove the pick pocketed item from the loot table. loot.items.remove(item) if not loot.tin and not len(loot.items): tgt.loot = None # If the mob was wearing the item pick pocketed, # need to unequip it. if slot != -1: tgt.unequipItem(slot) tgt.mobInfo.refresh() return (True, True) # Check if we try to pick pocket an item or money. takeItem = False if len(pickPocketNormal): if loot.tin: # 66.67% chance to prefer item even if money is available. if randint(0, 2): takeItem = True else: takeItem = True # We want an item. if takeItem: # Choose the item to pick pocket. x = len(pickPocketNormal) - 1 if x >= 1: x = randint(0, x) item = pickPocketNormal[x] # Save item slot here because it will eventually be altered. slot = item.slot # If the item is being worn, some special rules apply. if slot != -1: # Tiered difficulty for equipped items. # Jewelry behaves like normal, so don't test for the following slots: # RPG_SLOT_LEAR, RPG_SLOT_REAR, RPG_SLOT_LFINGER, RPG_SLOT_RFINGER # RPG_SLOT_NECK, RPG_SLOT_LWRIST ,RPG_SLOT_RWRIST skip = doNotice = False # First difficulty stage: there's always a chance to wake up if # sleeping and to trigger aggro. if slot in (RPG_SLOT_HEAD, RPG_SLOT_WAIST, RPG_SLOT_BACK, RPG_SLOT_PRIMARY, RPG_SLOT_SECONDARY, RPG_SLOT_RANGED, RPG_SLOT_AMMO, RPG_SLOT_SHIELD, RPG_SLOT_LIGHT): doNotice = not noticed # Second difficulty stage: can only pick pocket if stunned or asleep # and has a chance to wake up if sleeping and to trigger aggro. elif slot in (RPG_SLOT_SHOULDERS, RPG_SLOT_HANDS, RPG_SLOT_FEET): doNotice = not noticed # Third difficulty stage: second check if pick pocketing succeeds. # Also can only pick pocket if stunned and there's always a chance # to trigger aggro. elif slot in (RPG_SLOT_CHEST, RPG_SLOT_ARMS, RPG_SLOT_LEGS): # Fail by 25% straight. skip = not randint(0, 3) doNotice = not noticed # If by any of the above rules set, check if the thief gets noticed. if doNotice: span = pplevel - 10 * tgt.plevel # If the target is less than 20 levels below the associated # pick pocket level, there's an increasing chance to get noticed. if span < 200: # If the target is more than 10 levels above the associated # pick pocket level, always get noticed. if span < -100: noticed = True # Otherwise distribute linearly between 100% and 50%. else: noticed = randint(1, 100) > (span + 100) / 6 # There's always at least a chance of 50% to get noticed. else: noticed = randint(0, 1) # If we got noticed, wake up and add aggro. if noticed: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$tgt has noticed $src's <a:SkillPickPocket>pick pocketing</a>!\\n", mob) if tgt.sleep > 0: tgt.cancelSleep() tgt.addAggro(mob, 10) if skip: mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$src fails to remove the <a:Item%s>%s</a> from its victim. It's not as easy as it looks after all.\\n" % (GetTWikiName(item.itemProto.name), item.name), mob) return (False, True) # Try to give the item to the thief. if mob.player.giveItemInstance(item): mob.player.sendGameText( RPG_MSG_GAME_GAINED, "%s successfully <a:SkillPickPocket>pick pockets</a> a <a:Item%s>%s</a>!\\n" % (item.character.name, GetTWikiName( item.itemProto.name), item.name)) # Remove the pick pocketed item from the loot table. loot.items.remove(item) if not loot.tin and not len(loot.items): tgt.loot = None # If the mob was wearing the item pick pocketed, # need to unequip it. if slot != -1: tgt.unequipItem(slot) tgt.mobInfo.refresh() return (True, True) # Try to take some money. if loot.tin: half = loot.tin / 2 # divide in half tin = loot.tin - half # for odd numbers loot.tin = half worth = GenMoneyText(tin) mob.player.giveMoney(tin) mob.player.sendGameText( RPG_MSG_GAME_GAINED, "$src successfully <a:SkillPickPocket>pick pockets</a> %s.\\n" % worth, mob) if not loot.tin and not len(loot.items): tgt.loot = None return (True, True) # Pick pocket failed, probably because there was # no money to be pick pocketed and player had no # place for pick pocketed item to go into. else: if tgt.sleep > 0: # wake up tgt.cancelSleep() mob.player.sendGameText( RPG_MSG_GAME_DENIED, "$src quickly retracts $srchis hand before $tgt notices $srchim.\\n", mob) return (True, True)
def DoDisarm(mob): # Mobs can't disarm for now. If disarm gets added for PvP, mobs may learn how to do it. if not mob.player: print "WARNING: Non-player mob attempting to disarm." return (False, False) tgt = mob.target player = mob.player # Disarm needs a target. if not tgt: player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:SkillDisarm>disarm</a> failed, no target.\\n", mob) return (False, False) # Don't allow disarm in PvP for now. if tgt.player or (tgt.master and tgt.master.player): player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:SkillDisarm>disarm</a> failed, can't disarm other players.\\n", mob) return (False, False) # Get a possible weapon to disarm. weapon = tgt.worn.get(RPG_SLOT_SECONDARY) if not weapon: weapon = tgt.worn.get(RPG_SLOT_PRIMARY) if not weapon: player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:SkillDisarm>disarm</a> failed, $tgt carries no weapon.\\n", mob) return (False, False) # Check if target is in disarm range. if GetRangeMin(mob, tgt) > 2.0: player.sendGameText( RPG_MSG_GAME_DENIED, "$src's <a:SkillDisarm>disarm</a> failed, $tgt is out of range.\\n", mob) return (False, False) # Fairly simple disarm success calculation. Needs redoing sometime. pplevel = mob.plevel #skillLevels['Disarm']/10 spread = pplevel - mob.target.plevel failed = False if spread < -5: failed = True else: chance = 6 + spread r = randint(0, chance) if not r: failed = True # Attempted to disarm, add aggro if necessary. if not tgt.aggro.get(mob, 0): tgt.addAggro(mob, 10) # Failed to disarm target. if failed: player.sendGameText( RPG_MSG_GAME_DENIED, "$src has failed to <a:SkillDisarm>disarm</a> $tgt!\\n", mob) return (False, True) # Disarm succeeded, unequip weapon and put it into loot table. tgt.unequipItem(weapon.slot) weapon.slot = -1 tgt.mobInfo.refresh() stolen = False # If weapon is not soulbound or unique, thiefs have a chance # to directly steal the disarmed weapon. Success depends on # pick pocket skill. if not weapon.flags & RPG_ITEM_SOULBOUND and not weapon.flags & RPG_ITEM_UNIQUE: pplevel = mob.skillLevels.get('Pick Pocket', 0) / 10 mod = mob.target.difficultyMod if pplevel: difficulty = int( round(5.0 * (mod * mod * float(mob.target.plevel)) / float(pplevel))) # Success! not only disarm, but also steal weapon. if not randint(0, difficulty): if player.giveItemInstance(weapon): player.sendGameText( RPG_MSG_GAME_GAINED, "%s successfully yanks away $tgt's <a:Item%s>%s</a>!\\n" % (weapon.character.name, GetTWikiName(weapon.itemProto.name), weapon.name), mob) loot = tgt.loot loot.items.remove(weapon) if not len(loot.items): tgt.loot = None stolen = True # If the weapon wasn't stolen, inform about successful disarm. if not stolen: player.sendGameText( RPG_MSG_GAME_GAINED, "$src has <a:SkillDisarm>disarmed</a> $tgt's <a:Item%s>%s</a>.\\n" % (GetTWikiName(weapon.itemProto.name), weapon.name), mob) # Give a possible skill raise and play a nice sound. mob.character.checkSkillRaise("Disarm") player.mind.callRemote("playSound", "sfx/Hit_HugeMetalPlatformDrop.ogg") return (True, True)
def UseSkill(mob, tgt, skillname): if not mob or mob.detached or not mob.simObject: return player = mob.player # Check if mob is in a condition to use a skill. if 0 < mob.sleep or 0 < mob.stun or mob.isFeared: if player: player.sendGameText(RPG_MSG_GAME_DENIED, r'$src is in no condition to use a skill!\n', mob) return # Find the skill. mobSkill = mob.mobSkillProfiles.get(skillname, None) if not mobSkill: #todo, better warning if player: player.sendGameText( RPG_MSG_GAME_DENIED, "$src has lost $srchis ability in <a:Skill%s>%s</a>!\\n" % (GetTWikiName(skillname), skillname), mob) return classSkill = mobSkill.classSkill # Only passive skills don't have a reuse time. # Skip if such a skill should end up here. if not mobSkill.reuseTime: return # Can't use that skill yet. if mob.skillReuse.has_key(classSkill.skillname): return # If there is one, process the non-spell part # of the skill. success = used = False if skillname in SKILLS: if skillname not in mob.skillLevels: traceback.print_stack() print "AssertionError: mob %s doesn't know the skill %s!" % ( mob.name, skillname) return success, used = SKILLS[skillname](mob) else: success = True # If the non-spell part of the skill succeeded, # continue with spell part if there is one. if success and classSkill.spellProto: used = DoSkillSpell(mob, skillname) # If the skill got actually used, set reuse timer. if used: mob.skillReuse[classSkill.skillname] = mobSkill.reuseTime # Also cancel feign death, unless this was the skill used. if skillname != "Feign Death": mob.cancelStatProcess("feignDeath", "$tgt is obviously not dead!\\n") # Player just did a special action which might have helped # or hurt in PvP. Reset counter on encounter setting. if player: player.mind.callRemote("disturbEncounterSetting")
def checkItems(self, itemDict, silent=False): # Do some sanity check on the item requirements. # Don't use iteritems so we iterate over a copy. for proto, count in itemDict.items(): if count <= 0: del itemDict[proto] # If the dictionary to check is empty, return early. if not len(itemDict): return True # Run through all of this Player's party members. for member in self.party.members: # Run through all items in the current Character's possession. for item in member.items: # Skip items in a trade slot. if RPG_SLOT_TRADE_END > item.slot >= RPG_SLOT_TRADE_BEGIN: continue # Also skip items in a loot slot. if RPG_SLOT_LOOT_END > item.slot >= RPG_SLOT_LOOT_BEGIN: continue # Start by checking container contents. if item.container: # Run through all items in the container. for citem in item.container.content: # Get the current container item's item proto. citemProto = citem.itemProto # Get the amount of items we need of this specific # item proto. needed = itemDict.get(citemProto, None) # If we don't need any, skip to the next content item. if not needed: continue # Get the stack count of the current content item. sc = citem.stackCount if not sc: sc = 1 # If the requirement is only partially satisfied, # decrement the needed amount and continue to the # next content item. if sc < needed: itemDict[citemProto] -= sc continue # Otherwise the requirement was completely satisfied, # so remove it from the dictionary. del itemDict[citemProto] # Check if there actually are more items to be checked # for and return success otherwise. if not len(itemDict): return True # Get the current item's item proto. itemProto = item.itemProto # Get the amount of items we need of this specific item proto. needed = itemDict.get(itemProto, None) # If we don't need any, skip to the next item. if not needed: continue # Get the stack count of the current item. sc = item.stackCount if not sc: sc = 1 # If the requirement is only partially satisfied, decrement # the needed amount and continue to the next item. if sc < needed: itemDict[itemProto] -= sc continue # Otherwise the requirement was completely satisfied, so remove # it from the dictionary. del itemDict[itemProto] # Check if there actually are more items to be checked for and # return success otherwise. if not len(itemDict): return True # If we get here, there are still items in the dictionary that couldn't # be found. # Give feedback to the player. if not silent: self.sendGameText( RPG_MSG_GAME_DENIED, "You need %s.\\n" % ', '.join('<a:Item%s>%i %s</a>' % (GetTWikiName(ip.name), c, ip.name) for ip, c in itemDict.iteritems())) # Return the failure. return False
def lootMessage(self,sender, lootitem): senderName = sender.charName ssenderName = senderName.replace(' ','_') for m in self.members: if sender == m: m.sendGameText(RPG_MSG_GAME_YELLOW,r'You have looted: <a:Item%s>%s</a>\n'%(GetTWikiName(lootitem.itemProto.name),lootitem.name)) else: m.sendGameText(RPG_MSG_GAME_YELLOW,r'<a:gamelinkcharlink%s>%s</a> has looted: <a:Item%s>%s</a>\n'%(ssenderName,senderName,GetTWikiName(lootitem.itemProto.name),lootitem.name))
def OnCraft(): cinfo = CRAFTINGWND.charInfo charItems = cinfo.ITEMS # Get all items present in the crafting window. citems = [ charItems[slot] for slot in xrange(RPG_SLOT_CRAFTING_BEGIN, RPG_SLOT_CRAFTING_END) if charItems.has_key(slot) ] # If there are no items present in the crafting window, give a message and return. if not len(citems): TomeGui.receiveGameText( RPG_MSG_GAME_DENIED, "You first need to put the desired ingredients into the crafting window.\\n" ) return con = GetMoMClientDBConnection() # Check if the items in crafting window form a valid recipe. recipe = None for recipe_id, skillname, skill_level in con.execute( "SELECT DISTINCT id,skillname,skill_level FROM recipe WHERE id in (SELECT recipe_id FROM recipe_ingredient WHERE item_proto_id=%i);" % citems[0].PROTOID): ingredients = dict(( item_proto_id, count ) for item_proto_id, count in con.execute( "SELECT item_proto_id,count FROM recipe_ingredient WHERE recipe_id=%i AND count!=0" % recipe_id).fetchall()) passed = True for item in citems: found = False for item_proto_id, count in ingredients.iteritems(): if item.PROTOID == item_proto_id: sc = item.STACKCOUNT if not sc: sc = 1 ingredients[item_proto_id] -= sc found = True break if not found: passed = False break # All items were found in the current recipe. else: for x in ingredients.itervalues(): if x: # Can be negative if too much passed = False break # All ingredients no longer have a required count assigned. else: recipe = recipe_id # Check skill requirements charSkillLevel = cinfo.SKILLS.get(skillname, 0) if charSkillLevel < skill_level: TomeGui.receiveGameText( RPG_MSG_GAME_DENIED, "%s requires a %i skill in <a:Skill%s>%s</a>.\\n" % (cinfo.NAME, skill_level, GetTWikiName(skillname), skillname)) return # Check for crafting delays if skillname.upper() in cinfo.SKILLREUSE: TomeGui.receiveGameTextPersonalized( RPG_MSG_GAME_DENIED, "$src is still cleaning $srchis tools,\\n$srche can use the <a:Skill%s>%s</a> skill again in about %i seconds.\\n" % (GetTWikiName(skillname), skillname, cinfo.SKILLREUSE[skillname.upper()]), cinfo) return break if not recipe and cinfo.SKILLS.get("Scribing", 0): if "SCRIBING" in cinfo.SKILLREUSE: TomeGui.receiveGameTextPersonalized( RPG_MSG_GAME_DENIED, "$src is still cleaning $srchis tools,\\n$srche can use the <a:SkillScribing>Scribing</a> skill again in about %i seconds.\\n" % (cinfo.SKILLREUSE["SCRIBING"]), cinfo) return spellEnhanceLevel = citems[0].spellEnhanceLevel name = citems[0].NAME passed = True if spellEnhanceLevel > 0 and spellEnhanceLevel < 10: count = 0 for item in citems: if spellEnhanceLevel != item.spellEnhanceLevel or name != item.NAME: passed = False break count += item.STACKCOUNT # Player has the correct amount of tomes in crafting window for a merge if count == 2 and passed: recipe = -1 # Hack for tome merging if not recipe: TomeGui.receiveGameText( RPG_MSG_GAME_DENIED, r'%s is unable to craft anything with these items.\n' % (cinfo.NAME)) else: # Send craft command. from partyWnd import PARTYWND PARTYWND.mind.perspective.callRemote("PlayerAvatar", "onCraft", PARTYWND.curIndex, recipe, True)