Exemplo n.º 1
0
 def func(self):
     """Implement the command"""
     caller = self.caller
     all_recipes = CraftingRecipe.objects.all()
     recipes = all_recipes.filter(known_by__player__player=caller.player)
     unknown = all_recipes.exclude(known_by__player__player=caller.player)
     if self.args and (not self.switches or "known" in self.switches):
         filters = (Q(name__iexact=self.args)
                    | Q(skill__iexact=self.args)
                    | Q(ability__iexact=self.args))
         recipes = recipes.filter(filters)
         unknown = unknown.filter(filters)
     orgs = AssetOwner.objects.select_related("organization_owner").filter(
         organization_owner__isnull=False)
     unknown = unknown.prefetch_related(
         Prefetch("known_by", queryset=orgs, to_attr="_org_owners"))
     recipes = list(recipes)
     can_learn = [ob for ob in unknown if ob.can_be_learned_by(self.caller)]
     try:
         dompc = PlayerOrNpc.objects.get(player=caller.player)
     except PlayerOrNpc.DoesNotExist:
         dompc = setup_dom_for_char(caller)
     if not self.switches:
         visible = recipes + can_learn
         self.display_recipes(visible)
         return
     if "known" in self.switches:
         self.display_recipes(recipes)
         return
     if "learn" in self.switches or "cost" in self.switches:
         match = None
         if self.args:
             match = [
                 ob for ob in can_learn
                 if ob.name.lower() == self.args.lower()
             ]
         if not match:
             learn_msg = ("You cannot learn '%s'. " %
                          self.lhs) if self.lhs else ""
             caller.msg("%sRecipes you can learn:" % learn_msg)
             self.display_recipes(can_learn)
             return
         match = match[0]
         cost = 0 if caller.check_permstring(
             "builders") else match.additional_cost
         cost_msg = "It will cost %s for you to learn %s." % (
             cost or "nothing",
             match.name,
         )
         if "cost" in self.switches:
             return caller.msg(cost_msg)
         elif cost > caller.currency:
             return caller.msg("You have %s silver. %s" %
                               (caller.currency, cost_msg))
         caller.pay_money(cost)
         dompc.assets.recipes.add(match)
         coststr = (" for %s silver" % cost) if cost else ""
         caller.msg("You have learned %s%s." % (match.name, coststr))
         return
     if "info" in self.switches:
         match = None
         info = list(can_learn) + list(recipes)
         if self.args:
             match = [
                 ob for ob in info if ob.name.lower() == self.args.lower()
             ]
         if not match:
             caller.msg(
                 "No recipe by that name. Recipes you can get /info on:")
             self.display_recipes(info)
             return
         match = match[0]
         display = match.display_reqs(dompc, full=True)
         caller.msg(display, options={"box": True})
         return
     if "teach" in self.switches:
         match = None
         can_teach = [ob for ob in recipes if ob.access(caller, "teach")]
         if self.rhs:
             match = [
                 ob for ob in can_teach
                 if ob.name.lower() == self.rhs.lower()
             ]
         if not match:
             teach_msg = ("You cannot teach '%s'. " %
                          self.rhs) if self.rhs else ""
             caller.msg("%sRecipes you can teach:" % teach_msg)
             self.display_recipes(can_teach)
             return
         recipe = match[0]
         character = caller.search(self.lhs)
         if not character:
             return
         if not recipe.access(character, "learn"):
             caller.msg("They cannot learn %s." % recipe.name)
             return
         try:
             dompc = PlayerOrNpc.objects.get(player=character.player)
         except PlayerOrNpc.DoesNotExist:
             dompc = setup_dom_for_char(character)
         if recipe in dompc.assets.recipes.all():
             caller.msg("They already know %s." % recipe.name)
             return
         dompc.assets.recipes.add(recipe)
         caller.msg("Taught %s %s." % (character, recipe.name))
Exemplo n.º 2
0
 def func(self):
     """Execute command."""
     caller = self.caller
     try:
         dompc = caller.player.Dominion
     except AttributeError:
         dompc = setup_utils.setup_dom_for_char(caller)
     org_accounts = [member.organization.assets for member in dompc.memberships.filter(deguilded=False)]
     all_accounts = [dompc.assets] + org_accounts
     if ("payments" in self.switches or "endpayment" in self.switches or "adjustpayment" in self.switches
             or "payment" in self.switches):
         debts = list(dompc.assets.debts.all())
         for acc in org_accounts:
             if acc.can_be_viewed_by(caller) and acc.debts.all():
                 debts += list(acc.debts.all())
         if not self.args:                
             caller.msg(str(self.get_debt_table(debts)), options={'box': True})
             return
         if "endpayment" in self.switches or "adjustpayment" in self.switches:
             try:
                 if "endpayment" in self.switches:
                     debts += list(dompc.assets.incomes.all())
                 val = int(self.lhs)
                 debt = AccountTransaction.objects.get(id=val, id__in=(ob.id for ob in debts))
             except (ValueError, AccountTransaction.DoesNotExist):
                 caller.msg("Invalid number. Select one of the following:")
                 caller.msg(str(self.get_debt_table(debts)), options={'box': True})
                 return
             if "endpayment" in self.switches:
                 debt.delete()
                 caller.msg("Payment cancelled.")
                 return
             try:
                 amt = int(self.rhs)
                 if amt <= 0:
                     raise ValueError
             except ValueError:
                 caller.msg("Please give a positive value as the new amount.")
                 return
             check = self.check_money(debt.sender, (amt - debt.weekly_amount))
             if check < 0:
                 caller.msg("Insufficient funds. You need %s more." % (-check))
                 return
             debt.weekly_amount = amt
             debt.save()
             caller.msg("Weekly payment amount is now %s." % amt)
             return
         # set up a new payment
         try:
             sender = self.match_account(all_accounts, self.lhslist[0])
             if not sender:
                 return
             if not sender.access(caller, 'withdraw'):
                 caller.msg("You lack permission to set up a payment.")
                 return
             amt = int(self.lhslist[1])
             if amt <= 0:
                 raise ValueError
             try:
                 receiver = AssetOwner.objects.get(player__player__username__iexact=self.rhs)
             except AssetOwner.DoesNotExist:
                 receiver = AssetOwner.objects.get(organization_owner__name__iexact=self.rhs)
             if sender == receiver:
                 caller.msg("Sender and receiver must be different.")
                 return
         except (ValueError, IndexError):
             caller.msg("Must give a positive number as an amount.")
             return
         except (AssetOwner.DoesNotExist, AssetOwner.MultipleObjectsReturned):
             caller.msg("Could find neither a player nor organization by that name.")
             return
         check = self.check_money(sender, amt)
         if check < 0:
             caller.msg("Insufficient funds: %s more required to set up payment." % (-check))
             return
         sender.debts.create(receiver=receiver, weekly_amount=amt, repetitions_left=-1)
         caller.msg("New weekly payment set up: %s pays %s to %s every week." % (sender, amt, receiver))
         return
     if not self.args:
         msg = "{wAccounts{n".center(60)
         msg += "\n"
         actable = evtable.EvTable("{wOwner{n", "{wBalance{n", "{wNet Income{n", "{wMaterials{n",
                                   "{wEcon{n", "{wSoc{n", "{wMil{n", width=78, border="cells")
         
         for account in all_accounts:
             if not account.can_be_viewed_by(self.caller):
                 continue
             mats = ", ".join(str(mat) for mat in account.materials.filter(amount__gte=1))
             actable.add_row(str(account.owner), str(account.vault), str(account.net_income),
                             mats, account.economic, account.social, account.military)
             actable.reformat_column(0, width=14)
             actable.reformat_column(1, width=11)
             actable.reformat_column(2, width=10)
             actable.reformat_column(3, width=21)
             actable.reformat_column(4, width=8)
             actable.reformat_column(5, width=7)
             actable.reformat_column(6, width=7)
             incomes = account.incomes.all()
             debts = account.debts.all()               
             if incomes:
                 msg += ("{w%s Incomes{n" % str(account)).center(60)
                 msg += "\n"
                 table = evtable.EvTable("{wSender{n", "{wAmount{n", "{wTime Remaining{n", width=60)
                 for inc in incomes:
                     time = "Permanent" if inc.repetitions_left == -1 else inc.repetitions_left
                     table.add_row(inc.sender, inc.weekly_amount, time)
                 msg += str(table)
                 msg += "\n"
             if debts:
                 msg += ("{w%s Payments{n" % str(account)).center(60)
                 msg += "\n"
                 msg += str(self.get_debt_table(debts))
                 msg += "\n"
         msg += str(actable)
         caller.msg(msg, options={'box': True})
         return       
     if ("depositmats" in self.switches or "withdrawmats" in self.switches
             or "depositres" in self.switches or "withdrawres" in self.switches):
         account = self.match_account(all_accounts)
         if not account:
             return
         if account == dompc.assets:
             caller.msg("Characters always have access to their own materials as an "
                        "abstraction, so withdraws and deposits " +
                        "are only between organizations and characters.")
             return
         usingmats = "depositmats" in self.switches or "withdrawmats" in self.switches
         if usingmats:
             attr_type = "materials"
         else:
             attr_type = "resources"
         if "depositmats" in self.switches or "depositres" in self.switches:
             sender = dompc.assets
             receiver = account
             verb = "deposit"
         else:
             if not account.access(caller, 'withdraw'):
                 caller.msg("You do not have permission to withdraw from that account.")
                 return
             receiver = dompc.assets
             sender = account
             verb = "withdraw"
         try:
             matname, val = self.lhslist[0], int(self.lhslist[1])
             source = sender
             targ = receiver
             if val <= 0:
                 caller.msg("You must specify a positive number.")
                 return
             if usingmats:
                 source = sender.materials.get(type__name__iexact=matname)
                 if source.amount < val:
                     caller.msg("You tried to %s %s %s, but only %s available." % (
                         verb, val, source.type.name, source.amount))
                     return
                 try:
                     targ = receiver.materials.get(type__name__iexact=matname)
                 except CraftingMaterials.DoesNotExist:
                     targ = receiver.materials.create(type=source.type, amount=0)
                 source.amount -= val
                 targ.amount += val
                 samt = source.amount
                 tamt = targ.amount
             else:
                 restypes = ("economic", "social", "military")
                 matname = matname.lower()
                 if matname not in restypes:
                     caller.msg("Resource must be one of: %s" % ", ".join(restypes))
                     return
                 sresamt = getattr(sender, matname)
                 if sresamt < val:
                     matname += " resources"
                     caller.msg("You tried to %s %s %s, but only %s available." % (
                         verb, val, matname, sresamt))
                     return
                 tresamt = getattr(receiver, matname)
                 samt = sresamt - val
                 tamt = tresamt + val
                 setattr(sender, matname, samt)
                 setattr(receiver, matname, tamt)
                 matname += " resources"
             source.save()    
             targ.save()
             caller.msg("You have transferred %s %s from %s to %s." % (
                 val, matname, sender, receiver))
             if account.can_be_viewed_by(caller):
                 caller.msg("Sender now has %s, receiver has %s." % (samt, tamt))
             else:
                 caller.msg("Transaction successful.")
             self.inform_owner(account, verb, val, attr_type, matname)
         except CraftingMaterials.DoesNotExist:
             caller.msg("No match for that material. Valid materials: %s" % ", ".join(
                 str(mat) for mat in sender.materials.all()))
             return
         except (ValueError, IndexError):
             caller.msg("Invalid usage.")
             return
         return
     try:
         amount = int(self.lhs)
         if amount <= 0:
             caller.msg("Amount must be positive.")
             return
     except ValueError:
         caller.msg("Amount must be a number.")
         return
     if not self.rhs:
         account = dompc.assets
     else:
         account = self.match_account(all_accounts)
         if not account:
             return
     if "deposit" in self.switches:
         cash = caller.db.currency or 0.0
         if not cash:
             caller.msg("You have no money to deposit.")
             return
         if amount > cash:
             caller.msg("You tried to deposit %s, but only have %s on hand." % (amount, cash))
             return
         account.vault += amount
         caller.db.currency = cash - amount
         account.save()
         if account.can_be_viewed_by(caller):
             caller.msg("You have deposited %s. The new balance is %s." % (amount, account.vault))
         else:
             caller.msg("You have deposited %s." % amount)
         self.inform_owner(account, "deposited", amount)
         return
     if "withdraw" in self.switches:
         if not account.access(caller, "withdraw"):
             caller.msg("You do not have permission to withdraw from that account.")
             return
         cash = caller.db.currency or 0.0
         check = self.check_money(account, amount)
         if check < 0:
             caller.msg("You cannot withdraw more than the balance minus an account's debt obligations.")
             caller.msg("You want to withdraw %s but only %s is available after debt obligations." % (amount,
                                                                                                      check+amount))
             if account.debts.all():
                 caller.msg("Cancelling payments would increase the amount available.")
                 return
             return
         account.vault -= amount
         caller.db.currency = cash + amount
         account.save()
         caller.msg("You have withdrawn %s. New balance is %s." % (amount, account.vault))
         self.inform_owner(account, "withdrawn", amount)
         return
     else:
         caller.msg("Unrecognized switch.")
         return
Exemplo n.º 3
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
Exemplo n.º 4
0
    def func(self):
        """Implement the command"""

        caller = self.caller
        args = self.args
        switches = self.switches
        apps = get_apps_manager(caller)
        if not apps:
            caller.msg(
                "Apps manager not found! Please inform the administrators.")
            return
        if not args and not switches:
            # '@app'
            # List all pending applications
            all_apps = apps.view_all_apps()
            if not all_apps:
                caller.msg("No applications found.")
                return
            # application[9] field is 'True' if pending/open
            pend_list = [app for app in all_apps.values() if app[9]]
            if not pend_list:
                caller.msg("No pending applications found.")
                return
            # app = [app_num, char_ob, email, date_submit, application_string,
            # gm_ob, date_answer, gm_notes, approval, pending]
            table = prettytable.PrettyTable(
                ["{w#", "{wCharacter", "{wEmail", "{wDate"])
            for app in pend_list:
                table.add_row(
                    [app[0], app[1].key.capitalize(), app[2], app[3]])
            caller.msg("{wApplications for Characters pending approval:\n%s" %
                       table)
            caller.msg("To view a particular application, @app <app number>")
            caller.msg("To view closed applications, use @app/old")
            return
        if args and not switches and not args.isdigit():
            # '@app <character>'
            # List all pending apps for a particular character
            apps_for_char = apps.view_all_apps_for_char(args)
            if not apps_for_char:
                caller.msg("No applications found.")
                return
            pend_list = [ob for ob in apps_for_char if ob[9]]
            if not pend_list:
                caller.msg("No pending applications found.")
                return
            # app = [app_num, char_ob, email, date_submit, application_string, gm_ob,
            # date_answer, gm_notes, approval, pending]
            table = prettytable.PrettyTable(
                ["{w#", "{wCharacter", "{wEmail", "{wDate"])
            for app in pend_list:
                table.add_row(
                    [app[0], app[1].key.capitalize(), app[2], app[3]])
            caller.msg("{wPending applications for %s:\n%s" % (args, table))
            caller.msg("To view a specific application, @app <app number>")
            return
        if args and args.isdigit() and (not switches or 'old' in switches):
            # '@app <#>
            # List a given ticket by
            app = apps.view_app(int(args))
            if not app:
                caller.msg("No application by that number for that character.")
                return
            email = app[2]
            alts = RosterEntry.objects.filter(current_account__email=email)
            caller.msg("{wCharacter:{n %s" % app[1].key.capitalize())
            caller.msg("{wApp Email:{n %s" % email)
            if alts:
                caller.msg("{wCurrent characters:{n %s" %
                           ", ".join(str(ob) for ob in alts))
            caller.msg("{wDate Submitted:{n %s" % app[3])
            caller.msg("{wApplication:{n %s" % app[4])
            if not app[9]:
                caller.msg("{wGM:{n %s" % app[5])
                caller.msg("{wDate Answered:{n %s" % app[6])
                caller.msg("{wGM Notes:{n %s" % app[7])
                caller.msg("{wApproved:{n %s" % app[8])
            return
        if 'approve' in switches:
            # @app/approve <#>=<notes>
            # mark a character as approved, then send an email to the player
            if not self.lhs or not self.rhs or not self.lhs.isdigit():
                caller.msg("Usage: @app/approve <#>=<notes>")
                return
            app = apps.view_app(int(self.lhs))
            if apps.close_app(int(self.lhs), caller, self.rhs, True):
                caller.msg("Application successfully approved.")
                if app and app[1]:
                    inform_staff(
                        "{w%s has approved %s's application.{n" %
                        (caller.key.capitalize(), app[1].key.capitalize()))
                try:

                    entry = RosterEntry.objects.get(
                        character__id=app[1].id,
                        player__id=app[1].player_ob.id)
                    active_roster = Roster.objects.get(name="Active")
                    entry.roster = active_roster
                    try:
                        account = PlayerAccount.objects.get(email=app[2])
                    except PlayerAccount.DoesNotExist:
                        account = PlayerAccount.objects.create(email=app[2])
                    entry.current_account = account
                    entry.save()
                    # clear cache so the character is moved correctly
                    entry.character.flush_from_cache(force=True)
                    entry.player.flush_from_cache(force=True)
                    from datetime import datetime
                    date = datetime.now()
                    if not AccountHistory.objects.filter(
                            entry=entry, account=account,
                            end_date__isnull=True).exists():
                        AccountHistory.objects.create(entry=entry,
                                                      account=account,
                                                      start_date=date)
                    # make sure all their Attributes are clean for new player
                    from server.utils.arx_utils import post_roster_cleanup, reset_to_default_channels
                    post_roster_cleanup(entry)
                    reset_to_default_channels(entry.player)
                    try:
                        from commands.cmdsets.starting_gear import setup_gear_for_char
                        if not entry.character:
                            raise ValueError(
                                "No character found for setup gear")
                        setup_gear_for_char(entry.character)
                    except ValueError:
                        traceback.print_exc()
                except (RosterEntry.DoesNotExist,
                        RosterEntry.MultipleObjectsReturned,
                        Roster.DoesNotExist, Roster.MultipleObjectsReturned,
                        AttributeError, ValueError, TypeError):
                    print(
                        "Error when attempting to mark closed application as active."
                    )
                    traceback.print_exc()
                try:
                    from world.dominion.setup_utils import setup_dom_for_char
                    setup_dom_for_char(app[1])
                except (ValueError, TypeError):
                    # will throw an exception if Dominion already set up
                    pass
                try:
                    bb = BBoard.objects.get(db_key__iexact="Roster Changes")
                    msg = "%s now has a new player and is on the active roster." % app[
                        1]
                    url = "http://play.arxmush.org" + app[1].get_absolute_url()
                    msg += "\nCharacter page: %s" % url
                    subject = "%s now active" % app[1]
                    bb.bb_post(self.caller,
                               msg,
                               subject=subject,
                               poster_name="Roster")
                except BBoard.DoesNotExist:
                    self.msg("Board not found for posting announcement")
                return
            else:
                caller.msg("Application closure failed.")
                return
        if 'delete' in switches or 'del' in switches:
            try:
                apps.delete_app(caller, int(self.args))
                return
            except (ValueError, TypeError):
                caller.msg("Could not delete an app for value of %s." %
                           self.args)
                return
        if 'deny' in switches:
            # @app/deny <#>=<notes>
            # mark a character as declined, then send an email to the player
            if not self.lhs or not self.rhs or not self.lhs.isdigit():
                caller.msg("Usage: @app/deny <#>=<notes>")
                return
            if apps.close_app(int(self.lhs), caller, self.rhs, False):
                caller.msg("Application successfully declined.")
                app = apps.view_app(int(self.lhs))
                if app and app[1]:
                    inform_staff(
                        "{w%s has declined %s's application.{n" %
                        (caller.key.capitalize(), app[1].key.capitalize()))
                return
            else:
                caller.msg("Application closure failed.")
                return
        if 'old' in switches:
            # List all non-pending applications
            all_apps = apps.view_all_apps()
            if not all_apps:
                caller.msg("No applications found.")
                return
            # application[9] field is 'True' if pending/open
            pend_list = [_app for _app in all_apps.values() if not _app[9]]
            pend_list.sort(key=lambda appl: appl[0])
            if not pend_list:
                caller.msg("No closed applications found.")
                return
            if not self.args:
                pend_list = pend_list[-20:]
            else:
                try:
                    pend_list = pend_list[-int(self.args):]
                except (TypeError, ValueError):
                    caller.msg("Could not display entries for that range.")
                    return
            # app = [app_num, char_ob, email, date_submit, application_string, gm_ob,
            #  date_answer, gm_notes, approval, pending]
            table = prettytable.PrettyTable(
                ["{w#", "{wCharacter", "{wEmail", "{wDate", "{wApproved"])
            for app in pend_list:
                table.add_row([
                    app[0], app[1].key.capitalize(), app[2], app[3][:9],
                    str(app[8])
                ])
            caller.msg("{wOld/Closed applications for characters:\n%s" % table)
            caller.msg("To view a particular application, @app <app number>")
            return
            pass
        if 'oldchar' in switches:
            apps_for_char = apps.view_all_apps_for_char(args)
            if not apps_for_char:
                caller.msg("No applications found.")
                return
            pend_list = [ob for ob in apps_for_char if not ob[9]]
            if not pend_list:
                caller.msg("No closed applications found.")
                return
            # app = [app_num, char_ob, email, date_submit, application_string, gm_ob,
            # date_answer, gm_notes, approval, pending]
            table = prettytable.PrettyTable([
                "{w#", "{wCharacter", "{wEmail", "{wDate", "{wGM", "{wApproved"
            ])
            for app in pend_list:
                table.add_row([
                    app[0], app[1].key.capitalize(), app[2], app[3][:9],
                    app[5].key,
                    str(app[8])
                ])
            caller.msg("{wOld/Closed applications for %s:\n%s" % (args, table))
            caller.msg("To view a particular application, @app <app number>")
            return
        if 'email' in switches:
            apps_for_email = apps.view_apps_for_email(args)
            if not apps_for_email:
                caller.msg("No applications found.")
                return
            table = prettytable.PrettyTable(
                ["{w#", "{wCharacter", "{wEmail", "{wDate"])
            for app in apps_for_email:
                table.add_row(
                    [app[0], app[1].key.capitalize(), app[2], app[3]])
            caller.msg("{wApplications for %s:\n%s" % (args, table))
            caller.msg("To view a particular application, @app <app number>")
            return
        if 'fixemail' in switches:
            try:
                if apps.fix_email(int(self.lhs), caller, self.rhs):
                    caller.msg("App email changed to %s." % self.rhs)
                return
            except (TypeError, ValueError, AttributeError):
                caller.msg("Must provide an app # and an email address.")
                return
        if 'resend' in switches:
            try:
                apps.resend(int(self.lhs), caller)
                return
            except (ValueError, TypeError, AttributeError):
                caller.msg("Must provide a valid app #.")
                return
        caller.msg("Invalid switch for @app.")
Exemplo n.º 5
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.")
Exemplo n.º 6
0
 def func(self):
     """Implement the command"""
     from django.db.models import Q
     caller = self.caller
     filters = None
     if self.args and (not self.switches or 'known' in self.switches):
         filters = Q(name__iexact=self.args) | Q(
             skill__iexact=self.args) | Q(ability__iexact=self.args)
     recipes = CraftingRecipe.objects.filter(
         known_by__player__player=caller.player)
     unknown = CraftingRecipe.objects.exclude(
         known_by__player__player=caller.player).order_by("additional_cost")
     if filters:
         recipes = recipes.filter(filters)
         unknown = unknown.filter(filters)
     recipes = list(recipes)
     can_learn = [ob for ob in unknown if ob.access(caller, 'learn')]
     try:
         dompc = PlayerOrNpc.objects.get(player=caller.player)
     except PlayerOrNpc.DoesNotExist:
         dompc = setup_dom_for_char(caller)
     if not self.switches:
         caller.msg("Recipes you know or can learn:")
         visible = recipes + can_learn
         self.display_recipes(visible)
         return
     if 'known' in self.switches:
         self.msg("Recipes you know:")
         self.display_recipes(recipes)
         return
     if 'learn' in self.switches:
         match = None
         if self.args:
             match = [
                 ob for ob in can_learn
                 if ob.name.lower() == self.args.lower()
             ]
         if not match:
             caller.msg("No recipe by that name.")
             caller.msg("\nRecipes you can learn:")
             self.display_recipes(can_learn)
             return
         match = match[0]
         cost = match.additional_cost
         if cost > caller.db.currency:
             caller.msg("It costs %s to learn %s, and you only have %s." %
                        (cost, match.name, caller.db.currency))
             return
         caller.pay_money(cost)
         dompc.assets.recipes.add(match)
         if cost:
             coststr = " for %s silver" % cost
         else:
             coststr = ""
         caller.msg("You have learned %s%s." % (match.name, coststr))
         return
     if 'info' in self.switches:
         match = None
         info = list(can_learn) + list(recipes)
         if self.args:
             match = [
                 ob for ob in info if ob.name.lower() == self.args.lower()
             ]
         if not match:
             caller.msg("No recipe by that name.")
             caller.msg("Recipes you can get /info on:")
             self.display_recipes(info)
             return
         match = match[0]
         display = match.display_reqs(dompc, full=True)
         caller.msg(display, options={'box': True})
         return
     if 'teach' in self.switches:
         match = None
         can_teach = [ob for ob in recipes if ob.access(caller, 'teach')]
         if self.rhs:
             match = [
                 ob for ob in can_teach
                 if ob.name.lower() == self.rhs.lower()
             ]
         if not match:
             caller.msg("Recipes you can teach:")
             self.display_recipes(can_teach)
             if self.rhs:
                 caller.msg("You entered: %s." % self.rhs)
             return
         recipe = match[0]
         character = caller.search(self.lhs)
         if not character:
             return
         if not recipe.access(character, 'learn'):
             caller.msg("They cannot learn %s." % recipe.name)
             return
         try:
             dompc = PlayerOrNpc.objects.get(player=character.player)
         except PlayerOrNpc.DoesNotExist:
             dompc = setup_dom_for_char(character)
         if recipe in dompc.assets.recipes.all():
             caller.msg("They already know %s." % recipe.name)
             return
         dompc.assets.recipes.add(recipe)
         caller.msg("Taught %s %s." % (character, recipe.name))
Exemplo n.º 7
0
 def func(self):
     """Execute command."""
     caller = self.caller
     usemats = True
     material = None
     if self.cmdstring == "buy" and not ("economic" in self.switches
                                         or "social" in self.switches
                                         or "military" in self.switches):
         # allow for buy/economic, etc. buy switch precludes that, so we
         # only add it if we don't have the above switches
         self.switches.append("buy")
     if self.cmdstring == "sell":
         # having other switches is misleading. They could think they can sell
         # other things.
         if self.switches:
             caller.msg("Use market/sell or just 'sell' as the command.")
             return
         self.switches.append("sell")
     materials = CraftingMaterialType.objects.filter(
         value__gte=0).order_by("value")
     if not caller.check_permstring("builders"):
         materials = materials.exclude(contraband=True)
     if not self.args:
         mult = get_cost_multipler()
         mtable = prettytable.PrettyTable(
             ["{wMaterial", "{wCategory", "{wCost"])
         for mat in materials:
             mtable.add_row([mat.name, mat.category, str(mat.value * mult)])
         # add other items by hand
         for mat in other_items:
             mtable.add_row([mat, other_items[mat][1], other_items[mat][0]])
         caller.msg("\n{w" + "=" * 60 + "{n\n%s" % mtable)
         pmats = OwnedMaterial.objects.filter(
             owner__player__player=caller.player)
         if pmats:
             caller.msg("\n{wYour materials:{n %s" %
                        ", ".join(str(ob) for ob in pmats))
         return
     if not ("economic" in self.switches or "buyeconomic" in self.switches
             or "social" in self.switches or "military" in self.switches):
         try:
             material = materials.get(name__icontains=self.lhs)
         except CraftingMaterialType.DoesNotExist:
             if self.lhs not in other_items:
                 caller.msg("No material found for name %s." % self.lhs)
                 return
             material = OtherMaterial(self.lhs)
             usemats = False
         except CraftingMaterialType.MultipleObjectsReturned:
             try:
                 material = materials.get(name__iexact=self.lhs)
             except (
                     CraftingMaterialType.DoesNotExist,
                     CraftingMaterialType.MultipleObjectsReturned,
             ):
                 caller.msg("Unable to get a unique match for that.")
                 return
     if "buy" in self.switches:
         if not usemats:
             amt = 1
         else:
             try:
                 amt = int(self.rhs)
             except (ValueError, TypeError):
                 caller.msg("Amount must be a number.")
                 return
             if amt < 1:
                 caller.msg("Amount must be a positive number")
                 return
         cost = material.value * amt * get_cost_multipler()
         try:
             dompc = caller.player_ob.Dominion
         except AttributeError:
             dompc = setup_utils.setup_dom_for_char(caller)
         # use silver
         if cost > caller.db.currency:
             caller.msg(
                 "That would cost %s silver coins, and you only have %s." %
                 (cost, caller.db.currency))
             return
         caller.pay_money(cost)
         paystr = "%s silver" % cost
         if usemats:
             try:
                 mat = dompc.assets.owned_materials.get(type=material)
                 mat.amount += amt
                 mat.save()
             except OwnedMaterial.DoesNotExist:
                 dompc.assets.owned_materials.create(type=material,
                                                     amount=amt)
         else:
             material.create(caller)
         caller.msg("You buy %s %s for %s." % (amt, material, paystr))
         return
     if "sell" in self.switches:
         try:
             amt = int(self.rhs)
         except (ValueError, TypeError):
             caller.msg("Amount must be a number.")
             return
         if amt < 1:
             caller.msg("Must be a positive number.")
             return
         if not usemats:
             caller.msg("The market will only buy raw materials.")
             return
         try:
             dompc = PlayerOrNpc.objects.get(player=caller.player)
         except PlayerOrNpc.DoesNotExist:
             dompc = setup_utils.setup_dom_for_char(caller)
         try:
             mat = dompc.assets.owned_materials.get(type=material)
         except OwnedMaterial.DoesNotExist:
             caller.msg("You don't have any of %s." % material.name)
             return
         if mat.amount < amt:
             caller.msg("You want to sell %s %s, but only have %s." %
                        (amt, material, mat.amount))
             return
         mat.amount -= amt
         mat.save()
         money = caller.db.currency or 0.0
         sale = amt * material.value / 20
         money += sale
         caller.db.currency = money
         caller.msg("You have sold %s %s for %s silver coins." %
                    (amt, material.name, sale))
         return
     if "info" in self.switches:
         msg = "{wInformation on %s:{n %s\n" % (material.name,
                                                material.desc)
         price = material.value * get_cost_multipler()
         msg += "{wPrice in silver: {c%s{n\n" % price
         cost = price / 250
         if price % 250:
             cost += 1
         msg += "{wPrice in economic resources: {c%s{n" % cost
         caller.msg(msg)
         return
     if ("economic" in self.switches or "military" in self.switches
             or "social" in self.switches):
         try:
             assets = caller.player_ob.Dominion.assets
             amt = int(self.args)
             if amt <= 0:
                 raise ValueError
         except (TypeError, ValueError):
             caller.msg("Must specify a positive number.")
             return
         cost = 500 * amt * get_cost_multipler()
         if cost > caller.db.currency:
             caller.msg("That would cost %s and you have %s." %
                        (cost, caller.db.currency))
             return
         caller.pay_money(cost)
         if "economic" in self.switches:
             assets.economic += amt
         elif "social" in self.switches:
             assets.social += amt
         elif "military" in self.switches:
             assets.military += amt
         assets.save()
         caller.msg("You have bought %s resources for %s." % (amt, cost))
         return
     caller.msg("Invalid switch.")
     return
Exemplo n.º 8
0
 def func(self):
     """Implement the command"""
     from django.db.models import Q
     caller = self.caller
     all_recipes = CraftingRecipe.objects.all()
     recipes = all_recipes.filter(known_by__player__player=caller.player)
     unknown = all_recipes.exclude(known_by__player__player=caller.player)
     if self.args and (not self.switches or 'known' in self.switches):
         filters = Q(name__iexact=self.args) | Q(
             skill__iexact=self.args) | Q(ability__iexact=self.args)
         recipes = recipes.filter(filters)
         unknown = unknown.filter(filters)
     recipes = list(recipes)
     can_learn = [ob for ob in unknown if ob.access(caller, 'learn')]
     try:
         dompc = PlayerOrNpc.objects.get(player=caller.player)
     except PlayerOrNpc.DoesNotExist:
         dompc = setup_dom_for_char(caller)
     if not self.switches:
         visible = recipes + can_learn
         self.display_recipes(visible)
         return
     if 'known' in self.switches:
         self.display_recipes(recipes)
         return
     if 'learn' in self.switches or 'cost' in self.switches:
         match = None
         if self.args:
             match = [
                 ob for ob in can_learn
                 if ob.name.lower() == self.args.lower()
             ]
         if not match:
             learn_msg = ("You cannot learn '%s'. " %
                          self.lhs) if self.lhs else ""
             caller.msg("%sRecipes you can learn:" % learn_msg)
             self.display_recipes(can_learn)
             return
         match = match[0]
         cost = 0 if caller.check_permstring(
             'builders') else match.additional_cost
         cost_msg = "It will cost %s for you to learn %s." % (
             cost or "nothing", match.name)
         if 'cost' in self.switches:
             return caller.msg(cost_msg)
         elif cost > caller.currency:
             return caller.msg("You have %s silver. %s" %
                               (caller.currency, cost_msg))
         caller.pay_money(cost)
         dompc.assets.recipes.add(match)
         coststr = (" for %s silver" % cost) if cost else ""
         caller.msg("You have learned %s%s." % (match.name, coststr))
         return
     if 'info' in self.switches:
         match = None
         info = list(can_learn) + list(recipes)
         if self.args:
             match = [
                 ob for ob in info if ob.name.lower() == self.args.lower()
             ]
         if not match:
             caller.msg(
                 "No recipe by that name. Recipes you can get /info on:")
             self.display_recipes(info)
             return
         match = match[0]
         display = match.display_reqs(dompc, full=True)
         caller.msg(display, options={'box': True})
         return
     if 'teach' in self.switches:
         match = None
         can_teach = [ob for ob in recipes if ob.access(caller, 'teach')]
         if self.rhs:
             match = [
                 ob for ob in can_teach
                 if ob.name.lower() == self.rhs.lower()
             ]
         if not match:
             teach_msg = ("You cannot teach '%s'. " %
                          self.rhs) if self.rhs else ""
             caller.msg("%sRecipes you can teach:" % teach_msg)
             self.display_recipes(can_teach)
             return
         recipe = match[0]
         character = caller.search(self.lhs)
         if not character:
             return
         if not recipe.access(character, 'learn'):
             caller.msg("They cannot learn %s." % recipe.name)
             return
         try:
             dompc = PlayerOrNpc.objects.get(player=character.player)
         except PlayerOrNpc.DoesNotExist:
             dompc = setup_dom_for_char(character)
         if recipe in dompc.assets.recipes.all():
             caller.msg("They already know %s." % recipe.name)
             return
         dompc.assets.recipes.add(recipe)
         caller.msg("Taught %s %s." % (character, recipe.name))