def locks(self): return LockHandler(self)
class CraftingRecipe(CachedPropertiesMixin, SharedMemoryModel): """ For crafting, a recipe has a name, description, then materials. A lot of information is saved as a parsable text string in the 'result' text field. It'll take a form like: "baseval:0;scaling:1" and so on. baseval is a value the object has (for armor, say) for minimum quality level, while scaling is the increase per quality level to stats. "slot" and "slot limit" are used for wearable objects to denote the slot they're worn in and how many other objects may be worn in that slot, respectively. """ name = models.CharField(unique=True, max_length=255) desc = models.TextField(blank=True) # organizations or players that know this recipe known_by = models.ManyToManyField("dominion.AssetOwner", blank=True, related_name="crafting_recipes") materials = models.ManyToManyField("CraftingMaterialType", blank=True, through="RequiredMaterial") difficulty = models.PositiveSmallIntegerField(default=0) additional_cost = models.PositiveIntegerField(default=0) # the ability/profession that is used in creating this ability = models.CharField(blank=True, max_length=80, db_index=True) skill = models.CharField(blank=True, max_length=80, db_index=True) # the type of object we're creating type = models.CharField(blank=True, max_length=80, db_index=True) # level in ability this recipe corresponds to. 1 through 6, usually level = models.PositiveSmallIntegerField(default=1) allow_adorn = models.BooleanField(default=True) lock_storage = models.TextField("locks", blank=True, help_text="defined in setup_utils") # values for items created by this recipe volume = models.IntegerField( default=0, help_text="The size of objects created by this recipe.") base_value = models.DecimalField( default=0.0, help_text="Value the recipe uses in different " "calculations for typeclass properties.", max_digits=6, decimal_places=2, ) scaling = models.DecimalField( default=0.0, help_text="Adjusts calculated value based on item quality", max_digits=6, decimal_places=2, ) # values for containers displayable = models.BooleanField(default=True, help_text="Used for furniture types") display_by_line = models.BooleanField( default=True, help_text="If true, display inventory by line for container recipe", ) # values for equipment slot = models.CharField(max_length=80, blank=True, help_text="Location where clothing/armor is worn") slot_limit = models.PositiveSmallIntegerField( default=1, help_text="Max number that can be worn") fashion_mult = models.DecimalField( null=True, blank=True, help_text="If defined, multiplier for modeling", max_digits=6, decimal_places=2, ) armor_penalty = models.DecimalField( default=0.0, help_text="Value for armor impairing movement", max_digits=6, decimal_places=2, ) weapon_skill = models.CharField( max_length=80, blank=True, help_text="Weapon skill used for weapons made by this recipe", ) def __init__(self, *args, **kwargs): super(CraftingRecipe, self).__init__(*args, **kwargs) self.locks = LockHandler(self) def access(self, accessing_obj, access_type="learn", default=False): """ Determines if another object has permission to access. accessing_obj - object trying to access this one access_type - type of access sought default - what to return if no lock of access_type was found """ return self.locks.check(accessing_obj, access_type=access_type, default=default) def org_owners(self): return self.known_by.select_related("organization_owner").filter( organization_owner__isnull=False) org_owners: Iterable = CachedProperty(org_owners, "_org_owners") def can_be_learned_by(self, learner): """Returns True if learner can learn this recipe, False otherwise""" if not self.access(learner): return False # if we have no orgs that know this recipe, anyone can learn it normally if not self.org_owners: return True # check if they have granted access from any of the orgs that know it return any( ob.access(learner, access_type="recipe") for ob in self.org_owners) def display_reqs(self, dompc=None, full=False): """Returns string display for recipe""" msg = "" if full: msg += "{wName:{n %s\n" % self.name msg += "{wDescription:{n %s\n" % self.desc msg += "{wSilver:{n %s\n" % self.additional_cost material_msgs = [] for material_requirement in self.required_materials.all(): mat = material_requirement.type req_amt = material_requirement.amount mat_msg = f"{mat}: {req_amt}" if dompc: try: pcmat = dompc.assets.owned_materials.get(type=mat) amt = pcmat.amount except OwnedMaterial.DoesNotExist: amt = 0 mat_msg += f"({amt}/{req_amt})" material_msgs.append(mat_msg) if material_msgs: msg += "{wMaterials:{n %s\n" % ", ".join(material_msgs) return msg @CachedProperty def value(self): """Returns total cost of all materials used""" val = self.additional_cost val += RequiredMaterial.objects.filter(recipe=self).total_value() return val def __str__(self): return self.name @property def attack_type(self): if self.weapon_skill == "archery": return "ranged" return "melee" def create_obj(self, typec, key, loc, home, quality, crafter=None): if "{" in key and not key.endswith("{n"): key += "{n" obj = create.create_object(typeclass=typec, key=key, location=loc, home=home) CraftingRecord.objects.create(objectdb=obj, quality_level=quality, crafted_by=crafter, recipe=self) # will set color name and strip ansi from colorized name for key obj.name = key return obj
def __init__(self, *args, **kwargs): super(CraftingRecipe, self).__init__(*args, **kwargs) self.locks = LockHandler(self)
def __init__(self, lockstring): self.lock_storage = "" self.locks = LockHandler(self) self.locks.add(lockstring)