Пример #1
0
 def change_name(self, agent):
     """Changes an agent's name"""
     old = agent.name
     name = self.rhs
     if not validate_name(name):
         self.msg("That is not a valid name.")
         return
     agent.set_name(name)
     self.caller.msg("Name changed from %s to %s." % (old, self.rhs))
     return
Пример #2
0
    def func(self):
        """Implement the command"""
        caller = self.caller
        if not self.crafter:
            self.crafter = caller
        crafter = self.crafter
        try:
            dompc = PlayerOrNpc.objects.get(player=caller.player)
            assets = AssetOwner.objects.get(player=dompc)
        except PlayerOrNpc.DoesNotExist:
            # dominion not set up on player
            dompc = setup_dom_for_char(caller)
            assets = dompc.assets
        except AssetOwner.DoesNotExist:
            # assets not initialized on player
            dompc = setup_dom_for_char(caller, create_dompc=False)
            assets = dompc.assets
        recipes = crafter.player_ob.Dominion.assets.recipes.all()
        if not self.args and not self.switches:
            # display recipes and any crafting project we have unfinished
            materials = assets.materials.all()
            caller.msg("{wAvailable recipes:{n %s" %
                       ", ".join(recipe.name for recipe in recipes))
            caller.msg("{wYour materials:{n %s" %
                       ", ".join(str(mat) for mat in materials))
            project = caller.db.crafting_project
            if project:
                self.display_project(project)
            return
        # start a crafting project
        if not self.switches or "craft" in self.switches:
            try:
                recipe = recipes.get(name__iexact=self.lhs)
            except CraftingRecipe.DoesNotExist:
                caller.msg("No recipe found by the name %s." % self.lhs)
                return
            try:
                self.get_recipe_price(recipe)
            except ValueError:
                caller.msg("That recipe does not have a price defined.")
                return
            # proj = [id, name, desc, adorns, forgery, translation]
            proj = [recipe.id, "", "", {}, {}, {}, ""]
            caller.db.crafting_project = proj
            stmsg = "You have" if caller == crafter else "%s has" % crafter
            caller.msg("{w%s started to craft:{n %s." % (stmsg, recipe.name))
            caller.msg(
                "{wTo finish it, use /finish after you gather the following:{n"
            )
            caller.msg(recipe.display_reqs(dompc))
            return
        if ("changename" in self.switches or "refine" in self.switches
                or "addadorn" in self.switches):
            targ = caller.search(self.lhs, location=caller)
            if not targ:
                return
            recipe = None
            try:
                recipe = targ.item_data.recipe
            except AttributeError:
                pass
            if not recipe:
                caller.msg("No recipe found for that item.")
                return
            if "changename" in self.switches:
                if not self.rhs:
                    self.msg("Usage: /changename <object>=<new name>")
                    return
                if not validate_name(self.rhs):
                    caller.msg("That is not a valid name.")
                    return
                if targ.tags.get("plot"):
                    self.msg("It cannot be renamed.")
                    return
                targ.aliases.clear()
                targ.name = self.rhs
                caller.msg("Changed name to %s." % targ)
                return
            # adding adorns post-creation
            if "addadorn" in self.switches:
                try:
                    material = self.rhslist[0]
                    amt = int(self.rhslist[1])
                    if amt < 1 and not caller.check_permstring("builders"):
                        raise ValueError
                except (IndexError, ValueError, TypeError):
                    caller.msg(
                        "Usage: /addadorn <object>=<adornment>,<amount>")
                    return
                if not recipe.allow_adorn:
                    caller.msg(
                        "This recipe does not allow for additional materials to be used."
                    )
                    return
                try:
                    mat = CraftingMaterialType.objects.get(
                        name__iexact=material)
                except CraftingMaterialType.DoesNotExist:
                    self.msg(
                        "Cannot use %s as it does not appear to be a crafting material."
                        % material)
                    return
                # if caller isn't a builder, check and consume their materials
                if not caller.check_permstring("builders"):
                    pmats = caller.player.Dominion.assets.materials
                    try:
                        pmat = pmats.get(type=mat)
                        if pmat.amount < amt:
                            caller.msg("You need %s of %s, and only have %s." %
                                       (amt, mat.name, pmat.amount))
                            return
                    except CraftingMaterials.DoesNotExist:
                        caller.msg("You do not have any of the material %s." %
                                   mat.name)
                        return
                    pmat.amount -= amt
                    pmat.save()
                targ.item_data.add_adorn(mat, amt)
                caller.msg("%s is now adorned with %s of the material %s." %
                           (targ, amt, mat))
                return
            if "refine" in self.switches:
                base_cost = recipe.value / 4
                caller.msg("The base cost of refining this recipe is %s." %
                           base_cost)
                try:
                    price = self.get_refine_price(base_cost)
                except ValueError:
                    caller.msg("Price for refining not set.")
                    return
                if price:
                    caller.msg("The additional price for refining is %s." %
                               price)
                action_points = 0
                invest = 0
                if self.rhs:
                    try:
                        invest = int(self.rhslist[0])
                        if len(self.rhslist) > 1:
                            action_points = int(self.rhslist[1])
                    except ValueError:
                        caller.msg(
                            "Amount of silver/action points to invest must be a number."
                        )
                        return
                    if invest < 0 or action_points < 0:
                        caller.msg("Amount must be positive.")
                        return
                if not recipe:
                    caller.msg(
                        "This is not a crafted object that can be refined.")
                    return
                if targ.item_data.quality_level and targ.item_data.quality_level >= 10:
                    caller.msg("This object can no longer be improved.")
                    return
                ability = get_ability_val(crafter, recipe)
                if ability < recipe.level:
                    err = "You lack" if crafter == caller else "%s lacks" % crafter
                    caller.msg(
                        "%s the skill required to attempt to improve this." %
                        err)
                    return
                if not self.check_max_invest(recipe, invest):
                    return
                cost = base_cost + invest + price
                # don't display a random number when they're prepping
                if caller.ndb.refine_targ != (targ, cost):
                    diffmod = get_difficulty_mod(recipe, invest)
                else:
                    diffmod = get_difficulty_mod(recipe, invest, action_points,
                                                 ability)
                # difficulty gets easier by 1 each time we attempt it
                attempts = targ.item_data.get_refine_attempts_for_character(
                    crafter)
                if attempts > 60:
                    attempts = 60
                diffmod += attempts
                if diffmod:
                    self.msg(
                        "Based on silver spent and previous attempts, the difficulty is adjusted by %s."
                        % diffmod)
                if caller.ndb.refine_targ != (targ, cost):
                    caller.ndb.refine_targ = (targ, cost)
                    caller.msg(
                        "The total cost would be {w%s{n. To confirm this, execute the command again."
                        % cost)
                    return
                if cost > caller.db.currency:
                    caller.msg("This would cost %s, and you only have %s." %
                               (cost, caller.db.currency))
                    return
                if action_points and not caller.player_ob.pay_action_points(
                        action_points):
                    self.msg("You do not have enough action points to refine.")
                    return
                # pay for it
                caller.pay_money(cost)
                self.pay_owner(
                    price,
                    "%s has refined '%s', a %s, at your shop and you earn %s silver."
                    % (caller, targ, recipe.name, price),
                )

                roll = do_crafting_roll(crafter,
                                        recipe,
                                        diffmod,
                                        diffmult=0.75,
                                        room=caller.location)
                quality = get_quality_lvl(roll, recipe.difficulty)
                old = targ.item_data.quality_level or 0
                attempts += 1
                targ.item_data.set_refine_attempts_for_character(
                    crafter, attempts)
                self.msg("The roll is %s, a quality level of %s." %
                         (roll, QUALITY_LEVELS[quality]))
                if quality <= old:
                    caller.msg(
                        "You failed to improve %s; the quality will remain %s."
                        % (targ, QUALITY_LEVELS[old]))
                    return
                caller.msg("New quality level is %s." %
                           QUALITY_LEVELS[quality])
                change_quality(targ, quality)
                return
        proj = caller.db.crafting_project
        if not proj:
            caller.msg("You have no crafting project.")
            return
        if "name" in self.switches:
            if not self.args:
                caller.msg("Name it what?")
                return
            if not validate_name(self.args):
                caller.msg("That is not a valid name.")
                return
            proj[1] = self.args
            caller.db.crafting_project = proj
            caller.msg("Name set to %s." % self.args)
            return
        if "desc" in self.switches:
            if not self.args:
                caller.msg("Describe it how?")
                return

            if not self.can_apply_templates(self.caller, self.args):
                return

            proj[2] = self.args
            caller.db.crafting_project = proj
            caller.msg("Desc set to:\n%s" % self.args)
            return
        if "abandon" in self.switches:
            caller.msg(
                "You have abandoned this crafting project. You may now start another."
            )
            caller.db.crafting_project = None
            return
        if "translated_text" in self.switches:
            if not (self.lhs and self.rhs):
                caller.msg("Usage: craft/translated_text <language>=<text>")
                return
            lhs = self.lhs.lower()
            if lhs not in self.caller.languages.known_languages:
                caller.msg("Nice try. You cannot speak %s." % self.lhs)
                return
            proj[5].update({lhs: self.rhs})
            caller.db.crafting_project = proj
            self.display_project(proj)
            return
        if "altdesc" in self.switches:
            if not self.args:
                caller.msg(
                    "Describe them how? This is only used for disguise recipes."
                )
                return
            proj[6] = self.args
            caller.msg(
                "This is only used for disguise recipes. Alternate description set to:\n%s"
                % self.args)
            return
        if "adorn" in self.switches:
            if not (self.lhs and self.rhs):
                caller.msg("Usage: craft/adorn <material>=<amount>")
                return
            try:
                mat = CraftingMaterialType.objects.get(name__iexact=self.lhs)
                amt = int(self.rhs)
            except CraftingMaterialType.DoesNotExist:
                caller.msg("No material named %s." % self.lhs)
                return
            except CraftingMaterialType.MultipleObjectsReturned:
                caller.msg("More than one match. Please be more specific.")
                return
            except (TypeError, ValueError):
                caller.msg("Amount must be a number.")
                return
            if amt < 1:
                caller.msg("Amount must be positive.")
                return
            recipe = CraftingRecipe.objects.get(id=proj[0])
            if not recipe.allow_adorn:
                caller.msg(
                    "This recipe does not allow for additional materials to be used."
                )
                return
            adorns = proj[3] or {}
            adorns[mat.id] = amt
            proj[3] = adorns
            caller.db.crafting_project = proj
            caller.msg(
                "Additional materials: %s" %
                ", ".join("%s: %s" %
                          (CraftingMaterialType.objects.get(id=mat).name, amt)
                          for mat, amt in adorns.items()))
            return
        if "forgery" in self.switches:
            self.msg("Temporarily disabled until I have time to revamp this.")
            return
        if "preview" in self.switches:
            if self.args:
                viewer = self.caller.player.search(self.args)
                if not viewer:
                    return
                viewer.msg(
                    "{c%s{n is sharing a preview of their crafting project with you."
                    % self.caller)
                self.msg(
                    "You share a preview of your crafting project with %s." %
                    viewer)
            else:
                viewer = self.caller.player
            name = proj[1] or "[No Name Yet]"
            viewer.msg("{wPreview of {n%s {wdesc:{n\n%s" % (name, proj[2]))
            return
        # do rolls for our crafting. determine quality level, handle forgery stuff
        if "finish" in self.switches:
            if not proj[1]:
                caller.msg("You must give it a name first.")
                return
            if not proj[2]:
                caller.msg("You must write a description first.")
                return
            invest = 0
            action_points = 0
            if self.lhs:
                try:
                    invest = int(self.lhslist[0])
                    if len(self.lhslist) > 1:
                        action_points = int(self.lhslist[1])
                except ValueError:
                    caller.msg(
                        "Silver/Action Points to invest must be a number.")
                    return
                if invest < 0 or action_points < 0:
                    caller.msg(
                        "Silver/Action Points cannot be a negative number.")
                    return
            # first, check if we have all the materials required
            mats = {}
            try:
                recipe = recipes.get(id=proj[0])
            except CraftingRecipe.DoesNotExist:
                caller.msg("You lack the ability to finish that recipe.")
                return
            if not self.check_max_invest(recipe, invest):
                return
            if recipe.type == "disguise":
                if not proj[6]:
                    caller.msg(
                        "This kind of item requires craft/altdesc before it can be finished."
                    )
                    return
            for mat in recipe.materials.all():
                mats[mat.id] = mats.get(mat.id, 0) + mat.amount
            for adorn in proj[3]:
                mats[adorn] = mats.get(adorn, 0) + proj[3][adorn]
            # replace with forgeries
            for rep in proj[4].keys():
                # rep is ID to replace
                forg = proj[4][rep]
                if rep in mats:
                    amt = mats[rep]
                    del mats[rep]
                    mats[forg] = amt
            # check silver cost
            try:
                price = self.get_recipe_price(recipe)
            except ValueError:
                caller.msg("That recipe does not have a price defined.")
                return
            cost = recipe.additional_cost + invest + price
            if cost < 0 or price < 0:
                errmsg = "For %s at %s, recipe %s, cost %s, price %s" % (
                    caller,
                    caller.location,
                    recipe.id,
                    cost,
                    price,
                )
                raise ValueError(errmsg)
            if not caller.check_permstring("builders"):
                if caller.db.currency < cost:
                    caller.msg(
                        "The recipe costs %s on its own, and you are trying to spend an additional %s."
                        % (recipe.additional_cost, invest))
                    if price:
                        caller.msg(
                            "The additional price charged by the crafter for this recipe is %s."
                            % price)
                    caller.msg("You need %s silver total, and have only %s." %
                               (cost, caller.db.currency))
                    return
                pmats = caller.player.Dominion.assets.materials
                # add up the total cost of the materials we're using for later
                realvalue = 0
                for mat in mats:
                    try:
                        c_mat = CraftingMaterialType.objects.get(id=mat)
                    except CraftingMaterialType.DoesNotExist:
                        inform_staff(
                            "Attempted to craft using material %s which does not exist."
                            % mat)
                        self.msg(
                            "One of the materials required no longer seems to exist. Informing staff."
                        )
                        return
                    try:
                        pmat = pmats.get(type=c_mat)
                        if pmat.amount < mats[mat]:
                            caller.msg("You need %s of %s, and only have %s." %
                                       (mats[mat], c_mat.name, pmat.amount))
                            return
                        realvalue += c_mat.value * mats[mat]
                    except CraftingMaterials.DoesNotExist:
                        caller.msg("You do not have any of the material %s." %
                                   c_mat.name)
                        return
                # check if they have enough action points
                if not caller.player_ob.pay_action_points(2 + action_points):
                    self.msg(
                        "You do not have enough action points left to craft that."
                    )
                    return
                # pay the money
                caller.pay_money(cost)
                # we're still here, so we have enough materials. spend em all
                for mat in mats:
                    cmat = CraftingMaterialType.objects.get(id=mat)
                    pmat = pmats.get(type=cmat)
                    pmat.amount -= mats[mat]
                    pmat.save()
            else:
                realvalue = recipe.value
            # determine difficulty modifier if we tossed in more money
            ability = get_ability_val(crafter, recipe)
            diffmod = get_difficulty_mod(recipe, invest, action_points,
                                         ability)
            # do crafting roll
            roll = do_crafting_roll(crafter,
                                    recipe,
                                    diffmod,
                                    room=caller.location)
            # get type from recipe
            otype = recipe.type
            # create object
            if otype == "wieldable":
                obj, quality = create_weapon(recipe, roll, proj, caller)
            elif otype == "wearable":
                obj, quality = create_wearable(recipe, roll, proj, caller)
            elif otype == "place":
                obj, quality = create_place(recipe, roll, proj, caller)
            elif otype == "book":
                obj, quality = create_book(recipe, roll, proj, caller)
            elif otype == "container":
                obj, quality = create_container(recipe, roll, proj, caller)
            elif otype == "decorative_weapon":
                obj, quality = create_decorative_weapon(
                    recipe, roll, proj, caller)
            elif otype == "wearable_container":
                obj, quality = create_wearable_container(
                    recipe, roll, proj, caller)
            elif otype == "perfume":
                obj, quality = create_consumable(recipe, roll, proj, caller,
                                                 PERFUME)
            elif otype == "disguise":
                obj, quality = create_mask(recipe, roll, proj, caller, proj[6])
            else:
                obj, quality = create_generic(recipe, roll, proj, caller)
            # finish stuff universal to all crafted objects
            obj.desc = proj[2]
            obj.save()

            self.apply_templates_to(obj)

            obj.item_data.materials = mats
            obj.item_data.recipe = recipe.id
            obj.item_data.adorns = proj[3]
            obj.item_data.crafted_by = crafter
            obj.item_data.size = int(recipe.resultsdict.get("volume", 0))
            self.pay_owner(
                price,
                "%s has crafted '%s', a %s, at your shop and you earn %s silver."
                % (caller, obj, recipe.name, price),
            )
            try:
                if proj[5]:
                    obj.item_data.translation = proj[5]
            except IndexError:
                pass
            cnoun = "You" if caller == crafter else crafter
            caller.msg("%s created %s." % (cnoun, obj.name))
            quality = QUALITY_LEVELS[quality]
            caller.msg("It is of %s quality." % quality)
            caller.db.crafting_project = None
            return
Пример #3
0
 def func(self):
     """Executes agents command"""
     caller = self.caller
     personal = Agent.objects.filter(owner__player__player=caller)
     orgs = [
         org.assets for org in Organization.objects.filter(
             members__player=caller.Dominion)
         if org.access(caller, 'guards')
     ]
     house = Agent.objects.filter(
         owner__organization_owner__members__player__player=caller,
         owner__organization_owner__in=[
             org.organization_owner for org in orgs
         ])
     agents = personal | house
     if not self.args:
         caller.msg(
             "{WYour agents:{n\n%s" %
             "".join(agent.display(caller=self.caller) for agent in agents),
             options={'box': True})
         barracks = self.find_barracks(caller.Dominion.assets)
         for org in orgs:
             barracks.extend(self.find_barracks(org))
         caller.msg("{wBarracks locations:{n %s" %
                    ", ".join(ob.key for ob in barracks))
         return
     if not self.switches:
         try:
             org = Organization.objects.get(name__iexact=self.args,
                                            members__player=caller.Dominion)
         except Organization.DoesNotExist:
             caller.msg(
                 "You are not a member of an organization named %s." %
                 self.args)
             return
         caller.msg(", ".join(agent.display()
                              for agent in org.assets.agents.all()),
                    options={'box': True})
         barracks = self.find_barracks(org.assets)
         caller.msg("{wBarracks locations:{n %s" %
                    ", ".join(ob.key for ob in barracks))
         return
     try:
         owner_ids = []
         loc = caller.character.location
         if loc == caller.character.home:
             owner_ids.append(caller.Dominion.assets.id)
         if loc.db.barracks_owner:
             owner_ids.append(loc.db.barracks_owner)
         if loc.db.room_owner:
             owner_ids.append(loc.db.room_owner)
         if owner_ids:
             owners = [
                 ob for ob in AssetOwner.objects.filter(id__in=owner_ids)
                 if ob == caller.Dominion.assets or (
                     ob.organization_owner
                     and ob.organization_owner.access(caller, 'guards'))
             ]
             if not owners:
                 caller.msg("You do not have access to guards here.")
         else:
             self.msg("You do not have access to guards here.")
             return
         owner_ids = [ob.id for ob in owners]
         owner_names = ", ".join(str(ob) for ob in owners)
     except (AttributeError, AssetOwner.DoesNotExist, ValueError,
             TypeError):
         caller.msg("You do not have access to guards here.")
         return
     if not self.lhslist:
         caller.msg("Must provide arguments separated by commas.")
         return
     if 'guard' in self.switches:
         try:
             player, pid, amt = self.lhslist
             amt = int(amt)
             if amt < 1:
                 self.msg("Must assign a positive number.")
                 return
             pid = int(pid)
             targ = caller.search(player)
             if not targ:
                 caller.msg("Could not find player by name %s." % player)
                 return
             avail_agent = Agent.objects.get(id=pid, owner_id__in=owner_ids)
             if avail_agent.quantity < amt:
                 caller.msg(
                     "You tried to assign %s, but only have %s available." %
                     (amt, avail_agent.quantity))
                 return
             try:
                 # assigning it to their character
                 targ = targ.db.char_ob
                 if not targ:
                     caller.msg("They have no character to assign to.")
                     return
                 cap = self.get_guard_cap(targ)
                 if targ.num_guards + amt > cap:
                     caller.msg(
                         "They can only have %s guards assigned to them." %
                         cap)
                     return
                 avail_agent.assign(targ, amt)
                 if avail_agent.unique:
                     self.msg("Assigned %s to %s." % (avail_agent, targ))
                 else:
                     caller.msg("Assigned %s %s to %s." %
                                (amt, avail_agent.name, targ))
                 return
             except ValueError as err:
                 caller.msg(err)
                 return
         except Agent.DoesNotExist:
             caller.msg("%s owns no agents by that name." % owner_names)
             agents = Agent.objects.filter(owner_id__in=owner_ids)
             caller.msg("{wAgents:{n %s" % ", ".join("%s (#%s)" %
                                                     (agent.name, agent.id)
                                                     for agent in agents))
             return
         except ValueError:
             caller.msg(
                 "Invalid usage: provide player, ID, and amount, separated by commas."
             )
             return
     if 'recall' in self.switches:
         try:
             pname, pid, amt = self.lhslist
             player = caller.search(pname)
             if not player:
                 caller.msg("No player found by %s." % pname)
                 return
             amt = int(amt)
             pid = int(pid)
             if amt < 1:
                 raise ValueError
             agent = Agent.objects.get(id=pid)
             if agent.owner.id not in owner_ids:
                 self.msg(
                     "They are owned by %s, and must be recalled from their barracks."
                     % agent.owner)
                 return
             # look through our agent actives for a dbobj assigned to player
             agentob = agent.find_assigned(player)
             if not agentob:
                 caller.msg("No agents assigned to %s by %s." %
                            (player, owner_names))
                 return
             num = agentob.recall(amt)
             if agent.unique:
                 caller.msg("You have recalled %s from %s." %
                            (agent, player))
             else:
                 caller.msg(
                     "You have recalled %s from %s. They have %s left." %
                     (num, player, agentob.quantity))
             return
         except Agent.DoesNotExist:
             caller.msg("No agents found for those arguments.")
             return
         except ValueError:
             caller.msg("Amount and ID must be positive numbers.")
             return
     if 'hire' in self.switches:
         try:
             org = caller.Dominion.current_orgs.get(name__iexact=self.rhs)
             owner = org.assets
         except (AttributeError, Organization.DoesNotExist):
             caller.msg("You are not in an organization by that name.")
             return
         try:
             gtype, level, amt = self.lhslist[0], int(self.lhslist[1]), int(
                 self.lhslist[2])
         except (IndexError, TypeError, ValueError):
             caller.msg(
                 "Please give the type, level, and amount of agents to buy."
             )
             return
         if not org.access(caller, 'agents'):
             caller.msg(
                 "You do not have permission to hire agents for %s." % org)
             return
         types = self.get_allowed_types_from_org(org)
         if gtype not in types:
             caller.msg("%s is not a type %s is allowed to hire." %
                        (gtype, org))
             caller.msg("You can buy: %s" % ", ".join(types))
             return
         if level < 0 or amt < 1:
             self.msg("Level and amt must be positive.")
             return
         gtype_num = get_npc_type(gtype)
         cost = self.get_cost(level)
         cost *= amt
         if owner.military < cost:
             caller.msg(
                 "%s does not enough military resources. Cost was %s." %
                 (owner, cost))
             return
         owner.military -= cost
         owner.save()
         # get or create agents of the appropriate type
         try:
             agent = owner.agents.get(quality=level, type=gtype_num)
         except Agent.DoesNotExist:
             gname, gdesc = generate_default_name_and_desc(
                 gtype_num, level, org)
             agent = owner.agents.create(quality=level,
                                         type=gtype_num,
                                         name=gname,
                                         desc=gdesc)
         except Agent.MultipleObjectsReturned:
             agent = owner.agents.filter(quality=level, type=gtype_num)[0]
         agent.quantity += amt
         agent.save()
         caller.msg("You bought %s, and now have %s." % (amt, agent))
         return
     if 'desc' in self.switches or 'name' in self.switches or 'transferowner' in self.switches:
         try:
             agent = Agent.objects.get(id=int(self.lhslist[0]))
             strval = self.rhs
             if not agent.access(caller, 'agents'):
                 caller.msg("No access.")
                 return
             if 'desc' in self.switches:
                 attr = 'desc'
                 strval = strval or ", ".join(self.lhslist[1:])
                 agent.desc = strval
             elif 'name' in self.switches:
                 strval = strval or ", ".join(self.lhslist[1:])
                 name = strval
                 if not validate_name(name):
                     self.msg("That is not a valid name.")
                     return
                 agent.set_name(name)
                 self.msg("Name changed to %s" % name)
                 return
             elif 'transferowner' in self.switches:
                 attr = 'owner'
                 strval = self.lhslist[1]
                 try:
                     agent.owner = AssetOwner.objects.get(
                         Q(player__player__username__iexact=self.lhslist[1])
                         | Q(organization_owner__name__iexact=self.
                             lhslist[1]))
                     if agent.unique:
                         agent.dbobj.unassign()
                         try:
                             char = agent.owner.player.player.db.char_ob
                             agent.assign(char, 1)
                         except AttributeError:
                             pass
                 except AssetOwner.DoesNotExist:
                     self.msg("No owner found by that name to transfer to.")
                     return
             else:
                 self.msg("Invalid attr")
                 return
             agent.save()
             # do we need to do any refresh_from_db calls here to prevent sync errors with stale foreignkeys?
             caller.msg("Changed %s to %s." % (attr, strval))
             if attr == 'owner':
                 agent.owner.inform_owner(
                     "You have been transferred ownership of %s from %s." %
                     (agent, caller),
                     category="agents")
             return
         except IndexError:
             self.msg("Wrong number of arguments.")
         except (TypeError, ValueError):
             self.msg("Wrong type of arguments.")
         except Agent.DoesNotExist:
             caller.msg("No agent found by that number.")
             return
     self.msg("Unrecognized switch.")
Пример #4
0
    def func(self):
        """Implement the command"""
        caller = self.caller
        try:
            dompc = PlayerOrNpc.objects.get(player=caller.player)
            AssetOwner.objects.get(player=dompc)
        except PlayerOrNpc.DoesNotExist:
            # dominion not set up on player
            setup_dom_for_char(caller)
        except AssetOwner.DoesNotExist:
            # assets not initialized on player
            setup_dom_for_char(caller, create_dompc=False)

        if not self.args and not self.switches:
            project = caller.db.startgear_project
            if project:
                caller.msg(self.display_project(project))
                caller.msg("{wTo finish it, use /finish.")
            caller.msg(
                "You have the equivalent of {w%s{n silver remaining to spend on gear."
                % caller.db.startgear_val)
            return
        # start a crafting project
        if not self.switches:
            try:
                recipe = CraftingRecipe.objects.get(name__iexact=self.lhs)
            except CraftingRecipe.DoesNotExist:
                caller.msg("No recipe found by the name %s." % self.lhs)
                return
            # proj = [id, name, desc, adorns, altdesc]
            proj = [recipe.id, "", "", {}, ""]
            cost = recipe.value
            caller.msg("Its cost is {w%s{n." % cost)
            if cost > caller.db.startgear_val:
                caller.msg(
                    "{rYou only have {w%s{r silver remaining for gear.{n" %
                    caller.db.startgear_val)
                return
            caller.db.startgear_project = proj
            caller.msg("{wYou have started to craft:{n %s." % recipe.name)
            caller.msg("You will have {w%s{n remaining after finishing." %
                       (caller.db.startgear_val - cost))
            caller.msg(
                "{wTo finish it, use /finish after you set its name and description."
            )
            caller.msg("{wTo abandon this, use /abandon.{n")
            return
        proj = caller.db.startgear_project
        if not proj and "refundremainder" not in self.switches:
            caller.msg("You have no crafting project.")
            return
        if "adorn" in self.switches:
            if not (self.lhs and self.rhs):
                caller.msg("Usage: craft/adorn <material>=<amount>")
                return
            try:
                mat = CraftingMaterialType.objects.get(name__iexact=self.lhs)
                amt = int(self.rhs)
            except CraftingMaterialType.DoesNotExist:
                caller.msg("No material named %s." % self.lhs)
                return
            except CraftingMaterialType.MultipleObjectsReturned:
                caller.msg("More than one match. Please be more specific.")
                return
            except (TypeError, ValueError):
                caller.msg("Amount must be a number.")
                return
            if amt < 1:
                caller.msg("Amount must be positive.")
                return
            recipe = CraftingRecipe.objects.get(id=proj[0])
            if not recipe.allow_adorn:
                caller.msg(
                    "This recipe does not allow for additional materials to be used."
                )
                return

            cost = recipe.value
            adorns = proj[3] or {}
            adorns[mat.id] = amt
            for adorn_id in adorns:
                mat = CraftingMaterialType.objects.get(id=adorn_id)
                amt = adorns[adorn_id]
                cost += mat.value * amt
            caller.msg("The cost of your item is now %s." % cost)
            if cost > caller.db.startgear_val:
                caller.msg(
                    "You cannot afford those adorns. Removing them all.")
                proj[3] = {}
                return
            proj[3] = adorns
            caller.db.crafting_project = proj
            caller.msg(
                "Additional materials: %s" %
                ", ".join("%s: %s" %
                          (CraftingMaterialType.objects.get(id=mat).name, amt)
                          for mat, amt in adorns.items()))
            return
        if "name" in self.switches:
            if not self.args:
                caller.msg("Name it what?")
                return
            if not arx_utils.validate_name(self.args):
                caller.msg("That is not a valid name.")
                return
            proj[1] = self.args
            caller.db.startgear_project = proj
            caller.msg("Name set to %s." % self.args)
            return
        if "desc" in self.switches:
            if not self.args:
                caller.msg("Name it what?")
                return
            proj[2] = self.args
            caller.db.startgear_project = proj
            caller.msg("Desc set to:\n%s" % self.args)
            return
        if "altdesc" in self.switches:
            if not self.args:
                caller.msg(
                    "Describe them how? This is only used for disguise recipes."
                )
                return
            proj[4] = self.args
            caller.msg(
                "This is only used for disguise recipes. Alternate description set to:\n%s"
                % self.args)
            return
        if "abandon" in self.switches or "abort" in self.switches:
            caller.msg(
                "You have abandoned this crafting project. You may now start another."
            )
            caller.attributes.remove("startgear_project")
            return
        # do rolls for our crafting. determine quality level, handle forgery stuff
        if "finish" in self.switches:
            if not proj[1]:
                caller.msg("You must give it a name first.")
                return
            if not proj[2]:
                caller.msg("You must write a description first.")
                return
            # first, check if we have all the materials required
            mats = {}
            recipe = CraftingRecipe.objects.get(id=proj[0])
            cost = recipe.value
            for mat in recipe.required_materials.all():
                mats[mat.id] = mats.get(mat.type_id, 0) + mat.amount
            for adorn in proj[3]:
                mats[adorn] = mats.get(adorn, 0) + proj[3][adorn]
                mat = CraftingMaterialType.objects.get(id=adorn)
                cost += mat.value * proj[3][adorn]
            if caller.db.startgear_val < cost:
                caller.msg(
                    "You need %s silver to finish the recipe, and have only %s."
                    % (cost, caller.db.startgear_val))
                return
            caller.db.startgear_val -= cost
            # quality will always be average
            roll = 0
            # get type from recipe
            otype = recipe.type
            # create object
            crafter = caller
            if otype == "wieldable":
                obj, quality = create_weapon(recipe, roll, proj, caller,
                                             crafter)
            elif otype == "wearable":
                obj, quality = create_wearable(recipe, roll, proj, caller,
                                               crafter)
            elif otype == "place":
                obj, quality = create_place(recipe, roll, proj, caller,
                                            crafter)
            elif otype == "container":
                obj, quality = create_container(recipe, roll, proj, caller,
                                                crafter)
            elif otype == "decorative_weapon":
                obj, quality = create_decorative_weapon(
                    recipe, roll, proj, caller, crafter)
            elif otype == "wearable_container":
                obj, quality = create_wearable_container(
                    recipe, roll, proj, caller, crafter)
            elif otype == "perfume":
                obj, quality = create_consumable(recipe, roll, proj, caller,
                                                 PERFUME, crafter)
            elif otype == "disguise":
                obj, quality = create_mask(recipe, roll, proj, caller, proj[6],
                                           crafter)
            else:
                obj, quality = create_generic(recipe, roll, proj, caller,
                                              crafter)
            # finish stuff universal to all crafted objects
            obj.desc = proj[2]
            obj.save()
            for mat_id, amount in proj[3].items():
                obj.item_data.add_adorn(mat_id, amount)
            caller.msg("You created %s." % obj.name)
            caller.attributes.remove("startgear_project")
            return
        if "refundremainder" in self.switches:
            money = caller.db.currency or 0.0
            refund = caller.db.startgear_val
            money += refund
            caller.attributes.remove("startgear_val")
            caller.db.currency = money
            caller.msg("You receive %s silver coins." % refund)
            caller.cmdset.delete(StartingGearCmdSet)
            return
        caller.msg("Invalid switch.")