P08-03: 配置の通常操作受入

This commit is contained in:
Agent Control Runner
2026-10-14 03:22:38 +09:00
parent 12430ba899
commit 7dd450c64c
22 changed files with 7543 additions and 2 deletions
+92 -1
View File
@@ -148,6 +148,11 @@ var world_preview: WorldPreview
var front_button: Button
var back_button: Button
var excavation_button: Button
var demolition_button: Button
var demolition_dialog: ConfirmationDialog
var _demolition_mode := false
var _demolition_target: StringName = &""
var _pending_demolition_commands: Dictionary = {}
var pan_button: Button
var pause_button: Button
var speed_buttons: Dictionary = {}
@@ -792,10 +797,14 @@ func _create_bottom_bar() -> Control:
column.add_child(palette_scroll)
var grid := GridContainer.new()
grid.name = "BuildPalette"
grid.columns = MVP_FACILITY_IDS.size()
grid.columns = MVP_FACILITY_IDS.size() + 1
grid.add_theme_constant_override("h_separation", 4)
grid.add_theme_constant_override("v_separation", 0)
palette_scroll.add_child(grid)
demolition_button = _button("撤去", _toggle_demolition_mode, 72)
demolition_button.name = "DemolitionButton"
demolition_button.toggle_mode = true
grid.add_child(demolition_button)
build_status_label = Label.new()
build_status_label.name = "BuildStatusLabel"
@@ -1241,6 +1250,7 @@ func _select_build_definition(definition_id: StringName) -> void:
if definition == null:
_set_status("選択した施設定義が見つかりません。", false)
return
_set_demolition_mode(false, false)
_set_excavation_mode(false, false)
_set_pan_mode(false)
_selected_definition_id = definition_id
@@ -1267,6 +1277,9 @@ func _clear_build_selection(announce := true) -> void:
func _clear_active_tool() -> void:
if _demolition_mode:
_set_demolition_mode(false)
return
if world_preview.pan_mode:
_set_pan_mode(false)
_set_status("画面移動を解除しました。施設をクリックすると情報を表示します。", true, true)
@@ -1299,6 +1312,7 @@ func _toggle_pan_mode() -> void:
func _set_pan_mode(enabled: bool) -> void:
if enabled:
_set_demolition_mode(false, false)
_clear_build_selection(false)
_set_excavation_mode(false, false)
_set_build_palette_open(false)
@@ -1309,6 +1323,7 @@ func _set_pan_mode(enabled: bool) -> void:
func _set_excavation_mode(enabled: bool, announce := true) -> void:
if enabled:
_set_demolition_mode(false, false)
_set_pan_mode(false)
_excavation_mode = enabled
if excavation_button != null:
@@ -1354,6 +1369,9 @@ func _rotate_build_preview() -> void:
func _on_map_cell_clicked(cell: Vector3i) -> void:
if _audio_feedback != null:
_audio_feedback.request_click()
if _demolition_mode:
_preview_demolition(cell)
return
if _excavation_mode:
_start_excavation(cell)
return
@@ -2331,6 +2349,8 @@ func _apply_loaded_interface(result: Dictionary) -> void:
if _audio_feedback != null:
_audio_feedback.begin_loaded_epoch(_current_audio_foreground())
_pending_build_commands.clear()
_pending_demolition_commands.clear()
_set_demolition_mode(false, false)
_pending_excavation_commands.clear()
_pending_hire_commands.clear()
_pending_elevator_commands.clear()
@@ -2570,6 +2590,10 @@ func _on_snapshot_published(_snapshot: Dictionary = {}, _digest: String = "") ->
func _on_command_completed(result: Variant) -> void:
if result == null:
return
if _pending_demolition_commands.has(int(result.command_id)):
_pending_demolition_commands.erase(int(result.command_id))
_show_demolition_result(result)
return
if _pending_related_commands.has(int(result.command_id)):
_pending_related_commands.erase(int(result.command_id))
_set_status("関連施設の設定を反映しました。" if result.is_success() else result.message, result.is_success())
@@ -3083,3 +3107,70 @@ func _submit_ui_command(
if _audio_feedback != null:
return _audio_feedback.submit_command(command_type, payload, actor_id, target_id, priority, execute_at, idempotency_key)
return _runtime.call(&"submit_command", command_type, payload, actor_id, target_id, priority, execute_at, idempotency_key)
func _toggle_demolition_mode() -> void:
_set_demolition_mode(not _demolition_mode)
func _set_demolition_mode(enabled: bool, announce := true) -> void:
if enabled:
_set_pan_mode(false)
_set_excavation_mode(false, false)
_clear_build_selection(false)
_demolition_mode = enabled
_demolition_target = &""
if demolition_dialog != null:
demolition_dialog.hide()
if demolition_button != null:
demolition_button.set_pressed_no_signal(enabled)
if world_preview != null:
world_preview.set_demolition_mode(enabled)
if announce:
_set_status("撤去する施設のマスを選択してください。確認画面で取り消せます。" if enabled else "撤去モードを解除しました。", true, true)
func _preview_demolition(cell: Vector3i) -> void:
# Selection only; Runtime owns eligibility, occupancy and refunds.
_demolition_target = world_preview.facility_at_canvas(world_preview.cell_to_canvas(cell))
world_preview.selected_entity_id = _demolition_target
if demolition_dialog == null:
demolition_dialog = ConfirmationDialog.new()
demolition_dialog.name = "DemolitionDialog"
demolition_dialog.title = "施設の撤去"
demolition_dialog.ok_button_text = "撤去する"
demolition_dialog.cancel_button_text = "戻る"
demolition_dialog.confirmed.connect(_confirm_demolition)
demolition_dialog.canceled.connect(_cancel_demolition)
add_child(demolition_dialog)
_apply_button_style(demolition_dialog.get_ok_button())
_apply_button_style(demolition_dialog.get_cancel_button())
demolition_dialog.dialog_text = "座標 (%d, %d / %d)\n施設: %s\n\n撤去を指示しますか?" % [cell.x, cell.y, cell.z, String(_demolition_target)]
demolition_dialog.popup_centered(Vector2i(420, 210))
func _cancel_demolition() -> void:
_demolition_target = &""
_set_status("撤去を取り消しました。", true, true)
func _confirm_demolition() -> void:
if not _demolition_mode:
return
if _runtime == null or not _runtime.has_method(&"submit_command"):
_set_status("Simulation Runtimeへ接続できません。", false)
return
var target := _demolition_target
_demolition_target = &""
var result: CommandResult = _runtime.submit_command(&"demolish_facility", {&"instance_id": target})
# Paused play returns execution synchronously; running play returns acceptance.
if result.is_success() and _runtime.command_queue.get_processed_result(result.command_id) == null:
_pending_demolition_commands[result.command_id] = target
_show_demolition_result(result)
func _show_demolition_result(result: CommandResult) -> void:
var code := String(CommandResult.Code.keys()[result.code])
var reason := String(result.details.get(&"reason", ""))
_set_status("%s | %s | %s" % [code, reason, result.message], result.is_success())
_refresh_selected_entity()
world_preview.queue_redraw()
+13 -1
View File
@@ -51,6 +51,7 @@ var selected_entity_id: StringName = &"":
var build_definition: Variant = null
var build_rotation := 0
var excavation_mode := false
var demolition_mode := false
var visual_theme: VisualThemeProfile = null
var zoom_level := 1.0
@@ -134,6 +135,8 @@ func set_visual_theme(profile: VisualThemeProfile) -> void:
func set_build_definition(definition: Variant, rotation := 0) -> void:
if definition != null:
demolition_mode = false
if definition != null and excavation_mode:
set_excavation_mode(false)
build_definition = definition
@@ -157,6 +160,8 @@ func set_build_rotation(value: int) -> void:
func set_excavation_mode(enabled: bool) -> void:
if enabled:
demolition_mode = false
if excavation_mode == enabled:
_update_excavation_preview()
return
@@ -461,7 +466,7 @@ func _gui_input(event: InputEvent) -> void:
var cell: Variant = canvas_to_cell(event.position)
if not cell is Vector3i:
return
if build_definition != null or excavation_mode:
if build_definition != null or excavation_mode or demolition_mode:
cell_clicked.emit(cell)
accept_event()
return
@@ -1685,3 +1690,10 @@ func _draw_build_connection(report: Dictionary) -> void:
var message := "入口への経路接続済" if status == &"CONNECTED" else "入口への経路未接続" if status == &"DISCONNECTED" else "入口・経路を確認できません"
draw_string(ThemeDB.fallback_font, target+Vector2(8,-12), message,
HORIZONTAL_ALIGNMENT_LEFT, -1, 13, color)
func set_demolition_mode(enabled: bool) -> void:
demolition_mode = enabled
if enabled:
clear_build_definition()
set_excavation_mode(false)
queue_redraw()