From a00e601a140c807daef16584946fff81164464f5 Mon Sep 17 00:00:00 2001 From: AURUMVORXX Date: Sun, 30 Mar 2025 16:30:54 +0300 Subject: [PATCH] feat: Added new module-specific functions + Added exception handling inside python scripts + Changed some G2O functions to accept python objects as arguments --- CHANGELOG.md | 15 +- .../functions/exception/handle_exception.md | 2 + .../functions/exception/set_default_logger.md | 2 + .../functions/player/setPlayerAttributes.md | 2 + .../docs/functions/player/setPlayerTalents.md | 2 + python/g2o/__init__.py | 5 + python/g2o/exception.py | 68 ++++ python/g2o/functions/event.py | 29 +- python/g2o/functions/game.py | 28 +- python/g2o/functions/math.py | 63 +++- python/g2o/functions/player.py | 290 +++++++++++++++++- python/mkdocs.yml | 5 + 12 files changed, 485 insertions(+), 26 deletions(-) create mode 100644 python/docs/functions/exception/handle_exception.md create mode 100644 python/docs/functions/exception/set_default_logger.md create mode 100644 python/docs/functions/player/setPlayerAttributes.md create mode 100644 python/docs/functions/player/setPlayerTalents.md create mode 100644 python/g2o/exception.py diff --git a/CHANGELOG.md b/CHANGELOG.md index dfff88e..e78f1a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ ## Changelog -- Creating new embedded modules changed for using existing ones (needed for proper launch under venv; reverse compatible change) -- Entry point module now will be added to ``sys.path`` on the server launch -- Server will now throw an exception if entry point module doesn't exist -- Fix for ``Packet.sendToAll`` had incorrect argument list \ No newline at end of file +- All event functions, called events and some other functions now have built-in exception handler +- Added new function: ``set_default_logger`` for redirect all built-in exception messages to your custom logger +- Added new decorator: ``handle_exception`` for convinient exception handling +- Changed function ``setTime``: now all arguments are optional, so you can partially change time, and you can pass negative values to subtract them from current time. +- Changed function ``getDistance2d``: now accepts old variant ``(x1, y1, x2, y2)`` OR ``({x: value1, y: value1}, {x: value2, y: value2})`` +- Changed function ``getDistance3d``: now accepts old variant ``(x1, y1, z1, x2, y2, z2)`` OR ``({x: value1, y: value1, z: value1}, {x: value2, y: value2, z: value2})`` +- Changed function ``getVectorAngle``: now accepts old variant ``(x1, y1, z1, x2, y2, z2)`` OR ``({x: value1, y: value1, z: value1}, {x: value2, y: value2, z: value2})`` +- Changed function ``setPlayerPosition``: now accepts old variant ``(playerid, x, y, z)`` OR ``(playerid, {x: value, y: value, z: value})`` +- Changed function ``setPlayerScale``: now accepts old variant ``(playerid, x, y, z)`` OR ``(playerid, {x: value, y: value, z: value})`` +- Added function ``setPlayerAttributes`` (module-specific function) +- Added function ``setPlayerTalents`` (module-specific function) \ No newline at end of file diff --git a/python/docs/functions/exception/handle_exception.md b/python/docs/functions/exception/handle_exception.md new file mode 100644 index 0000000..3d88aab --- /dev/null +++ b/python/docs/functions/exception/handle_exception.md @@ -0,0 +1,2 @@ +# `function` handle_exception +::: g2o.exception.handle_exception \ No newline at end of file diff --git a/python/docs/functions/exception/set_default_logger.md b/python/docs/functions/exception/set_default_logger.md new file mode 100644 index 0000000..8cd44c8 --- /dev/null +++ b/python/docs/functions/exception/set_default_logger.md @@ -0,0 +1,2 @@ +# `function` set_default_logger +::: g2o.exception.set_default_logger \ No newline at end of file diff --git a/python/docs/functions/player/setPlayerAttributes.md b/python/docs/functions/player/setPlayerAttributes.md new file mode 100644 index 0000000..687db67 --- /dev/null +++ b/python/docs/functions/player/setPlayerAttributes.md @@ -0,0 +1,2 @@ +#`function` setPlayerAttributes +::: g2o.functions.player.setPlayerAttributes \ No newline at end of file diff --git a/python/docs/functions/player/setPlayerTalents.md b/python/docs/functions/player/setPlayerTalents.md new file mode 100644 index 0000000..204eb67 --- /dev/null +++ b/python/docs/functions/player/setPlayerTalents.md @@ -0,0 +1,2 @@ +#`function` setPlayerTalents +::: g2o.functions.player.setPlayerTalents \ No newline at end of file diff --git a/python/g2o/__init__.py b/python/g2o/__init__.py index a239247..ee5e076 100644 --- a/python/g2o/__init__.py +++ b/python/g2o/__init__.py @@ -144,6 +144,8 @@ from g2o.functions.player import unreadySpell from g2o.functions.player import unspawnPlayer from g2o.functions.player import useItem from g2o.functions.player import useItemToState +from g2o.functions.player import setPlayerAttributes +from g2o.functions.player import setPlayerTalents from g2o.functions.streamer import findNearbyPlayers from g2o.functions.streamer import getStreamedPlayersByPlayer @@ -152,4 +154,7 @@ from g2o.functions.streamer import getSpawnedPlayersForPlayer from g2o.functions.waypoint import getNearestWaypoint from g2o.functions.waypoint import getWaypoint +from g2o.exception import set_default_logger +from g2o.exception import handle_exception + from g2o.constants import * \ No newline at end of file diff --git a/python/g2o/exception.py b/python/g2o/exception.py new file mode 100644 index 0000000..6f72b5a --- /dev/null +++ b/python/g2o/exception.py @@ -0,0 +1,68 @@ +import logging +from functools import wraps + +logger = None + +def set_default_logger(value: logging.Logger): + """ + This function will the change default to your custom one. + + ## Declaration + ```python + def set_default_logger(value: logging.Logger): + ``` + + ## Parameters + * `logging.Logger` **value**: custom logger object. + """ + global logger + logger = value + +def handle_exception(func = None): + """ + This decorator will handle all occuring exceptions and print them into the logger. + + ## Declaration + ```python + def handle_exception(func = None): + ``` + + ## Usage + ```python + from g2o import handle_exception + + @handle_exception + def terrifying_function(): + print(5/0) + + @handle_exception + def check_pass_exception(): + wrong_position = {'x': 100, 'z': 300} # missing 'y' + try: + g2o.setPlayerPosition(0, wrong_position, pass_exception=True) # exception will occur inside this function, but `pass_exception` will also raise it here + except: + print('Exception passed to the parent') + ``` + """ + global logger + def decorator(f): + @wraps(f) + def wrapper(*args, **kwargs): + pass_exception = kwargs.pop('pass_exception', False) + try: + return f(*args, **kwargs) + except Exception as e: + if logger is not None: + logger.exception(e) + else: + logging.exception(e) + + if pass_exception: + raise + + return wrapper + + if func is not None: + return decorator(func) + + return decorator \ No newline at end of file diff --git a/python/g2o/functions/event.py b/python/g2o/functions/event.py index d19305b..7cde477 100644 --- a/python/g2o/functions/event.py +++ b/python/g2o/functions/event.py @@ -1,9 +1,13 @@ +from g2o.exception import handle_exception eventList = {} disabledEventList = [] +@handle_exception def callEvent(evtName : str, **kwargs : dict): """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will notify (call) every handler bound to specified event. Original: [callEvent](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/event/callEvent/) @@ -43,9 +47,12 @@ def callEvent(evtName : str, **kwargs : dict): isEventCancelled = not result return isEventCancelled - + +@handle_exception def addEvent(name : str): """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will register a new event with specified name. Events can be used to notify function(s) when something will happen, like player joins the server, etc. Original: [addEvent](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/event/addEvent/) @@ -67,9 +74,12 @@ def addEvent(name : str): """ if not name in eventList: eventList[name] = [] - + +@handle_exception def event(name : str, priority : int = 9999): """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will bind function to specified event. Original: [addEventHandler](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/event/addEventHandler/) @@ -99,9 +109,12 @@ def event(name : str, priority : int = 9999): eventList[name].sort(key = lambda x: x['priority']) return func return inlineEvt - + +@handle_exception def removeEventHandler(name : str, func : object): """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will unbind function from specified event. Original: [removeEventHandler](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/event/removeEventHandler/) @@ -130,11 +143,14 @@ def removeEventHandler(name : str, func : object): for index, item in enumerate(eventList[name]): if item['function'] == func: del eventList[name][index] - + +@handle_exception def toggleEvent(name : str, toggle : bool): ''' !!! note By default every event is toggled `on` (enabled). + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will toggle event (enable or disable it globally). By toggling event off, you can completely disable certain event from calling it's handlers. Original: [toggleEvent](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/event/toggleEvent/) @@ -162,11 +178,14 @@ def toggleEvent(name : str, toggle : bool): disabledEventList.append(name) elif toggle and name in disabledEventList: disabledEventList.remove(name) - + +@handle_exception def removeEvent(name : str): ''' !!! warning Removing an event also cause all event handlers to unregister. + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will unregister an event with specified name. Original: [removeEvent](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/event/removeEvent/) diff --git a/python/g2o/functions/game.py b/python/g2o/functions/game.py index 4fb7641..76f59c4 100644 --- a/python/g2o/functions/game.py +++ b/python/g2o/functions/game.py @@ -1,4 +1,5 @@ import sqg2o +from g2o.exception import handle_exception def getHostname() -> str: """ @@ -206,18 +207,33 @@ def setServerWorld(world : str): """ return sqg2o.setServerWorld(world) -def setTime(hour : int, min : int, day : int = 0): +@handle_exception +def setTime(hour : int = None, mins : int = None, day : int = None): """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will set the current time in the game to the given time, for all the players. Original: [setTime](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/server-functions/game/setTime/) ## Declaration ```python - def setTime(hour : int, min : int, day : int = 0) + def setTime(hour : int = None, mins : int = None, day : int = None) ``` ## Parameters - `int` **hour**: the hour of new time (in the range between 0-23). - `int` **min**: the minute of new time (in the range between 0-59). - `int` **day**: the day of new time. + `int` **hour**: the hour of new time (in the range between 0-23) or subtract value from hour (hour < 0). + `int` **mins**: the minute of new time (in the range between 0-59) or subtract value from mins (mins < 0). + `int` **day**: the day of new time or subtract value from day (day < 0). """ - return sqg2o.setTime(hour, min, day) \ No newline at end of file + current_time = getTime() + + # Check for provided arguments + hour = current_time['hour'] if hour is None else hour + mins = current_time['min'] if mins is None else mins + day = current_time['day'] if day is None else day + + # Check for negative arguments + hour = current_time['hour'] + hour if hour < 0 else hour + mins = current_time['min'] + mins if mins < 0 else mins + day = current_time['day'] + day if day < 0 else day + + return sqg2o.setTime(hour, mins, day) \ No newline at end of file diff --git a/python/g2o/functions/math.py b/python/g2o/functions/math.py index dc1e9d3..383574c 100644 --- a/python/g2o/functions/math.py +++ b/python/g2o/functions/math.py @@ -1,7 +1,18 @@ import sqg2o +from g2o.exception import handle_exception -def getDistance2d(x1 : float, y1: float, x2 : float, y2 : float) -> float: +@handle_exception +def getDistance2d( + x1: float = 0, + y1: float = 0, + x2: float = 0, + y2 : float = 0, + first: dict[str, float] = None, + second: dict[str, float] = None +) -> float: """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will get the 2d distance between two points. Original: [getDistance2d](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/math/getDistance2d/) @@ -15,13 +26,31 @@ def getDistance2d(x1 : float, y1: float, x2 : float, y2 : float) -> float: * `float` **y1**: the position on Y axis of the first point. * `float` **x2**: the position on X axis of the second point. * `float` **y2**: the position on Y axis of the second point. + **OR** + * `dict[str, float]` **first**: the poistion on XY axis of the first point. + * `dict[str, float]` **second**: the position of XY axis of the second point. ## Returns `float`: Returns the calculated 2d distance between two points as floating point number. """ - return sqg2o.getDistance2d(x1, y1, x2, y2) + if first is not None and second is not None: + return sqg2o.getDistance2d(first['x'], first['y'], second['x'], second['y']) + else: + return sqg2o.getDistance2d(x1, y1, x2, y2) -def getDistance3d(x1 : float, y1: float, z1 : float, x2 : float, y2 : float, z2 : float) -> float: +@handle_exception +def getDistance3d( + x1 : float = 0, + y1: float = 0, + z1 : float = 0, + x2 : float = 0, + y2 : float = 0, + z2 : float = 0, + first: dict[str, float] = None, + second: dict[str, float] = None +) -> float: """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will get the 3d distance between two points. Original: [getDistance3d](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/math/getDistance3d/) @@ -37,13 +66,29 @@ def getDistance3d(x1 : float, y1: float, z1 : float, x2 : float, y2 : float, z2 * `float` **x2**: the position on X axis of the second point. * `float` **y2**: the position on Y axis of the second point. * `float` **z2**: the position on Z axis of the second point. + **OR** + * `dict[str, float]` **first**: the position on XYZ axis of the first point. + * `dict[str, float]` **second**: the position on XYZ axic of the second point. ## Returns `float`: Returns the calculated 3d distance between two points as floating point number. """ - return sqg2o.getDistance3d(x1, y1, z1, x2, y2, z2) + if first is not None and second is not None: + return sqg2o.getDistance3d(first['x'], first['y'], first['z'], second['x'], second['y'], second['z']) + else: + return sqg2o.getDistance3d(x1, y1, z1, x2, y2, z2) -def getVectorAngle(x1 : float, y1: float, x2 : float, y2 : float) -> float: +@handle_exception +def getVectorAngle( + x1: float = 0, + y1: float = 0, + x2: float = 0, + y2 : float = 0, + first: dict[str, float] = None, + second: dict[str, float] = None +) -> float: """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will get angle on Y axis directed towards the second point. Original: [getVectorAngle](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/shared-functions/math/getVectorAngle/) @@ -57,7 +102,13 @@ def getVectorAngle(x1 : float, y1: float, x2 : float, y2 : float) -> float: * `float` **y1**: the position on Y axis of the first point. * `float` **x2**: the position on X axis of the second point. * `float` **y2**: the position on Y axis of the second point. + **OR** + * `dict[str, float]` **first**: the poistion on XY axis of the first point. + * `dict[str, float]` **second**: the position of XY axis of the second point. ## Returns `float`: Returns the angle on Y axis directed towards the second point. """ - return sqg2o.getVectorAngle(x1, y1, x2, y2) \ No newline at end of file + if first is not None and second is not None: + return sqg2o.getVectorAngle(first['x'], first['y'], second['x'], second['y']) + else: + return sqg2o.getVectorAngle(x1, y1, x2, y2) \ No newline at end of file diff --git a/python/g2o/functions/player.py b/python/g2o/functions/player.py index 995471f..c17e849 100644 --- a/python/g2o/functions/player.py +++ b/python/g2o/functions/player.py @@ -1,4 +1,6 @@ import sqg2o +from g2o.exception import handle_exception +from g2o.constants import * def addBan(info : dict) -> bool: """ @@ -1189,8 +1191,11 @@ def setPlayerName(id : int, name : str) -> bool: """ return sqg2o.setPlayerName(id, name) -def setPlayerPosition(id : int, x : float, y : float, z : float): +@handle_exception +def setPlayerPosition(id : int, x : float = 0, y : float = 0, z : float = 0, pos: dict[str, float] = None): """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will set the player world position for all players. Original: [setPlayerPosition](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/server-functions/player/setPlayerPosition/) @@ -1203,8 +1208,13 @@ def setPlayerPosition(id : int, x : float, y : float, z : float): `float` **x**: the position in the world on the x axis. `float` **y**: the position in the world on the y axis. `float` **z**: the position in the world on the z axis. + OR + `dict[str, float]` **pos**: the position in the world on the XYZ axis. """ - return sqg2o.setPlayerPosition(id, x, y, z) + if pos is not None: + return sqg2o.setPlayerPosition(id, pos['x'], pos['y'], pos['z']) + else: + return sqg2o.setPlayerPosition(id, x, y, z) def setPlayerRespawnTime(id : int, respawnTime : int): """ @@ -1223,8 +1233,11 @@ def setPlayerRespawnTime(id : int, respawnTime : int): """ return sqg2o.setPlayerRespawnTime(id, respawnTime) -def setPlayerScale(id : int, x : float, y : float, z : float): +@handle_exception +def setPlayerScale(id : int, x : float = 0, y : float = 0, z : float = 0, scale: dict[str, float] = None): """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. This function will set the player scale for all players. Original: [setPlayerScale](https://gothicmultiplayerteam.gitlab.io/docs/0.3.0/script-reference/server-functions/player/setPlayerScale/) @@ -1237,8 +1250,13 @@ def setPlayerScale(id : int, x : float, y : float, z : float): `float` **x**: the scale factor on x axis. `float` **y**: the scale factor on y axis. `float` **z**: the scale factor on z axis. + OR + `dict[str, float]` **pos**: the scale factor on the XYZ axis. """ - return sqg2o.setPlayerScale(id, x, y, z) + if scale is not None: + return sqg2o.setPlayerScale(id, scale['x'], scale['y'], scale['z']) + else: + return sqg2o.setPlayerScale(id, x, y, z) def setPlayerSkillWeapon(id : int, skillId : int, percentage : int): """ @@ -1475,4 +1493,266 @@ def useItemToState(id : int, instance : str, state : int): `str` **instance**: the item instance from Daedalus scripts. `int` **state**: the state that you'll start from interacting with item. """ - return sqg2o.useItemToState(id, instance, state) \ No newline at end of file + return sqg2o.useItemToState(id, instance, state) + +@handle_exception +def setPlayerAttributes( + id: int, + health: int = None, + max_health: int = None, + mana: int = None, + max_mana: int = None, + strength: int = None, + dexterity: int = None, + one_handed: int = None, + two_handed: int = None, + bow: int = None, + crossbow: int = None, +): + """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. + This function will modify player attributes for all players. + + ## Declaration + ```python + def setPlayerAttributes( + id: int, + health: int = None, + max_health: int = None, + mana: int = None, + max_mana: int = None, + strength: int = None, + dexterity: int = None, + two_handed: int = None, + two_handned: int = None, + bow: int = None, + crossbow: int = None, + ): + ``` + ## Parameters + `int` **id**: the player id. + `int` **health**: health points amount. + `int` **max_health**: maximum health points amount. + `int` **mana**: mana points amount. + `int` **max_mana**: maximum mana points amount. + `int` **strength**: strength points amount. + `int` **dexterity**: dexterity points amount. + `int` **one_handed**: one-handed weapon skill value. + `int` **two_handed**: two-handed weapon skill value. + `int` **bow**: bow weapon skill value. + `int` **crossbow**: crossbow skill value. + + ## Usage + ```python + import g2o + + @g2o.event('onPlayerJoin') + def evt_join(**kwargs): + pid = kwargs['playerid'] + g2o.setPlayerAttributes( + id=pid, + health=500, + max_health=500, + strength=1000, + dexterity=1000, + one_handed=90, + two_handed=90, + bow=90, + crossbow=90 + ) + ``` + """ + health = sqg2o.getPlayerHealth(id) if health is None else str(health) + max_health = sqg2o.getPlayerMaxHealth(id) if max_health is None else str(max_health) + mana = sqg2o.getPlayerMana(id) if mana is None else str(mana) + max_mana = sqg2o.getPlayerMaxMana(id) if max_mana is None else str(max_mana) + strength = sqg2o.getPlayerStrength(id) if strength is None else str(strength) + dexterity = sqg2o.getPlayerDexterity(id) if dexterity is None else str(dexterity) + one_handed = sqg2o.getPlayerSkillWeapon(id, 0) if one_handed is None else str(one_handed) + two_handed = sqg2o.getPlayerSkillWeapon(id, 1) if two_handed is None else str(two_handed) + bow = sqg2o.getPlayerSkillWeapon(id, 2) if bow is None else str(bow) + crossbow = sqg2o.getPlayerSkillWeapon(id, 3) if crossbow is None else str(crossbow) + + health = sqg2o.getPlayerHealth(id) + int(health) if type(health) is str and (health.startswith('+') or health.startswith('-')) else int(health) + max_health = sqg2o.getPlayerMaxHealth(id) + int(max_health) if type(max_health) is str and (max_health.startswith('+') or max_health.startswith('-')) else int(max_health) + mana = sqg2o.getPlayerMana(id) + int(mana) if type(mana) is str and (mana.startswith('+') or mana.startswith('-')) else int(mana) + max_mana = sqg2o.getPlayerMaxMana(id) + int(max_mana) if type(max_mana) is str and (max_mana.startswith('+') or max_mana.startswith('-')) else int(max_mana) + strength = sqg2o.getPlayerStrength(id) + int(strength) if type(strength) is str and (strength.startswith('+') or strength.startswith('-')) else int(strength) + dexterity = sqg2o.getPlayerDexterity(id) + int(dexterity) if type(dexterity) is str and (dexterity.startswith('+') or dexterity.startswith('-')) else int(dexterity) + one_handed = sqg2o.getPlayerSkillWeapon(id, 0) + int(one_handed) if type(one_handed) is str and (one_handed.startswith('+') or one_handed.startswith('-')) else int(one_handed) + two_handed = sqg2o.getPlayerSkillWeapon(id, 1) + int(two_handed) if type(two_handed) is str and (two_handed.startswith('+') or two_handed.startswith('-')) else int(two_handed) + bow = sqg2o.getPlayerSkillWeapon(id, 2) + int(two_handed) if type(bow) is str and (bow.startswith('+') or bow.startswith('-')) else int(bow) + crossbow = sqg2o.getPlayerSkillWeapon(id, 3) + int(crossbow) if type(crossbow) is str and (crossbow.startswith('+') or crossbow.startswith('-')) else int(crossbow) + + sqg2o.setPlayerMaxHealth(id, max_health) + sqg2o.setPlayerHealth(id, health) + sqg2o.setPlayerMaxMana(id, max_mana) + sqg2o.setPlayerMana(id, mana) + sqg2o.setPlayerStrength(id, strength) + sqg2o.setPlayerDexterity(id, dexterity) + sqg2o.setPlayerSkillWeapon(id, 0, one_handed) + sqg2o.setPlayerSkillWeapon(id, 1, two_handed) + sqg2o.setPlayerSkillWeapon(id, 2, bow) + sqg2o.setPlayerSkillWeapon(id, 3, crossbow) + +@handle_exception +def setPlayerTalents( + id: int, + one_handed: int = None, + two_handed: int = None, + bow: int = None, + crossbow: int = None, + pick_locks: int = None, + pickpocket: int = None, + mage: int = None, + sneak: int = None, + regenerate: int = None, + firemaster: int = None, + acrobatics: int = None, + pickpocket_unused: int = None, + smith: int = None, + runes: int = None, + alchemy: int = None, + throphy: int = None, + talent_a: int = None, + talent_b: int = None, + talent_c: int = None, + talent_d: int = None, + talent_e: int = None, +): + """ + !!! note + This functions supports ``pass_exception: bool`` optional argument for manual handling exceptions. + This function will modify player talents for all players. + + ## Declaration + ```python + def setPlayerTalents( + id: int, + one_handed: int = None, + two_handed: int = None, + bow: int = None, + crossbow: int = None, + pick_locks: int = None, + pickpocket: int = None, + mage: int = None, + sneak: int = None, + regenerate: int = None, + firemaster: int = None, + acrobatics: int = None, + pickpocket_unused: int = None, + smith: int = None, + runes: int = None, + alchemy: int = None, + throphy: int = None, + talent_a: int = None, + talent_b: int = None, + talent_c: int = None, + talent_d: int = None, + talent_e: int = None, + ): + ``` + ## Parameters + `int` **one_handed**: npc one handed weapon skill talent. + `int` **two_handed**: npc two handed weapon skill talent. + `int` **bow**: npc bow weapon skill talent. + `int` **crossbow**: npc crossbow weapon skill talent. + `int` **pick_locks**: npc picklock talent. + `int` **pickpocket**: npc pickpocket talent. + `int` **mage**: npc magic circle talent. + `int` **sneak**: npc sneak talent. + `int` **regenerate**: npc health regeneration talent. + `int` **firemaster**: npc firemaster talent (unused by the game). + `int` **acrobatics**: npc acrobatic talent. + `int` **pickpocket_unused**: npc old pickpocket talent (unused by the game). + `int` **smith**: npc smith talent. + `int` **runes**: npc runes creation talent. + `int` **alchemy**: npc potion creation talent. + `int` **throphy**: npc trophy gathering talent. + `int` **talent_a**: npc talent A (unused by the game). + `int` **talent_b**: npc talent B (unused by the game). + `int` **talent_c**: npc talent C (unused by the game). + `int` **talent_d**: npc talent D (unused by the game). + `int` **talent_e**: npc talent E (unused by the game). + + ## Usage + ```python + import g2o + + @g2o.event('onPlayerJoin') + def evt_join(**kwargs): + pid = kwargs['playerid'] + g2o.setPlayerTalents( + id=pid, + pick_locks=1, + mage=6, + smith=1 + ) + ``` + """ + one_handed = sqg2o.getPlayerTalent(id, TALENT_1H) if one_handed is None else str(one_handed) + two_handed = sqg2o.getPlayerTalent(id, TALENT_2H) if two_handed is None else str(two_handed) + bow = sqg2o.getPlayerTalent(id, TALENT_BOW) if bow is None else str(bow) + crossbow = sqg2o.getPlayerTalent(id, TALENT_CROSSBOW) if crossbow is None else str(crossbow) + pick_locks = sqg2o.getPlayerTalent(id, TALENT_PICK_LOCKS) if pick_locks is None else str(pick_locks) + pickpocket = sqg2o.getPlayerTalent(id, TALENT_PICKPOCKET) if pickpocket is None else str(pickpocket) + mage = sqg2o.getPlayerTalent(id, TALENT_MAGE) if mage is None else str(mage) + sneak = sqg2o.getPlayerTalent(id, TALENT_SNEAK) if sneak is None else str(sneak) + regenerate = sqg2o.getPlayerTalent(id, TALENT_REGENERATE) if regenerate is None else str(regenerate) + firemaster = sqg2o.getPlayerTalent(id, TALENT_FIREMASTER) if firemaster is None else str(firemaster) + acrobatics = sqg2o.getPlayerTalent(id, TALENT_ACROBATIC) if acrobatics is None else str(acrobatics) + pickpocket_unused = sqg2o.getPlayerTalent(id, TALENT_PICKPOCKET_UNUSED) if pickpocket_unused is None else str(pickpocket_unused) + smith = sqg2o.getPlayerTalent(id, TALENT_SMITH) if smith is None else str(smith) + runes = sqg2o.getPlayerTalent(id, TALENT_RUNES) if runes is None else str(runes) + alchemy = sqg2o.getPlayerTalent(id, TALENT_ALCHEMY) if alchemy is None else str(alchemy) + throphy = sqg2o.getPlayerTalent(id, TALENT_THROPHY) if throphy is None else str(throphy) + talent_a = sqg2o.getPlayerTalent(id, TALENT_A) if talent_a is None else str(talent_a) + talent_b = sqg2o.getPlayerTalent(id, TALENT_B) if talent_b is None else str(talent_b) + talent_c = sqg2o.getPlayerTalent(id, TALENT_C) if talent_c is None else str(talent_c) + talent_d = sqg2o.getPlayerTalent(id, TALENT_D) if talent_d is None else str(talent_d) + talent_e = sqg2o.getPlayerTalent(id, TALENT_E) if talent_e is None else str(talent_e) + + one_handed = sqg2o.getPlayerTalent(id, TALENT_1H) + int(one_handed) if type(one_handed) is str and (one_handed.startswith('+') or one_handed.startswith('-')) else int(one_handed) + two_handed = sqg2o.getPlayerTalent(id, TALENT_2H) + int(two_handed) if type(two_handed) is str and (two_handed.startswith('+') or two_handed.startswith('-')) else int(two_handed) + bow = sqg2o.getPlayerTalent(id, TALENT_BOW) + int(bow) if type(bow) is str and (bow.startswith('+') or bow.startswith('-')) else int(bow) + crossbow = sqg2o.getPlayerTalent(id, TALENT_CROSSBOW) + int(crossbow) if type(crossbow) is str and (crossbow.startswith('+') or crossbow.startswith('-')) else int(crossbow) + pick_locks = sqg2o.getPlayerTalent(id, TALENT_PICK_LOCKS) + int(pick_locks) if type(pick_locks) is str and (pick_locks.startswith('+') or pick_locks.startswith('-')) else int(pick_locks) + pickpocket = sqg2o.getPlayerTalent(id, TALENT_PICKPOCKET) + int(pickpocket) if type(pickpocket) is str and (pickpocket.startswith('+') or pickpocket.startswith('-')) else int(pickpocket) + mage = sqg2o.getPlayerTalent(id, TALENT_MAGE) + int(mage) if type(mage) is str and (mage.startswith('+') or mage.startswith('-')) else int(mage) + sneak = sqg2o.getPlayerTalent(id, TALENT_SNEAK) + int(sneak) if type(sneak) is str and (sneak.startswith('+') or sneak.startswith('-')) else int(sneak) + regenerate = sqg2o.getPlayerTalent(id, TALENT_REGENERATE) + int(regenerate) if type(regenerate) is str and (regenerate.startswith('+') or regenerate.startswith('-')) else int(regenerate) + firemaster = sqg2o.getPlayerTalent(id, TALENT_FIREMASTER) + int(firemaster) if type(firemaster) is str and (firemaster.startswith('+') or firemaster.startswith('-')) else int(firemaster) + acrobatics = sqg2o.getPlayerTalent(id, TALENT_ACROBATIC) + int(acrobatics) if type(acrobatics) is str and (acrobatics.startswith('+') or acrobatics.startswith('-')) else int(acrobatics) + pickpocket_unused = sqg2o.getPlayerTalent(id, TALENT_PICKPOCKET_UNUSED) + int(pickpocket_unused) if type(pickpocket_unused) is str and (pickpocket_unused.startswith('+') or pickpocket_unused.startswith('-')) else int(pickpocket_unused) + smith = sqg2o.getPlayerTalent(id, TALENT_SMITH) + int(smith) if type(smith) is str and (smith.startswith('+') or smith.startswith('-')) else int(smith) + runes = sqg2o.getPlayerTalent(id, TALENT_RUNES) + int(runes) if type(runes) is str and (runes.startswith('+') or runes.startswith('-')) else int(runes) + alchemy = sqg2o.getPlayerTalent(id, TALENT_ALCHEMY) + int(alchemy) if type(alchemy) is str and (alchemy.startswith('+') or alchemy.startswith('-')) else int(alchemy) + throphy = sqg2o.getPlayerTalent(id, TALENT_THROPHY) + int(throphy) if type(throphy) is str and (throphy.startswith('+') or throphy.startswith('-')) else int(throphy) + talent_a = sqg2o.getPlayerTalent(id, TALENT_A) + int(talent_a) if type(talent_a) is str and (talent_a.startswith('+') or talent_a.startswith('-')) else int(talent_a) + talent_b = sqg2o.getPlayerTalent(id, TALENT_B) + int(talent_b) if type(talent_b) is str and (talent_b.startswith('+') or talent_b.startswith('-')) else int(talent_b) + talent_c = sqg2o.getPlayerTalent(id, TALENT_C) + int(talent_c) if type(talent_c) is str and (talent_c.startswith('+') or talent_c.startswith('-')) else int(talent_c) + talent_d = sqg2o.getPlayerTalent(id, TALENT_D) + int(talent_d) if type(talent_d) is str and (talent_d.startswith('+') or talent_d.startswith('-')) else int(talent_d) + talent_e = sqg2o.getPlayerTalent(id, TALENT_E) + int(talent_e) if type(talent_e) is str and (talent_e.startswith('+') or talent_e.startswith('-')) else int(talent_e) + + sqg2o.setPlayerTalent(id, TALENT_1H, one_handed) + sqg2o.setPlayerTalent(id, TALENT_2H, two_handed) + sqg2o.setPlayerTalent(id, TALENT_BOW, bow) + sqg2o.setPlayerTalent(id, TALENT_CROSSBOW, crossbow) + sqg2o.setPlayerTalent(id, TALENT_PICK_LOCKS, pick_locks) + sqg2o.setPlayerTalent(id, TALENT_PICKPOCKET, pickpocket) + sqg2o.setPlayerTalent(id, TALENT_MAGE, mage) + sqg2o.setPlayerTalent(id, TALENT_SNEAK, sneak) + sqg2o.setPlayerTalent(id, TALENT_REGENERATE, regenerate) + sqg2o.setPlayerTalent(id, TALENT_FIREMASTER, firemaster) + sqg2o.setPlayerTalent(id, TALENT_ACROBATIC, acrobatics) + sqg2o.setPlayerTalent(id, TALENT_PICKPOCKET_UNUSED, pickpocket_unused) + sqg2o.setPlayerTalent(id, TALENT_SMITH, smith) + sqg2o.setPlayerTalent(id, TALENT_RUNES, runes) + sqg2o.setPlayerTalent(id, TALENT_ALCHEMY, alchemy) + sqg2o.setPlayerTalent(id, TALENT_THROPHY, throphy) + sqg2o.setPlayerTalent(id, TALENT_A, talent_a) + sqg2o.setPlayerTalent(id, TALENT_B, talent_b) + sqg2o.setPlayerTalent(id, TALENT_C, talent_c) + sqg2o.setPlayerTalent(id, TALENT_D, talent_d) + sqg2o.setPlayerTalent(id, TALENT_E, talent_e) \ No newline at end of file diff --git a/python/mkdocs.yml b/python/mkdocs.yml index a78a404..f7cdc7f 100644 --- a/python/mkdocs.yml +++ b/python/mkdocs.yml @@ -106,6 +106,9 @@ nav: - onPlayerTeleport: defaultEvents/player/onPlayerTeleport.md - onPlayerToggleFaceAni: defaultEvents/player/onPlayerToggleFaceAni.md - Functions: + - Exception: + - set_default_logger: functions/exception/set_default_logger.md + - handle_exception: functions/exception/handle_exception.md - Chat: - sendMessageToAll: functions/chat/sendMessageToAll.md - sendMessageToPlayer: functions/chat/sendMessageToPlayer.md @@ -225,6 +228,8 @@ nav: - setPlayerVisual: functions/player/setPlayerVisual.md - setPlayerWeaponMode: functions/player/setPlayerWeaponMode.md - setPlayerWorld: functions/player/setPlayerWorld.md + - setPlayerAttributes: functions/player/setPlayerAttributes.md + - setPlayerTalents: functions/player/setPlayerTalents.md - spawnPlayer: functions/player/spawnPlayer.md - stopAni: functions/player/stopAni.md - stopFaceAni: functions/player/stopFaceAni.md