Enhance flag handling and XML integration for standalone mode

- Updated `GamesController` to support XML flag hints for standalone mode, improving backward compatibility with legacy flag input.
- Introduced `parse_flag_hints_xml` method in `Mission` model to extract flags from XML content.
- Enhanced `Game` model to incorporate `flags_by_vm` from player state for better flag management.
- Modified `new.html.erb` to update UI for flag hints input, replacing the previous comma-separated flags format.
- Improved `FlagStationMinigame` to display accepted VM flags and handle flag submissions more effectively.
- Adjusted scenario JSON to include flag stations with VM-specific flag handling.
This commit is contained in:
Z. Cliffe Schreuders
2025-11-29 20:57:39 +00:00
parent bb2b0c206e
commit 92330b04dc
13 changed files with 1741 additions and 40 deletions

View File

@@ -42,8 +42,14 @@ module BreakEscape
end
end
# Standalone mode with manual flags
if params[:standalone_flags].present?
# Standalone mode with XML flag hints
if params[:flag_hints_xml].present?
flags_by_vm = Mission.parse_flag_hints_xml(params[:flag_hints_xml])
initial_player_state['flags_by_vm'] = flags_by_vm
# Also store flat list for backward compatibility
initial_player_state['standalone_flags'] = flags_by_vm.values.flatten.uniq
# Legacy: comma-separated flags (backward compatibility)
elsif params[:standalone_flags].present?
flags = if params[:standalone_flags].is_a?(Array)
params[:standalone_flags]
else
@@ -678,6 +684,12 @@ module BreakEscape
Rails.logger.warn "[BreakEscape] #{error_msg}"
return error_msg
end
elsif location[:type] == 'flag_station'
# Flag station items are valid if they're in the player's inventory (already awarded server-side)
# or if the corresponding flag has been submitted
flag_station_id = location[:flag_station_id]
Rails.logger.info "[BreakEscape] Item from flag station #{flag_station_id}, allowing (flag reward)"
# Flag rewards are always valid - the server already validated and added them
end
Rails.logger.info "[BreakEscape] Item collection valid: #{item_type}"
@@ -709,6 +721,15 @@ module BreakEscape
return { item: content, location: { type: 'container', container_id: obj['id'] || obj['name'] } }
end
end
# Search flag-station itemsHeld (flag reward items)
if obj['type'] == 'flag-station' && obj['itemsHeld'].present?
obj['itemsHeld'].each do |held_item|
if held_item['type'] == item_type && (held_item['key_id'] == item_id || held_item['keyId'] == item_id || held_item['id'] == item_id || held_item['name'] == item_name || held_item['name'] == item_id)
return { item: held_item, location: { type: 'flag_station', flag_station_id: obj['id'] || obj['name'], room_id: room_id } }
end
end
end
end
end

View File

@@ -28,10 +28,10 @@ module BreakEscape
redirect_to "/break_escape/games/new?mission_id=#{@mission.id}"
else
# Legacy behavior for non-VM missions - auto-create game
@game = Game.find_or_create_by!(
player: current_player,
mission: @mission
)
@game = Game.find_or_create_by!(
player: current_player,
mission: @mission
)
# Use explicit path instead of route helper to ensure it works in engine context
redirect_to "/break_escape/games/#{@game.id}"
end