Network: implement 0.4 marked compatibility removals (#757)
* world remote items handling * players list when connecting
This commit is contained in:
parent
ce42fda85f
commit
2cdd03f786
4
Main.py
4
Main.py
|
@ -381,10 +381,6 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
|
||||||
"names": names, # TODO: remove around 0.2.5 in favor of slot_info
|
"names": names, # TODO: remove around 0.2.5 in favor of slot_info
|
||||||
"games": games, # TODO: remove around 0.2.5 in favor of slot_info
|
"games": games, # TODO: remove around 0.2.5 in favor of slot_info
|
||||||
"connect_names": {name: (0, player) for player, name in world.player_name.items()},
|
"connect_names": {name: (0, player) for player, name in world.player_name.items()},
|
||||||
"remote_items": {player for player in world.player_ids if
|
|
||||||
world.worlds[player].remote_items},
|
|
||||||
"remote_start_inventory": {player for player in world.player_ids if
|
|
||||||
world.worlds[player].remote_start_inventory},
|
|
||||||
"locations": locations_data,
|
"locations": locations_data,
|
||||||
"checks_in_area": checks_in_area,
|
"checks_in_area": checks_in_area,
|
||||||
"server_options": baked_server_options,
|
"server_options": baked_server_options,
|
||||||
|
|
|
@ -148,8 +148,6 @@ class Context:
|
||||||
self.player_name_lookup: typing.Dict[str, team_slot] = {}
|
self.player_name_lookup: typing.Dict[str, team_slot] = {}
|
||||||
self.connect_names = {} # names of slots clients can connect to
|
self.connect_names = {} # names of slots clients can connect to
|
||||||
self.allow_forfeits = {}
|
self.allow_forfeits = {}
|
||||||
self.remote_items = set()
|
|
||||||
self.remote_start_inventory = set()
|
|
||||||
# player location_id item_id target_player_id
|
# player location_id item_id target_player_id
|
||||||
self.locations = {}
|
self.locations = {}
|
||||||
self.host = host
|
self.host = host
|
||||||
|
@ -366,8 +364,6 @@ class Context:
|
||||||
self.seed_name = decoded_obj["seed_name"]
|
self.seed_name = decoded_obj["seed_name"]
|
||||||
self.random.seed(self.seed_name)
|
self.random.seed(self.seed_name)
|
||||||
self.connect_names = decoded_obj['connect_names']
|
self.connect_names = decoded_obj['connect_names']
|
||||||
self.remote_items = decoded_obj['remote_items']
|
|
||||||
self.remote_start_inventory = decoded_obj.get('remote_start_inventory', decoded_obj['remote_items'])
|
|
||||||
self.locations = decoded_obj['locations']
|
self.locations = decoded_obj['locations']
|
||||||
self.slot_data = decoded_obj['slot_data']
|
self.slot_data = decoded_obj['slot_data']
|
||||||
for slot, data in self.slot_data.items():
|
for slot, data in self.slot_data.items():
|
||||||
|
@ -548,7 +544,7 @@ class Context:
|
||||||
|
|
||||||
if "stored_data" in savedata:
|
if "stored_data" in savedata:
|
||||||
self.stored_data = savedata["stored_data"]
|
self.stored_data = savedata["stored_data"]
|
||||||
# count items and slots from lists for item_handling = remote
|
# count items and slots from lists for items_handling = remote
|
||||||
logging.info(
|
logging.info(
|
||||||
f'Loaded save file with {sum([len(v) for k, v in self.received_items.items() if k[2]])} received items '
|
f'Loaded save file with {sum([len(v) for k, v in self.received_items.items() if k[2]])} received items '
|
||||||
f'for {sum(k[2] for k in self.received_items)} players')
|
f'for {sum(k[2] for k in self.received_items)} players')
|
||||||
|
@ -708,10 +704,7 @@ async def on_client_connected(ctx: Context, client: Client):
|
||||||
await ctx.send_msgs(client, [{
|
await ctx.send_msgs(client, [{
|
||||||
'cmd': 'RoomInfo',
|
'cmd': 'RoomInfo',
|
||||||
'password': bool(ctx.password),
|
'password': bool(ctx.password),
|
||||||
# TODO remove around 0.4
|
'games': {ctx.games[x] for x in range(1, len(ctx.games) + 1)},
|
||||||
'players': players,
|
|
||||||
# TODO convert to list of games present in 0.4
|
|
||||||
'games': [ctx.games[x] for x in range(1, len(ctx.games) + 1)],
|
|
||||||
# tags are for additional features in the communication.
|
# tags are for additional features in the communication.
|
||||||
# Name them by feature or fork, as you feel is appropriate.
|
# Name them by feature or fork, as you feel is appropriate.
|
||||||
'tags': ctx.tags,
|
'tags': ctx.tags,
|
||||||
|
@ -719,8 +712,6 @@ async def on_client_connected(ctx: Context, client: Client):
|
||||||
'permissions': get_permissions(ctx),
|
'permissions': get_permissions(ctx),
|
||||||
'hint_cost': ctx.hint_cost,
|
'hint_cost': ctx.hint_cost,
|
||||||
'location_check_points': ctx.location_check_points,
|
'location_check_points': ctx.location_check_points,
|
||||||
'datapackage_version': sum(game_data["version"] for game_data in ctx.gamespackage.values())
|
|
||||||
if all(game_data["version"] for game_data in ctx.gamespackage.values()) else 0,
|
|
||||||
'datapackage_versions': {game: game_data["version"] for game, game_data
|
'datapackage_versions': {game: game_data["version"] for game, game_data
|
||||||
in ctx.gamespackage.items()},
|
in ctx.gamespackage.items()},
|
||||||
'seed_name': ctx.seed_name,
|
'seed_name': ctx.seed_name,
|
||||||
|
@ -1557,20 +1548,10 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
|
||||||
minver = min_client_version if ignore_game else ctx.minimum_client_versions[slot]
|
minver = min_client_version if ignore_game else ctx.minimum_client_versions[slot]
|
||||||
if minver > args['version']:
|
if minver > args['version']:
|
||||||
errors.add('IncompatibleVersion')
|
errors.add('IncompatibleVersion')
|
||||||
if args.get('items_handling', None) is None:
|
try:
|
||||||
# fall back to load from multidata
|
client.items_handling = args['items_handling']
|
||||||
client.no_items = False
|
except (ValueError, TypeError):
|
||||||
client.remote_items = slot in ctx.remote_items
|
errors.add('InvalidItemsHandling')
|
||||||
client.remote_start_inventory = slot in ctx.remote_start_inventory
|
|
||||||
await ctx.send_msgs(client, [{
|
|
||||||
"cmd": "Print", "text":
|
|
||||||
"Warning: Client is not sending items_handling flags, "
|
|
||||||
"which will not be supported in the future."}])
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
client.items_handling = args['items_handling']
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
errors.add('InvalidItemsHandling')
|
|
||||||
|
|
||||||
# only exact version match allowed
|
# only exact version match allowed
|
||||||
if ctx.compatibility == 0 and args['version'] != version_tuple:
|
if ctx.compatibility == 0 and args['version'] != version_tuple:
|
||||||
|
|
|
@ -39,10 +39,11 @@ def get_datapackage():
|
||||||
|
|
||||||
@api_endpoints.route('/datapackage_version')
|
@api_endpoints.route('/datapackage_version')
|
||||||
@cache.cached()
|
@cache.cached()
|
||||||
|
|
||||||
def get_datapackage_versions():
|
def get_datapackage_versions():
|
||||||
from worlds import network_data_package, AutoWorldRegister
|
from worlds import network_data_package, AutoWorldRegister
|
||||||
|
|
||||||
version_package = {game: world.data_version for game, world in AutoWorldRegister.world_types.items()}
|
version_package = {game: world.data_version for game, world in AutoWorldRegister.world_types.items()}
|
||||||
version_package["version"] = network_data_package["version"]
|
|
||||||
return version_package
|
return version_package
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,6 @@ Sent to clients when they connect to an Archipelago server.
|
||||||
| hint_cost | int | The amount of points it costs to receive a hint from the server. |
|
| hint_cost | int | The amount of points it costs to receive a hint from the server. |
|
||||||
| location_check_points | int | The amount of hint points you receive per item/location check completed. ||
|
| location_check_points | int | The amount of hint points you receive per item/location check completed. ||
|
||||||
| games | list\[str\] | List of games present in this multiworld. |
|
| games | list\[str\] | List of games present in this multiworld. |
|
||||||
| datapackage_version | int | Sum of individual games' datapackage version. Deprecated. Use `datapackage_versions` instead. |
|
|
||||||
| datapackage_versions | dict\[str, int\] | Data versions of the individual games' data packages the server will send. Used to decide which games' caches are outdated. See [Data Package Contents](#Data-Package-Contents). |
|
| datapackage_versions | dict\[str, int\] | Data versions of the individual games' data packages the server will send. Used to decide which games' caches are outdated. See [Data Package Contents](#Data-Package-Contents). |
|
||||||
| seed_name | str | uniquely identifying name of this generation |
|
| seed_name | str | uniquely identifying name of this generation |
|
||||||
| time | float | Unix time stamp of "now". Send for time synchronization if wanted for things like the DeathLink Bounce. |
|
| time | float | Unix time stamp of "now". Send for time synchronization if wanted for things like the DeathLink Bounce. |
|
||||||
|
|
|
@ -343,18 +343,6 @@ class MyGameWorld(World):
|
||||||
option_definitions = mygame_options # assign the options dict to the world
|
option_definitions = mygame_options # assign the options dict to the world
|
||||||
#...
|
#...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Local or Remote
|
|
||||||
|
|
||||||
A world with `remote_items` set to `True` gets all items items from the server
|
|
||||||
and no item from the local game. So for an RPG opening a chest would not add
|
|
||||||
any item to your inventory, instead the server will send you what was in that
|
|
||||||
chest. The advantage is that a generic mod can be used that does not need to
|
|
||||||
know anything about the seed.
|
|
||||||
|
|
||||||
A world with `remote_items` set to `False` will locally reward its local items.
|
|
||||||
For console games this can remove delay and make script/animation/dialog flow
|
|
||||||
more natural. These games typically have been edited to 'bake in' the items.
|
|
||||||
|
|
||||||
### A World Class Skeleton
|
### A World Class Skeleton
|
||||||
|
|
||||||
|
@ -379,8 +367,6 @@ class MyGameWorld(World):
|
||||||
game: str = "My Game" # name of the game/world
|
game: str = "My Game" # name of the game/world
|
||||||
option_definitions = mygame_options # options the player can set
|
option_definitions = mygame_options # options the player can set
|
||||||
topology_present: bool = True # show path to required location checks in spoiler
|
topology_present: bool = True # show path to required location checks in spoiler
|
||||||
remote_items: bool = False # True if all items come from the server
|
|
||||||
remote_start_inventory: bool = False # True if start inventory comes from the server
|
|
||||||
|
|
||||||
# data_version is used to signal that items, locations or their names
|
# data_version is used to signal that items, locations or their names
|
||||||
# changed. Set this to 0 during development so other games' clients do not
|
# changed. Set this to 0 during development so other games' clients do not
|
||||||
|
@ -415,17 +401,13 @@ The world has to provide the following things for generation
|
||||||
* additions to the item pool
|
* additions to the item pool
|
||||||
* additions to the regions list: at least one called "Menu"
|
* additions to the regions list: at least one called "Menu"
|
||||||
* locations placed inside those regions
|
* locations placed inside those regions
|
||||||
* a `def create_item(self, item: str) -> MyGameItem` for plando/manual placing
|
* a `def create_item(self, item: str) -> MyGameItem` to create any item on demand
|
||||||
* applying `self.world.precollected_items` for plando/start inventory
|
* applying `self.world.push_precollected` for start inventory
|
||||||
if not using a `remote_start_inventory`
|
|
||||||
* a `def generate_output(self, output_directory: str)` that creates the output
|
* a `def generate_output(self, output_directory: str)` that creates the output
|
||||||
if there is output to be generated. If only items are randomized and
|
files if there is output to be generated. When this is
|
||||||
`remote_items = True` it is possible to have a generic mod and output
|
called, `self.world.get_locations(self.player)` has all locations for the player, with
|
||||||
generation can be skipped. In all other cases this is required. When this is
|
attribute `item` pointing to the item.
|
||||||
called, `self.world.get_locations()` has all locations for all players, with
|
`location.item.player` can be used to see if it's a local item.
|
||||||
properties `item` pointing to the item and `player` identifying the player.
|
|
||||||
`self.world.get_filled_locations(self.player)` will filter for this world.
|
|
||||||
`item.player` can be used to see if it's a local item.
|
|
||||||
|
|
||||||
In addition, the following methods can be implemented and attributes can be set
|
In addition, the following methods can be implemented and attributes can be set
|
||||||
|
|
||||||
|
@ -433,12 +415,13 @@ In addition, the following methods can be implemented and attributes can be set
|
||||||
called per player before any items or locations are created. You can set
|
called per player before any items or locations are created. You can set
|
||||||
properties on your world here. Already has access to player options and RNG.
|
properties on your world here. Already has access to player options and RNG.
|
||||||
* `def create_regions(self)`
|
* `def create_regions(self)`
|
||||||
called to place player's regions into the MultiWorld's regions list. If it's
|
called to place player's regions and their locations into the MultiWorld's regions list. If it's
|
||||||
hard to separate, this can be done during `generate_early` or `basic` as well.
|
hard to separate, this can be done during `generate_early` or `basic` as well.
|
||||||
* `def create_items(self)`
|
* `def create_items(self)`
|
||||||
called to place player's items into the MultiWorld's itempool.
|
called to place player's items into the MultiWorld's itempool.
|
||||||
* `def set_rules(self)`
|
* `def set_rules(self)`
|
||||||
called to set access and item rules on locations and entrances.
|
called to set access and item rules on locations and entrances.
|
||||||
|
Locations have to be defined before this, or rule application can miss them.
|
||||||
* `def generate_basic(self)`
|
* `def generate_basic(self)`
|
||||||
called after the previous steps. Some placement and player specific
|
called after the previous steps. Some placement and player specific
|
||||||
randomizations can be done here. After this step all regions and items have
|
randomizations can be done here. After this step all regions and items have
|
||||||
|
|
|
@ -160,18 +160,6 @@ class World(metaclass=AutoWorldRegister):
|
||||||
|
|
||||||
hint_blacklist: ClassVar[FrozenSet[str]] = frozenset() # any names that should not be hintable
|
hint_blacklist: ClassVar[FrozenSet[str]] = frozenset() # any names that should not be hintable
|
||||||
|
|
||||||
# NOTE: remote_items and remote_start_inventory are now available in the network protocol for the client to set.
|
|
||||||
# These values will be removed.
|
|
||||||
# if a world is set to remote_items, then it just needs to send location checks to the server and the server
|
|
||||||
# sends back the items
|
|
||||||
# if a world is set to remote_items = False, then the server never sends an item where receiver == finder,
|
|
||||||
# the client finds its own items in its own world.
|
|
||||||
remote_items: bool = True
|
|
||||||
|
|
||||||
# If remote_start_inventory is true, the start_inventory/world.precollected_items is sent on connection,
|
|
||||||
# otherwise the world implementation is in charge of writing the items to their output data.
|
|
||||||
remote_start_inventory: bool = True
|
|
||||||
|
|
||||||
# For games where after a victory it is impossible to go back in and get additional/remaining Locations checked.
|
# For games where after a victory it is impossible to go back in and get additional/remaining Locations checked.
|
||||||
# this forces forfeit: auto for those games.
|
# this forces forfeit: auto for those games.
|
||||||
forced_auto_forfeit: bool = False
|
forced_auto_forfeit: bool = False
|
||||||
|
|
|
@ -81,13 +81,11 @@ for world_name, world in AutoWorldRegister.world_types.items():
|
||||||
lookup_any_location_id_to_name.update(world.location_id_to_name)
|
lookup_any_location_id_to_name.update(world.location_id_to_name)
|
||||||
|
|
||||||
network_data_package: DataPackage = {
|
network_data_package: DataPackage = {
|
||||||
"version": sum(world.data_version for world in AutoWorldRegister.world_types.values()),
|
|
||||||
"games": games,
|
"games": games,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set entire datapackage to version 0 if any of them are set to 0
|
# Set entire datapackage to version 0 if any of them are set to 0
|
||||||
if any(not world.data_version for world in AutoWorldRegister.world_types.values()):
|
if any(not world.data_version for world in AutoWorldRegister.world_types.values()):
|
||||||
network_data_package["version"] = 0
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logging.warning(f"Datapackage is in custom mode. Custom Worlds: "
|
logging.warning(f"Datapackage is in custom mode. Custom Worlds: "
|
||||||
|
|
|
@ -795,11 +795,11 @@ def patch_rom(world, rom, player, enemized):
|
||||||
itemid = 0x33
|
itemid = 0x33
|
||||||
elif location.item.compass:
|
elif location.item.compass:
|
||||||
itemid = 0x25
|
itemid = 0x25
|
||||||
if world.worlds[player].remote_items: # remote items does not currently work
|
# if world.worlds[player].remote_items: # remote items does not currently work
|
||||||
itemid = list(location_table.keys()).index(location.name) + 1
|
# itemid = list(location_table.keys()).index(location.name) + 1
|
||||||
assert itemid < 0x100
|
# assert itemid < 0x100
|
||||||
rom.write_byte(location.player_address, 0xFF)
|
# rom.write_byte(location.player_address, 0xFF)
|
||||||
elif location.item.player != player:
|
if location.item.player != player:
|
||||||
if location.player_address is not None:
|
if location.player_address is not None:
|
||||||
rom.write_byte(location.player_address, min(location.item.player, ROM_PLAYER_LIMIT))
|
rom.write_byte(location.player_address, min(location.item.player, ROM_PLAYER_LIMIT))
|
||||||
else:
|
else:
|
||||||
|
@ -1654,7 +1654,7 @@ def patch_rom(world, rom, player, enemized):
|
||||||
write_strings(rom, world, player)
|
write_strings(rom, world, player)
|
||||||
|
|
||||||
# remote items flag, does not currently work
|
# remote items flag, does not currently work
|
||||||
rom.write_byte(0x18637C, int(world.worlds[player].remote_items))
|
rom.write_byte(0x18637C, 0)
|
||||||
|
|
||||||
# set rom name
|
# set rom name
|
||||||
# 21 bytes
|
# 21 bytes
|
||||||
|
|
|
@ -121,8 +121,6 @@ class ALTTPWorld(World):
|
||||||
location_name_to_id = lookup_name_to_id
|
location_name_to_id = lookup_name_to_id
|
||||||
|
|
||||||
data_version = 8
|
data_version = 8
|
||||||
remote_items: bool = False
|
|
||||||
remote_start_inventory: bool = False
|
|
||||||
required_client_version = (0, 3, 2)
|
required_client_version = (0, 3, 2)
|
||||||
web = ALTTPWeb()
|
web = ALTTPWeb()
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,6 @@ class DarkSouls3World(World):
|
||||||
game: str = "Dark Souls III"
|
game: str = "Dark Souls III"
|
||||||
option_definitions = dark_souls_options
|
option_definitions = dark_souls_options
|
||||||
topology_present: bool = True
|
topology_present: bool = True
|
||||||
remote_items: bool = False
|
|
||||||
remote_start_inventory: bool = False
|
|
||||||
web = DarkSouls3Web()
|
web = DarkSouls3Web()
|
||||||
data_version = 4
|
data_version = 4
|
||||||
base_id = 100000
|
base_id = 100000
|
||||||
|
|
|
@ -30,9 +30,7 @@ class FF1World(World):
|
||||||
option_definitions = ff1_options
|
option_definitions = ff1_options
|
||||||
game = "Final Fantasy"
|
game = "Final Fantasy"
|
||||||
topology_present = False
|
topology_present = False
|
||||||
remote_items = True
|
|
||||||
data_version = 2
|
data_version = 2
|
||||||
remote_start_inventory = True
|
|
||||||
|
|
||||||
ff1_items = FF1Items()
|
ff1_items = FF1Items()
|
||||||
ff1_locations = FF1Locations()
|
ff1_locations = FF1Locations()
|
||||||
|
|
|
@ -36,8 +36,6 @@ class Hylics2World(World):
|
||||||
option_definitions = Options.hylics2_options
|
option_definitions = Options.hylics2_options
|
||||||
|
|
||||||
topology_present: bool = True
|
topology_present: bool = True
|
||||||
remote_items: bool = True
|
|
||||||
remote_start_inventory: bool = True
|
|
||||||
|
|
||||||
data_version: 1
|
data_version: 1
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,6 @@ class OOTWorld(World):
|
||||||
item_name_to_id = {item_name: oot_data_to_ap_id(data, False) for item_name, data in item_table.items() if
|
item_name_to_id = {item_name: oot_data_to_ap_id(data, False) for item_name, data in item_table.items() if
|
||||||
data[2] is not None}
|
data[2] is not None}
|
||||||
location_name_to_id = location_name_to_id
|
location_name_to_id = location_name_to_id
|
||||||
remote_items: bool = False
|
|
||||||
remote_start_inventory: bool = False
|
|
||||||
web = OOTWeb()
|
web = OOTWeb()
|
||||||
|
|
||||||
data_version = 2
|
data_version = 2
|
||||||
|
|
|
@ -49,8 +49,6 @@ class Overcooked2World(World):
|
||||||
required_client_version = (0, 3, 4)
|
required_client_version = (0, 3, 4)
|
||||||
option_definitions = overcooked_options
|
option_definitions = overcooked_options
|
||||||
topology_present: bool = False
|
topology_present: bool = False
|
||||||
remote_items: bool = True
|
|
||||||
remote_start_inventory: bool = False
|
|
||||||
data_version = 2
|
data_version = 2
|
||||||
|
|
||||||
item_name_to_id = item_name_to_id
|
item_name_to_id = item_name_to_id
|
||||||
|
|
|
@ -38,9 +38,10 @@ class PokemonRedBlueWorld(World):
|
||||||
# -MuffinJets#4559
|
# -MuffinJets#4559
|
||||||
game = "Pokemon Red and Blue"
|
game = "Pokemon Red and Blue"
|
||||||
option_definitions = pokemon_rb_options
|
option_definitions = pokemon_rb_options
|
||||||
remote_items = False
|
|
||||||
data_version = 3
|
data_version = 3
|
||||||
required_client_version = (0, 3, 7)
|
required_client_version = (0, 3, 7)
|
||||||
|
|
||||||
topology_present = False
|
topology_present = False
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,6 @@ class SMWorld(World):
|
||||||
location_name_to_id = {key: locations_start_id + value.Id for key, value in locationsDict.items() if value.Id != None}
|
location_name_to_id = {key: locations_start_id + value.Id for key, value in locationsDict.items() if value.Id != None}
|
||||||
web = SMWeb()
|
web = SMWeb()
|
||||||
|
|
||||||
remote_items: bool = False
|
|
||||||
remote_start_inventory: bool = False
|
|
||||||
|
|
||||||
# changes to client DeathLink handling for 0.2.1
|
# changes to client DeathLink handling for 0.2.1
|
||||||
# changes to client Remote Item handling for 0.2.6
|
# changes to client Remote Item handling for 0.2.6
|
||||||
required_client_version = (0, 2, 6)
|
required_client_version = (0, 2, 6)
|
||||||
|
|
|
@ -76,9 +76,6 @@ class SMZ3World(World):
|
||||||
for key, value in TotalSMZ3World(Config(), "", 0, "").locationLookup.items()}
|
for key, value in TotalSMZ3World(Config(), "", 0, "").locationLookup.items()}
|
||||||
web = SMZ3Web()
|
web = SMZ3Web()
|
||||||
|
|
||||||
remote_items: bool = False
|
|
||||||
remote_start_inventory: bool = False
|
|
||||||
|
|
||||||
locationNamesGT: Set[str] = {loc.Name for loc in GanonsTower(None, None).Locations}
|
locationNamesGT: Set[str] = {loc.Name for loc in GanonsTower(None, None).Locations}
|
||||||
|
|
||||||
# first added for 0.2.6
|
# first added for 0.2.6
|
||||||
|
@ -485,9 +482,9 @@ class SMZ3World(World):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def create_item(self, name: str) -> Item:
|
def create_item(self, name: str) -> Item:
|
||||||
return SMZ3Item(name,
|
return SMZ3Item(name,
|
||||||
ItemClassification.progression if SMZ3World.isProgression(TotalSMZ3Item.ItemType[name]) else ItemClassification.filler,
|
ItemClassification.progression if SMZ3World.isProgression(TotalSMZ3Item.ItemType[name]) else ItemClassification.filler,
|
||||||
TotalSMZ3Item.ItemType[name], self.item_name_to_id[name],
|
TotalSMZ3Item.ItemType[name], self.item_name_to_id[name],
|
||||||
self.player,
|
self.player,
|
||||||
TotalSMZ3Item.Item(TotalSMZ3Item.ItemType[name], self))
|
TotalSMZ3Item.Item(TotalSMZ3Item.ItemType[name], self))
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,6 @@ class SoEWorld(World):
|
||||||
game: str = "Secret of Evermore"
|
game: str = "Secret of Evermore"
|
||||||
option_definitions = soe_options
|
option_definitions = soe_options
|
||||||
topology_present = False
|
topology_present = False
|
||||||
remote_items = False
|
|
||||||
data_version = 4
|
data_version = 4
|
||||||
web = SoEWebWorld()
|
web = SoEWebWorld()
|
||||||
required_client_version = (0, 3, 5)
|
required_client_version = (0, 3, 5)
|
||||||
|
|
|
@ -43,7 +43,6 @@ class TimespinnerWorld(World):
|
||||||
option_definitions = timespinner_options
|
option_definitions = timespinner_options
|
||||||
game = "Timespinner"
|
game = "Timespinner"
|
||||||
topology_present = True
|
topology_present = True
|
||||||
remote_items = False
|
|
||||||
data_version = 10
|
data_version = 10
|
||||||
web = TimespinnerWebWorld()
|
web = TimespinnerWebWorld()
|
||||||
|
|
||||||
|
|
|
@ -61,14 +61,6 @@ class ZillionWorld(World):
|
||||||
# retrieved by clients on every connection.
|
# retrieved by clients on every connection.
|
||||||
data_version: int = 1
|
data_version: int = 1
|
||||||
|
|
||||||
# NOTE: remote_items and remote_start_inventory are now available in the network protocol for the client to set.
|
|
||||||
# These values will be removed.
|
|
||||||
# if a world is set to remote_items, then it just needs to send location checks to the server and the server
|
|
||||||
# sends back the items
|
|
||||||
# if a world is set to remote_items = False, then the server never sends an item where receiver == finder,
|
|
||||||
# the client finds its own items in its own world.
|
|
||||||
remote_items: bool = False
|
|
||||||
|
|
||||||
logger: logging.Logger
|
logger: logging.Logger
|
||||||
|
|
||||||
class LogStreamInterface:
|
class LogStreamInterface:
|
||||||
|
|
Loading…
Reference in New Issue