Files
whale-town/scripts/CharacterPersonalization.gd
2025-12-05 19:00:14 +08:00

293 lines
8.6 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 角色个性化管理器
## 处理角色外观、属性、技能和成就系统
## 这是一个静态工具类,所有方法都是静态的
# 预定义的个性特征
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)