diff --git a/.efrocachemap b/.efrocachemap
index 26963766..9e595257 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -4132,16 +4132,16 @@
"assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c",
"assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb",
"assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe",
- "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/97/fd0e5553917019236912a7010d38",
- "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/43/32/c48a4da7fcc8c17132077da852d7",
- "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/75/13/2bc3ae9026386d1b515ede107e17",
- "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1f/9a/b112f788f528ec9e3627622698ac",
- "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/87/fdb3e925f3be1cc353db94d61c5a",
- "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fa/ba/125457c69bc2940850ab84c4cc6a",
- "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a1/d4/5efcef1f85b2bfea7bbb81800580",
- "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fa/66/75a3a0f27d07131473e804a5b937",
- "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/51/6c/911ba80ba913e6dac1cafa5c8a74",
- "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/01/cc/cf896173a8d5731ada2aace59146",
- "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a2/12/aa1f0ca5506f0b57f93ca9adf7be",
- "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e1/5f/f372d0ba9591b99284b9b50d7cdf"
+ "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/35/3b6bc5c5609b1dd37bd65c39df45",
+ "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a6/bc/c2c7231dc6bf085eda15d6198554",
+ "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6b/fd/020ed9bb0e8c8a18b2d793fee8bd",
+ "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/43/0b/78c8bacb215abaf50dcb3284eef7",
+ "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f8/e1/e0dc64b5c00661cce19530c0e836",
+ "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e6/74/73a514993d626a6bc75717d185ef",
+ "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f0/7d/dbd2624759a1fdce2a20d53cab1a",
+ "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/1c/01/4833ec215cc6c53f7e4ebf850608",
+ "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/b1/57/b72500d2a568df5afa36556f89dd",
+ "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/48/ea/c83f97f44703b16eeec794d29da6",
+ "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a3/16/284b9953c7ef4a841ff907079cbd",
+ "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/12/43/d0513cf8f8dac0712cbf42d4b94b"
}
\ No newline at end of file
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index 1cf96c30..16a51b7c 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -1114,6 +1114,7 @@
mhsh
microprotocols
mikirog
+ millisecs
mimetypes
mimportedby
mindepth
diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py
index f1f90179..3e0e0d1f 100644
--- a/assets/src/ba_data/python/_ba.py
+++ b/assets/src/ba_data/python/_ba.py
@@ -34,7 +34,7 @@ NOTE: This file was autogenerated by gendummymodule; do not edit by hand.
"""
# (hash we can use to see if this file is out of date)
-# SOURCES_HASH=318889180473540875493180206824864665481
+# SOURCES_HASH=223083205204988067566025188831386474803
# I'm sorry Pylint. I know this file saddens you. Be strong.
# pylint: disable=useless-suppression
@@ -3729,11 +3729,35 @@ def textwidget(edit: Widget = None,
return Widget()
+# Overloads to return a type based on requested format.
+
+
+@overload
+def time(
+ timetype: ba.TimeType = TimeType.SIM,
+ timeformat: Literal[TimeFormat.SECONDS] = TimeFormat.SECONDS) -> float:
+ ...
+
+
+# This "*" keyword-only hack lets us accept 1 arg (timeformat=MILLISECS) forms.
+@overload
def time(timetype: ba.TimeType = TimeType.SIM,
- timeformat: ba.TimeFormat = TimeFormat.SECONDS) -> Union[float, int]:
+ *,
+ timeformat: Literal[TimeFormat.MILLISECONDS]) -> int:
+ ...
+
+
+@overload
+def time(timetype: ba.TimeType,
+ timeformat: Literal[TimeFormat.MILLISECONDS]) -> int:
+ ...
+
+
+def time(timetype: ba.TimeType = TimeType.SIM,
+ timeformat: ba.TimeFormat = TimeFormat.SECONDS) -> Any:
"""time(timetype: ba.TimeType = TimeType.SIM,
timeformat: ba.TimeFormat = TimeFormat.SECONDS)
- -> Union[float, int]
+ ->
Return the current time.
@@ -3766,7 +3790,7 @@ def time(timetype: ba.TimeType = TimeType.SIM,
Note: If you need pure unfiltered clock time, just use the standard
Python functions such as time.time().
"""
- return 0.0
+ return None
def time_format_check(time_format: ba.TimeFormat, length: Union[float,
diff --git a/assets/src/ba_data/python/ba/_store.py b/assets/src/ba_data/python/ba/_store.py
index 09e27e01..c68aa6f8 100644
--- a/assets/src/ba_data/python/ba/_store.py
+++ b/assets/src/ba_data/python/ba/_store.py
@@ -494,7 +494,7 @@ def get_available_sale_time(tab: str) -> Optional[int]:
assert app.pro_sale_start_val is not None
val: Optional[int] = max(
0, app.pro_sale_start_val -
- (int(_ba.time(TimeType.REAL, TimeFormat.MILLISECONDS)) -
+ (_ba.time(TimeType.REAL, TimeFormat.MILLISECONDS) -
app.pro_sale_start_time))
# Keep the value in the config up to date. I suppose we should
diff --git a/assets/src/ba_data/python/bastd/actor/onscreentimer.py b/assets/src/ba_data/python/bastd/actor/onscreentimer.py
index 422a630c..8b5699b6 100644
--- a/assets/src/ba_data/python/bastd/actor/onscreentimer.py
+++ b/assets/src/ba_data/python/bastd/actor/onscreentimer.py
@@ -21,12 +21,13 @@
"""Defines Actor(s)."""
from __future__ import annotations
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, overload
import ba
if TYPE_CHECKING:
from typing import Optional, Union, Any
+ from typing_extensions import Literal
class OnScreenTimer(ba.Actor):
@@ -39,7 +40,7 @@ class OnScreenTimer(ba.Actor):
def __init__(self) -> None:
super().__init__()
- self._starttime: Optional[int] = None
+ self._starttime_ms: Optional[int] = None
self.node = ba.newnode('text',
attrs={
'v_attach': 'top',
@@ -63,13 +64,13 @@ class OnScreenTimer(ba.Actor):
"""Start the timer."""
tval = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
assert isinstance(tval, int)
- self._starttime = tval
- self.inputnode.time1 = self._starttime
+ self._starttime_ms = tval
+ self.inputnode.time1 = self._starttime_ms
ba.sharedobj('globals').connectattr('time', self.inputnode, 'time2')
def has_started(self) -> bool:
"""Return whether this timer has started yet."""
- return self._starttime is not None
+ return self._starttime_ms is not None
def stop(self,
endtime: Union[int, float] = None,
@@ -85,7 +86,7 @@ class OnScreenTimer(ba.Actor):
endtime = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
timeformat = ba.TimeFormat.MILLISECONDS
- if self._starttime is None:
+ if self._starttime_ms is None:
print('Warning: OnScreenTimer.stop() called without start() first')
else:
endtime_ms: int
@@ -97,7 +98,20 @@ class OnScreenTimer(ba.Actor):
else:
raise ValueError(f'invalid timeformat: {timeformat}')
- self.inputnode.timemax = endtime_ms - self._starttime
+ self.inputnode.timemax = endtime_ms - self._starttime_ms
+
+ # Overloads so type checker knows our exact return type based in args.
+ @overload
+ def getstarttime(
+ self,
+ timeformat: Literal[ba.TimeFormat.SECONDS] = ba.TimeFormat.SECONDS
+ ) -> float:
+ ...
+
+ @overload
+ def getstarttime(self,
+ timeformat: Literal[ba.TimeFormat.MILLISECONDS]) -> int:
+ ...
def getstarttime(
self,
@@ -109,11 +123,11 @@ class OnScreenTimer(ba.Actor):
milliseconds if it is MILLISECONDS.
"""
val_ms: Any
- if self._starttime is None:
+ if self._starttime_ms is None:
print('WARNING: getstarttime() called on un-started timer')
val_ms = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
else:
- val_ms = self._starttime
+ val_ms = self._starttime_ms
assert isinstance(val_ms, int)
if timeformat is ba.TimeFormat.SECONDS:
return 0.001 * val_ms
@@ -121,6 +135,11 @@ class OnScreenTimer(ba.Actor):
return val_ms
raise ValueError(f'invalid timeformat: {timeformat}')
+ @property
+ def starttime(self) -> float:
+ """Shortcut for start time in seconds."""
+ return self.getstarttime()
+
def handlemessage(self, msg: Any) -> Any:
# if we're asked to die, just kill our node/timer
if isinstance(msg, ba.DieMessage):
diff --git a/assets/src/ba_data/python/bastd/game/ninjafight.py b/assets/src/ba_data/python/bastd/game/ninjafight.py
index 439aab2a..42e73e51 100644
--- a/assets/src/ba_data/python/bastd/game/ninjafight.py
+++ b/assets/src/ba_data/python/bastd/game/ninjafight.py
@@ -77,6 +77,7 @@ class NinjaFightGame(ba.TeamGameActivity[Player, Team]):
self._won = False
self._timer: Optional[OnScreenTimer] = None
self._bots = SpazBotSet()
+ self._preset = str(settings['preset'])
# Called when our game is transitioning in but not ready to begin;
# we can go ahead and start creating stuff, playing music, etc.
@@ -87,7 +88,7 @@ class NinjaFightGame(ba.TeamGameActivity[Player, Team]):
# Called when our game actually begins.
def on_begin(self) -> None:
super().on_begin()
- is_pro = self.settings_raw.get('preset') == 'pro'
+ is_pro = self._preset == 'pro'
# In pro mode there's no powerups.
if not is_pro:
@@ -156,9 +157,11 @@ class NinjaFightGame(ba.TeamGameActivity[Player, Team]):
# marked dead yet) ..so lets push a call into the event loop to
# check once this guy has finished dying.
ba.pushcall(self._check_if_won)
+
+ # Let the base class handle anything we don't.
else:
- # Let the base class handle anything we don't.
- super().handlemessage(msg)
+ return super().handlemessage(msg)
+ return None
# When this is called, we should fill out results and end the game
# *regardless* of whether is has been won. (this may be called due
@@ -171,17 +174,12 @@ class NinjaFightGame(ba.TeamGameActivity[Player, Team]):
results = ba.TeamGameResults()
- # If we won, set our score to the elapsed time
+ # If we won, set our score to the elapsed time in milliseconds.
# (there should just be 1 team here since this is co-op).
# ..if we didn't win, leave scores as default (None) which means
# we lost.
if self._won:
- curtime = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
- assert isinstance(curtime, int)
- starttime = self._timer.getstarttime(
- timeformat=ba.TimeFormat.MILLISECONDS)
- assert isinstance(starttime, int)
- elapsed_time_ms = curtime - starttime
+ elapsed_time_ms = int((ba.time() - self._timer.starttime) * 1000.0)
ba.cameraflash()
ba.playsound(self._winsound)
for team in self.teams:
diff --git a/docs/ba_module.md b/docs/ba_module.md
index c7da0733..d6b1b011 100644
--- a/docs/ba_module.md
+++ b/docs/ba_module.md
@@ -1,5 +1,5 @@
-last updated on 2020-05-25 for Ballistica version 1.5.0 build 20028
+last updated on 2020-05-25 for Ballistica version 1.5.0 build 20029
This page documents the Python classes and functions in the 'ba' module,
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please let me know. Happy modding!
@@ -6382,7 +6382,7 @@ are applied to the Widget.
time(timetype: ba.TimeType = TimeType.SIM,
timeformat: ba.TimeFormat = TimeFormat.SECONDS)
- -> Union[float, int]
+ -> <varies>
Return the current time.