parent
3aacaffe6b
commit
48dd1a1aa6
|
@ -29,7 +29,6 @@ game: # Pick a game to play
|
||||||
Minecraft: 0
|
Minecraft: 0
|
||||||
Subnautica: 0
|
Subnautica: 0
|
||||||
Slay the Spire: 0
|
Slay the Spire: 0
|
||||||
Terraria: 0
|
|
||||||
requires:
|
requires:
|
||||||
version: 0.1.6 # Version of Archipelago required for this yaml to work as expected.
|
version: 0.1.6 # Version of Archipelago required for this yaml to work as expected.
|
||||||
# Shared Options supported by all games:
|
# Shared Options supported by all games:
|
||||||
|
@ -280,18 +279,6 @@ Minecraft:
|
||||||
send_defeated_mobs: # Send killed mobs to other Minecraft worlds which have this option enabled.
|
send_defeated_mobs: # Send killed mobs to other Minecraft worlds which have this option enabled.
|
||||||
on: 0
|
on: 0
|
||||||
off: 1
|
off: 1
|
||||||
Terraria:
|
|
||||||
include_hardmode_achievements: # Junk-fills achievements which can only be obtained after defeating the Wall of Flesh.
|
|
||||||
on: 0
|
|
||||||
off: 1
|
|
||||||
# Junk-fills extremely difficult advancements; this is primarily for achievements which require completing large parts of the game
|
|
||||||
# (such as gelatin world tour or Real Estate Agent) as well as the more advanced fishing quests.
|
|
||||||
include_insane_achievements:
|
|
||||||
on: 0
|
|
||||||
off: 1
|
|
||||||
include_postgame_achievements: # Some achievements require defeating the Moon Lord first; this will junk-fill them so you won't have to finish to send some items.
|
|
||||||
on: 0
|
|
||||||
off: 1
|
|
||||||
A Link to the Past:
|
A Link to the Past:
|
||||||
### Logic Section ###
|
### Logic Section ###
|
||||||
glitches_required: # Determine the logic required to complete the seed
|
glitches_required: # Determine the logic required to complete the seed
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
from BaseClasses import Item
|
|
||||||
import typing
|
|
||||||
|
|
||||||
|
|
||||||
class ItemData(typing.NamedTuple):
|
|
||||||
code: typing.Optional[int]
|
|
||||||
progression: bool
|
|
||||||
|
|
||||||
|
|
||||||
class TerrariaItem(Item):
|
|
||||||
game: str = "Terraria"
|
|
||||||
|
|
||||||
|
|
||||||
item_table = {
|
|
||||||
"Copper Shortsword": ItemData(73001, False),
|
|
||||||
|
|
||||||
"Victory": ItemData(73000, True)
|
|
||||||
}
|
|
||||||
|
|
||||||
# If not listed here then has frequency 1
|
|
||||||
item_frequencies = {
|
|
||||||
"Copper Shortsword": 87,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code}
|
|
|
@ -1,166 +0,0 @@
|
||||||
from BaseClasses import Location
|
|
||||||
import typing
|
|
||||||
|
|
||||||
|
|
||||||
class AchieveData(typing.NamedTuple):
|
|
||||||
id: typing.Optional[int]
|
|
||||||
region: str
|
|
||||||
|
|
||||||
|
|
||||||
class TerrariaAchievement(Location):
|
|
||||||
game: str = "Terraria"
|
|
||||||
|
|
||||||
def __init__(self, player: int, name: str, address: typing.Optional[int], parent):
|
|
||||||
super().__init__(player, name, address, parent)
|
|
||||||
self.event = not address
|
|
||||||
|
|
||||||
|
|
||||||
achievement_table = {
|
|
||||||
"Timber!!": AchieveData(0, "Overworld"),
|
|
||||||
"No Hobo": AchieveData(1, "Overworld"),
|
|
||||||
"Stop! Hammer Time!": AchieveData(2, "Overworld"),
|
|
||||||
"Ooo! Shiny!": AchieveData(3, "Overworld"),
|
|
||||||
"Heart Breaker": AchieveData(4, "Overworld"),
|
|
||||||
"Heavy Metal": AchieveData(5, "Overworld"),
|
|
||||||
"I Am Loot!": AchieveData(6, "Overworld"),
|
|
||||||
"Star Power": AchieveData(7, "Overworld"),
|
|
||||||
"Hold on Tight!": AchieveData(8, "Overworld"),
|
|
||||||
"Eye on You": AchieveData(9, "Overworld"),
|
|
||||||
"Smashing, Poppet!": AchieveData(10, "Overworld"),
|
|
||||||
"Worm Fodder": AchieveData(11, "Corruption"),
|
|
||||||
"Mastermind": AchieveData(12, "Crimson"),
|
|
||||||
"Where's My Honey?": AchieveData(13, "Jungle"),
|
|
||||||
"Sting Operation": AchieveData(14, "Jungle"),
|
|
||||||
"Boned": AchieveData(15, "Overworld"),
|
|
||||||
"Dungeon Heist": AchieveData(16, "Dungeon"),
|
|
||||||
"It's Getting Hot in Here": AchieveData(17, "Underworld"),
|
|
||||||
"Miner for Fire": AchieveData(18, "Underworld"),
|
|
||||||
"Still Hungry": AchieveData(19, "Underworld"),
|
|
||||||
"It's Hard!": AchieveData(20, "Underworld"),
|
|
||||||
"Begone, Evil!": AchieveData(21, "Hardmode"),
|
|
||||||
"Extra Shiny!": AchieveData(22, "Hardmode"),
|
|
||||||
"Head in the Clouds": AchieveData(23, "Hardmode"),
|
|
||||||
"Like a Boss": AchieveData(24, "Overworld"),
|
|
||||||
"Buckets of Bolts": AchieveData(25, "Hardmode"),
|
|
||||||
"Drax Attax": AchieveData(26, "Hardmode"),
|
|
||||||
"Photosynthesis": AchieveData(27, "Hardmode Jungle"),
|
|
||||||
"Get a Life": AchieveData(28, "Hardmode Jungle"),
|
|
||||||
"The Great Southern Plantkill": AchieveData(29, "Hardmode Jungle"),
|
|
||||||
"Temple Raider": AchieveData(30, "Post-Plantera"),
|
|
||||||
"Lihzahrdian Idol": AchieveData(31, "Post-Plantera"),
|
|
||||||
"Robbing the Grave": AchieveData(32, "Post-Plantera"),
|
|
||||||
"Big Booty": AchieveData(33, "Post-Plantera"),
|
|
||||||
"Fish Out of Water": AchieveData(34, "Overworld"),
|
|
||||||
"Obsessive Devotion": AchieveData(35, "Post-Golem"),
|
|
||||||
"Star Destroyer": AchieveData(36, "Post-Golem"),
|
|
||||||
"Champion of Terraria": AchieveData(37, "Post-Golem"),
|
|
||||||
"Bloodbath": AchieveData(38, "Overworld"),
|
|
||||||
"Slippery Shinobi": AchieveData(39, "Overworld"),
|
|
||||||
"Goblin Punter": AchieveData(40, "Overworld"),
|
|
||||||
"Walk the Plank": AchieveData(41, "Hardmode"),
|
|
||||||
"Kill the Sun": AchieveData(42, "Hardmode"),
|
|
||||||
"Do You Want to Slay a Snowman?": AchieveData(43, "Hardmode"),
|
|
||||||
"Tin-Foil Hatter": AchieveData(44, "Post-Golem"),
|
|
||||||
"Baleful Harvest": AchieveData(45, "Post-Plantera"),
|
|
||||||
"Ice Scream": AchieveData(46, "Post-Plantera"),
|
|
||||||
"Sticky Situation": AchieveData(47, "Overworld"),
|
|
||||||
"Real Estate Agent": AchieveData(48, "Postgame"),
|
|
||||||
"Not the Bees!": AchieveData(49, "Jungle"),
|
|
||||||
"Jeepers Creepers": AchieveData(50, "Overworld"),
|
|
||||||
"Funkytown": AchieveData(51, "Overworld"),
|
|
||||||
"Into Orbit": AchieveData(52, "Overworld"),
|
|
||||||
"Rock Bottom": AchieveData(53, "Underworld"),
|
|
||||||
"Mecha Mayhem": AchieveData(54, "Hardmode"),
|
|
||||||
"Gelatin World Tour": AchieveData(55, "Postgame"),
|
|
||||||
"Fashion Statement": AchieveData(56, "Overworld"),
|
|
||||||
"Vehicular Manslaughter": AchieveData(57, "Overworld"),
|
|
||||||
"Bulldozer": AchieveData(58, "Overworld"),
|
|
||||||
"There are Some Who Call Him...": AchieveData(59, "Overworld"),
|
|
||||||
"Deceiver of Fools": AchieveData(60, "Overworld"),
|
|
||||||
"Sword of the Hero": AchieveData(61, "Hardmode"),
|
|
||||||
"Lucky Break": AchieveData(62, "Overworld"),
|
|
||||||
"Throwing Lines": AchieveData(63, "Overworld"),
|
|
||||||
"Dye Hard": AchieveData(64, "Overworld"),
|
|
||||||
"Sick Throw": AchieveData(65, "Postgame"),
|
|
||||||
"The Frequent Flyer": AchieveData(66, "Overworld"),
|
|
||||||
"The Cavalry": AchieveData(67, "Overworld"),
|
|
||||||
"Completely Awesome": AchieveData(68, "Overworld"),
|
|
||||||
"Til Death...": AchieveData(69, "Overworld"),
|
|
||||||
"Archaeologist": AchieveData(70, "Jungle"),
|
|
||||||
"Pretty in Pink": AchieveData(71, "Overworld"),
|
|
||||||
"Rainbows and Unicorns": AchieveData(72, "Hardmode"),
|
|
||||||
"You and What Army?": AchieveData(73, "Hardmode"),
|
|
||||||
"Prismancer": AchieveData(74, "Hardmode"),
|
|
||||||
"It Can Talk?!": AchieveData(75, "Hardmode"),
|
|
||||||
"Watch Your Step!": AchieveData(76, "Overworld"),
|
|
||||||
"Marathon Medalist": AchieveData(77, "Overworld"),
|
|
||||||
"Glorious Golden Pole": AchieveData(78, "Overworld"),
|
|
||||||
"Servant-in-Training": AchieveData(79, "Overworld"),
|
|
||||||
"Good Little Slave": AchieveData(80, "Overworld"),
|
|
||||||
"Trout Monkey": AchieveData(81, "Overworld"),
|
|
||||||
"Fast and Fishious": AchieveData(82, "Overworld"),
|
|
||||||
"Supreme Helper Minion!": AchieveData(83, "Overworld"),
|
|
||||||
"Topped Off": AchieveData(84, "Hardmode"),
|
|
||||||
"Slayer of Worlds": AchieveData(85, "Postgame"),
|
|
||||||
"You Can Do It!": AchieveData(86, "Overworld"),
|
|
||||||
"Matching Attire": AchieveData(87, "Overworld"),
|
|
||||||
}
|
|
||||||
|
|
||||||
exclusion_table = {
|
|
||||||
"hardmode": {
|
|
||||||
"It's Hard!",
|
|
||||||
"Extra Shiny!",
|
|
||||||
"Head in the Clouds",
|
|
||||||
"Buckets of Bolts",
|
|
||||||
"Drax Attax",
|
|
||||||
"Photosynthesis",
|
|
||||||
"Get a Life",
|
|
||||||
"The Great Southern Plantkill",
|
|
||||||
"Temple Raider",
|
|
||||||
"Lihzahrdian Idol",
|
|
||||||
"Robbing the Grave",
|
|
||||||
"Big Booty",
|
|
||||||
"Fish Out of Water",
|
|
||||||
"Obsessive Devotion",
|
|
||||||
"Star Destroyer",
|
|
||||||
"Champion of Terraria",
|
|
||||||
"Walk the Plank",
|
|
||||||
"Kill the Sun",
|
|
||||||
"Do You Want to Slay a Snowman?",
|
|
||||||
"Tin-Foil Hatter",
|
|
||||||
"Baleful Harvest",
|
|
||||||
"Ice Scream",
|
|
||||||
"Real Estate Agent",
|
|
||||||
"Mecha Mayhem",
|
|
||||||
"Gelatin World Tour",
|
|
||||||
"Sword of the Hero",
|
|
||||||
"Sick Throw",
|
|
||||||
"Rainbows and Unicorns",
|
|
||||||
"You and What Army?",
|
|
||||||
"Prismancer",
|
|
||||||
"It Can Talk?!",
|
|
||||||
"Topped Off",
|
|
||||||
"Slayer of Worlds",
|
|
||||||
},
|
|
||||||
"insane": {
|
|
||||||
"Gelatin World Tour",
|
|
||||||
"Fast and Fishious",
|
|
||||||
"Supreme Helper Minion!",
|
|
||||||
"Real Estate Agent",
|
|
||||||
"Mecha Mayhem",
|
|
||||||
"Bulldozer",
|
|
||||||
"Marathon Medalist",
|
|
||||||
"Slayer of Worlds",
|
|
||||||
},
|
|
||||||
"postgame": {
|
|
||||||
"Slayer of Worlds",
|
|
||||||
"Sick Throw",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
events_table = {
|
|
||||||
"Still Hungry": "Victory"
|
|
||||||
}
|
|
||||||
|
|
||||||
lookup_id_to_name: typing.Dict[int, str] = {loc_data.id: loc_name for loc_name, loc_data in achievement_table.items() if
|
|
||||||
loc_data.id}
|
|
|
@ -1,8 +0,0 @@
|
||||||
import typing
|
|
||||||
from Options import Choice, Option, Toggle, Range
|
|
||||||
|
|
||||||
terraria_options: typing.Dict[str, type(Option)] = {
|
|
||||||
"include_hardmode_achievements": Toggle,
|
|
||||||
"include_insane_achievements": Toggle,
|
|
||||||
"include_postgame_achievements": Toggle,
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
|
|
||||||
def link_terraria_structures(world, player):
|
|
||||||
|
|
||||||
# Link mandatory connections first
|
|
||||||
for (exit, region) in mandatory_connections:
|
|
||||||
world.get_entrance(exit, player).connect(world.get_region(region, player))
|
|
||||||
|
|
||||||
# Get all unpaired exits and all regions without entrances (except the Menu)
|
|
||||||
# This function is destructive on these lists.
|
|
||||||
exits = [exit.name for r in world.regions if r.player == player for exit in r.exits if exit.connected_region == None]
|
|
||||||
structs = [r.name for r in world.regions if r.player == player and r.entrances == [] and r.name != 'Menu']
|
|
||||||
exits_spoiler = exits[:] # copy the original order for the spoiler log
|
|
||||||
#try:
|
|
||||||
# assert len(exits) == len(structs)
|
|
||||||
#except AssertionError as e: # this should never happen
|
|
||||||
# raise Exception(f"Could not obtain equal numbers of Minecraft exits and structures for player {player} ({world.player_names[player]})")
|
|
||||||
|
|
||||||
pairs = {}
|
|
||||||
|
|
||||||
def set_pair(exit, struct):
|
|
||||||
if (exit in exits) and (struct in structs) and (exit not in illegal_connections.get(struct, [])):
|
|
||||||
pairs[exit] = struct
|
|
||||||
exits.remove(exit)
|
|
||||||
structs.remove(struct)
|
|
||||||
else:
|
|
||||||
raise Exception(f"Invalid connection: {exit} => {struct} for player {player} ({world.player_names[player]})")
|
|
||||||
|
|
||||||
|
|
||||||
for (exit, struct) in default_connections:
|
|
||||||
if exit in exits:
|
|
||||||
set_pair(exit, struct)
|
|
||||||
|
|
||||||
# Make sure we actually paired everything; might fail if plando
|
|
||||||
try:
|
|
||||||
assert len(exits) == len(structs) == 0
|
|
||||||
except AssertionError:
|
|
||||||
raise Exception(f"Failed to connect all Minecraft structures for player {player} ({world.player_names[player]})")
|
|
||||||
|
|
||||||
for exit in exits_spoiler:
|
|
||||||
world.get_entrance(exit, player).connect(world.get_region(pairs[exit], player))
|
|
||||||
if world.shuffle_structures[player] or world.plando_connections[player]:
|
|
||||||
world.spoiler.set_entrance(exit, pairs[exit], 'entrance', player)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# (Region name, list of exits)
|
|
||||||
terraria_regions = [
|
|
||||||
('Menu', ['New World']),
|
|
||||||
('Overworld', ['Descend to Underworld', 'Go to Jungle', 'Go to Dungeon', 'Go to Corruption', 'Go to Crimson']),
|
|
||||||
('Underworld', ['Kill WoF']),
|
|
||||||
('Jungle', []),
|
|
||||||
('Corruption', []),
|
|
||||||
('Crimson', []),
|
|
||||||
('Dungeon', []),
|
|
||||||
('Hardmode Jungle', []),
|
|
||||||
('Hardmode', ['Kill Plantera', 'Go to Hardmode Jungle']),
|
|
||||||
('Post-Plantera', ['Kill Golem']),
|
|
||||||
('Post-Golem', ['Kill Moon Lord']),
|
|
||||||
('Postgame', [])
|
|
||||||
]
|
|
||||||
|
|
||||||
# (Entrance, region pointed to)
|
|
||||||
mandatory_connections = [
|
|
||||||
('New World', 'Overworld'),
|
|
||||||
('Descend to Underworld', 'Underworld'),
|
|
||||||
('Go to Jungle', 'Jungle'),
|
|
||||||
('Go to Corruption', 'Corruption'),
|
|
||||||
('Go to Crimson', 'Crimson'),
|
|
||||||
('Go to Hardmode Jungle', 'Hardmode Jungle'),
|
|
||||||
('Go to Dungeon', 'Dungeon'),
|
|
||||||
('Kill WoF', 'Hardmode'),
|
|
||||||
('Kill Plantera', 'Post-Plantera'),
|
|
||||||
('Kill Golem', 'Post-Golem'),
|
|
||||||
('Kill Moon Lord', 'Postgame'),
|
|
||||||
]
|
|
||||||
|
|
||||||
default_connections = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Structure: illegal locations
|
|
||||||
illegal_connections = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
from ..generic.Rules import set_rule
|
|
||||||
from .Locations import exclusion_table, events_table
|
|
||||||
from BaseClasses import MultiWorld
|
|
||||||
from ..AutoWorld import LogicMixin
|
|
||||||
|
|
||||||
|
|
||||||
class TerrariaLogic(LogicMixin):
|
|
||||||
# Defs here
|
|
||||||
|
|
||||||
def temp(self, player: int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_rules(world: MultiWorld, player: int):
|
|
||||||
def reachable_locations(state):
|
|
||||||
postgame_advancements = exclusion_table['postgame'].copy()
|
|
||||||
for event in events_table.keys():
|
|
||||||
postgame_advancements.add(event)
|
|
||||||
return [location for location in world.get_locations() if
|
|
||||||
location.player == player and
|
|
||||||
location.name not in postgame_advancements and
|
|
||||||
location.can_reach(state)]
|
|
||||||
|
|
||||||
# 88 total achievements. Goal is to defeat Wall of Flesh.
|
|
||||||
goal = 20#int(world.achievement_goal[player].value)
|
|
||||||
can_complete = lambda state: len(reachable_locations(state)) >= goal and state.can_reach('Hardmode', 'Region', player)
|
|
||||||
|
|
||||||
if world.logic[player] != 'nologic':
|
|
||||||
world.completion_condition[player] = lambda state: state.has('Victory', player)
|
|
||||||
|
|
||||||
set_rule(world.get_entrance("Kill WoF", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Kill Plantera", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Kill Golem", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Kill Moon Lord", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Descend to Underworld", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Go to Corruption", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Go to Crimson", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Go to Dungeon", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Go to Jungle", player), lambda state: True)
|
|
||||||
set_rule(world.get_entrance("Go to Hardmode Jungle", player), lambda state: True)
|
|
||||||
|
|
||||||
set_rule(world.get_location("Still Hungry", player), lambda state: can_complete(state))
|
|
||||||
|
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
from .Items import TerrariaItem, item_table, item_frequencies
|
|
||||||
from .Locations import TerrariaAchievement, achievement_table, exclusion_table, events_table
|
|
||||||
from .Regions import terraria_regions, link_terraria_structures, default_connections
|
|
||||||
from .Rules import set_rules
|
|
||||||
from worlds.generic.Rules import exclusion_rules
|
|
||||||
|
|
||||||
from BaseClasses import Region, Entrance, Item
|
|
||||||
from .Options import terraria_options
|
|
||||||
from ..AutoWorld import World
|
|
||||||
|
|
||||||
client_version = 5
|
|
||||||
|
|
||||||
class TerrariaWorld(World):
|
|
||||||
game: str = "Terraria"
|
|
||||||
options = terraria_options
|
|
||||||
topology_present = True
|
|
||||||
|
|
||||||
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
|
||||||
location_name_to_id = {name: data.id for name, data in achievement_table.items()}
|
|
||||||
|
|
||||||
data_version = 2
|
|
||||||
|
|
||||||
def _get_terraria_data(self):
|
|
||||||
exits = [connection[0] for connection in default_connections]
|
|
||||||
return {
|
|
||||||
'world_seed': self.world.slot_seeds[self.player].getrandbits(32),
|
|
||||||
# consistent and doesn't interfere with other generation
|
|
||||||
'seed_name': self.world.seed_name,
|
|
||||||
'player_name': self.world.get_player_name(self.player),
|
|
||||||
'player_id': self.player,
|
|
||||||
'client_version': client_version,
|
|
||||||
'race': self.world.is_race
|
|
||||||
}
|
|
||||||
|
|
||||||
def generate_basic(self):
|
|
||||||
|
|
||||||
# Generate item pool
|
|
||||||
itempool = []
|
|
||||||
pool_counts = item_frequencies.copy()
|
|
||||||
for item_name in item_table:
|
|
||||||
for count in range(pool_counts.get(item_name, 1)):
|
|
||||||
itempool.append(self.create_item(item_name))
|
|
||||||
|
|
||||||
# Choose locations to automatically exclude based on settings
|
|
||||||
exclusion_pool = set()
|
|
||||||
exclusion_types = ['hardmode', 'insane', 'postgame']
|
|
||||||
for key in exclusion_types:
|
|
||||||
if not getattr(self.world, f"include_{key}_achievements")[self.player]:
|
|
||||||
exclusion_pool.update(exclusion_table[key])
|
|
||||||
exclusion_rules(self.world, self.player, exclusion_pool)
|
|
||||||
|
|
||||||
# Prefill the Wall of Flesh with the completion condition
|
|
||||||
completion = self.create_item("Victory")
|
|
||||||
self.world.get_location("Still Hungry", self.player).place_locked_item(completion)
|
|
||||||
itempool.remove(completion)
|
|
||||||
self.world.itempool += itempool
|
|
||||||
|
|
||||||
def set_rules(self):
|
|
||||||
set_rules(self.world, self.player)
|
|
||||||
|
|
||||||
def create_regions(self):
|
|
||||||
def TerrariaRegion(region_name: str, exits=[]):
|
|
||||||
ret = Region(region_name, None, region_name, self.player, self.world)
|
|
||||||
ret.locations = [TerrariaAchievement(self.player, loc_name, loc_data.id, ret)
|
|
||||||
for loc_name, loc_data in achievement_table.items()
|
|
||||||
if loc_data.region == region_name]
|
|
||||||
for exit in exits:
|
|
||||||
ret.exits.append(Entrance(self.player, exit, ret))
|
|
||||||
return ret
|
|
||||||
|
|
||||||
self.world.regions += [TerrariaRegion(*r) for r in terraria_regions]
|
|
||||||
link_terraria_structures(self.world, self.player)
|
|
||||||
|
|
||||||
def generate_output(self, output_directory: str):
|
|
||||||
import json
|
|
||||||
from base64 import b64encode
|
|
||||||
|
|
||||||
data = self._get_terraria_data()
|
|
||||||
filename = f"AP_{self.world.seed_name}_P{self.player}_{self.world.get_player_name(self.player)}.apterra"
|
|
||||||
with open(os.path.join(output_directory, filename), 'wb') as f:
|
|
||||||
f.write(b64encode(bytes(json.dumps(data), 'utf-8')))
|
|
||||||
|
|
||||||
def fill_slot_data(self):
|
|
||||||
slot_data = self._get_terraria_data()
|
|
||||||
for option_name in terraria_options:
|
|
||||||
option = getattr(self.world, option_name)[self.player]
|
|
||||||
slot_data[option_name] = int(option.value)
|
|
||||||
return slot_data
|
|
||||||
|
|
||||||
def create_item(self, name: str) -> Item:
|
|
||||||
item_data = item_table[name]
|
|
||||||
item = TerrariaItem(name, item_data.progression, item_data.code, self.player)
|
|
||||||
nonexcluded_items = []
|
|
||||||
if name in nonexcluded_items: # prevent books from going on excluded locations
|
|
||||||
item.never_exclude = True
|
|
||||||
return item
|
|
Loading…
Reference in New Issue