289 lines
7.2 KiB
GDScript
289 lines
7.2 KiB
GDScript
extends Node
|
||
class_name CharacterStatusManager
|
||
## 角色状态和心情管理器
|
||
## 处理角色的状态变化、心情系统和相关UI
|
||
|
||
# 状态持续时间(秒)
|
||
const STATUS_DURATIONS = {
|
||
"busy": 300, # 5分钟
|
||
"away": 900, # 15分钟
|
||
}
|
||
|
||
# 心情自动变化的触发条件
|
||
const MOOD_TRIGGERS = {
|
||
"achievement_earned": "happy",
|
||
"level_up": "excited",
|
||
"long_idle": "tired",
|
||
"social_interaction": "happy",
|
||
"problem_solved": "excited"
|
||
}
|
||
|
||
# 心情持续时间(秒)
|
||
const MOOD_DURATION = 600 # 10分钟
|
||
|
||
# 当前管理的角色数据
|
||
var character_data: Dictionary = {}
|
||
var status_timer: Timer
|
||
var mood_timer: Timer
|
||
|
||
# 信号
|
||
signal status_changed(old_status: String, new_status: String)
|
||
signal mood_changed(old_mood: String, new_mood: String)
|
||
signal status_expired(status: String)
|
||
|
||
func _ready():
|
||
"""初始化状态管理器"""
|
||
_setup_timers()
|
||
|
||
## 设置定时器
|
||
func _setup_timers():
|
||
"""设置状态和心情定时器"""
|
||
# 状态定时器
|
||
status_timer = Timer.new()
|
||
status_timer.one_shot = true
|
||
status_timer.timeout.connect(_on_status_timer_timeout)
|
||
add_child(status_timer)
|
||
|
||
# 心情定时器
|
||
mood_timer = Timer.new()
|
||
mood_timer.one_shot = true
|
||
mood_timer.timeout.connect(_on_mood_timer_timeout)
|
||
add_child(mood_timer)
|
||
|
||
## 设置角色数据
|
||
func set_character_data(data: Dictionary):
|
||
"""
|
||
设置要管理的角色数据
|
||
@param data: 角色数据字典
|
||
"""
|
||
character_data = data
|
||
|
||
# 检查当前状态是否需要定时器
|
||
var current_status = data.get(CharacterData.FIELD_STATUS, "active")
|
||
if current_status in STATUS_DURATIONS:
|
||
var duration = STATUS_DURATIONS[current_status]
|
||
status_timer.start(duration)
|
||
|
||
## 设置角色状态
|
||
func set_status(new_status: String, auto_revert: bool = true):
|
||
"""
|
||
设置角色状态
|
||
@param new_status: 新状态
|
||
@param auto_revert: 是否自动恢复到active状态
|
||
"""
|
||
if character_data.is_empty():
|
||
push_error("No character data set")
|
||
return
|
||
|
||
var old_status = character_data.get(CharacterData.FIELD_STATUS, "active")
|
||
|
||
if old_status == new_status:
|
||
return
|
||
|
||
# 更新状态
|
||
CharacterData.set_status(character_data, new_status)
|
||
status_changed.emit(old_status, new_status)
|
||
|
||
# 停止现有定时器
|
||
status_timer.stop()
|
||
|
||
# 如果需要自动恢复且状态有持续时间
|
||
if auto_revert and new_status in STATUS_DURATIONS:
|
||
var duration = STATUS_DURATIONS[new_status]
|
||
status_timer.start(duration)
|
||
|
||
print("Character status changed from %s to %s" % [old_status, new_status])
|
||
|
||
## 设置角色心情
|
||
func set_mood(new_mood: String, duration: float = MOOD_DURATION):
|
||
"""
|
||
设置角色心情
|
||
@param new_mood: 新心情
|
||
@param duration: 心情持续时间(秒)
|
||
"""
|
||
if character_data.is_empty():
|
||
push_error("No character data set")
|
||
return
|
||
|
||
var old_mood = character_data.get(CharacterData.FIELD_MOOD, "neutral")
|
||
|
||
if old_mood == new_mood:
|
||
return
|
||
|
||
# 更新心情
|
||
CharacterData.set_mood(character_data, new_mood)
|
||
mood_changed.emit(old_mood, new_mood)
|
||
|
||
# 设置心情恢复定时器
|
||
mood_timer.stop()
|
||
if new_mood != "neutral" and duration > 0:
|
||
mood_timer.start(duration)
|
||
|
||
print("Character mood changed from %s to %s" % [old_mood, new_mood])
|
||
|
||
## 触发心情变化
|
||
func trigger_mood_change(trigger: String):
|
||
"""
|
||
根据触发条件改变心情
|
||
@param trigger: 触发条件
|
||
"""
|
||
if trigger in MOOD_TRIGGERS:
|
||
var new_mood = MOOD_TRIGGERS[trigger]
|
||
set_mood(new_mood)
|
||
|
||
## 获取当前状态
|
||
func get_current_status() -> String:
|
||
"""获取当前状态"""
|
||
return character_data.get(CharacterData.FIELD_STATUS, "active")
|
||
|
||
## 获取当前心情
|
||
func get_current_mood() -> String:
|
||
"""获取当前心情"""
|
||
return character_data.get(CharacterData.FIELD_MOOD, "neutral")
|
||
|
||
## 获取状态显示文本
|
||
func get_status_display_text() -> String:
|
||
"""获取状态的显示文本"""
|
||
var status = get_current_status()
|
||
var mood = get_current_mood()
|
||
|
||
var status_text = ""
|
||
match status:
|
||
"active":
|
||
status_text = "在线"
|
||
"busy":
|
||
status_text = "忙碌"
|
||
"away":
|
||
status_text = "离开"
|
||
"offline":
|
||
status_text = "离线"
|
||
_:
|
||
status_text = status
|
||
|
||
var personalization = preload("res://scripts/CharacterPersonalization.gd")
|
||
var mood_emoji = personalization.get_mood_emoji(mood)
|
||
return "%s %s" % [status_text, mood_emoji]
|
||
|
||
## 获取状态颜色
|
||
func get_status_color() -> Color:
|
||
"""获取状态对应的颜色"""
|
||
var status = get_current_status()
|
||
var personalization = preload("res://scripts/CharacterPersonalization.gd")
|
||
return personalization.get_status_color(status)
|
||
|
||
## 状态定时器超时
|
||
func _on_status_timer_timeout():
|
||
"""状态定时器超时,恢复到active状态"""
|
||
var current_status = get_current_status()
|
||
set_status("active", false)
|
||
status_expired.emit(current_status)
|
||
|
||
## 心情定时器超时
|
||
func _on_mood_timer_timeout():
|
||
"""心情定时器超时,恢复到neutral心情"""
|
||
set_mood("neutral", 0)
|
||
|
||
## 处理活动事件
|
||
func handle_activity_event(event_type: String, _data: Dictionary = {}):
|
||
"""
|
||
处理角色活动事件,可能触发状态或心情变化
|
||
@param event_type: 事件类型
|
||
@param _data: 事件数据(暂未使用)
|
||
"""
|
||
match event_type:
|
||
"dialogue_started":
|
||
# 开始对话时设为忙碌
|
||
set_status("busy")
|
||
trigger_mood_change("social_interaction")
|
||
|
||
"dialogue_ended":
|
||
# 对话结束后恢复活跃
|
||
set_status("active")
|
||
|
||
"achievement_earned":
|
||
trigger_mood_change("achievement_earned")
|
||
|
||
"level_up":
|
||
trigger_mood_change("level_up")
|
||
|
||
"idle_too_long":
|
||
trigger_mood_change("long_idle")
|
||
|
||
"problem_solved":
|
||
trigger_mood_change("problem_solved")
|
||
|
||
"manual_away":
|
||
# 手动设置离开状态
|
||
set_status("away")
|
||
|
||
"manual_busy":
|
||
# 手动设置忙碌状态
|
||
set_status("busy")
|
||
|
||
## 创建状态选择菜单
|
||
func create_status_menu() -> PopupMenu:
|
||
"""
|
||
创建状态选择菜单
|
||
@return: PopupMenu节点
|
||
"""
|
||
var menu = PopupMenu.new()
|
||
|
||
menu.add_item("🟢 在线", 0)
|
||
menu.add_item("🟡 忙碌", 1)
|
||
menu.add_item("🟠 离开", 2)
|
||
|
||
menu.id_pressed.connect(_on_status_menu_selected)
|
||
|
||
return menu
|
||
|
||
## 状态菜单选择回调
|
||
func _on_status_menu_selected(id: int):
|
||
"""状态菜单选择回调"""
|
||
match id:
|
||
0:
|
||
set_status("active", false)
|
||
1:
|
||
handle_activity_event("manual_busy")
|
||
2:
|
||
handle_activity_event("manual_away")
|
||
|
||
## 创建心情选择菜单
|
||
func create_mood_menu() -> PopupMenu:
|
||
"""
|
||
创建心情选择菜单
|
||
@return: PopupMenu节点
|
||
"""
|
||
var menu = PopupMenu.new()
|
||
|
||
menu.add_item("😊 开心", 0)
|
||
menu.add_item("😢 难过", 1)
|
||
menu.add_item("🤩 兴奋", 2)
|
||
menu.add_item("😴 疲惫", 3)
|
||
menu.add_item("😐 平静", 4)
|
||
|
||
menu.id_pressed.connect(_on_mood_menu_selected)
|
||
|
||
return menu
|
||
|
||
## 心情菜单选择回调
|
||
func _on_mood_menu_selected(id: int):
|
||
"""心情菜单选择回调"""
|
||
var moods = ["happy", "sad", "excited", "tired", "neutral"]
|
||
if id >= 0 and id < moods.size():
|
||
set_mood(moods[id])
|
||
|
||
## 获取状态统计信息
|
||
func get_status_stats() -> Dictionary:
|
||
"""
|
||
获取状态统计信息
|
||
@return: 统计信息字典
|
||
"""
|
||
return {
|
||
"current_status": get_current_status(),
|
||
"current_mood": get_current_mood(),
|
||
"status_display": get_status_display_text(),
|
||
"status_color": get_status_color(),
|
||
"has_active_timer": not status_timer.is_stopped(),
|
||
"timer_remaining": status_timer.time_left if not status_timer.is_stopped() else 0.0
|
||
}
|