Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions worlds/rac3/client/rac3_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@
from worlds.rac3.constants.player_action import PLAYER_ACTION_NAMES, RAC3PLAYERACTION
from worlds.rac3.constants.player_type import PLAYER_TYPE_TO_NAME, RAC3PLAYERTYPE
from worlds.rac3.constants.progress_flag import HALO_JUMP_TO_REGION, RAC3PROGRESSFLAG
from worlds.rac3.constants.region import (PLANET_LOAD_OFFSET, PLANET_NAME_FROM_ID, PLANET_VENDOR_OFFSET,
PLANETS_WITH_HACKER_PUZZLES, PLANETS_WITH_REFRACTOR_PUZZLES,
from worlds.rac3.constants.region import (PLANET_LOAD_OFFSET, PLANET_NAME_FROM_ID, PLANET_VENDOR_OFFSET, PLANETS_WITH_HACKER_PUZZLES, PLANETS_WITH_REFRACTOR_PUZZLES,
PLANETS_WITH_TYHRRANOID_PUZZLES, RAC3REGION, REGION_TO_HACKER_DOOR_COUNT,
RESPAWN_COORDS_OFFSET)
from worlds.rac3.constants.ship_slot import RAC3SHIPSLOT, SHIP_SLOTS
Expand All @@ -70,6 +69,7 @@
from worlds.rac3.constants.version import (GAME_ID_TO_OFFSET, GAME_ID_TO_VERSION, PAL_SHIFTED_PLANETS, RAC3VERSION,
VERSION_TO_BLACK_SCREEN_ORIGINAL_VALUE, jp_convert_address,
jp_get_pause_physical_address, )
from worlds.rac3.constants.wrench import RAC3WRENCH


class Rac3Interface(GameInterface):
Expand Down Expand Up @@ -97,6 +97,7 @@ class Options:
starting_weapons: dict[str, int]
bolt_and_xp_multiplier: int
progressive_weapons: int
progressive_wrench: int
armor_upgrade: int
skill_points: int
trophies: int
Expand Down Expand Up @@ -324,6 +325,7 @@ def proc_option(self, slot_data: dict[str, Any]):
self.options.starting_weapons = slot_data[RAC3OPTION.STARTING_WEAPONS]
self.options.bolt_and_xp_multiplier = slot_data[RAC3OPTION.BOLT_AND_XP_MULTIPLIER]
self.options.progressive_weapons = slot_data[RAC3OPTION.PROGRESSIVE_WEAPONS]
self.options.progressive_wrench = slot_data[RAC3OPTION.PROGRESSIVE_WRENCH]
self.options.armor_upgrade = slot_data[RAC3OPTION.ARMOR_UPGRADE]
self.options.skill_points = slot_data[RAC3OPTION.SKILL_POINTS]
self.options.trophies = slot_data[RAC3OPTION.TROPHIES]
Expand Down Expand Up @@ -925,6 +927,8 @@ def item_received(self,
case RAC3ITEM.CLANK:
self.UnlockItem[RAC3ITEM.HELI_PACK].status = 1
self.UnlockItem[RAC3ITEM.THRUSTER_PACK].status = 1
#case RAC3ITEM.PROGRESSIVE_WRENCH:
# pass
case RAC3ITEM.TITANIUM_BOLT:
pass
case RAC3ITEM.BOLTS:
Expand Down Expand Up @@ -1780,6 +1784,7 @@ def late_update(self):
self.gadget_cycler()
self.planet_cycler()
self.weapon_cycler()
self.wrench_cycler()
self.vidcomic_cycler()
self.armor_cycler()
self.timer_cycler()
Expand Down Expand Up @@ -1926,8 +1931,6 @@ def weapon_cycler(self):
for name in non_prog_weapon_data.keys():
unlock_addr = non_prog_weapon_data[name].UNLOCK_ADDRESS
ammo_addr = non_prog_weapon_data[name].AMMO_ADDRESS
xp_addr = non_prog_weapon_data[name].XP_ADDRESS
level_addr = non_prog_weapon_data[name].LEVEL_ADDRESS
if self.UnlockItem[name].status:
if self.UnlockItem[name].unlock_delay:
self._write8(unlock_addr, 1)
Expand All @@ -1945,8 +1948,6 @@ def weapon_cycler(self):
# Prevent the player from using locked weapons and leveling them to accidentally break vendors
self._write8(unlock_addr, 0)
self._write32(ammo_addr, 0)
self._write32(xp_addr, 0)
self._write8(level_addr, UPGRADE_DICT[name][0])

if self.equipped_item > 1 and self.UnlockItem[ITEM_NAME_FROM_ID[self.equipped_item]].status == 0:
if self.last_used_1 == 0:
Expand All @@ -1967,6 +1968,22 @@ def weapon_cycler(self):
else:
self.update_weapon_equip(self.last_used_3, self.last_used_3, self.last_used_4, self.last_used_5)

def wrench_cycler(self):
"""Cycle through the wrench properties and update its state"""
if self.options.progressive_wrench:
prog_wrench = self.UnlockItem[RAC3ITEM.PROGRESSIVE_WRENCH]
if self.planet != RAC3REGION.MENU and self.between_planets is False:
wrench_instruction = RAC3WRENCH.get_wrench_property_address(self.planet, self.current_game) + RAC3WRENCH.BASE_ITEM_ID_OFFSET
wrench_upgrade = RAC3WRENCH.get_wrench_property_address(self.planet, self.current_game) + RAC3WRENCH.UPGRADE_ID_OFFSET
target_id = UPGRADE_DICT[RAC3ITEM.WRENCH][prog_wrench.status]
if self._read32(wrench_instruction) == 0xA0620009:
for _ in range(6):
self._write8(wrench_upgrade, target_id)
wrench_upgrade += RAC3WRENCH.PER_LEVEL_OFFSET

else:
return

def update_weapon_equip(self, equip: int | None, last_0: int | None,
last_1: int | None, last_2: int | None):
"""Writes new values to the player's last used item history"""
Expand Down
1 change: 1 addition & 0 deletions worlds/rac3/constants/data/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(self, data: tuple[int, CHECKTYPE, int]):
RAC3ADDRESSDATA((RAC3STATUS.CRYSTALS_CURRENT, CHECKTYPE.BYTE, 0)),
*[RAC3ADDRESSDATA((weapon.AMMO_ADDRESS, CHECKTYPE.INT, weapon.AMMO)) for weapon in non_prog_weapon_data.values()],
*[RAC3ADDRESSDATA((weapon.XP_ADDRESS, CHECKTYPE.INT, 0)) for weapon in non_prog_weapon_data.values()],
*[RAC3ADDRESSDATA((weapon.LEVEL_ADDRESS, CHECKTYPE.BYTE, weapon.ID)) for weapon in non_prog_weapon_data.values()],
# Stored Fillers
RAC3ADDRESSDATA((RAC3STATUS.BOLT_PACKS, CHECKTYPE.INT, 0)),
RAC3ADDRESSDATA((RAC3STATUS.NANOTECH_EXP_PACKS, CHECKTYPE.INT, 0)),
Expand Down
30 changes: 23 additions & 7 deletions worlds/rac3/constants/data/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,16 @@ def construct_vidcomic(idx: int,
else:
tags: list[str] = [RAC3ITEMTAG.VIDCOMIC]
return RAC3ITEMDATA(idx, address, ap_classification=ItemClassification.progression, tags=tags)

@staticmethod
def construct_wrench(idx: int,
tag: list[str] | None = None):
"""Construct a progressive OmniWrench item"""
if tag:
tags: list[str] = [*tag, RAC3ITEMTAG.PROG_WRENCH]
else:
tags: list[str] = [RAC3ITEMTAG.PROG_WRENCH]
return RAC3ITEMDATA(idx, ap_classification=ItemClassification.progression, tags=tags)

@staticmethod
def construct_trap(idx: int,
Expand Down Expand Up @@ -367,8 +377,6 @@ def construct_cheat(idx: int,
RAC3ITEM.PLASMA_COIL_V2: RAC3ITEMDATA.construct_weapon_level(0xA0, 3000, 15, 8000),
RAC3ITEM.LAVA_GUN_V2: RAC3ITEMDATA.construct_weapon_level(0xA1, 240, 150, 600),
RAC3ITEM.MINI_TURRET_V2: RAC3ITEMDATA.construct_weapon_level(0xA2, 800, 10, 400),
RAC3ITEM.WRENCH_V2: RAC3ITEMDATA.construct_unused(0xA4),
RAC3ITEM.WRENCH_V3: RAC3ITEMDATA.construct_unused(0xA5),
RAC3ITEM.BOUNCER_V2: RAC3ITEMDATA.construct_weapon_level(0xA6, 1400, 10, 2500),
RAC3ITEM.SHIELD_CHARGER_V2: RAC3ITEMDATA.construct_weapon_level(0xA7, 100, 3, 2200),
RAC3ITEM.MINI_TURRET_V3: RAC3ITEMDATA.construct_weapon_level(0xA8, 1000, 12, 1000),
Expand Down Expand Up @@ -401,11 +409,6 @@ def construct_cheat(idx: int,
RAC3ITEM.TESLA_BARRIER_V6: RAC3ITEMDATA.construct_weapon_level(0xC3, 300, 4, tags=[RAC3ITEMTAG.NGPLUS]),
RAC3ITEM.TESLA_BARRIER_V7: RAC3ITEMDATA.construct_weapon_level(0xC4, 400, 5, 12000, [RAC3ITEMTAG.NGPLUS]),
RAC3ITEM.TESLA_BARRIER_V8: RAC3ITEMDATA.construct_weapon_level(0xC5, 500, 5, 30000, [RAC3ITEMTAG.NGPLUS]),
RAC3ITEM.WRENCH_V4: RAC3ITEMDATA.construct_unused(0xC6),
RAC3ITEM.WRENCH_V5: RAC3ITEMDATA.construct_unused(0xC7),
RAC3ITEM.WRENCH_V6: RAC3ITEMDATA.construct_unused(0xC8),
RAC3ITEM.WRENCH_V7: RAC3ITEMDATA.construct_unused(0xC9),
RAC3ITEM.WRENCH_V8: RAC3ITEMDATA.construct_unused(0xCA),
# Progressive
RAC3ITEM.PROGRESSIVE_PLASMA_COIL: RAC3ITEMDATA.construct_rac2_prog(0xCB, ItemClassification.progression_skip_balancing),
RAC3ITEM.PROGRESSIVE_LAVA_GUN: RAC3ITEMDATA.construct_rac2_prog(0xCC, ItemClassification.progression_skip_balancing),
Expand Down Expand Up @@ -438,6 +441,15 @@ def construct_cheat(idx: int,
RAC3ITEMDATA.construct_weapon_prog(0xDD, ItemClassification.progression_skip_balancing),
RAC3ITEM.PROGRESSIVE_RY3N0:
RAC3ITEMDATA.construct_weapon_prog(0xDE, ItemClassification.progression_skip_balancing, [RAC3ITEMTAG.NGPLUS]),
RAC3ITEM.PROGRESSIVE_WRENCH:
RAC3ITEMDATA.construct_wrench(0xDF, [RAC3ITEMTAG.PROGRESSIVE]),
RAC3ITEM.WRENCH_V2: RAC3ITEMDATA.construct_wrench(0xA4),
RAC3ITEM.WRENCH_V3: RAC3ITEMDATA.construct_wrench(0xA5),
RAC3ITEM.WRENCH_V4: RAC3ITEMDATA.construct_wrench(0xC6),
RAC3ITEM.WRENCH_V5: RAC3ITEMDATA.construct_wrench(0xC7),
RAC3ITEM.WRENCH_V6: RAC3ITEMDATA.construct_wrench(0xC8),
RAC3ITEM.WRENCH_V7: RAC3ITEMDATA.construct_wrench(0xC9),
RAC3ITEM.WRENCH_V8: RAC3ITEMDATA.construct_wrench(0xCA),
# Infobots
RAC3ITEM.VELDIN: RAC3ITEMDATA.construct_infobot(0xE1, ItemClassification.progression),
RAC3ITEM.FLORANA: RAC3ITEMDATA.construct_infobot(0xE2, ItemClassification.progression),
Expand Down Expand Up @@ -526,6 +538,7 @@ def from_tag(tag: str) -> dict[str, RAC3ITEMDATA]:
ngplus_data: dict[str, RAC3ITEMDATA] = from_tag(RAC3ITEMTAG.NGPLUS)
non_prog_weapon_data: dict[str, RAC3ITEMDATA] = from_tag(RAC3ITEMTAG.NON_PROG_WEAPON)
prog_weapon_data: dict[str, RAC3ITEMDATA] = from_tag(RAC3ITEMTAG.PROG_WEAPON)
prog_wrench_data: dict[str, RAC3ITEMDATA] = from_tag(RAC3ITEMTAG.PROG_WRENCH)
progressive_data: dict[str, RAC3ITEMDATA] = from_tag(RAC3ITEMTAG.PROGRESSIVE)
trap_data: dict[str, RAC3ITEMDATA] = from_tag(RAC3ITEMTAG.TRAP)
unused_data: dict[str, RAC3ITEMDATA] = from_tag(RAC3ITEMTAG.UNUSED)
Expand All @@ -542,6 +555,7 @@ def from_tag(tag: str) -> dict[str, RAC3ITEMDATA]:
item_counts: dict[str, int] = {
**dict.fromkeys(non_prog_weapon_data.keys(), 1),
**dict.fromkeys(prog_weapon_data.keys(), 5),
**dict.fromkeys(prog_wrench_data.keys(), 5),
**dict.fromkeys(gadget_data.keys(), 1),
**dict.fromkeys(cheat_data.keys(), 1),
RAC3ITEM.CLANK: 1,
Expand All @@ -555,6 +569,7 @@ def from_tag(tag: str) -> dict[str, RAC3ITEMDATA]:
ngplus_item_counts: dict[str, int] = {
**dict.fromkeys(non_prog_weapon_data.keys(), 1),
**dict.fromkeys(prog_weapon_data.keys(), 8),
**dict.fromkeys(prog_wrench_data.keys(), 8),
**dict.fromkeys(gadget_data.keys(), 1),
**dict.fromkeys(cheat_data.keys(), 1),
RAC3ITEM.CLANK: 1,
Expand Down Expand Up @@ -599,6 +614,7 @@ def from_tag(tag: str) -> dict[str, RAC3ITEMDATA]:
RAC3ITEMTAG.NGPLUS: set(ngplus_data.keys()),
RAC3ITEMTAG.NON_PROG_WEAPON: set(non_prog_weapon_data.keys()),
RAC3ITEMTAG.PROG_WEAPON: set(prog_weapon_data.keys()),
RAC3ITEMTAG.PROG_WRENCH: set(prog_wrench_data.keys()),
RAC3ITEMTAG.PROGRESSIVE: set(progressive_data.keys()),
RAC3ITEMTAG.TRAP: set(trap_data.keys()),
RAC3ITEMTAG.UNUSED: set(unused_data.keys()),
Expand Down
Loading