293 lines
8.6 KiB
GDScript
293 lines
8.6 KiB
GDScript
## 角色个性化管理器
|
||
## 处理角色外观、属性、技能和成就系统
|
||
## 这是一个静态工具类,所有方法都是静态的
|
||
|
||
# 预定义的个性特征
|
||
const PERSONALITY_TRAITS = [
|
||
"friendly", "curious", "creative", "analytical", "energetic",
|
||
"calm", "adventurous", "thoughtful", "optimistic", "practical",
|
||
"artistic", "logical", "social", "independent", "collaborative"
|
||
]
|
||
|
||
# 预定义的活动类型
|
||
const ACTIVITIES = [
|
||
"exploring", "learning", "creating", "socializing", "problem_solving",
|
||
"teaching", "researching", "building", "organizing", "innovating"
|
||
]
|
||
|
||
# 成就定义
|
||
const ACHIEVEMENTS = {
|
||
"first_login": {
|
||
"name": "初来乍到",
|
||
"description": "首次登录游戏",
|
||
"icon": "🎉"
|
||
},
|
||
"social_butterfly": {
|
||
"name": "社交达人",
|
||
"description": "与10个不同角色对话",
|
||
"icon": "🦋"
|
||
},
|
||
"explorer": {
|
||
"name": "探索者",
|
||
"description": "访问场景的所有区域",
|
||
"icon": "🗺️"
|
||
},
|
||
"communicator": {
|
||
"name": "沟通专家",
|
||
"description": "发送100条消息",
|
||
"icon": "💬"
|
||
},
|
||
"veteran": {
|
||
"name": "老玩家",
|
||
"description": "连续登录7天",
|
||
"icon": "⭐"
|
||
},
|
||
"level_5": {
|
||
"name": "小有成就",
|
||
"description": "达到5级",
|
||
"icon": "🏆"
|
||
},
|
||
"level_10": {
|
||
"name": "经验丰富",
|
||
"description": "达到10级",
|
||
"icon": "👑"
|
||
}
|
||
}
|
||
|
||
# 心情对应的表情符号
|
||
const MOOD_EMOJIS = {
|
||
"happy": "😊",
|
||
"sad": "😢",
|
||
"excited": "🤩",
|
||
"tired": "😴",
|
||
"neutral": "😐"
|
||
}
|
||
|
||
# 状态对应的颜色
|
||
const STATUS_COLORS = {
|
||
"active": Color.GREEN,
|
||
"busy": Color.ORANGE,
|
||
"away": Color.YELLOW,
|
||
"offline": Color.GRAY
|
||
}
|
||
|
||
## 生成随机外观
|
||
static func generate_random_appearance() -> Dictionary:
|
||
## 生成随机的角色外观
|
||
## @return: 外观数据字典
|
||
var colors = [
|
||
"#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEAA7",
|
||
"#DDA0DD", "#98D8C8", "#F7DC6F", "#BB8FCE", "#85C1E9"
|
||
]
|
||
|
||
return {
|
||
"sprite": "character_01",
|
||
"color": "#FFFFFF",
|
||
"body_color": colors[randi() % colors.size()],
|
||
"head_color": "#F5E6D3",
|
||
"hair_color": ["#8B4513", "#000000", "#FFD700", "#FF4500", "#4B0082"][randi() % 5],
|
||
"clothing_color": colors[randi() % colors.size()]
|
||
}
|
||
|
||
## 生成随机个性
|
||
static func generate_random_personality() -> Dictionary:
|
||
## 生成随机的角色个性
|
||
## @return: 个性数据字典
|
||
var traits = []
|
||
var num_traits = randi_range(2, 4)
|
||
|
||
for i in range(num_traits):
|
||
var trait_in = PERSONALITY_TRAITS[randi() % PERSONALITY_TRAITS.size()]
|
||
if trait_in not in traits:
|
||
traits.append(trait_in)
|
||
|
||
return {
|
||
"traits": traits,
|
||
"bio": "",
|
||
"favorite_activity": ACTIVITIES[randi() % ACTIVITIES.size()]
|
||
}
|
||
|
||
## 生成随机属性
|
||
static func generate_random_attributes() -> Dictionary:
|
||
## 生成随机的角色属性
|
||
## @return: 属性数据字典
|
||
return {
|
||
"charisma": randi_range(3, 7),
|
||
"intelligence": randi_range(3, 7),
|
||
"creativity": randi_range(3, 7),
|
||
"energy": randi_range(3, 7)
|
||
}
|
||
|
||
## 检查并授予成就
|
||
static func check_achievements(character_data: Dictionary, action: String, value: int = 1) -> Array:
|
||
## 检查并授予成就
|
||
## @param character_data: 角色数据
|
||
## @param action: 触发的动作类型
|
||
## @param value: 动作的值
|
||
## @return: 新获得的成就列表
|
||
var new_achievements = []
|
||
var current_achievements = character_data.get(CharacterData.FIELD_ACHIEVEMENTS, [])
|
||
var achievement_ids = []
|
||
|
||
# 获取已有成就的ID列表
|
||
for achievement in current_achievements:
|
||
achievement_ids.append(achievement.get("id", ""))
|
||
|
||
match action:
|
||
"first_login":
|
||
if "first_login" not in achievement_ids:
|
||
new_achievements.append(_create_achievement("first_login"))
|
||
|
||
"dialogue_sent":
|
||
# 检查消息数量成就
|
||
if value >= 100 and "communicator" not in achievement_ids:
|
||
new_achievements.append(_create_achievement("communicator"))
|
||
|
||
"character_met":
|
||
# 检查社交成就
|
||
if value >= 10 and "social_butterfly" not in achievement_ids:
|
||
new_achievements.append(_create_achievement("social_butterfly"))
|
||
|
||
"level_up":
|
||
var level = character_data.get(CharacterData.FIELD_LEVEL, 1)
|
||
if level >= 5 and "level_5" not in achievement_ids:
|
||
new_achievements.append(_create_achievement("level_5"))
|
||
if level >= 10 and "level_10" not in achievement_ids:
|
||
new_achievements.append(_create_achievement("level_10"))
|
||
|
||
# 添加新成就到角色数据
|
||
for achievement in new_achievements:
|
||
CharacterData.add_achievement(character_data, achievement)
|
||
|
||
return new_achievements
|
||
|
||
## 创建成就对象
|
||
static func _create_achievement(achievement_id: String) -> Dictionary:
|
||
## 创建成就对象
|
||
## @param achievement_id: 成就ID
|
||
## @return: 成就数据字典
|
||
var achievement_data = ACHIEVEMENTS.get(achievement_id, {})
|
||
return {
|
||
"id": achievement_id,
|
||
"name": achievement_data.get("name", "未知成就"),
|
||
"description": achievement_data.get("description", ""),
|
||
"icon": achievement_data.get("icon", "🏆"),
|
||
"earned_at": Time.get_unix_time_from_system()
|
||
}
|
||
|
||
## 计算技能经验奖励
|
||
static func calculate_skill_experience(action: String) -> Dictionary:
|
||
## 根据动作计算技能经验奖励
|
||
## @param action: 动作类型
|
||
## @return: 技能经验字典 {skill_name: exp_amount}
|
||
match action:
|
||
"dialogue_sent":
|
||
return {"communication": 2}
|
||
"problem_solved":
|
||
return {"problem_solving": 5}
|
||
"helped_player":
|
||
return {"collaboration": 3, "leadership": 1}
|
||
"creative_action":
|
||
return {"creativity": 3}
|
||
_:
|
||
return {}
|
||
|
||
## 更新角色技能
|
||
static func update_character_skills(character_data: Dictionary, skill_exp: Dictionary) -> Array:
|
||
## 更新角色技能并返回升级的技能
|
||
## @param character_data: 角色数据
|
||
## @param skill_exp: 技能经验字典
|
||
## @return: 升级的技能列表
|
||
var leveled_skills = []
|
||
|
||
if not character_data.has(CharacterData.FIELD_SKILLS):
|
||
character_data[CharacterData.FIELD_SKILLS] = {
|
||
"communication": 1,
|
||
"problem_solving": 1,
|
||
"leadership": 1,
|
||
"collaboration": 1
|
||
}
|
||
|
||
for skill in skill_exp:
|
||
var current_level = character_data[CharacterData.FIELD_SKILLS].get(skill, 1)
|
||
var exp_needed = current_level * 10 # 每级需要更多经验
|
||
|
||
# 简化:直接根据经验值判断是否升级
|
||
if skill_exp[skill] >= exp_needed and current_level < 10:
|
||
character_data[CharacterData.FIELD_SKILLS][skill] = current_level + 1
|
||
leveled_skills.append({
|
||
"skill": skill,
|
||
"old_level": current_level,
|
||
"new_level": current_level + 1
|
||
})
|
||
|
||
return leveled_skills
|
||
|
||
## 获取心情表情符号
|
||
static func get_mood_emoji(mood: String) -> String:
|
||
## 获取心情对应的表情符号
|
||
## @param mood: 心情名称
|
||
## @return: 表情符号
|
||
return MOOD_EMOJIS.get(mood, "😐")
|
||
|
||
## 获取状态颜色
|
||
static func get_status_color(status: String) -> Color:
|
||
## 获取状态对应的颜色
|
||
## @param status: 状态名称
|
||
## @return: 颜色
|
||
return STATUS_COLORS.get(status, Color.WHITE)
|
||
|
||
## 生成个性化描述
|
||
static func generate_personality_description(character_data: Dictionary) -> String:
|
||
## 生成角色的个性化描述
|
||
## @param character_data: 角色数据
|
||
## @return: 描述文本
|
||
var personality = character_data.get(CharacterData.FIELD_PERSONALITY, {})
|
||
var traits = personality.get("traits", [])
|
||
var activity = personality.get("favorite_activity", "exploring")
|
||
var level = character_data.get(CharacterData.FIELD_LEVEL, 1)
|
||
var mood = character_data.get(CharacterData.FIELD_MOOD, "neutral")
|
||
|
||
var description = "这是一个"
|
||
|
||
if traits.size() > 0:
|
||
description += "、".join(traits) + "的"
|
||
|
||
description += "角色,"
|
||
description += "喜欢" + activity + ","
|
||
description += "目前是" + str(level) + "级,"
|
||
description += "心情" + mood + "。"
|
||
|
||
return description
|
||
|
||
## 自定义外观验证
|
||
static func validate_appearance(appearance: Dictionary) -> bool:
|
||
## 验证外观数据是否有效
|
||
## @param appearance: 外观数据
|
||
## @return: 是否有效
|
||
# 检查必需字段
|
||
var required_fields = ["body_color", "head_color", "hair_color", "clothing_color"]
|
||
for field in required_fields:
|
||
if not appearance.has(field):
|
||
return false
|
||
|
||
# 验证颜色格式
|
||
var color_str = appearance[field]
|
||
if not color_str is String or not color_str.begins_with("#") or color_str.length() != 7:
|
||
return false
|
||
|
||
return true
|
||
|
||
## 应用外观到精灵
|
||
static func apply_appearance_to_sprite(sprite: CharacterSprite, appearance: Dictionary) -> void:
|
||
## 将外观数据应用到角色精灵
|
||
## @param sprite: 角色精灵
|
||
## @param appearance: 外观数据
|
||
if not sprite or not validate_appearance(appearance):
|
||
return
|
||
|
||
var body_color = Color(appearance.get("body_color", "#4A90E2"))
|
||
var head_color = Color(appearance.get("head_color", "#F5E6D3"))
|
||
|
||
sprite.set_character_color(body_color, head_color)
|