Connect physical elevators and staff commutes to construction, saves, and cutaway UI
This commit is contained in:
@@ -35,6 +35,7 @@ const FACILITY_STATE_NAMES := [
|
||||
"低下運転",
|
||||
"営業中",
|
||||
]
|
||||
const ELEVATOR_PHASE_NAMES := {&"IDLE": "待機", &"PICKUP": "迎車中", &"BOARDING": "乗車中", &"TRAVEL": "運行中", &"ALIGHTING": "降車中"}
|
||||
const FACILITY_REASON_NAMES := {
|
||||
&"BROKEN": "故障",
|
||||
&"NO_ACCESS": "経路なし",
|
||||
@@ -125,6 +126,9 @@ var staff_candidate_buttons: Dictionary = {}
|
||||
var selected_heading_label: Label
|
||||
var selected_detail_label: Label
|
||||
var selected_entity_icon: TextureRect
|
||||
var selected_elevator_controls: VBoxContainer
|
||||
var elevator_operation_button: Button
|
||||
var elevator_operation_hint: Label
|
||||
var build_status_label: Label
|
||||
var build_buttons: Dictionary = {}
|
||||
var navigation_buttons: Dictionary = {}
|
||||
@@ -152,6 +156,8 @@ var _build_rotation := 0
|
||||
var _build_sequence := 1
|
||||
var _excavation_sequence := 1
|
||||
var _hire_sequence := 1
|
||||
var _elevator_sequence := 1
|
||||
var _pending_elevator_commands: Dictionary = {}
|
||||
var _pending_build_commands: Dictionary = {}
|
||||
var _excavation_mode := false
|
||||
var _pending_excavation_commands: Dictionary = {}
|
||||
@@ -533,6 +539,18 @@ func _create_side_panel() -> Control:
|
||||
selected_detail_label.add_theme_color_override("font_color", Color("4d341f"))
|
||||
selected_detail_label.add_theme_font_size_override("font_size", 13)
|
||||
selected_row.add_child(selected_detail_label)
|
||||
selected_elevator_controls = VBoxContainer.new()
|
||||
selected_elevator_controls.name = "SelectedElevatorControls"
|
||||
selected_elevator_controls.visible = false
|
||||
column.add_child(selected_elevator_controls)
|
||||
elevator_operation_button = _button("昇降機を停止", _on_elevator_operation_pressed, 160)
|
||||
elevator_operation_button.name = "ElevatorOperationButton"
|
||||
selected_elevator_controls.add_child(elevator_operation_button)
|
||||
elevator_operation_hint = Label.new()
|
||||
elevator_operation_hint.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
elevator_operation_hint.add_theme_font_size_override("font_size", 12)
|
||||
elevator_operation_hint.add_theme_color_override("font_color", Color("654d37"))
|
||||
selected_elevator_controls.add_child(elevator_operation_hint)
|
||||
|
||||
operating_ledger_panel = OperatingLedgerPanelScript.new()
|
||||
root_column.add_child(operating_ledger_panel)
|
||||
@@ -1138,6 +1156,8 @@ func _on_map_cell_clicked(cell: Vector3i) -> void:
|
||||
_selected_entity_id = &""
|
||||
_selected_entity_kind = &""
|
||||
world_preview.selected_entity_id = &""
|
||||
selected_elevator_controls.visible = false
|
||||
selected_entity_icon.texture = null
|
||||
selected_heading_label.text = "選択中のマス"
|
||||
selected_detail_label.text = "座標 (%d, %d)\nレイヤー %s\n\n施設のないマスです。" % [cell.x, cell.y, "FRONT / 表層" if cell.z == 0 else "BACK / 裏層"]
|
||||
return
|
||||
@@ -1499,7 +1519,9 @@ func _operations_dashboard_text() -> String:
|
||||
|
||||
|
||||
func _refresh_selected_entity() -> void:
|
||||
selected_elevator_controls.visible = false
|
||||
if _selected_entity_id.is_empty():
|
||||
_move_selected_detail_first(false)
|
||||
selected_entity_icon.texture = null
|
||||
selected_heading_label.text = "掘削モード" if _excavation_mode else "選択中の施設"
|
||||
selected_detail_label.text = (
|
||||
@@ -1508,11 +1530,18 @@ func _refresh_selected_entity() -> void:
|
||||
)
|
||||
return
|
||||
if _selected_entity_kind == &"construction":
|
||||
_move_selected_detail_first(false)
|
||||
_refresh_selected_construction()
|
||||
return
|
||||
if _selected_entity_kind == &"excavation":
|
||||
_move_selected_detail_first(false)
|
||||
_refresh_selected_excavation()
|
||||
return
|
||||
var shaft := _selected_elevator_report()
|
||||
if not shaft.is_empty():
|
||||
_refresh_selected_elevator(shaft)
|
||||
return
|
||||
_move_selected_detail_first(false)
|
||||
var facility_service: Variant = _service(&"facility_service")
|
||||
if facility_service == null or not facility_service.has_method(&"get_instance"):
|
||||
selected_detail_label.text = "施設サービスを利用できません。"
|
||||
@@ -1552,6 +1581,106 @@ func _refresh_selected_entity() -> void:
|
||||
)
|
||||
|
||||
|
||||
func _selected_elevator_report() -> Dictionary:
|
||||
if _selected_entity_kind != &"facility" or _selected_entity_id.is_empty():
|
||||
return {}
|
||||
var transport: Variant = _service(&"elevators")
|
||||
if transport == null or not transport.has_method(&"get_report"):
|
||||
return {}
|
||||
for shaft: Dictionary in transport.call(&"get_report").get(&"shafts", []):
|
||||
if (shaft.get(&"module_ids", []) as Array).has(_selected_entity_id):
|
||||
return shaft
|
||||
return {}
|
||||
|
||||
|
||||
func _refresh_selected_elevator(shaft: Dictionary) -> void:
|
||||
_move_selected_detail_first(true)
|
||||
var construction_facility := _construction_facility(_selected_entity_id)
|
||||
var definition_id := StringName(construction_facility.get(&"definition_id", &"guest_elevator"))
|
||||
var definition: Variant = _facility_definition(definition_id)
|
||||
selected_heading_label.text = String(_definition_value(definition, &"display_name", "昇降機"))
|
||||
selected_entity_icon.texture = visual_theme.facility_icon(definition_id) if visual_theme != null else null
|
||||
var powered := bool(shaft.get(&"powered", true))
|
||||
var operator_open := bool(shaft.get(&"operator_open", true))
|
||||
var state_text := String(ELEVATOR_PHASE_NAMES.get(StringName(shaft.get(&"phase", &"IDLE")), "待機"))
|
||||
if not operator_open:
|
||||
state_text = "手動停止"
|
||||
elif not powered:
|
||||
state_text = "魔力供給なし"
|
||||
var floor_index := int(shaft.get(&"current_floor", 0))
|
||||
var target_index := int(shaft.get(&"boarding_floor", floor_index) if StringName(shaft.get(&"phase", &"IDLE")) == &"PICKUP" else shaft.get(&"target_floor", floor_index))
|
||||
var stops: Array = shaft.get(&"stops", [])
|
||||
var stop_text := "—"
|
||||
if not stops.is_empty():
|
||||
stop_text = "%s 〜 %s" % [_elevator_floor_name(stops.front().y), _elevator_floor_name(stops.back().y)]
|
||||
selected_detail_label.text = (
|
||||
"状態 %s\n" % state_text
|
||||
+ "現在階 %s 目的階 %s\n" % [_elevator_floor_name(floor_index), _elevator_floor_name(target_index)]
|
||||
+ "乗客 %d / %d人 待機 %d人\n" % [int(shaft.get(&"passenger_count", 0)), int(shaft.get(&"capacity", 0)), int(shaft.get(&"waiting_count", 0))]
|
||||
+ "停止階 %s\n" % stop_text
|
||||
+ "魔力 %s %s" % ["供給中" if powered else "不足", "客・従業員用" if definition_id == &"guest_elevator" else "従業員・物資用"]
|
||||
)
|
||||
selected_elevator_controls.visible = true
|
||||
elevator_operation_button.disabled = _pending_elevator_commands.values().has(shaft.get(&"shaft_id", &""))
|
||||
elevator_operation_button.text = "指示を受理済み…" if elevator_operation_button.disabled else ("昇降機を停止" if operator_open else "運行を再開")
|
||||
elevator_operation_hint.text = "停止すると最寄りの階で降車し、待機中の呼び出しを解除します。" if operator_open else ("再開すると新しい呼び出しを受け付けます。" if powered else "魔力が供給されると運行を再開できます。")
|
||||
|
||||
|
||||
func _move_selected_detail_first(first: bool) -> void:
|
||||
var column := selected_heading_label.get_parent()
|
||||
var selected_row := selected_detail_label.get_parent()
|
||||
# The transport action fits without scrolling; other management views keep
|
||||
# their existing staff-first layout.
|
||||
var desired_index := 0 if first else column.get_child_count()-3
|
||||
if selected_heading_label.get_index() == desired_index:
|
||||
return
|
||||
column.move_child(selected_heading_label, 0 if first else -1)
|
||||
column.move_child(selected_row, 1 if first else -1)
|
||||
column.move_child(selected_elevator_controls, 2 if first else -1)
|
||||
|
||||
|
||||
func _elevator_floor_name(floor_index: int) -> String:
|
||||
return "%dF" % (floor_index+1) if floor_index >= 0 else "B%d" % -floor_index
|
||||
|
||||
|
||||
func _on_elevator_operation_pressed() -> void:
|
||||
var shaft := _selected_elevator_report()
|
||||
if shaft.is_empty() or _runtime == null:
|
||||
return
|
||||
var shaft_id := StringName(shaft[&"shaft_id"])
|
||||
if _pending_elevator_commands.values().has(shaft_id):
|
||||
return
|
||||
var key := StringName("ui.elevator.%08d" % _elevator_sequence)
|
||||
_elevator_sequence += 1
|
||||
var open_value := not bool(shaft.get(&"operator_open", true))
|
||||
var result: Variant = _runtime.call(&"submit_command", &"set_elevator_operation", {&"shaft_id": shaft_id, &"operator_open": open_value}, &"player", &"", 50, -1, key)
|
||||
if result == null or not result.is_success():
|
||||
_set_status("昇降機の指示を反映できませんでした。", false)
|
||||
return
|
||||
if not result.details.has(&"shaft_id"):
|
||||
_pending_elevator_commands[int(result.command_id)] = shaft_id
|
||||
_set_status("昇降機の運行指示を受理しました。", true)
|
||||
else:
|
||||
var message := "昇降機を停止しました。"
|
||||
if open_value:
|
||||
message = "昇降機の運行を再開しました。" if bool(shaft.get(&"powered", true)) else "運行を許可しました。魔力の供給待ちです。"
|
||||
_set_status(message, true)
|
||||
_refresh_selected_entity()
|
||||
|
||||
|
||||
func _synchronize_elevator_pending() -> void:
|
||||
var queue: Variant = _service(&"command_queue")
|
||||
if queue == null:
|
||||
return
|
||||
if queue.pending_count() == 0:
|
||||
_pending_elevator_commands.clear()
|
||||
return
|
||||
_pending_elevator_commands.clear()
|
||||
for command: Dictionary in queue.create_snapshot().get("pending", []):
|
||||
if StringName(command.get("command_type", &"")) == &"set_elevator_operation":
|
||||
_pending_elevator_commands[int(command.get("command_id", 0))] = StringName((command.get("payload", {}) as Dictionary).get(&"shaft_id", &""))
|
||||
|
||||
|
||||
func _refresh_selected_construction() -> void:
|
||||
var construction: Variant = _service(&"construction_service")
|
||||
if construction == null or not construction.has_method(&"get_job"):
|
||||
@@ -1764,6 +1893,7 @@ func _load_manual() -> void:
|
||||
_pending_build_commands.clear()
|
||||
_pending_excavation_commands.clear()
|
||||
_pending_hire_commands.clear()
|
||||
_pending_elevator_commands.clear()
|
||||
_synchronize_ui_command_state()
|
||||
if staff_management_panel != null:
|
||||
staff_management_panel.refresh()
|
||||
@@ -1820,6 +1950,8 @@ func _synchronize_ui_command_state() -> void:
|
||||
if command_id <= 0:
|
||||
continue
|
||||
match command_type:
|
||||
&"set_elevator_operation":
|
||||
_pending_elevator_commands[command_id] = StringName(payload.get(&"shaft_id", &""))
|
||||
&"build_facility":
|
||||
var definition_id := StringName(payload.get(&"definition_id", payload.get("definition_id", &"")))
|
||||
if not definition_id.is_empty():
|
||||
@@ -1850,9 +1982,12 @@ func _advance_ui_sequence_from_key(key: String) -> void:
|
||||
_excavation_sequence = maxi(_excavation_sequence, next_sequence)
|
||||
elif key.begins_with("ui.hire."):
|
||||
_hire_sequence = maxi(_hire_sequence, next_sequence)
|
||||
elif key.begins_with("ui.elevator."):
|
||||
_elevator_sequence = maxi(_elevator_sequence, next_sequence)
|
||||
|
||||
|
||||
func _on_snapshot_published(_snapshot: Dictionary, _digest: String) -> void:
|
||||
_synchronize_elevator_pending()
|
||||
_refresh_dashboard()
|
||||
_update_pause_and_speed()
|
||||
|
||||
@@ -1860,6 +1995,11 @@ func _on_snapshot_published(_snapshot: Dictionary, _digest: String) -> void:
|
||||
func _on_command_completed(result: Variant) -> void:
|
||||
if result == null:
|
||||
return
|
||||
if _pending_elevator_commands.has(int(result.command_id)):
|
||||
_pending_elevator_commands.erase(int(result.command_id))
|
||||
_set_status("昇降機の運行設定を反映しました。" if result.is_success() else "昇降機の運行設定を反映できませんでした。", result.is_success())
|
||||
_refresh_selected_entity()
|
||||
return
|
||||
if _pending_hire_commands.has(int(result.command_id)):
|
||||
var candidate_id := StringName(_pending_hire_commands[int(result.command_id)])
|
||||
_pending_hire_commands.erase(int(result.command_id))
|
||||
|
||||
@@ -49,6 +49,8 @@ var show_grid := false
|
||||
var _animation_time := 0.0
|
||||
var _animation_frame := -1
|
||||
var _actor_tracks: Dictionary = {}
|
||||
var _elevator_tracks: Dictionary = {}
|
||||
var _boarded_actor_ids: Dictionary = {}
|
||||
var _dragging := false
|
||||
|
||||
var _runtime: Variant = null
|
||||
@@ -74,6 +76,8 @@ func set_runtime(value: Variant) -> void:
|
||||
_disconnect_runtime()
|
||||
_runtime = value
|
||||
_actor_tracks.clear()
|
||||
_elevator_tracks.clear()
|
||||
_boarded_actor_ids.clear()
|
||||
_connect_runtime()
|
||||
queue_redraw()
|
||||
_update_build_preview()
|
||||
@@ -349,6 +353,7 @@ func _draw() -> void:
|
||||
if show_grid:
|
||||
_draw_congestion_overlay(bounds)
|
||||
_draw_world_entity_icons()
|
||||
_draw_elevators()
|
||||
_draw_construction_labels()
|
||||
_draw_facility_labels()
|
||||
_draw_queue_badges()
|
||||
@@ -611,6 +616,93 @@ func _draw_facility_labels() -> void:
|
||||
draw_string(ThemeDB.fallback_font,at+Vector2(4,12),label,HORIZONTAL_ALIGNMENT_CENTER,label_width-8,font_size,Color("f0e2b9"))
|
||||
|
||||
|
||||
func _draw_elevators() -> void:
|
||||
_boarded_actor_ids.clear()
|
||||
var transport: Variant = _service(&"elevators")
|
||||
if transport == null or not transport.has_method(&"get_report"):
|
||||
_elevator_tracks.clear()
|
||||
return
|
||||
var report_value: Variant = transport.call(&"get_report")
|
||||
if not report_value is Dictionary:
|
||||
return
|
||||
var alive: Dictionary = {}
|
||||
var p := _cell_dimensions().x/16.0
|
||||
for value: Variant in report_value.get(&"shafts", []):
|
||||
if not value is Dictionary:
|
||||
continue
|
||||
var shaft: Dictionary = value
|
||||
var stops := _cells_from_serialized(shaft.get(&"stops", []))
|
||||
if stops.is_empty():
|
||||
continue
|
||||
var shaft_id := StringName(shaft.get(&"shaft_id", &""))
|
||||
alive[shaft_id] = true
|
||||
var passengers: Array = shaft.get(&"boarded", [])
|
||||
for actor_id: Variant in passengers:
|
||||
_boarded_actor_ids[_elevator_actor_key(String(actor_id))] = true
|
||||
var floor_value := float(shaft.get(&"visual_floor", shaft.get(&"current_floor", stops[0].y)))
|
||||
var visual_floor := _tracked_elevator_floor(shaft_id, floor_value)
|
||||
if stops[0].z != layer_mode:
|
||||
continue
|
||||
var origin := get_cell_rect(stops[0])
|
||||
var width := maxi(int(shaft.get(&"width", 2)), 1)
|
||||
var baseline := origin.end.y-float(visual_floor-stops[0].y)*_cell_dimensions().y-3*p
|
||||
var cabin := Rect2(Vector2(origin.position.x+4*p,baseline-19*p).round(),Vector2(width*_cell_dimensions().x-8*p,19*p))
|
||||
if not cabin.intersects(Rect2(Vector2.ZERO,size)):
|
||||
continue
|
||||
var operational := bool(shaft.get(&"operational", true))
|
||||
var phase := StringName(shaft.get(&"phase", &"IDLE"))
|
||||
var doors_open := operational and phase in [&"IDLE", &"BOARDING", &"ALIGHTING"]
|
||||
PixelArt.elevator_cabin(self,cabin,p,layer_mode==LayerMode.BACK,operational)
|
||||
var visible_count := mini(passengers.size(), maxi(width*2-1,1))
|
||||
for index: int in range(visible_count):
|
||||
var actor_key := _elevator_actor_key(String(passengers[index]))
|
||||
var is_staff := actor_key.begins_with("staff/")
|
||||
var person: Variant = null
|
||||
var people: Variant = _service(&"staff_service" if is_staff else &"guest_service")
|
||||
var getter := &"get_staff" if is_staff else &"get_guest"
|
||||
if people != null and people.has_method(getter):
|
||||
person = people.call(getter,StringName(actor_key.get_slice("/",1)))
|
||||
var carrying := is_staff and person != null and not String(person.carried_inventory_id).is_empty()
|
||||
var state := int(person.state) if person != null else 0
|
||||
var x := cabin.position.x+5*p+float(index)*(cabin.size.x-10*p)/maxf(float(visible_count-1),1.0)
|
||||
if visible_count == 1:
|
||||
x = cabin.get_center().x
|
||||
var center := Vector2(x,cabin.end.y-_cell_dimensions().y*0.5)
|
||||
_draw_pixel_actor(center,actor_key,is_staff,state,false,carrying,&"",true)
|
||||
PixelArt.elevator_gate(self,cabin,p,doors_open)
|
||||
var waiting := int(shaft.get(&"waiting_count",0))
|
||||
if waiting > 0:
|
||||
var badge := Vector2(cabin.end.x+2*p,cabin.position.y+2*p)
|
||||
draw_rect(Rect2(badge,Vector2(20,12)*p),Color("76593f"))
|
||||
draw_string(ThemeDB.fallback_font,badge+Vector2(2,9)*p,"待%d" % waiting,HORIZONTAL_ALIGNMENT_LEFT,-1,clampi(int(7*p),8,13),Color("f6e8bc"))
|
||||
for shaft_id: Variant in _elevator_tracks.keys():
|
||||
if not alive.has(shaft_id):
|
||||
_elevator_tracks.erase(shaft_id)
|
||||
|
||||
|
||||
func _elevator_actor_key(actor_id: String) -> String:
|
||||
if actor_id.begins_with("guest:"):
|
||||
return "guest/" + actor_id.trim_prefix("guest:")
|
||||
if actor_id.begins_with("staff:"):
|
||||
return "staff/" + actor_id.trim_prefix("staff:")
|
||||
return actor_id
|
||||
|
||||
|
||||
func _tracked_elevator_floor(shaft_id: StringName, current_floor: float) -> float:
|
||||
if not _elevator_tracks.has(shaft_id):
|
||||
_elevator_tracks[shaft_id] = {&"floor":current_floor,&"from":current_floor,&"at":_animation_time}
|
||||
var track: Dictionary = _elevator_tracks[shaft_id]
|
||||
if not is_equal_approx(float(track[&"floor"]),current_floor):
|
||||
track[&"from"] = float(track[&"floor"])
|
||||
track[&"floor"] = current_floor
|
||||
track[&"at"] = _animation_time
|
||||
var clock := get_node_or_null("/root/GameClock")
|
||||
if clock != null and bool(clock.get("paused")):
|
||||
return current_floor
|
||||
var t := clampf((_animation_time-float(track[&"at"]))/0.42,0.0,1.0)
|
||||
return lerpf(float(track[&"from"]),current_floor,t)
|
||||
|
||||
|
||||
func _draw_actors() -> void:
|
||||
var counts: Dictionary = {}
|
||||
var alive: Dictionary = {}
|
||||
@@ -622,6 +714,9 @@ func _draw_actors() -> void:
|
||||
continue
|
||||
var key := "guest/"+String(guest.guest_id)
|
||||
alive[key] = true
|
||||
if _boarded_actor_ids.has(key):
|
||||
_actor_tracks.erase(key)
|
||||
continue
|
||||
var position := _tracked_actor_position(key,guest.current_cell)
|
||||
if guest.current_cell.z==layer_mode:
|
||||
var receiving := not String(guest.current_service_id).is_empty()
|
||||
@@ -637,6 +732,9 @@ func _draw_actors() -> void:
|
||||
continue
|
||||
var key := "staff/"+String(staff.staff_id)
|
||||
alive[key] = true
|
||||
if _boarded_actor_ids.has(key):
|
||||
_actor_tracks.erase(key)
|
||||
continue
|
||||
var position := _tracked_actor_position(key,staff.current_cell)
|
||||
if staff.current_cell.z==layer_mode:
|
||||
_draw_pixel_actor(position+_actor_offset(staff.current_cell,counts),key,true,int(staff.state),false,not String(staff.carried_inventory_id).is_empty(),staff.role_id)
|
||||
@@ -690,7 +788,7 @@ func _guest_activity(guest: Variant) -> StringName:
|
||||
return StringName(facility.definition_id) if facility != null else &""
|
||||
|
||||
|
||||
func _draw_pixel_actor(center: Vector2, key: String, staff: bool, state: int, receiving: bool, carrying: bool, activity: StringName = &"") -> void:
|
||||
func _draw_pixel_actor(center: Vector2, key: String, staff: bool, state: int, receiving: bool, carrying: bool, activity: StringName = &"", riding := false) -> void:
|
||||
var texture := visual_theme.pixel_dungeon_tiles if visual_theme != null else null
|
||||
if texture==null:
|
||||
return
|
||||
@@ -700,7 +798,7 @@ func _draw_pixel_actor(center: Vector2, key: String, staff: bool, state: int, re
|
||||
var moving: bool = track.get(&"cell",Vector3i.ZERO)!=track.get(&"from",Vector3i.ZERO) and _animation_time-float(track.get(&"at",0.0))<0.42
|
||||
var clock := get_node_or_null("/root/GameClock")
|
||||
var paused := clock != null and bool(clock.get("paused"))
|
||||
moving = moving and not paused
|
||||
moving = moving and not paused and not riding
|
||||
var variant := int(absi(key.hash()))%5
|
||||
var tile_id := (96 if staff else 84)+variant
|
||||
var frame := int(_animation_time*9.0+variant)%4
|
||||
@@ -729,7 +827,7 @@ func _draw_pixel_actor(center: Vector2, key: String, staff: bool, state: int, re
|
||||
draw_rect(Rect2(at+Vector2(7,8)*p,Vector2(2,3)*p),Color("81c6ba"))
|
||||
if carrying:
|
||||
PixelArt.tile(self,texture,89,Rect2(at+Vector2(9,6)*p,Vector2(9,9)*p))
|
||||
var working := staff and state==StaffRuntime.State.WORKING
|
||||
var working := staff and state==StaffRuntime.State.WORKING and not riding
|
||||
var resting := receiving and activity==&"standard_room"
|
||||
if resting:
|
||||
var lift := float(int(_animation_time*2)%3) if not paused else 0.0
|
||||
@@ -741,7 +839,7 @@ func _draw_pixel_actor(center: Vector2, key: String, staff: bool, state: int, re
|
||||
if receiving and activity in [&"cafeteria",&"tavern"]:
|
||||
var lift := p if not paused and int(_animation_time*3)%2==0 else 0.0
|
||||
draw_rect(Rect2(at+Vector2(11*p,8*p-lift),Vector2(3*p,2*p)),Color("e6d7b5"))
|
||||
var waiting := not staff and state==GuestRuntime.State.QUEUING
|
||||
var waiting := not staff and state==GuestRuntime.State.QUEUING and not riding
|
||||
if (receiving and not resting) or working or waiting:
|
||||
var badge := Rect2(at+Vector2(10,-4)*p,Vector2(6,5)*p)
|
||||
draw_rect(badge,Color("f2e9cb"))
|
||||
|
||||
Reference in New Issue
Block a user