Skip to content

Commit

Permalink
Handle Queuing traps and new Timer Trap
Browse files Browse the repository at this point in the history
  • Loading branch information
PoryGone committed Dec 16, 2022
1 parent 67c37d8 commit 5a0e389
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 13 deletions.
83 changes: 79 additions & 4 deletions worlds/smw/Client.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,75 @@ async def handle_message_queue(self, ctx):

await snes_flush_writes(ctx)

return

def add_trap_to_queue(self, trap_item, trap_msg):
if not hasattr(self, "trap_queue"):
self.trap_queue = []

self.trap_queue.append((trap_item, trap_msg))


async def handle_trap_queue(self, ctx):
from SNIClient import snes_buffered_write, snes_flush_writes, snes_read

if not hasattr(self, "trap_queue") or len(self.trap_queue) == 0:
return

game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1)
if game_state[0] != 0x14:
return

mario_state = await snes_read(ctx, SMW_MARIO_STATE_ADDR, 0x1)
if mario_state[0] != 0x00:
return

pause_state = await snes_read(ctx, SMW_PAUSE_ADDR, 0x1)
if pause_state[0] != 0x00:
return

next_trap, message = self.trap_queue.pop(0)

from worlds.smw.Rom import trap_rom_data
if next_trap.item in trap_rom_data:
trap_active = await snes_read(ctx, WRAM_START + trap_rom_data[next_trap.item][0], 0x3)

if next_trap.item == 0xBC0016:
# Timer Trap
if trap_active[0] == 0 or (trap_active[0] == 1 and trap_active[1] == 0 and trap_active[2] == 0):
# Trap already active
self.add_trap_to_queue(next_trap, message)
return
else:
snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0], bytes([0x01]))
snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0] + 1, bytes([0x00]))
snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0] + 2, bytes([0x00]))
else:
if trap_active[0] > 0:
# Trap already active
self.add_trap_to_queue(next_trap, message)
return
else:
verify_game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1)
if verify_game_state[0] == 0x14 and len(trap_rom_data[next_trap.item]) > 2:
snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([trap_rom_data[next_trap.item][2]]))

new_item_count = trap_rom_data[next_trap.item][1]
snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0], bytes([new_item_count]))

current_level = await snes_read(ctx, SMW_CURRENT_LEVEL_ADDR, 0x1)
if current_level[0] in SMW_BAD_TEXT_BOX_LEVELS:
return

boss_state = await snes_read(ctx, SMW_BOSS_STATE_ADDR, 0x1)
if boss_state[0] in SMW_BOSS_STATES:
return

active_boss = await snes_read(ctx, SMW_ACTIVE_BOSS_ADDR, 0x1)
if active_boss[0] != 0x00:
return

if ctx.receive_option == 1 or (ctx.receive_option == 2 and ((next_trap.flags & 1) != 0)):
self.add_message_to_queue(message)


async def game_watcher(self, ctx):
Expand Down Expand Up @@ -229,13 +297,14 @@ async def game_watcher(self, ctx):
await snes_flush_writes(ctx)

await self.handle_message_queue(ctx)
await self.handle_trap_queue(ctx)

new_checks = []
event_data = await snes_read(ctx, SMW_EVENT_ROM_DATA, 0x60)
progress_data = bytearray(await snes_read(ctx, SMW_PROGRESS_DATA, 0x0F))
dragon_coins_data = bytearray(await snes_read(ctx, SMW_DRAGON_COINS_DATA, 0x0C))
dragon_coins_active = await snes_read(ctx, SMW_DRAGON_COINS_ACTIVE_ADDR, 0x1)
from worlds.smw.Rom import item_rom_data, ability_rom_data
from worlds.smw.Rom import item_rom_data, ability_rom_data, trap_rom_data
from worlds.smw.Levels import location_id_to_level_id, level_info_dict
from worlds import AutoWorldRegister
for loc_name, level_data in location_id_to_level_id.items():
Expand Down Expand Up @@ -307,7 +376,7 @@ async def game_watcher(self, ctx):
ctx.location_names[item.location], recv_index, len(ctx.items_received)))

if ctx.receive_option == 1 or (ctx.receive_option == 2 and ((item.flags & 1) != 0)):
if item.item != 0xBC0012:
if item.item != 0xBC0012 and item.item not in trap_rom_data:
# Don't send messages for Boss Tokens
item_name = ctx.item_names[item.item]
player_name = ctx.player_names[item.player]
Expand All @@ -316,7 +385,13 @@ async def game_watcher(self, ctx):
self.add_message_to_queue(receive_message)

snes_buffered_write(ctx, SMW_RECV_PROGRESS_ADDR, bytes([recv_index]))
if item.item in item_rom_data:
if item.item in trap_rom_data:
item_name = ctx.item_names[item.item]
player_name = ctx.player_names[item.player]

receive_message = generate_received_text(item_name, player_name)
self.add_trap_to_queue(item, receive_message)
elif item.item in item_rom_data:
item_count = await snes_read(ctx, WRAM_START + item_rom_data[item.item][0], 0x1)
increment = item_rom_data[item.item][1]

Expand Down
1 change: 1 addition & 0 deletions worlds/smw/Items.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class SMWItem(Item):
ItemName.ice_trap: ItemData(0xBC0013, False, True),
ItemName.stun_trap: ItemData(0xBC0014, False, True),
ItemName.literature_trap: ItemData(0xBC0015, False, True),
ItemName.timer_trap: ItemData(0xBC0016, False, True),
}

event_table = {
Expand Down
1 change: 1 addition & 0 deletions worlds/smw/Names/ItemName.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
ice_trap = "Ice Trap"
stun_trap = "Stun Trap"
literature_trap = "Literature Trap"
timer_trap = "Timer Trap"

# Other Definitions
victory = "The Princess"
Expand Down
8 changes: 8 additions & 0 deletions worlds/smw/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ class LiteratureTrapWeight(BaseTrapWeight):
display_name = "Literature Trap Weight"


class TimerTrapWeight(BaseTrapWeight):
"""
Likelihood of a receiving a trap which causes the timer to run low
"""
display_name = "Literature Trap Weight"


class Autosave(DefaultOnToggle):
"""
Whether a save prompt will appear after every level
Expand Down Expand Up @@ -271,6 +278,7 @@ class StartingLifeCount(Range):
"ice_trap_weight": IceTrapWeight,
"stun_trap_weight": StunTrapWeight,
"literature_trap_weight": LiteratureTrapWeight,
"timer_trap_weight": TimerTrapWeight,
"autosave": Autosave,
"music_shuffle": MusicShuffle,
"mario_palette": MarioPalette,
Expand Down
11 changes: 3 additions & 8 deletions worlds/smw/Rom.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,14 @@
0xBC000F: [0x1F27, 0x1, 0x1C], # Green Switch Palace
0xBC0010: [0x1F2A, 0x1, 0x1C], # Red Switch Palace
0xBC0011: [0x1F29, 0x1, 0x1C], # Blue Switch Palace
}

trap_rom_data = {
0xBC0013: [0x0086, 0x1, 0x0E], # Ice Trap
0xBC0014: [0x18BD, 0x7F, 0x18], # Stun Trap
0xBC0016: [0x0F31, 0x1], # Timer Trap
}

music_rom_data = [

]

level_music_ids = [

]


class SMWDeltaPatch(APDeltaPatch):
hash = USHASH
Expand Down
2 changes: 1 addition & 1 deletion worlds/smw/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class SMWWorld(World):
game: str = "Super Mario World"
option_definitions = smw_options
topology_present = False
data_version = 2
data_version = 3
required_client_version = (0, 3, 5)

item_name_to_id = {name: data.code for name, data in item_table.items()}
Expand Down

0 comments on commit 5a0e389

Please sign in to comment.