Add VVVVVV to Archipelago (#178)

This commit is contained in:
Yussur Mustafa Oraji
2022-01-21 22:42:11 +01:00
committed by GitHub
parent 4291912577
commit 344f4afdbd
9 changed files with 292 additions and 0 deletions

27
worlds/v6/Items.py Normal file
View File

@@ -0,0 +1,27 @@
from BaseClasses import Item
class V6Item(Item):
game: str = "VVVVVV"
item_table = {
"Trinket 01": 2515000,
"Trinket 02": 2515001,
"Trinket 03": 2515002,
"Trinket 04": 2515003,
"Trinket 05": 2515004,
"Trinket 06": 2515005,
"Trinket 07": 2515006,
"Trinket 08": 2515007,
"Trinket 09": 2515008,
"Trinket 10": 2515009,
"Trinket 11": 2515010,
"Trinket 12": 2515011,
"Trinket 13": 2515012,
"Trinket 14": 2515013,
"Trinket 15": 2515014,
"Trinket 16": 2515015,
"Trinket 17": 2515016,
"Trinket 18": 2515017,
"Trinket 19": 2515018,
"Trinket 20": 2515019
}

27
worlds/v6/Locations.py Normal file
View File

@@ -0,0 +1,27 @@
from BaseClasses import Location
class V6Location(Location):
game: str = "VVVVVV"
location_table = { # Correspond to 2515000 + index in collect array of game code
"It's a Secret to Nobody": 2515000,
"Trench Warfare": 2515001,
"One Way Room": 2515002,
"You Just Keep Coming Back": 2515003,
"Clarion Call": 2515004,
"Doing things the hard way": 2515005,
"Prize for the Reckless": 2515006,
"The Tower 1": 2515007,
"The Tower 2": 2515008,
"Young Man, It's Worth the Challenge": 2515009,
"The Tantalizing Trinket": 2515010,
"Purest Unobtainium": 2515011,
"Edge Games": 2515012,
"Overworld (Pipe-shaped Segment)": 2515013,
"Overworld (Outside Entanglement Generator)": 2515014,
"Overworld (Left of Ship)": 2515015,
"Overworld (Square Room)": 2515016,
"Overworld (Sad Elephant)": 2515017,
"NPC Trinket": 2515018,
"V": 2515019
}

20
worlds/v6/Options.py Normal file
View File

@@ -0,0 +1,20 @@
import typing
from Options import Option, DeathLink, Range
class DoorCost(Range):
"""Amount of Trinkets required to enter Areas. Set to 0 to disable artificial locks."""
range_start = 0
range_end = 3
default = 3
class DeathLinkAmnesty(Range):
"""Amount of Deaths to take before sending a DeathLink signal, for balancing difficulty"""
range_start = 0
range_end = 30
default = 15
v6_options: typing.Dict[str,type(Option)] = {
"DoorCost": DoorCost,
"DeathLink": DeathLink,
"DeathLinkAmnesty": DeathLinkAmnesty
}

45
worlds/v6/Regions.py Normal file
View File

@@ -0,0 +1,45 @@
import typing
from BaseClasses import MultiWorld, Region, Entrance, Location, RegionType
from .Locations import V6Location, location_table
def create_regions(world: MultiWorld, player: int):
regOvr = Region("Menu", RegionType.Generic, "Dimension VVVVVV", player, world)
locOvr_names = ["Overworld (Pipe-shaped Segment)", "Overworld (Left of Ship)", "Overworld (Square Room)", "Overworld (Sad Elephant)",
"It's a Secret to Nobody", "Trench Warfare", "NPC Trinket"]
regOvr.locations += [V6Location(player, loc_name, location_table[loc_name], regOvr) for loc_name in locOvr_names]
world.regions.append(regOvr)
regLab = Region("Laboratory", RegionType.Generic, "Laboratory", player, world)
locLab_names = ["Young Man, It's Worth the Challenge", "Overworld (Outside Entanglement Generator)", "The Tantalizing Trinket", "Purest Unobtainium"]
regLab.locations += [V6Location(player, loc_name, location_table[loc_name], regLab) for loc_name in locLab_names]
world.regions.append(regLab)
regTow = Region("The Tower", RegionType.Generic, "The Tower", player, world)
locTow_names = ["The Tower 1", "The Tower 2"]
regTow.locations += [V6Location(player, loc_name, location_table[loc_name], regTow) for loc_name in locTow_names]
world.regions.append(regTow)
regSp2 = Region("Space Station 2", RegionType.Generic, "Space Station 2", player, world)
locSp2_names = ["One Way Room", "You Just Keep Coming Back", "Clarion Call", "Prize for the Reckless", "Doing things the hard way"]
regSp2.locations += [V6Location(player, loc_name, location_table[loc_name], regSp2) for loc_name in locSp2_names]
world.regions.append(regSp2)
regWrp = Region("Warp Zone", RegionType.Generic, "Warp Zone", player, world)
locWrp_names = ["Edge Games"]
regWrp.locations += [V6Location(player, loc_name, location_table[loc_name], regWrp) for loc_name in locWrp_names]
world.regions.append(regWrp)
regEnd = Region("The Final Level", RegionType.Generic, "The Final Level", player, world)
locEnd_names = ["V"]
regEnd.locations += [V6Location(player, loc_name, location_table[loc_name], regEnd) for loc_name in locEnd_names]
world.regions.append(regEnd)
def connect_regions(world: MultiWorld, player: int, source: str, target: str, rule):
sourceRegion = world.get_region(source, player)
targetRegion = world.get_region(target, player)
connection = Entrance(player,'', sourceRegion)
connection.access_rule = rule
sourceRegion.exits.append(connection)
connection.connect(targetRegion)

34
worlds/v6/Rules.py Normal file
View File

@@ -0,0 +1,34 @@
import typing
from ..generic.Rules import add_rule
from .Regions import connect_regions
def _has_trinket_range(state,player,start,end):
for i in range(start+1,end+1):
if (not state.has("Trinket " + str(i).zfill(2), player)):
return False
return True
def create_npctrinket_rules(world,location,player):
add_rule(location, lambda state: state.can_reach(world.get_region("Laboratory",player),'Region',player) or
state.can_reach(world.get_region("Space Station 2",player),'Region',player))
def set_rules(world,player):
if (world.DoorCost[player].value == 0): pass
connect_regions(world, player, "Menu", "Laboratory", lambda state: _has_trinket_range(state,player,0,world.DoorCost[player].value))
connect_regions(world, player, "Menu", "The Tower", lambda state: _has_trinket_range(state,player,world.DoorCost[player].value,world.DoorCost[player].value*2))
connect_regions(world, player, "Menu", "Space Station 2", lambda state: _has_trinket_range(state,player,world.DoorCost[player].value*2,world.DoorCost[player].value*3))
connect_regions(world, player, "Menu", "Warp Zone", lambda state: _has_trinket_range(state,player,world.DoorCost[player].value*3,world.DoorCost[player].value*4))
connect_regions(world, player, "Menu", "The Final Level", lambda state : state.can_reach("Laboratory",'Region',player) and
state.can_reach("The Tower",'Region',player) and
state.can_reach("Space Station 2",'Region',player) and
state.can_reach("Warp Zone",'Region',player))
connect_regions(world, player, "Laboratory", "Menu", lambda state: True)
connect_regions(world, player, "The Tower", "Menu", lambda state: True)
connect_regions(world, player, "Space Station 2", "Menu", lambda state: True)
connect_regions(world, player, "Warp Zone", "Menu", lambda state: True)
connect_regions(world, player, "The Final Level", "Menu", lambda state: True)
create_npctrinket_rules(world,world.get_location("NPC Trinket",player),player)
world.completion_condition[player] = lambda state: state.can_reach(world.get_region("The Final Level",player),'Region',player)

47
worlds/v6/__init__.py Normal file
View File

@@ -0,0 +1,47 @@
import string
from .Items import item_table, V6Item
from .Locations import location_table, V6Location
from .Options import v6_options
from .Rules import set_rules
from .Regions import create_regions
from BaseClasses import Region, RegionType, Entrance, Item, MultiWorld
from ..AutoWorld import World
client_version = 1
class V6World(World):
"""
VVVVVV is a platform game all about exploring one simple mechanical idea - what if you reversed gravity instead of jumping?
""" #Lifted from Store Page
game: str = "VVVVVV"
topology_present = False
item_name_to_id = item_table
location_name_to_id = location_table
data_version = 1
forced_auto_forfeit = False
options = v6_options
def create_regions(self):
create_regions(self.world,self.player)
def set_rules(self):
set_rules(self.world,self.player)
def create_item(self, name: str) -> Item:
item_id = item_table[name]
item = V6Item(name, True, item_id, self.player)
return item
def generate_basic(self):
self.world.itempool += [self.create_item(name) for name in self.item_names]
def fill_slot_data(self):
return {
"DoorCost": self.world.DoorCost[self.player].value,
"DeathLink": self.world.DeathLink[self.player].value,
"DeathLink_Amnesty": self.world.DeathLinkAmnesty[self.player].value
}