mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
Refactor code to remove trailing whitespace and improve readability
- Cleaned up trailing whitespace in `games_controller.rb`, `game.rb`, and `validate_scenario.rb` to enhance code quality and maintain consistency across the codebase. - Updated migration file `remove_unique_game_constraint.rb` to remove unnecessary whitespace, ensuring a cleaner migration history. - Improved overall readability of the code by eliminating redundant blank lines in various files.
This commit is contained in:
@@ -672,7 +672,7 @@ module BreakEscape
|
||||
inventory = @game.player_state['inventory'] || []
|
||||
Rails.logger.debug "[BreakEscape] Filtering container contents. Inventory has #{inventory.length} items"
|
||||
Rails.logger.debug "[BreakEscape] Container has #{contents.length} items before filtering"
|
||||
|
||||
|
||||
filtered_contents = contents.reject do |item|
|
||||
in_inventory = item_in_inventory?(item, inventory)
|
||||
if in_inventory
|
||||
@@ -689,7 +689,7 @@ module BreakEscape
|
||||
# Matches by type, id, or name (similar to validation logic)
|
||||
def item_in_inventory?(item, inventory)
|
||||
return false if inventory.blank? || item.blank?
|
||||
|
||||
|
||||
# Normalize item data (handle both string and symbol keys)
|
||||
item_type = item['type'] || item[:type]
|
||||
item_id = item['key_id'] || item[:key_id] || item['id'] || item[:id]
|
||||
|
||||
@@ -104,7 +104,7 @@ module BreakEscape
|
||||
player_state['encounteredNPCs'] ||= []
|
||||
unless player_state['encounteredNPCs'].include?(npc_id)
|
||||
player_state['encounteredNPCs'] << npc_id
|
||||
|
||||
|
||||
# Try to get NPC display name from scenario for better logging
|
||||
npc_display_name = npc_id
|
||||
if scenario_data && scenario_data['rooms']
|
||||
@@ -116,7 +116,7 @@ module BreakEscape
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Rails.logger.info "[BreakEscape] 🎭 NPC ENCOUNTERED (via encounter_npc!): #{npc_display_name} (#{npc_id})"
|
||||
save!
|
||||
end
|
||||
@@ -485,35 +485,35 @@ module BreakEscape
|
||||
inventory = player_state['inventory'] || []
|
||||
target_items = Array(task['targetItems'] || [])
|
||||
target_item_ids = Array(task['targetItemIds'] || [])
|
||||
|
||||
|
||||
count = inventory.count do |item|
|
||||
item_type = item['type'] || item.dig('scenarioData', 'type')
|
||||
item_id = item['id'] || item.dig('scenarioData', 'id')
|
||||
item_name = item['name'] || item.dig('scenarioData', 'name')
|
||||
identifier = item_id || item_name
|
||||
|
||||
|
||||
matches = false
|
||||
|
||||
|
||||
# Type-based matching
|
||||
if target_items.any?
|
||||
matches = target_items.include?(item_type)
|
||||
end
|
||||
|
||||
|
||||
# ID-based matching (more specific)
|
||||
if target_item_ids.any?
|
||||
matches = target_item_ids.include?(identifier)
|
||||
end
|
||||
|
||||
|
||||
# If both specified, match either
|
||||
if target_items.any? && target_item_ids.any?
|
||||
type_match = target_items.include?(item_type)
|
||||
id_match = target_item_ids.include?(identifier)
|
||||
matches = type_match || id_match
|
||||
end
|
||||
|
||||
|
||||
matches
|
||||
end
|
||||
|
||||
|
||||
count >= (task['targetCount'] || 1)
|
||||
end
|
||||
|
||||
@@ -525,7 +525,7 @@ module BreakEscape
|
||||
return false unless task['targetFlags'].is_a?(Array)
|
||||
|
||||
task_id = task['taskId']
|
||||
|
||||
|
||||
# Use submittedFlags from request if provided (latest data), otherwise use stored state
|
||||
if submitted_flags_from_request.present?
|
||||
submitted = Array(submitted_flags_from_request)
|
||||
@@ -537,9 +537,9 @@ module BreakEscape
|
||||
|
||||
# Check that all targetFlags are in submittedFlags
|
||||
all_submitted = task['targetFlags'].all? { |target_flag| submitted.include?(target_flag) }
|
||||
|
||||
|
||||
Rails.logger.debug "[BreakEscape] Flag validation: targetFlags=#{task['targetFlags'].inspect}, submitted=#{submitted.inspect}, result=#{all_submitted}"
|
||||
|
||||
|
||||
all_submitted
|
||||
end
|
||||
|
||||
|
||||
@@ -16,8 +16,3 @@ class RemoveUniqueGameConstraint < ActiveRecord::Migration[7.0]
|
||||
name: 'index_games_on_player_and_mission_non_unique'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@ begin
|
||||
rescue LoadError
|
||||
$stderr.puts <<~ERROR
|
||||
ERROR: json-schema gem is required for validation.
|
||||
|
||||
|
||||
Install it with:
|
||||
gem install json-schema
|
||||
|
||||
|
||||
Or add to Gemfile:
|
||||
gem 'json-schema'
|
||||
|
||||
|
||||
Then run: bundle install
|
||||
ERROR
|
||||
exit 1
|
||||
@@ -147,11 +147,11 @@ def check_common_issues(json_data)
|
||||
# Check reverse connections if target is a single room
|
||||
if target.is_a?(String) && json_data['rooms'][target]
|
||||
reverse_dir = case direction
|
||||
when 'north' then 'south'
|
||||
when 'south' then 'north'
|
||||
when 'east' then 'west'
|
||||
when 'west' then 'east'
|
||||
end
|
||||
when 'north' then 'south'
|
||||
when 'south' then 'north'
|
||||
when 'east' then 'west'
|
||||
when 'west' then 'east'
|
||||
end
|
||||
target_room = json_data['rooms'][target]
|
||||
if target_room['connections']
|
||||
has_reverse = target_room['connections'].any? do |dir, targets|
|
||||
@@ -169,7 +169,7 @@ def check_common_issues(json_data)
|
||||
if room['objects']
|
||||
room['objects'].each_with_index do |obj, idx|
|
||||
path = "rooms/#{room_id}/objects[#{idx}]"
|
||||
|
||||
|
||||
# Check for incorrect VM launcher configuration (type: "pc" with vmAccess)
|
||||
if obj['type'] == 'pc' && obj['vmAccess']
|
||||
issues << "❌ INVALID: '#{path}' uses type: 'pc' with vmAccess - should use type: 'vm-launcher' instead. See scenarios/secgen_vm_lab/scenario.json.erb for example"
|
||||
@@ -279,11 +279,11 @@ def check_common_issues(json_data)
|
||||
if room['npcs']
|
||||
room['npcs'].each_with_index do |npc, idx|
|
||||
path = "rooms/#{room_id}/npcs[#{idx}]"
|
||||
|
||||
|
||||
# Track person NPCs
|
||||
if npc['npcType'] == 'person' || (!npc['npcType'] && npc['position'])
|
||||
has_person_npcs = true
|
||||
|
||||
|
||||
# Check for waypoints in behavior.patrol
|
||||
if npc['behavior'] && npc['behavior']['patrol']
|
||||
patrol = npc['behavior']['patrol']
|
||||
@@ -297,7 +297,7 @@ def check_common_issues(json_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Check for opening cutscene in starting room
|
||||
if room_id == start_room_id && npc['timedConversation']
|
||||
has_opening_cutscene = true
|
||||
@@ -326,27 +326,27 @@ def check_common_issues(json_data)
|
||||
# Track phone NPCs (phone contacts)
|
||||
if npc['npcType'] == 'phone'
|
||||
has_phone_contacts = true
|
||||
|
||||
|
||||
# Validate phone NPC structure - should have phoneId
|
||||
unless npc['phoneId']
|
||||
issues << "❌ INVALID: '#{path}' (phone NPC) missing required 'phoneId' field - phone NPCs must specify which phone they appear on (e.g., 'player_phone')"
|
||||
end
|
||||
|
||||
|
||||
# Validate phone NPC structure - should have storyPath
|
||||
unless npc['storyPath']
|
||||
issues << "❌ INVALID: '#{path}' (phone NPC) missing required 'storyPath' field - phone NPCs must have a path to their Ink story JSON file"
|
||||
end
|
||||
|
||||
|
||||
# Validate phone NPC structure - should NOT have position (phone NPCs don't have positions)
|
||||
if npc['position']
|
||||
issues << "⚠ WARNING: '#{path}' (phone NPC) has 'position' field - phone NPCs should NOT have position (they're not in-world sprites). Remove the position field."
|
||||
end
|
||||
|
||||
|
||||
# Validate phone NPC structure - should NOT have spriteSheet (phone NPCs don't have sprites)
|
||||
if npc['spriteSheet']
|
||||
issues << "⚠ WARNING: '#{path}' (phone NPC) has 'spriteSheet' field - phone NPCs should NOT have spriteSheet (they're not in-world sprites). Remove the spriteSheet field."
|
||||
end
|
||||
|
||||
|
||||
# Track phone NPCs with messages in rooms
|
||||
if npc['timedMessages'] && !npc['timedMessages'].empty?
|
||||
has_phone_npc_with_messages = true
|
||||
@@ -367,7 +367,7 @@ def check_common_issues(json_data)
|
||||
if item['id']
|
||||
issues << "❌ INVALID: '#{path}/itemsHeld[#{item_idx}]' has 'id' field - items should NOT have 'id' field. Use 'type' field to match #give_item tag parameter (e.g., type: 'id_badge' matches #give_item:id_badge)"
|
||||
end
|
||||
|
||||
|
||||
# Track security tools in NPC itemsHeld
|
||||
if ['fingerprint_kit', 'pin-cracker', 'bluetooth_scanner', 'rfid_cloner'].include?(item['type'])
|
||||
has_security_tools = true
|
||||
@@ -386,7 +386,7 @@ def check_common_issues(json_data)
|
||||
if ['fingerprint_kit', 'pin-cracker', 'bluetooth_scanner', 'rfid_cloner'].include?(item['type'])
|
||||
has_security_tools = true
|
||||
end
|
||||
|
||||
|
||||
# Track readable items
|
||||
if item['readable'] || (item['type'] == 'notes' && item['text'])
|
||||
has_readable_items = true
|
||||
@@ -398,13 +398,13 @@ def check_common_issues(json_data)
|
||||
if json_data['phoneNPCs']
|
||||
json_data['phoneNPCs'].each_with_index do |npc, idx|
|
||||
path = "phoneNPCs[#{idx}]"
|
||||
|
||||
|
||||
# Flag incorrect structure - phone NPCs should be in rooms, not phoneNPCs section
|
||||
issues << "❌ INVALID: '#{path}' - Phone NPCs should be defined in 'rooms/{room_id}/npcs[]' arrays, NOT in a separate 'phoneNPCs' section. See scenarios/npc-sprite-test3/scenario.json.erb for correct format. Phone NPCs should be in the starting room (or room where phone is accessible) with npcType: 'phone'"
|
||||
|
||||
|
||||
# Track phone NPCs (phone contacts) - but note they're in wrong location
|
||||
has_phone_contacts = true
|
||||
|
||||
|
||||
# Track phone NPCs with messages
|
||||
if npc['timedMessages'] && !npc['timedMessages'].empty?
|
||||
has_phone_npc_with_messages = true
|
||||
@@ -465,7 +465,7 @@ def check_common_issues(json_data)
|
||||
issues << "💡 SUGGESTION: Consider adding timedMessages to phone contacts for more engaging interactions - see scenarios/npc-sprite-test3/scenario.json.erb for example. Phone NPCs without timed messages: #{npc_list}"
|
||||
end
|
||||
|
||||
# Suggest variety in lock types
|
||||
# Suggest variety in lock types
|
||||
if lock_types_used.size < 2
|
||||
issues << "💡 SUGGESTION: Consider adding variety in lock types - scenarios typically use 2+ different lock mechanisms (key, pin, rfid, password). Currently using: #{lock_types_used.to_a.join(', ') || 'none'}. See scenarios/ceo_exfil/scenario.json.erb for examples"
|
||||
end
|
||||
@@ -529,7 +529,6 @@ def check_recommended_fields(json_data)
|
||||
room['objects'].each_with_index do |obj, idx|
|
||||
path = "rooms/#{room_id}/objects[#{idx}]"
|
||||
warnings << "Missing recommended field: '#{path}/observations' - helps players understand what items are" unless obj.key?('observations')
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -538,28 +537,28 @@ def check_recommended_fields(json_data)
|
||||
if room['npcs']
|
||||
room['npcs'].each_with_index do |npc, idx|
|
||||
path = "rooms/#{room_id}/npcs[#{idx}]"
|
||||
|
||||
|
||||
# Phone NPCs should have avatar
|
||||
if npc['npcType'] == 'phone' && !npc['avatar']
|
||||
warnings << "Missing recommended field: '#{path}/avatar' - phone NPCs should have avatar images"
|
||||
end
|
||||
|
||||
|
||||
# Person NPCs should have position
|
||||
if npc['npcType'] == 'person' && !npc['position']
|
||||
warnings << "Missing recommended field: '#{path}/position' - person NPCs need x,y coordinates"
|
||||
end
|
||||
|
||||
|
||||
# NPCs with storyPath should have currentKnot
|
||||
if npc['storyPath'] && !npc['currentKnot']
|
||||
warnings << "Missing recommended field: '#{path}/currentKnot' - specifies starting dialogue knot"
|
||||
end
|
||||
|
||||
# Check for NPCs without behavior (no storyPath, no timedMessages, no timedConversation, no eventMappings)
|
||||
has_behavior = npc['storyPath'] ||
|
||||
has_behavior = npc['storyPath'] ||
|
||||
(npc['timedMessages'] && !npc['timedMessages'].empty?) ||
|
||||
npc['timedConversation'] ||
|
||||
(npc['eventMappings'] && !npc['eventMappings'].empty?)
|
||||
|
||||
|
||||
unless has_behavior
|
||||
warnings << "Missing recommended: '#{path}' has no behavior - NPCs should have storyPath, timedMessages, timedConversation, or eventMappings"
|
||||
end
|
||||
@@ -583,7 +582,7 @@ def check_recommended_fields(json_data)
|
||||
json_data['objectives'].each_with_index do |objective, idx|
|
||||
path = "objectives[#{idx}]"
|
||||
warnings << "Missing recommended field: '#{path}/description' - helps players understand the objective" unless objective.key?('description')
|
||||
|
||||
|
||||
if objective['tasks']
|
||||
objective['tasks'].each_with_index do |task, task_idx|
|
||||
task_path = "#{path}/tasks[#{task_idx}]"
|
||||
@@ -738,4 +737,3 @@ def main
|
||||
end
|
||||
|
||||
main if __FILE__ == $PROGRAM_NAME
|
||||
|
||||
|
||||
Reference in New Issue
Block a user