From f7b4193c840f218ed250379fe338905ab582d49f Mon Sep 17 00:00:00 2001 From: Griatch Date: Fri, 17 Jul 2020 14:25:24 +0200 Subject: [PATCH] Add $random default inlinefunc because I expected it to be there --- CHANGELOG.md | 2 +- evennia/commands/default/building.py | 10 ++++- evennia/contrib/turnbattle/tb_range.py | 33 +++++++++-------- evennia/server/sessionhandler.py | 4 +- evennia/utils/inlinefuncs.py | 51 +++++++++++++++++++++++++- 5 files changed, 79 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcf218cb1e..87fd67b8d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,7 +62,7 @@ without arguments starts a full interactive Python console. now accept any input, including generators and single values. - EvTable should now correctly handle columns with wider asian-characters in them. - Update Twisted requirement to >=2.3.0 to close security vulnerability - +- Add `$random` inlinefunc, supports minval,maxval arguments that can be ints and floats. ## Evennia 0.9 (2018-2019) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index 65016bb23d..a51fd4169e 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -2406,7 +2406,13 @@ class CmdExamine(ObjManipCommand): """ Helper function that creates a nice report about an object. - returns a string. + Args: + obj (any): Object to analyze. + avail_cmdset (CmdSet): Current cmdset for object. + + Returns: + str: The formatted string. + """ string = "\n|wName/key|n: |c%s|n (%s)" % (obj.name, obj.dbref) if hasattr(obj, "aliases") and obj.aliases.all(): @@ -2633,7 +2639,7 @@ class CmdExamine(ObjManipCommand): if obj_attrs: for attrname in obj_attrs: # we are only interested in specific attributes - caller.msg(self.format_attributes(obj, attrname, crop=False)) + caller.msg(self.format_attributes(obj, attrname, crop=False), options={"raw": True}) else: session = None if obj.sessions.count(): diff --git a/evennia/contrib/turnbattle/tb_range.py b/evennia/contrib/turnbattle/tb_range.py index c0eca41487..f604de2d57 100644 --- a/evennia/contrib/turnbattle/tb_range.py +++ b/evennia/contrib/turnbattle/tb_range.py @@ -78,7 +78,7 @@ And change your game's character typeclass to inherit from TBRangeCharacter instead of the default: class Character(TBRangeCharacter): - + Do the same thing in your game's objects.py module for TBRangeObject: from evennia.contrib.turnbattle.tb_range import TBRangeObject @@ -246,10 +246,10 @@ def apply_damage(defender, damage): def at_defeat(defeated): """ Announces the defeat of a fighter in combat. - + Args: defeated (obj): Fighter that's been defeated. - + Notes: All this does is announce a defeat message by default, but if you want anything else to happen to defeated fighters (like putting them @@ -300,11 +300,11 @@ def resolve_attack(attacker, defender, attack_type, attack_value=None, defense_v def get_range(obj1, obj2): """ Gets the combat range between two objects. - + Args: obj1 (obj): First object obj2 (obj): Second object - + Returns: range (int or None): Distance between two objects or None if not applicable """ @@ -324,7 +324,7 @@ def get_range(obj1, obj2): def distance_inc(mover, target): """ Function that increases distance in range field between mover and target. - + Args: mover (obj): The object moving target (obj): The object to be moved away from @@ -340,11 +340,11 @@ def distance_inc(mover, target): def approach(mover, target): """ Manages a character's whole approach, including changes in ranges to other characters. - + Args: mover (obj): The object moving target (obj): The object to be moved toward - + Notes: The mover will also automatically move toward any objects that are closer to the target than the mover is. The mover will also move away from anything they started @@ -354,7 +354,7 @@ def approach(mover, target): def distance_dec(mover, target): """ Helper function that decreases distance in range field between mover and target. - + Args: mover (obj): The object moving target (obj): The object to be moved toward @@ -388,11 +388,11 @@ def approach(mover, target): def withdraw(mover, target): """ Manages a character's whole withdrawal, including changes in ranges to other characters. - + Args: mover (obj): The object moving target (obj): The object to be moved away from - + Notes: The mover will also automatically move away from objects that are close to the target of their withdrawl. The mover will never inadvertently move toward anything else while @@ -540,7 +540,8 @@ class TBRangeTurnHandler(DefaultScript): room as its object. Fights persist until only one participant is left with any HP or all - remaining participants choose to end the combat with the 'disengage' command. + remaining participants choose to end the combat with the 'disengage' + command. """ def at_script_creation(self): @@ -615,7 +616,7 @@ class TBRangeTurnHandler(DefaultScript): def init_range(self, to_init): """ Initializes range values for an object at the start of a fight. - + Args: to_init (object): Object to initialize range field for. """ @@ -638,14 +639,14 @@ class TBRangeTurnHandler(DefaultScript): def join_rangefield(self, to_init, anchor_obj=None, add_distance=0): """ Adds a new object to the range field of a fight in progress. - + Args: to_init (object): Object to initialize range field for. - + Kwargs: anchor_obj (object): Object to copy range values from, or None for a random object. add_distance (int): Distance to put between to_init object and anchor object. - + """ # Get a list of room's contents without to_init object. contents = self.obj.contents diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index 0d099d6d30..ed7fb2b94b 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -221,7 +221,9 @@ class SessionHandler(dict): elif isinstance(data, (str, bytes)): data = _utf8(data) - if _INLINEFUNC_ENABLED and not raw and isinstance(self, ServerSessionHandler): + if (_INLINEFUNC_ENABLED + and not raw + and isinstance(self, ServerSessionHandler)): # only parse inlinefuncs on the outgoing path (sessionhandler->) data = parse_inlinefunc(data, strip=strip_inlinefunc, session=session) diff --git a/evennia/utils/inlinefuncs.py b/evennia/utils/inlinefuncs.py index a92fa2ebbd..931d9eff3e 100644 --- a/evennia/utils/inlinefuncs.py +++ b/evennia/utils/inlinefuncs.py @@ -62,6 +62,7 @@ Error handling: import re import fnmatch +import random as base_random from django.conf import settings from evennia.utils import utils, logger @@ -69,6 +70,53 @@ from evennia.utils import utils, logger # example/testing inline functions +def random(*args, **kwargs): + """ + Inlinefunc. Returns a random number between + 0 and 1, from 0 to a maximum value, or within a given range (inclusive). + + Args: + minval (str, optional): Minimum value. If not given, assumed 0. + maxval (str, optional): Maximum value. + + Keyword argumuents: + session (Session): Session getting the string. + + Notes: + If either of the min/maxvalue has a '.' in it, a floating-point random + value will be returned. Otherwise it will be an integer value in the + given range. + + Example: + `$random()` + `$random(5)` + `$random(5, 10)` + + """ + nargs = len(args) + if nargs == 1: + # only maxval given + minval, maxval = '0', args[0] + elif nargs > 1: + minval, maxval = args[:2] + else: + minval, maxval = ('0', '1') + + if "." in minval or "." in maxval: + # float mode + try: + minval, maxval = float(minval), float(maxval) + except ValueError: + minval, maxval = 0, 1 + return "{:.2f}".format(minval + maxval * base_random.random()) + else: + # int mode + try: + minval, maxval = int(minval), int(maxval) + except ValueError: + minval, maxval = 0, 1 + return str(base_random.randint(minval, maxval)) + def pad(*args, **kwargs): """ @@ -79,7 +127,8 @@ def pad(*args, **kwargs): width (str, optional): Will be converted to integer. Width of padding. align (str, optional): Alignment of padding; one of 'c', 'l' or 'r'. - fillchar (str, optional): Character used for padding. Defaults to a space. + fillchar (str, optional): Character used for padding. Defaults to a + space. Kwargs: session (Session): Session performing the pad.