* Removed now unused imports from Launcher
* Moved ImageIcon and ImageButton to use ApAsyncImage for compatibility with apworlds
* Adjusted image size in the Launcher from 40x40 to 48x48. This is already larger than the size in previous versions, and a docs update is soon to follow.
* Expose `dynamic_scheme_contrast` to user.kv, allowing users to set high contrast.
* ScrollBox's default scroll_type was set to only content, so the scrollbar in Launcher was nonfunctional.
* Adjusted the spacing of the title of a component when a description is present to be closer to the center.
* Launcher now scrolls to the top automatically when changing between filters
Shifts the contents of `kvui.py`, and thus all CommonClient-based clients as well as Launcher, to using KivyMD. KivyMD is an extension for Kivy that is almost fully compatible with pre-existing Kivy components, while providing Material Design support for theming and overall visual design as well as useful pre-existing built in components such as Snackbars, Tooltips, and a built-in File Manager (not currently being used).
As a part of this shift, the launcher was completely overhauled, adding the ability to filter the list of components down to each type of component, the ability to define favorite components and filter to them, and add shortcuts for launcher components to the desktop. An optional description field was added to Component for display within the new launcher.
The theme (Light/Dark) and primary palette have also been exposed to users via client/user.kv.
* Core: Prevent people from using LogicMixin incorrectly
There's a world that ran into some issues because it defined its custom LogicMixin variables at the class level.
This caused "instance bleed" when new CollectionState objects were created.
I don't think there is ever a reason to have a non-function class variable on LogicMixin without also having `init_mixin`, so this asserts that this is the case.
Tested:
Doesn't fail any current worlds
Correctly fails the world in question
Also, not gonna call out that world because it was literally my fault for explaining it to them wrong :D
* Verbose af
* Update AutoWorld.py
`Location` does not override `__eq__` so should not override `__hash__`.
With this patch, this makes operations on sets of locations slightly
faster because they will use `object.__hash__` rather than
`Location.__hash__`.
`object.__hash__` is about 4 to 5 times faster than `Location.__hash__`
for me. Generation often uses sets of locations, so this slightly speeds
up generation.
The only place I could find that was hashing locations directly was
`WitnessLocationHint.__hash__`, but it has implemented a matching
`__eq__`, so is fine.
For security reasons, Python randomizes its hash seed each time it is
started, so the result of the `hash()` function is nondeterministic and
can't have been used by worlds for anything that needed to be
deterministic and can't have been used to compare information hashed at
generation time to information hashed by a client.
The base state passed to fill_restrictive should be as maximal as
possible otherwise fill_restrictive has to repeatedly re-sweep and
collect from advancement locations that were reachable from before
fill_restrictive has placed a single item.
This is not added within fill_restrictive itself because it is common
for fills to be performed using a partial 'all_state', which is already
a maximum exploration state.
With --skip_output generation of every template yaml, except FF, KH
and Shivers, this prevented repeatedly re-sweeping 576 advancement
locations in every sweep within progression fill, reducing the
generation time from 124s to 113s for me (8.8% reduction, averaged over
5 generations each).
Without implementing __iter__ directly, calling iter() on a
Region.Register on Python 3.12 would return a new generator implemented
as follows:
```py
def __iter__(self) -> int:
i = 0
try:
while True:
v = self[i]
yield v
i += 1
except IndexError:
return None
```
This was determined by disassembling the returned generator with
dis.dis() and then constructing a function that disassembles into the
same bytecode.
The iterator returned by `iter(self._list)` is faster than this
generator, so using it slightly improves generation performance on
average.
Iteration of Region.Register objects is used a lot in
`CollectionState.update_reachable_regions` in both of the private
_update methods that get called. The performance gain here will vary
depending on how many regions a world has and how many exits those
regions have on average.
For a game like Blasphemous, with a lot of regions and exits, generation
of 10 template Blasphemous yamls with `--skip_output --seed 1` and
progression balancing disabled went from 19.0s to 16.4s (14.2% reduction
in generation duration).
* Only consider usable exits when calculating whether or not a region is a dead-end
* Update EntranceLookup unit tests
* Add new dead-end test
* Add additional explanation to the new test
* minor formatting tweak
based on review feedback
---------
Co-authored-by: CodeGorilla <3672561+Ars-Ignis@users.noreply.github.com>
* DLC Quest Bug Fix
Start inventory item that do not exist in the present world do not make more trap item to appear anymore
* Update worlds/dlcquest/Items.py
Co-authored-by: Mysteryem <Mysteryem@users.noreply.github.com>
* DLC Quest Bug Fix
did the recommendation of Mysteryem and made the item not exist in the pool of item created
* DLC Quest Bug Fix
did the recommendation of agilbert1412 and made a check by name instead of item to itemData
* DLC Quest Bug Fix
overcook failed test
* DLC Quest Bug Fix
re-type correctly a type hint
---------
Co-authored-by: Mysteryem <Mysteryem@users.noreply.github.com>
* Note death link and trap link in game info page
* Update worlds/tunic/docs/en_TUNIC.md
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Turn it into a bulleted list