mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-28 18:15:45 +08:00
update docstrings
This commit is contained in:
parent
7ecd804c1b
commit
b06a2efcfc
@ -1 +1 @@
|
||||
225891607870108897605481763130834194451
|
||||
144616568017325747730083301686242056706
|
||||
@ -399,106 +399,111 @@ class Material:
|
||||
Add one or more actions to the material, optionally with conditions.
|
||||
|
||||
Conditions:
|
||||
Conditions are provided as tuples which can be combined to form boolean
|
||||
logic. A single condition might look like ``('condition_name', cond_arg)``,
|
||||
or a more complex nested one might look like ``(('some_condition',
|
||||
cond_arg), 'or', ('another_condition', cond2_arg))``.
|
||||
Conditions are provided as tuples which can be combined
|
||||
to form boolean logic. A single condition might look like
|
||||
``('condition_name', cond_arg)``, or a more complex nested one
|
||||
might look like ``(('some_condition', cond_arg), 'or',
|
||||
('another_condition', cond2_arg))``.
|
||||
|
||||
``'and'``, ``'or'``, and ``'xor'`` are available to chain together 2 conditions, as
|
||||
seen above.
|
||||
``'and'``, ``'or'``, and ``'xor'`` are available to chain
|
||||
together 2 conditions, as seen above.
|
||||
|
||||
Available Conditions:
|
||||
``('they_have_material', material)`` - does the part we're hitting have a
|
||||
given ba.Material?
|
||||
``('they_have_material', material)`` - does the part we're
|
||||
hitting have a given ba.Material?
|
||||
|
||||
``('they_dont_have_material', material)`` - does the part we're hitting
|
||||
not have a given ba.Material?
|
||||
``('they_dont_have_material', material)`` - does the part we're
|
||||
hitting not have a given ba.Material?
|
||||
|
||||
``('eval_colliding')`` - is ``'collide'`` true at this point in material
|
||||
evaluation? (see the modify_part_collision action)
|
||||
``('eval_colliding')`` - is ``'collide'`` true at this point
|
||||
in material evaluation? (see the modify_part_collision action)
|
||||
|
||||
``('eval_not_colliding')`` - is 'collide' false at this point in material
|
||||
evaluation? (see the modify_part_collision action)
|
||||
``('eval_not_colliding')`` - is 'collide' false at this point
|
||||
in material evaluation? (see the modify_part_collision action)
|
||||
|
||||
``('we_are_younger_than', age)`` - is our part younger than ``'age'``
|
||||
(in milliseconds)?
|
||||
``('we_are_younger_than', age)`` - is our part younger than
|
||||
``'age'`` (in milliseconds)?
|
||||
|
||||
``('we_are_older_than', age)`` - is our part older than ``'age'``
|
||||
(in milliseconds)?
|
||||
|
||||
``('they_are_younger_than', age)`` - is the part we're hitting younger than
|
||||
``'age'`` (in milliseconds)?
|
||||
``('they_are_younger_than', age)`` - is the part we're hitting
|
||||
younger than ``'age'`` (in milliseconds)?
|
||||
|
||||
``('they_are_older_than', age)`` - is the part we're hitting older than
|
||||
``'age'`` (in milliseconds)?
|
||||
``('they_are_older_than', age)`` - is the part we're hitting
|
||||
older than ``'age'`` (in milliseconds)?
|
||||
|
||||
``('they_are_same_node_as_us')`` - does the part we're hitting belong to
|
||||
the same ba.Node as us?
|
||||
``('they_are_same_node_as_us')`` - does the part we're hitting
|
||||
belong to the same ba.Node as us?
|
||||
|
||||
``('they_are_different_node_than_us')`` - does the part we're hitting
|
||||
belong to a different ba.Node than us?
|
||||
``('they_are_different_node_than_us')`` - does the part we're
|
||||
hitting belong to a different ba.Node than us?
|
||||
|
||||
Actions:
|
||||
In a similar manner, actions are specified as tuples. Multiple actions
|
||||
can be specified by providing a tuple of tuples.
|
||||
In a similar manner, actions are specified as tuples.
|
||||
Multiple actions can be specified by providing a tuple
|
||||
of tuples.
|
||||
|
||||
Available Actions:
|
||||
``('call', when, callable)`` - calls the provided callable; ``'when'`` can be
|
||||
either ``'at_connect'`` or ``'at_disconnect'``. ``'at_connect'`` means to fire
|
||||
when the two parts first come in contact; ``'at_disconnect'`` means to
|
||||
fire once they cease being in contact.
|
||||
``('call', when, callable)`` - calls the provided callable;
|
||||
``'when'`` can be either ``'at_connect'`` or ``'at_disconnect'``.
|
||||
``'at_connect'`` means to fire
|
||||
when the two parts first come in contact; ``'at_disconnect'``
|
||||
means to fire once they cease being in contact.
|
||||
|
||||
``('message', who, when, message_obj)`` - sends a message object; ``'who'`` can
|
||||
be either ``'our_node'`` or ``'their_node'``, ``'when'`` can be ``'at_connect'`` or
|
||||
``('message', who, when, message_obj)`` - sends a message object;
|
||||
``'who'`` can
|
||||
be either ``'our_node'`` or ``'their_node'``, ``'when'`` can be
|
||||
``'at_connect'`` or
|
||||
``'at_disconnect'``, and message_obj is the message object to send.
|
||||
This has the same effect as calling the node's ba.Node.handlemessage
|
||||
method.
|
||||
|
||||
``('modify_part_collision', attr, value)`` - changes some characteristic
|
||||
of the physical collision that will occur between our part and their
|
||||
part. This change will remain in effect as long as the two parts
|
||||
remain overlapping. This means if you have a part with a material
|
||||
that turns ``'collide'`` off against parts younger than 100ms, and it
|
||||
touches another part that is 50ms old, it will continue to not
|
||||
collide with that part until they separate, even if the 100ms
|
||||
threshold is passed. Options for attr/value are: ``'physical'`` (boolean
|
||||
value; whether a *physical* response will occur at all), ``'friction'``
|
||||
(float value; how friction-y the physical response will be),
|
||||
``'collide'`` (boolean value; whether *any* collision will occur at all,
|
||||
including non-physical stuff like callbacks), ``'use_node_collide'``
|
||||
(boolean value; whether to honor modify_node_collision overrides for
|
||||
this collision), ``'stiffness'`` (float value, how springy the physical
|
||||
response is), ``'damping'`` (float value, how damped the physical
|
||||
response is), ``'bounce'`` (float value; how bouncy the physical response
|
||||
is).
|
||||
This has the same effect as calling the node's
|
||||
ba.Node.handlemessage method.
|
||||
|
||||
``('modify_part_collision', attr, value)`` - changes some
|
||||
characteristic of the physical collision that will occur between
|
||||
our part and their part. This change will remain in effect as
|
||||
long as the two parts remain overlapping. This means if you have a
|
||||
part with a material that turns ``'collide'`` off against parts
|
||||
younger than 100ms, and it touches another part that is 50ms old,
|
||||
it will continue to not collide with that part until they separate,
|
||||
even if the 100ms threshold is passed. Options for attr/value are:
|
||||
``'physical'`` (boolean value; whether a *physical* response will
|
||||
occur at all), ``'friction'`` (float value; how friction-y the
|
||||
physical response will be), ``'collide'`` (boolean value;
|
||||
whether *any* collision will occur at all, including non-physical
|
||||
stuff like callbacks), ``'use_node_collide'``
|
||||
(boolean value; whether to honor modify_node_collision
|
||||
overrides for this collision), ``'stiffness'`` (float value,
|
||||
how springy the physical response is), ``'damping'`` (float
|
||||
value, how damped the physical response is), ``'bounce'`` (float
|
||||
value; how bouncy the physical response is).
|
||||
``('modify_node_collision', attr, value)`` - similar to
|
||||
``modify_part_collision``, but operates at a node-level.
|
||||
collision attributes set here will remain in effect as long as
|
||||
*anything* from our part's node and their part's node overlap.
|
||||
A key use of this functionality is to prevent new nodes from
|
||||
colliding with each other if they appear overlapped;
|
||||
if ``modify_part_collision`` is used, only the individual parts that
|
||||
were overlapping would avoid contact, but other parts could still
|
||||
contact leaving the two nodes 'tangled up'. Using
|
||||
if ``modify_part_collision`` is used, only the individual
|
||||
parts that were overlapping would avoid contact, but other parts
|
||||
could still contact leaving the two nodes 'tangled up'. Using
|
||||
``modify_node_collision ensures`` that the nodes must completely
|
||||
separate before they can start colliding. Currently the only attr
|
||||
available here is ``'collide'`` (a boolean value).
|
||||
|
||||
``('sound', sound, volume)`` - plays a ba.Sound when a collision occurs, at
|
||||
a given volume, regardless of the collision speed/etc.
|
||||
``('sound', sound, volume)`` - plays a ba.Sound when a collision
|
||||
occurs, at a given volume, regardless of the collision speed/etc.
|
||||
|
||||
``('impact_sound', sound, targetImpulse, volume)`` - plays a sound when a
|
||||
collision occurs, based on the speed of impact. Provide a ba.Sound, a
|
||||
target-impulse, and a volume.
|
||||
``('impact_sound', sound, targetImpulse, volume)`` - plays a sound
|
||||
when a collision occurs, based on the speed of impact.
|
||||
Provide a ba.Sound, a target-impulse, and a volume.
|
||||
|
||||
``('skid_sound', sound, targetImpulse, volume)`` - plays a sound during a
|
||||
collision when parts are 'scraping' against each other. Provide a
|
||||
ba.Sound, a target-impulse, and a volume.
|
||||
``('skid_sound', sound, targetImpulse, volume)`` - plays a sound
|
||||
during a collision when parts are 'scraping' against each other.
|
||||
Provide a ba.Sound, a target-impulse, and a volume.
|
||||
|
||||
``('roll_sound', sound, targetImpulse, volume)`` - plays a sound during a
|
||||
collision when parts are 'rolling' against each other. Provide a
|
||||
ba.Sound, a target-impulse, and a volume.
|
||||
``('roll_sound', sound, targetImpulse, volume)`` - plays a sound
|
||||
during a collision when parts are 'rolling' against each other.
|
||||
Provide a ba.Sound, a target-impulse, and a volume.
|
||||
|
||||
Examples:
|
||||
example 1: create a material that lets us ignore
|
||||
@ -818,42 +823,49 @@ class SessionPlayer:
|
||||
for any length of time.
|
||||
|
||||
Attributes:
|
||||
|
||||
id: int
|
||||
id (int):
|
||||
The unique numeric ID of the Player.
|
||||
|
||||
Note that you can also use the boolean operator for this same
|
||||
functionality, so a statement such as "if player" will do
|
||||
the right thing both for Player objects and values of None.
|
||||
|
||||
in_game: bool
|
||||
in_game (bool):
|
||||
This bool value will be True once the Player has completed
|
||||
any lobby character/team selection.
|
||||
|
||||
sessionteam: ba.SessionTeam
|
||||
sessionteam (ba.SessionTeam):
|
||||
The ba.SessionTeam this Player is on. If the SessionPlayer
|
||||
is still in its lobby selecting a team/etc. then a
|
||||
ba.SessionTeamNotFoundError will be raised.
|
||||
|
||||
inputdevice: ba.InputDevice
|
||||
inputdevice (ba.InputDevice):
|
||||
The input device associated with the player.
|
||||
|
||||
color: Sequence[float]
|
||||
color (Sequence[float]):
|
||||
The base color for this Player.
|
||||
In team games this will match the ba.SessionTeam's color.
|
||||
|
||||
highlight: Sequence[float]
|
||||
highlight (Sequence[float]):
|
||||
A secondary color for this player.
|
||||
This is used for minor highlights and accents
|
||||
to allow a player to stand apart from his teammates
|
||||
who may all share the same team (primary) color.
|
||||
|
||||
character: str
|
||||
character (str):
|
||||
The character this player has selected in their profile.
|
||||
|
||||
activityplayer: Optional[ba.Player]
|
||||
activityplayer (Optional[ba.Player]):
|
||||
The current game-specific instance for this player.
|
||||
"""
|
||||
id: int
|
||||
in_game: bool
|
||||
sessionteam: ba.SessionTeam
|
||||
inputdevice: ba.InputDevice
|
||||
color: Sequence[float]
|
||||
highlight: Sequence[float]
|
||||
character: str
|
||||
activityplayer: Optional[ba.Player]
|
||||
|
||||
def assigninput(self, type: Union[ba.InputType, tuple[ba.InputType, ...]],
|
||||
call: Callable) -> None:
|
||||
@ -1056,16 +1068,18 @@ class Vec3(Sequence[float]):
|
||||
- with a single three-member sequence arg, sequence values are copied
|
||||
- otherwise assumes individual x/y/z args (positional or keywords)
|
||||
Attributes:
|
||||
|
||||
x: float
|
||||
x (float):
|
||||
The vector's X component.
|
||||
|
||||
y: float
|
||||
y (float):
|
||||
The vector's Y component.
|
||||
|
||||
z: float
|
||||
z (float):
|
||||
The vector's Z component.
|
||||
"""
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
|
||||
# pylint: disable=function-redefined
|
||||
|
||||
@ -3593,8 +3607,8 @@ def set_have_mods(have_mods: bool) -> None:
|
||||
|
||||
|
||||
def set_internal_language_keys(
|
||||
listobj: list[tuple[str, str]],
|
||||
random_names_list: list[tuple[str, str]]) -> None:
|
||||
listobj: list[tuple[str, str]],
|
||||
random_names_list: list[tuple[str, str]]) -> None:
|
||||
"""set_internal_language_keys(listobj: list[tuple[str, str]],
|
||||
random_names_list: list[tuple[str, str]]) -> None
|
||||
|
||||
@ -3612,7 +3626,7 @@ def set_low_level_config_value(key: str, value: int) -> None:
|
||||
|
||||
|
||||
def set_map_bounds(
|
||||
bounds: tuple[float, float, float, float, float, float]) -> None:
|
||||
bounds: tuple[float, float, float, float, float, float]) -> None:
|
||||
"""set_map_bounds(bounds: tuple[float, float, float, float, float, float])
|
||||
-> None
|
||||
|
||||
@ -3964,8 +3978,8 @@ def textwidget(edit: ba.Widget = None,
|
||||
|
||||
@overload
|
||||
def time(
|
||||
timetype: ba.TimeType = TimeType.SIM,
|
||||
timeformat: Literal[TimeFormat.SECONDS] = TimeFormat.SECONDS) -> float:
|
||||
timetype: ba.TimeType = TimeType.SIM,
|
||||
timeformat: Literal[TimeFormat.SECONDS] = TimeFormat.SECONDS) -> float:
|
||||
...
|
||||
|
||||
|
||||
@ -4104,7 +4118,8 @@ def timer(time: float,
|
||||
>>> ba.timer(1.0, ba.Call(ba.screenmessage, 'hello from the future!'))
|
||||
>>> ba.timer(2.0, ba.Call(ba.screenmessage,
|
||||
... 'hello from the future 2!'))
|
||||
```"""
|
||||
```
|
||||
"""
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@ -42,14 +42,14 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
||||
passed to the Activity __init__ call.
|
||||
|
||||
teams
|
||||
The list of ba.Teams in the Activity. This gets populated just before
|
||||
The list of ba.Team-s in the Activity. This gets populated just
|
||||
before on_begin() is called and is updated automatically as players
|
||||
join or leave the game. (at least in free-for-all mode where every
|
||||
player gets their own team; in teams mode there are always 2 teams
|
||||
regardless of the player count).
|
||||
|
||||
players
|
||||
The list of ba.Players in the Activity. This gets populated just
|
||||
The list of ba.Player-s in the Activity. This gets populated just
|
||||
before on_begin() is called and is updated automatically as players
|
||||
join or leave the game.
|
||||
"""
|
||||
@ -129,7 +129,7 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
||||
def __init__(self, settings: dict):
|
||||
"""Creates an Activity in the current ba.Session.
|
||||
|
||||
The activity will not be actually run until ba.Session.setactivity()
|
||||
The activity will not be actually run until ba.Session.setactivity
|
||||
is called. 'settings' should be a dict of key/value pairs specific
|
||||
to the activity.
|
||||
|
||||
@ -363,14 +363,14 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
||||
Upon this call, the Activity should fade in backgrounds,
|
||||
start playing music, etc. It does not yet have access to players
|
||||
or teams, however. They remain owned by the previous Activity
|
||||
up until ba.Activity.on_begin() is called.
|
||||
up until ba.Activity.on_begin is called.
|
||||
"""
|
||||
|
||||
def on_transition_out(self) -> None:
|
||||
"""Called when your activity begins transitioning out.
|
||||
|
||||
Note that this may happen at any time even if end() has not been
|
||||
called.
|
||||
Note that this may happen at any time even if ba.Activity.end has
|
||||
not been called.
|
||||
"""
|
||||
|
||||
def on_begin(self) -> None:
|
||||
@ -386,11 +386,11 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
||||
return UNHANDLED
|
||||
|
||||
def has_transitioned_in(self) -> bool:
|
||||
"""Return whether on_transition_in() has been called."""
|
||||
"""Return whether ba.Activity.on_transition_in() has been called."""
|
||||
return self._has_transitioned_in
|
||||
|
||||
def has_begun(self) -> bool:
|
||||
"""Return whether on_begin() has been called."""
|
||||
"""Return whether ba.Activity.on_begin() has been called."""
|
||||
return self._has_begun
|
||||
|
||||
def has_ended(self) -> bool:
|
||||
@ -398,7 +398,7 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
||||
return self._has_ended
|
||||
|
||||
def is_transitioning_out(self) -> bool:
|
||||
"""Return whether on_transition_out() has been called."""
|
||||
"""Return whether ba.Activity.on_transition_out() has been called."""
|
||||
return self._transitioning_out
|
||||
|
||||
def transition_in(self, prev_globals: Optional[ba.Node]) -> None:
|
||||
@ -517,8 +517,8 @@ class Activity(DependencyComponent, Generic[PlayerType, TeamType]):
|
||||
Subclasses can override this if the activity's player class
|
||||
requires a custom constructor; otherwise it will be called with
|
||||
no args. Note that the player object should not be used at this
|
||||
point as it is not yet fully wired up; wait for on_player_join()
|
||||
for that.
|
||||
point as it is not yet fully wired up; wait for
|
||||
ba.Activity.on_player_join() for that.
|
||||
"""
|
||||
del sessionplayer # Unused.
|
||||
player = self._playertype()
|
||||
|
||||
@ -115,7 +115,7 @@ class Actor:
|
||||
return self
|
||||
|
||||
def on_expire(self) -> None:
|
||||
"""Called for remaining ba.Actors when their ba.Activity shuts down.
|
||||
"""Called for remaining ba.Actor-s when their ba.Activity shuts down.
|
||||
|
||||
Actors can use this opportunity to clear callbacks or other
|
||||
references which have the potential of keeping the ba.Activity
|
||||
|
||||
@ -23,7 +23,7 @@ def getcampaign(name: str) -> ba.Campaign:
|
||||
|
||||
|
||||
class Campaign:
|
||||
"""Represents a unique set or series of ba.Levels.
|
||||
"""Represents a unique set or series of ba.Level-s.
|
||||
|
||||
Category: App Classes
|
||||
"""
|
||||
@ -52,7 +52,7 @@ class Campaign:
|
||||
|
||||
@property
|
||||
def levels(self) -> list[ba.Level]:
|
||||
"""The list of ba.Levels in the Campaign."""
|
||||
"""The list of ba.Level-s in the Campaign."""
|
||||
return self._levels
|
||||
|
||||
def getlevel(self, name: str) -> ba.Level:
|
||||
|
||||
@ -380,7 +380,8 @@ def storagename(suffix: str = None) -> str:
|
||||
... # '_mymodule_submodule_mythingie_data'.
|
||||
... _STORENAME = ba.storagename('data')
|
||||
...
|
||||
... # Use that name to store some data in the Activity we were passed.
|
||||
... # Use that name to store some data in the Activity we were
|
||||
... # passed.
|
||||
... def __init__(self, activity):
|
||||
... activity.customdata[self._STORENAME] = {}
|
||||
```
|
||||
|
||||
@ -384,7 +384,8 @@ class Lstr:
|
||||
value; if a translated value is available, it will be used; otherwise
|
||||
the english value will be. To see available translation categories,
|
||||
look under the 'translations' resource section.
|
||||
>>> mynode.text = ba.Lstr(translate=('gameDescriptions', 'Defeat all enemies'))
|
||||
>>> mynode.text = ba.Lstr(translate=('gameDescriptions',
|
||||
... 'Defeat all enemies'))
|
||||
|
||||
EXAMPLE 3: specify a raw value and some substitutions. Substitutions
|
||||
can be used with resource and translate modes as well.
|
||||
|
||||
@ -345,7 +345,7 @@ class Map(Actor):
|
||||
self, players: Sequence[ba.Player]) -> Sequence[float]:
|
||||
"""Return a random starting position in one of the FFA spawn areas.
|
||||
|
||||
If a list of ba.Players is provided; the returned points will be
|
||||
If a list of ba.Player-s is provided; the returned points will be
|
||||
as far from these players as possible.
|
||||
"""
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ class DieMessage:
|
||||
|
||||
Category: Message Classes
|
||||
|
||||
Most ba.Actors respond to this.
|
||||
Most ba.Actor-s respond to this.
|
||||
|
||||
Attributes:
|
||||
|
||||
|
||||
@ -141,7 +141,7 @@ class MultiTeamSession(Session):
|
||||
team.customdata['previous_score'] = team.customdata['score'] = 0
|
||||
|
||||
def get_max_players(self) -> int:
|
||||
"""Return max number of ba.Players allowed to join the game at once."""
|
||||
"""Return max number of ba.Player-s allowed to join the game at once"""
|
||||
if self.use_teams:
|
||||
return _ba.app.config.get('Team Game Max Players', 8)
|
||||
return _ba.app.config.get('Free-for-All Max Players', 8)
|
||||
|
||||
@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class Session:
|
||||
"""Defines a high level series of ba.Activities with a common purpose.
|
||||
"""Defines a high level series of ba.Activity-es with a common purpose.
|
||||
|
||||
category: Gameplay Classes
|
||||
|
||||
@ -32,11 +32,11 @@ class Session:
|
||||
|
||||
sessionteams
|
||||
All the ba.SessionTeams in the Session. Most things should use the
|
||||
list of ba.Teams in ba.Activity; not this.
|
||||
list of ba.Team-s in ba.Activity; not this.
|
||||
|
||||
sessionplayers
|
||||
All ba.SessionPlayers in the Session. Most things should use the
|
||||
list of ba.Players in ba.Activity; not this. Some players, such as
|
||||
list of ba.Player-s in ba.Activity; not this. Some players, such as
|
||||
those who have not yet selected a character, will only be
|
||||
found on this list.
|
||||
|
||||
@ -48,7 +48,7 @@ class Session:
|
||||
The maximum number of players allowed in the Session.
|
||||
|
||||
lobby
|
||||
The ba.Lobby instance where new ba.Players go to select a
|
||||
The ba.Lobby instance where new ba.Player-s go to select a
|
||||
Profile/Team/etc. before being added to games.
|
||||
Be aware this value may be None if a Session does not allow
|
||||
any such selection.
|
||||
|
||||
@ -78,7 +78,7 @@ class BombFactory:
|
||||
A ba.Sound for random wood debris falling after an explosion.
|
||||
|
||||
explode_sounds: Sequence[ba.Sound]
|
||||
A tuple of ba.Sounds for explosions.
|
||||
A tuple of ba.Sound-s for explosions.
|
||||
|
||||
freeze_sound: ba.Sound
|
||||
A ba.Sound of an ice bomb freezing something.
|
||||
@ -119,7 +119,7 @@ class BombFactory:
|
||||
events with what it touches.
|
||||
|
||||
dink_sounds: Sequence[ba.Sound]
|
||||
A tuple of ba.Sounds for when bombs hit the ground.
|
||||
A tuple of ba.Sound-s for when bombs hit the ground.
|
||||
|
||||
sticky_impact_sound: ba.Sound
|
||||
The ba.Sound for a squish made by a sticky bomb hitting something.
|
||||
|
||||
@ -189,7 +189,7 @@ class Flag(ba.Actor):
|
||||
useful for things like king-of-the-hill where players should
|
||||
not be moving the flag around.
|
||||
|
||||
'materials can be a list of extra ba.Materials to apply to the flag.
|
||||
'materials can be a list of extra ba.Material-s to apply to the flag.
|
||||
|
||||
If 'dropped_timeout' is provided (in seconds), the flag will die
|
||||
after remaining untouched for that long once it has been moved
|
||||
|
||||
@ -26,13 +26,13 @@ class SpazFactory:
|
||||
Attributes:
|
||||
|
||||
impact_sounds_medium: Sequence[ba.Sound]
|
||||
A tuple of ba.Sounds for when a ba.Spaz hits something kinda hard.
|
||||
A tuple of ba.Sound-s for when a ba.Spaz hits something kinda hard.
|
||||
|
||||
impact_sounds_hard: Sequence[ba.Sound]
|
||||
A tuple of ba.Sounds for when a ba.Spaz hits something really hard.
|
||||
A tuple of ba.Sound-s for when a ba.Spaz hits something really hard.
|
||||
|
||||
impact_sounds_harder: Sequence[ba.Sound]
|
||||
A tuple of ba.Sounds for when a ba.Spaz hits something really
|
||||
A tuple of ba.Sound-s for when a ba.Spaz hits something really
|
||||
really hard.
|
||||
|
||||
single_player_death_sound: ba.Sound
|
||||
|
||||
@ -33,7 +33,8 @@ void PythonClassContext::SetupType(PyTypeObject* obj) {
|
||||
"the UI (there is a special 'ui' context for all user-interface-related\n"
|
||||
"functionality)\n"
|
||||
"\n"
|
||||
"When instantiating a ba.Context instance, a single ``'source'`` argument\n"
|
||||
"When instantiating a ba.Context instance, a single ``'source'`` "
|
||||
"argument\n"
|
||||
"is passed, which can be one of the following strings/objects:\n\n"
|
||||
"``'empty'``:\n"
|
||||
" Gives an empty context; it can be handy to run code here to ensure\n"
|
||||
@ -56,7 +57,8 @@ void PythonClassContext::SetupType(PyTypeObject* obj) {
|
||||
"\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
" Contexts are generally used with the python 'with' statement, which\n"
|
||||
" Contexts are generally used with the python 'with' statement, "
|
||||
"which\n"
|
||||
" sets the context as current on entry and resets it to the previous\n"
|
||||
" value on exit.\n"
|
||||
"\n"
|
||||
|
||||
@ -41,13 +41,15 @@ void PythonClassContextCall::SetupType(PyTypeObject* obj) {
|
||||
"Examples:\n"
|
||||
" Example A: code like this can inadvertently prevent our activity\n"
|
||||
" (self) from ending until the operation completes, since the bound\n"
|
||||
" method we're passing (self.dosomething) contains a strong-reference\n"
|
||||
" method we're passing (self.dosomething) contains a "
|
||||
"strong-reference\n"
|
||||
" to self).\n"
|
||||
" >>> start_some_long_action(callback_when_done=self.dosomething)\n"
|
||||
"\n"
|
||||
" Example B: in this case our activity (self) can still die\n"
|
||||
" properly; the callback will clear itself when the activity starts\n"
|
||||
" shutting down, becoming a harmless no-op and releasing the reference\n"
|
||||
" shutting down, becoming a harmless no-op and releasing the "
|
||||
"reference\n"
|
||||
" to our activity.\n"
|
||||
" ```python\n"
|
||||
" >>> start_long_action(\n"
|
||||
|
||||
@ -281,78 +281,84 @@ PyMethodDef PythonClassMaterial::tp_methods[] = {
|
||||
"Add one or more actions to the material, optionally with conditions.\n"
|
||||
"\n"
|
||||
"Conditions:\n"
|
||||
" Conditions are provided as tuples which can be combined to form boolean\n"
|
||||
" logic. A single condition might look like ``('condition_name', cond_arg)``,\n"
|
||||
" or a more complex nested one might look like ``(('some_condition',\n"
|
||||
" cond_arg), 'or', ('another_condition', cond2_arg))``.\n"
|
||||
" Conditions are provided as tuples which can be combined\n"
|
||||
" to form boolean logic. A single condition might look like\n"
|
||||
" ``('condition_name', cond_arg)``, or a more complex nested one\n"
|
||||
" might look like ``(('some_condition', cond_arg), 'or',\n"
|
||||
" ('another_condition', cond2_arg))``.\n"
|
||||
"\n"
|
||||
" ``'and'``, ``'or'``, and ``'xor'`` are available to chain together 2 conditions, as\n"
|
||||
" seen above.\n"
|
||||
" ``'and'``, ``'or'``, and ``'xor'`` are available to chain\n"
|
||||
" together 2 conditions, as seen above.\n"
|
||||
"\n"
|
||||
"Available Conditions:\n"
|
||||
" ``('they_have_material', material)`` - does the part we\'re hitting have a\n"
|
||||
" given ba.Material?\n"
|
||||
" ``('they_have_material', material)`` - does the part we\'re\n"
|
||||
" hitting have a given ba.Material?\n"
|
||||
"\n"
|
||||
" ``('they_dont_have_material', material)`` - does the part we\'re hitting\n"
|
||||
" not have a given ba.Material?\n"
|
||||
" ``('they_dont_have_material', material)`` - does the part we\'re\n"
|
||||
" hitting not have a given ba.Material?\n"
|
||||
"\n"
|
||||
" ``('eval_colliding')`` - is ``'collide'`` true at this point in material\n"
|
||||
" evaluation? (see the modify_part_collision action)\n"
|
||||
" ``('eval_colliding')`` - is ``'collide'`` true at this point\n"
|
||||
" in material evaluation? (see the modify_part_collision action)\n"
|
||||
"\n"
|
||||
" ``('eval_not_colliding')`` - is 'collide' false at this point in material\n"
|
||||
" evaluation? (see the modify_part_collision action)\n"
|
||||
" ``('eval_not_colliding')`` - is 'collide' false at this point\n"
|
||||
" in material evaluation? (see the modify_part_collision action)\n"
|
||||
"\n"
|
||||
" ``('we_are_younger_than', age)`` - is our part younger than ``'age'``\n"
|
||||
" (in milliseconds)?\n"
|
||||
" ``('we_are_younger_than', age)`` - is our part younger than\n"
|
||||
" ``'age'`` (in milliseconds)?\n"
|
||||
"\n"
|
||||
" ``('we_are_older_than', age)`` - is our part older than ``'age'``\n"
|
||||
" (in milliseconds)?\n"
|
||||
"\n"
|
||||
" ``('they_are_younger_than', age)`` - is the part we're hitting younger than\n"
|
||||
" ``'age'`` (in milliseconds)?\n"
|
||||
" ``('they_are_younger_than', age)`` - is the part we're hitting\n"
|
||||
" younger than ``'age'`` (in milliseconds)?\n"
|
||||
"\n"
|
||||
" ``('they_are_older_than', age)`` - is the part we're hitting older than\n"
|
||||
" ``'age'`` (in milliseconds)?\n"
|
||||
" ``('they_are_older_than', age)`` - is the part we're hitting\n"
|
||||
" older than ``'age'`` (in milliseconds)?\n"
|
||||
"\n"
|
||||
" ``('they_are_same_node_as_us')`` - does the part we're hitting belong to\n"
|
||||
" the same ba.Node as us?\n"
|
||||
" ``('they_are_same_node_as_us')`` - does the part we're hitting\n"
|
||||
" belong to the same ba.Node as us?\n"
|
||||
"\n"
|
||||
" ``('they_are_different_node_than_us')`` - does the part we're hitting\n"
|
||||
" belong to a different ba.Node than us?\n"
|
||||
" ``('they_are_different_node_than_us')`` - does the part we're\n"
|
||||
" hitting belong to a different ba.Node than us?\n"
|
||||
"\n"
|
||||
"Actions:\n"
|
||||
" In a similar manner, actions are specified as tuples. Multiple actions\n"
|
||||
" can be specified by providing a tuple of tuples.\n"
|
||||
" In a similar manner, actions are specified as tuples.\n"
|
||||
" Multiple actions can be specified by providing a tuple\n"
|
||||
" of tuples.\n"
|
||||
"\n"
|
||||
"Available Actions:\n"
|
||||
" ``('call', when, callable)`` - calls the provided callable; ``'when'`` can be\n"
|
||||
" either ``'at_connect'`` or ``'at_disconnect'``. ``'at_connect'`` means to fire\n"
|
||||
" when the two parts first come in contact; ``'at_disconnect'`` means to\n"
|
||||
" fire once they cease being in contact.\n"
|
||||
" ``('call', when, callable)`` - calls the provided callable;\n"
|
||||
" ``'when'`` can be either ``'at_connect'`` or ``'at_disconnect'``.\n"
|
||||
" ``'at_connect'`` means to fire\n"
|
||||
" when the two parts first come in contact; ``'at_disconnect'``\n"
|
||||
" means to fire once they cease being in contact.\n"
|
||||
"\n"
|
||||
" ``('message', who, when, message_obj)`` - sends a message object; ``'who'`` can\n"
|
||||
" be either ``'our_node'`` or ``'their_node'``, ``'when'`` can be ``'at_connect'`` or\n"
|
||||
" ``('message', who, when, message_obj)`` - sends a message object;\n"
|
||||
" ``'who'`` can\n"
|
||||
" be either ``'our_node'`` or ``'their_node'``, ``'when'`` can be\n"
|
||||
" ``'at_connect'`` or\n"
|
||||
" ``'at_disconnect'``, and message_obj is the message object to send.\n"
|
||||
" This has the same effect as calling the node's ba.Node.handlemessage\n"
|
||||
" method.\n"
|
||||
" This has the same effect as calling the node's\n"
|
||||
" ba.Node.handlemessage method.\n"
|
||||
"\n"
|
||||
" ``('modify_part_collision', attr, value)`` - changes some characteristic\n"
|
||||
" of the physical collision that will occur between our part and their\n"
|
||||
" part. This change will remain in effect as long as the two parts\n"
|
||||
" remain overlapping. This means if you have a part with a material\n"
|
||||
" that turns ``'collide'`` off against parts younger than 100ms, and it\n"
|
||||
" touches another part that is 50ms old, it will continue to not\n"
|
||||
" collide with that part until they separate, even if the 100ms\n"
|
||||
" threshold is passed. Options for attr/value are: ``'physical'`` (boolean\n"
|
||||
" value; whether a *physical* response will occur at all), ``'friction'``\n"
|
||||
" (float value; how friction-y the physical response will be),\n"
|
||||
" ``'collide'`` (boolean value; whether *any* collision will occur at all,\n"
|
||||
" including non-physical stuff like callbacks), ``'use_node_collide'``\n"
|
||||
" (boolean value; whether to honor modify_node_collision overrides for\n"
|
||||
" this collision), ``'stiffness'`` (float value, how springy the physical\n"
|
||||
" response is), ``'damping'`` (float value, how damped the physical\n"
|
||||
" response is), ``'bounce'`` (float value; how bouncy the physical response\n"
|
||||
" is).\n"
|
||||
" ``('modify_part_collision', attr, value)`` - changes some\n"
|
||||
" characteristic of the physical collision that will occur between\n"
|
||||
" our part and their part. This change will remain in effect as\n"
|
||||
" long as the two parts remain overlapping. This means if you have a\n"
|
||||
" part with a material that turns ``'collide'`` off against parts\n"
|
||||
" younger than 100ms, and it touches another part that is 50ms old,\n"
|
||||
" it will continue to not collide with that part until they separate,\n"
|
||||
" even if the 100ms threshold is passed. Options for attr/value are:\n"
|
||||
" ``'physical'`` (boolean value; whether a *physical* response will\n"
|
||||
" occur at all), ``'friction'`` (float value; how friction-y the\n"
|
||||
" physical response will be), ``'collide'`` (boolean value;\n"
|
||||
" whether *any* collision will occur at all, including non-physical\n"
|
||||
" stuff like callbacks), ``'use_node_collide'``\n"
|
||||
" (boolean value; whether to honor modify_node_collision\n"
|
||||
" overrides for this collision), ``'stiffness'`` (float value,\n"
|
||||
" how springy the physical response is), ``'damping'`` (float\n"
|
||||
" value, how damped the physical response is), ``'bounce'`` (float\n"
|
||||
" value; how bouncy the physical response is)."
|
||||
"\n"
|
||||
" ``('modify_node_collision', attr, value)`` - similar to\n"
|
||||
" ``modify_part_collision``, but operates at a node-level.\n"
|
||||
@ -360,27 +366,27 @@ PyMethodDef PythonClassMaterial::tp_methods[] = {
|
||||
" *anything* from our part's node and their part's node overlap.\n"
|
||||
" A key use of this functionality is to prevent new nodes from\n"
|
||||
" colliding with each other if they appear overlapped;\n"
|
||||
" if ``modify_part_collision`` is used, only the individual parts that\n"
|
||||
" were overlapping would avoid contact, but other parts could still\n"
|
||||
" contact leaving the two nodes 'tangled up'. Using\n"
|
||||
" if ``modify_part_collision`` is used, only the individual\n"
|
||||
" parts that were overlapping would avoid contact, but other parts\n"
|
||||
" could still contact leaving the two nodes 'tangled up'. Using\n"
|
||||
" ``modify_node_collision ensures`` that the nodes must completely\n"
|
||||
" separate before they can start colliding. Currently the only attr\n"
|
||||
" available here is ``'collide'`` (a boolean value).\n"
|
||||
"\n"
|
||||
" ``('sound', sound, volume)`` - plays a ba.Sound when a collision occurs, at\n"
|
||||
" a given volume, regardless of the collision speed/etc.\n"
|
||||
" ``('sound', sound, volume)`` - plays a ba.Sound when a collision\n"
|
||||
" occurs, at a given volume, regardless of the collision speed/etc.\n"
|
||||
"\n"
|
||||
" ``('impact_sound', sound, targetImpulse, volume)`` - plays a sound when a\n"
|
||||
" collision occurs, based on the speed of impact. Provide a ba.Sound, a\n"
|
||||
" target-impulse, and a volume.\n"
|
||||
" ``('impact_sound', sound, targetImpulse, volume)`` - plays a sound\n"
|
||||
" when a collision occurs, based on the speed of impact.\n"
|
||||
" Provide a ba.Sound, a target-impulse, and a volume.\n"
|
||||
"\n"
|
||||
" ``('skid_sound', sound, targetImpulse, volume)`` - plays a sound during a\n"
|
||||
" collision when parts are 'scraping' against each other. Provide a\n"
|
||||
" ba.Sound, a target-impulse, and a volume.\n"
|
||||
" ``('skid_sound', sound, targetImpulse, volume)`` - plays a sound\n"
|
||||
" during a collision when parts are 'scraping' against each other.\n"
|
||||
" Provide a ba.Sound, a target-impulse, and a volume.\n"
|
||||
"\n"
|
||||
" ``('roll_sound', sound, targetImpulse, volume)`` - plays a sound during a\n"
|
||||
" collision when parts are 'rolling' against each other. Provide a\n"
|
||||
" ba.Sound, a target-impulse, and a volume.\n"
|
||||
" ``('roll_sound', sound, targetImpulse, volume)`` - plays a sound\n"
|
||||
" during a collision when parts are 'rolling' against each other.\n"
|
||||
" Provide a ba.Sound, a target-impulse, and a volume.\n"
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" example 1: create a material that lets us ignore\n"
|
||||
|
||||
@ -58,40 +58,39 @@ void PythonClassSessionPlayer::SetupType(PyTypeObject* obj) {
|
||||
"for any length of time.\n"
|
||||
"\n"
|
||||
"Attributes:\n"
|
||||
"\n"
|
||||
" " ATTR_ID ": int\n"
|
||||
" " ATTR_ID " (int):\n"
|
||||
" The unique numeric ID of the Player.\n"
|
||||
"\n"
|
||||
" Note that you can also use the boolean operator for this same\n"
|
||||
" functionality, so a statement such as \"if player\" will do\n"
|
||||
" the right thing both for Player objects and values of None.\n"
|
||||
"\n"
|
||||
" " ATTR_IN_GAME ": bool\n"
|
||||
" " ATTR_IN_GAME " (bool):\n"
|
||||
" This bool value will be True once the Player has completed\n"
|
||||
" any lobby character/team selection.\n"
|
||||
"\n"
|
||||
" " ATTR_SESSIONTEAM ": ba.SessionTeam\n"
|
||||
" " ATTR_SESSIONTEAM " (ba.SessionTeam):\n"
|
||||
" The ba.SessionTeam this Player is on. If the SessionPlayer\n"
|
||||
" is still in its lobby selecting a team/etc. then a\n"
|
||||
" ba.SessionTeamNotFoundError will be raised.\n"
|
||||
"\n"
|
||||
" " ATTR_INPUT_DEVICE ": ba.InputDevice\n"
|
||||
" " ATTR_INPUT_DEVICE " (ba.InputDevice):\n"
|
||||
" The input device associated with the player.\n"
|
||||
"\n"
|
||||
" " ATTR_COLOR ": Sequence[float]\n"
|
||||
" " ATTR_COLOR " (Sequence[float]):\n"
|
||||
" The base color for this Player.\n"
|
||||
" In team games this will match the ba.SessionTeam's color.\n"
|
||||
"\n"
|
||||
" " ATTR_HIGHLIGHT ": Sequence[float]\n"
|
||||
" " ATTR_HIGHLIGHT " (Sequence[float]):\n"
|
||||
" A secondary color for this player.\n"
|
||||
" This is used for minor highlights and accents\n"
|
||||
" to allow a player to stand apart from his teammates\n"
|
||||
" who may all share the same team (primary) color.\n"
|
||||
"\n"
|
||||
" " ATTR_CHARACTER ": str\n"
|
||||
" " ATTR_CHARACTER " (str):\n"
|
||||
" The character this player has selected in their profile.\n"
|
||||
"\n"
|
||||
" " ATTR_ACTIVITYPLAYER ": Optional[ba.Player]\n"
|
||||
" " ATTR_ACTIVITYPLAYER " (Optional[ba.Player]):\n"
|
||||
" The current game-specific instance for this player.\n";
|
||||
|
||||
// clang-format on
|
||||
|
||||
@ -53,7 +53,8 @@ void PythonClassTimer::SetupType(PyTypeObject* obj) {
|
||||
" ... def stop_saying_it():\n"
|
||||
" ... self.t = None\n"
|
||||
" ... ba.screenmessage('MUSHROOM MUSHROOM!')\n"
|
||||
" ... # Create our timer; it will run as long as we have the self.t ref.\n"
|
||||
" ... # Create our timer; it will run as long as we have the self.t "
|
||||
"ref.\n"
|
||||
" ... self.t = ba.Timer(0.3, say_it, repeat=True)\n"
|
||||
" ... # Now fire off a one-shot timer to kill it.\n"
|
||||
" ... ba.timer(3.89, stop_saying_it)\n"
|
||||
|
||||
@ -38,14 +38,13 @@ void PythonClassVec3::SetupType(PyTypeObject* obj) {
|
||||
"- otherwise assumes individual x/y/z args (positional or keywords)"
|
||||
"\n"
|
||||
"Attributes:\n"
|
||||
"\n"
|
||||
" x: float\n"
|
||||
" x (float):\n"
|
||||
" The vector's X component.\n"
|
||||
"\n"
|
||||
" y: float\n"
|
||||
" y (float):\n"
|
||||
" The vector's Y component.\n"
|
||||
"\n"
|
||||
" z: float\n"
|
||||
" z (float):\n"
|
||||
" The vector's Z component.\n";
|
||||
|
||||
obj->tp_new = tp_new;
|
||||
|
||||
@ -1033,32 +1033,40 @@ auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
|
||||
"This timer cannot be canceled or modified once created. If you\n"
|
||||
" require the ability to do so, use the ba.Timer class instead.\n"
|
||||
"\n"
|
||||
"Arguments:\n"
|
||||
"Arguments:\n"
|
||||
" time (float):\n"
|
||||
" Length of time (in seconds by default) that the timer will wait\n"
|
||||
" before firing. Note that the actual delay experienced may vary\n "
|
||||
" Length of time (in seconds by default) that the timer will "
|
||||
"wait\n"
|
||||
" before firing. Note that the actual delay experienced may "
|
||||
"vary\n "
|
||||
" depending on the timetype. (see below)\n"
|
||||
"\n"
|
||||
" call (Callable[[], Any]):\n"
|
||||
" A callable Python object. Note that the timer will retain a\n"
|
||||
" strong reference to the callable for as long as it exists, so you\n"
|
||||
" may want to look into concepts such as ba.WeakCall if that is not\n"
|
||||
" A callable Python object. Note that the timer will retain a\n"
|
||||
" strong reference to the callable for as long as it exists, "
|
||||
"so you\n"
|
||||
" may want to look into concepts such as ba.WeakCall if that "
|
||||
"is not\n"
|
||||
" desired.\n"
|
||||
"\n"
|
||||
" repeat (bool):\n"
|
||||
" If True, the timer will fire repeatedly, with each successive\n"
|
||||
" If True, the timer will fire repeatedly, with each "
|
||||
"successive\n"
|
||||
" firing having the same delay as the first.\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" timetype (ba.TimeType):\n"
|
||||
" Can be either ``SIM``, ``BASE``, or ``REAL``. It defaults to\n"
|
||||
" ``SIM``. \n"
|
||||
"\n"
|
||||
" timeformat (ba.TimeFormat):\n"
|
||||
" Defaults to seconds but can also be milliseconds.\n"
|
||||
"\n"
|
||||
"- SIM time maps to local simulation time in ba.Activity or ba.Session\n"
|
||||
"Contexts. This means that it may progress slower in slow-motion play\n"
|
||||
" timetype (ba.TimeType):\n"
|
||||
" Can be either ``SIM``, ``BASE``, or ``REAL``. It defaults "
|
||||
"to\n"
|
||||
" ``SIM``.\n"
|
||||
"\n"
|
||||
" timeformat (ba.TimeFormat):\n"
|
||||
" Defaults to seconds but can also be milliseconds.\n"
|
||||
"\n"
|
||||
"- SIM time maps to local simulation time in ba.Activity or "
|
||||
"ba.Session\n"
|
||||
"Contexts. This means that it may progress slower in slow-motion "
|
||||
"play\n"
|
||||
"modes, stop when the game is paused, etc. This time type is not\n"
|
||||
"available in UI contexts.\n"
|
||||
"- BASE time is also linked to gameplay in ba.Activity or ba.Session\n"
|
||||
@ -1066,19 +1074,21 @@ auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
|
||||
"slow-motion states or pausing. It can, however, slow down or stop\n"
|
||||
"in certain cases such as network outages or game slowdowns due to\n"
|
||||
"cpu load. Like 'sim' time, this is unavailable in UI contexts.\n"
|
||||
"- REAL time always maps to actual clock time with a bit of filtering\n"
|
||||
"- REAL time always maps to actual clock time with a bit of "
|
||||
"filtering\n"
|
||||
"added, regardless of Context. (The filtering prevents it from going\n"
|
||||
"backwards or jumping forward by large amounts due to the app being\n"
|
||||
"backgrounded, system time changing, etc.)\n"
|
||||
"Real time timers are currently only available in the UI context.\n"
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
"Examples:\n"
|
||||
" Print some stuff through time:\n"
|
||||
" ```python\n"
|
||||
" >>> ba.screenmessage('hello from now!')\n"
|
||||
" >>> ba.timer(1.0, ba.Call(ba.screenmessage, 'hello from the future!'))\n"
|
||||
" >>> ba.timer(1.0, ba.Call(ba.screenmessage, 'hello from the "
|
||||
"future!'))\n"
|
||||
" >>> ba.timer(2.0, ba.Call(ba.screenmessage,\n"
|
||||
" ... 'hello from the future 2!'))\n"
|
||||
" ... 'hello from the future 2!'))\n"
|
||||
" ```\n"},
|
||||
|
||||
{"time", (PyCFunction)PyTime, METH_VARARGS | METH_KEYWORDS,
|
||||
|
||||
@ -89,7 +89,7 @@ def generate(projroot: str) -> None:
|
||||
pdoc.render.configure(docformat='google',
|
||||
search=True,
|
||||
show_source=True)
|
||||
pdoc.pdoc('ba', output_directory=outdirname)
|
||||
pdoc.pdoc('ba', 'bastd', output_directory=outdirname)
|
||||
except Exception as exc:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user