创建新工程

This commit is contained in:
moyin
2025-12-05 19:00:14 +08:00
commit ff4fa5fffd
227 changed files with 32804 additions and 0 deletions

View File

@@ -0,0 +1,661 @@
extends Node
class_name RelationshipNetwork
## 角色关系网络
## 管理角色之间的复杂关系和社交网络
# 关系类型枚举
enum RelationshipType {
FRIEND, # 好友
CLOSE_FRIEND, # 密友
ACQUAINTANCE, # 熟人
COLLEAGUE, # 同事
MENTOR, # 导师
STUDENT, # 学生
RIVAL, # 竞争对手
NEUTRAL, # 中性
DISLIKE # 不喜欢
}
# 关系数据结构
class Relationship:
var from_character: String
var to_character: String
var relationship_type: RelationshipType
var strength: float = 0.0 # 关系强度 -100 到 100
var trust_level: float = 0.0 # 信任度 0 到 100
var interaction_history: Array[Dictionary] = []
var shared_experiences: Array[String] = []
var created_at: float
var last_updated: float
var tags: Array[String] = [] # 关系标签
func _init(from_char: String, to_char: String, rel_type: RelationshipType = RelationshipType.NEUTRAL):
from_character = from_char
to_character = to_char
relationship_type = rel_type
created_at = Time.get_unix_time_from_system()
last_updated = created_at
strength = _get_default_strength(rel_type)
trust_level = _get_default_trust(rel_type)
func _get_default_strength(rel_type: RelationshipType) -> float:
match rel_type:
RelationshipType.FRIEND: return 30.0
RelationshipType.CLOSE_FRIEND: return 60.0
RelationshipType.ACQUAINTANCE: return 10.0
RelationshipType.COLLEAGUE: return 20.0
RelationshipType.MENTOR: return 40.0
RelationshipType.STUDENT: return 25.0
RelationshipType.RIVAL: return -20.0
RelationshipType.DISLIKE: return -40.0
_: return 0.0
func _get_default_trust(rel_type: RelationshipType) -> float:
match rel_type:
RelationshipType.FRIEND: return 50.0
RelationshipType.CLOSE_FRIEND: return 80.0
RelationshipType.ACQUAINTANCE: return 20.0
RelationshipType.COLLEAGUE: return 40.0
RelationshipType.MENTOR: return 70.0
RelationshipType.STUDENT: return 30.0
RelationshipType.RIVAL: return 10.0
RelationshipType.DISLIKE: return 5.0
_: return 25.0
# 网络数据存储
var relationships: Dictionary = {} # "from_id:to_id" -> Relationship
var character_connections: Dictionary = {} # character_id -> Array[character_id]
var relationship_groups: Dictionary = {} # group_name -> Array[character_id]
var influence_scores: Dictionary = {} # character_id -> float
# 数据持久化
var network_file_path: String = "user://relationship_network.json"
# 信号
signal relationship_created(from_character: String, to_character: String, relationship_type: RelationshipType)
signal relationship_updated(from_character: String, to_character: String, old_strength: float, new_strength: float)
signal relationship_type_changed(from_character: String, to_character: String, old_type: RelationshipType, new_type: RelationshipType)
signal influence_score_changed(character_id: String, old_score: float, new_score: float)
signal group_formed(group_name: String, members: Array[String])
signal group_disbanded(group_name: String)
func _ready():
"""初始化关系网络"""
load_network_data()
print("RelationshipNetwork initialized")
## 创建或更新关系
func create_relationship(from_character: String, to_character: String, rel_type: RelationshipType = RelationshipType.NEUTRAL) -> bool:
"""
创建或更新角色之间的关系
@param from_character: 源角色ID
@param to_character: 目标角色ID
@param rel_type: 关系类型
@return: 是否成功创建/更新
"""
if from_character == to_character:
print("Cannot create relationship with self")
return false
var relationship_key = _get_relationship_key(from_character, to_character)
var existing_relationship = relationships.get(relationship_key)
if existing_relationship:
# 更新现有关系
var old_type = existing_relationship.relationship_type
existing_relationship.relationship_type = rel_type
existing_relationship.strength = existing_relationship._get_default_strength(rel_type)
existing_relationship.trust_level = existing_relationship._get_default_trust(rel_type)
existing_relationship.last_updated = Time.get_unix_time_from_system()
relationship_type_changed.emit(from_character, to_character, old_type, rel_type)
print("Relationship updated: ", from_character, " -> ", to_character, " (", RelationshipType.keys()[rel_type], ")")
else:
# 创建新关系
var relationship = Relationship.new(from_character, to_character, rel_type)
relationships[relationship_key] = relationship
# 更新连接索引
_add_connection(from_character, to_character)
relationship_created.emit(from_character, to_character, rel_type)
print("Relationship created: ", from_character, " -> ", to_character, " (", RelationshipType.keys()[rel_type], ")")
# 重新计算影响力分数
_recalculate_influence_scores()
# 保存数据
save_network_data()
return true
## 记录互动
func record_interaction(from_character: String, to_character: String, interaction_type: String, data: Dictionary = {}) -> void:
"""
记录角色之间的互动
@param from_character: 源角色ID
@param to_character: 目标角色ID
@param interaction_type: 互动类型
@param data: 互动数据
"""
var relationship_key = _get_relationship_key(from_character, to_character)
var relationship = relationships.get(relationship_key)
if not relationship:
# 如果关系不存在,创建一个中性关系
create_relationship(from_character, to_character, RelationshipType.NEUTRAL)
relationship = relationships[relationship_key]
# 记录互动
var interaction_record = {
"type": interaction_type,
"timestamp": Time.get_unix_time_from_system(),
"data": data
}
relationship.interaction_history.append(interaction_record)
relationship.last_updated = interaction_record.timestamp
# 限制历史记录长度
if relationship.interaction_history.size() > 100:
relationship.interaction_history.pop_front()
# 根据互动类型调整关系强度
_adjust_relationship_strength(relationship, interaction_type, data)
# 保存数据
save_network_data()
## 调整关系强度
func _adjust_relationship_strength(relationship: Relationship, interaction_type: String, _data: Dictionary) -> void:
"""
根据互动类型调整关系强度
@param relationship: 关系对象
@param interaction_type: 互动类型
@param _data: 互动数据 (暂未使用)
"""
var old_strength = relationship.strength
var strength_change = 0.0
var trust_change = 0.0
match interaction_type:
"chat":
strength_change = 1.0
trust_change = 0.5
"private_chat":
strength_change = 2.0
trust_change = 1.0
"group_activity":
strength_change = 1.5
trust_change = 0.8
"help_given":
strength_change = 5.0
trust_change = 3.0
"help_received":
strength_change = 3.0
trust_change = 2.0
"conflict":
strength_change = -3.0
trust_change = -2.0
"collaboration":
strength_change = 4.0
trust_change = 2.5
"gift_given":
strength_change = 3.0
trust_change = 1.5
"shared_achievement":
strength_change = 6.0
trust_change = 3.0
_:
strength_change = 0.5
# 应用变化
relationship.strength = clamp(relationship.strength + strength_change, -100.0, 100.0)
relationship.trust_level = clamp(relationship.trust_level + trust_change, 0.0, 100.0)
# 检查关系类型是否需要更新
_check_relationship_type_change(relationship)
# 发射信号
if abs(relationship.strength - old_strength) > 0.1:
relationship_updated.emit(relationship.from_character, relationship.to_character, old_strength, relationship.strength)
## 检查关系类型变化
func _check_relationship_type_change(relationship: Relationship) -> void:
"""
根据关系强度检查是否需要改变关系类型
@param relationship: 关系对象
"""
var old_type = relationship.relationship_type
var new_type = old_type
# 根据强度和信任度确定新的关系类型
if relationship.strength >= 70 and relationship.trust_level >= 70:
new_type = RelationshipType.CLOSE_FRIEND
elif relationship.strength >= 40 and relationship.trust_level >= 50:
new_type = RelationshipType.FRIEND
elif relationship.strength >= 15:
new_type = RelationshipType.ACQUAINTANCE
elif relationship.strength <= -30:
new_type = RelationshipType.DISLIKE
elif relationship.strength <= -10:
new_type = RelationshipType.RIVAL
else:
new_type = RelationshipType.NEUTRAL
# 如果类型发生变化,更新并发射信号
if new_type != old_type:
relationship.relationship_type = new_type
relationship_type_changed.emit(relationship.from_character, relationship.to_character, old_type, new_type)
print("Relationship type changed: ", relationship.from_character, " -> ", relationship.to_character,
" (", RelationshipType.keys()[old_type], " -> ", RelationshipType.keys()[new_type], ")")
## 获取关系信息
func get_relationship(from_character: String, to_character: String) -> Dictionary:
"""
获取两个角色之间的关系信息
@param from_character: 源角色ID
@param to_character: 目标角色ID
@return: 关系信息字典
"""
var relationship_key = _get_relationship_key(from_character, to_character)
var relationship = relationships.get(relationship_key)
if not relationship:
return {}
return {
"from_character": relationship.from_character,
"to_character": relationship.to_character,
"type": relationship.relationship_type,
"type_name": RelationshipType.keys()[relationship.relationship_type],
"strength": relationship.strength,
"trust_level": relationship.trust_level,
"interaction_count": relationship.interaction_history.size(),
"shared_experiences": relationship.shared_experiences.duplicate(),
"created_at": relationship.created_at,
"last_updated": relationship.last_updated,
"tags": relationship.tags.duplicate()
}
## 获取角色的所有关系
func get_character_relationships(character_id: String) -> Array[Dictionary]:
"""
获取指定角色的所有关系
@param character_id: 角色ID
@return: 关系信息数组
"""
var character_relationships = []
for relationship_key in relationships:
var relationship = relationships[relationship_key]
if relationship.from_character == character_id:
character_relationships.append(get_relationship(relationship.from_character, relationship.to_character))
# 按关系强度排序
character_relationships.sort_custom(func(a, b): return a.strength > b.strength)
return character_relationships
## 获取最强关系
func get_strongest_relationships(character_id: String, limit: int = 5) -> Array[Dictionary]:
"""
获取指定角色的最强关系
@param character_id: 角色ID
@param limit: 限制返回数量
@return: 关系信息数组
"""
var all_relationships = get_character_relationships(character_id)
if limit <= 0 or limit >= all_relationships.size():
return all_relationships
return all_relationships.slice(0, limit)
## 查找共同好友
func find_mutual_connections(character1: String, character2: String) -> Array[String]:
"""
查找两个角色的共同好友
@param character1: 角色1 ID
@param character2: 角色2 ID
@return: 共同好友ID数组
"""
var connections1 = character_connections.get(character1, [])
var connections2 = character_connections.get(character2, [])
var mutual = []
for connection in connections1:
if connection in connections2:
mutual.append(connection)
return mutual
## 计算关系路径
func find_relationship_path(from_character: String, to_character: String, max_depth: int = 3) -> Array[String]:
"""
查找两个角色之间的关系路径
@param from_character: 源角色ID
@param to_character: 目标角色ID
@param max_depth: 最大搜索深度
@return: 关系路径角色ID数组
"""
if from_character == to_character:
return [from_character]
# 使用广度优先搜索
var queue = [[from_character]]
var visited = {from_character: true}
while queue.size() > 0:
var path = queue.pop_front()
var current = path[-1]
if path.size() > max_depth:
continue
var connections = character_connections.get(current, [])
for connection in connections:
if connection == to_character:
path.append(connection)
return path
if not visited.has(connection):
visited[connection] = true
var new_path = path.duplicate()
new_path.append(connection)
queue.append(new_path)
return [] # 没有找到路径
## 创建关系群组
func create_relationship_group(group_name: String, members: Array[String]) -> bool:
"""
创建关系群组
@param group_name: 群组名称
@param members: 成员ID数组
@return: 是否成功创建
"""
if relationship_groups.has(group_name):
print("Group already exists: ", group_name)
return false
if members.size() < 2:
print("Group must have at least 2 members")
return false
relationship_groups[group_name] = members.duplicate()
# 为群组成员之间创建或加强关系
for i in range(members.size()):
for j in range(i + 1, members.size()):
var member1 = members[i]
var member2 = members[j]
# 记录群组活动互动
record_interaction(member1, member2, "group_activity", {"group": group_name})
record_interaction(member2, member1, "group_activity", {"group": group_name})
# 保存数据
save_network_data()
# 发射信号
group_formed.emit(group_name, members)
print("Relationship group created: ", group_name, " with ", members.size(), " members")
return true
## 解散关系群组
func disband_relationship_group(group_name: String) -> bool:
"""
解散关系群组
@param group_name: 群组名称
@return: 是否成功解散
"""
if not relationship_groups.has(group_name):
print("Group not found: ", group_name)
return false
relationship_groups.erase(group_name)
# 保存数据
save_network_data()
# 发射信号
group_disbanded.emit(group_name)
print("Relationship group disbanded: ", group_name)
return true
## 计算影响力分数
func _recalculate_influence_scores() -> void:
"""重新计算所有角色的影响力分数"""
var new_scores = {}
# 为每个角色计算影响力分数
for character_id in character_connections:
var score = _calculate_influence_score(character_id)
var old_score = influence_scores.get(character_id, 0.0)
new_scores[character_id] = score
if abs(score - old_score) > 0.1:
influence_score_changed.emit(character_id, old_score, score)
influence_scores = new_scores
## 计算单个角色的影响力分数
func _calculate_influence_score(character_id: String) -> float:
"""
计算角色的影响力分数
@param character_id: 角色ID
@return: 影响力分数
"""
var score = 0.0
var connections = character_connections.get(character_id, [])
# 基础分数:连接数量
score += connections.size() * 10.0
# 关系质量加成
for connection in connections:
var relationship_key = _get_relationship_key(character_id, connection)
var relationship = relationships.get(relationship_key)
if relationship:
# 根据关系强度和类型加分
score += relationship.strength * 0.5
match relationship.relationship_type:
RelationshipType.CLOSE_FRIEND:
score += 20.0
RelationshipType.FRIEND:
score += 15.0
RelationshipType.MENTOR:
score += 25.0
RelationshipType.COLLEAGUE:
score += 10.0
# 群组参与加成
for group_name in relationship_groups:
var members = relationship_groups[group_name]
if character_id in members:
score += members.size() * 5.0
return score
## 获取影响力排行
func get_influence_ranking(limit: int = 10) -> Array[Dictionary]:
"""
获取影响力排行榜
@param limit: 限制返回数量
@return: 排行信息数组
"""
var ranking = []
for character_id in influence_scores:
ranking.append({
"character_id": character_id,
"influence_score": influence_scores[character_id]
})
# 按影响力分数排序
ranking.sort_custom(func(a, b): return a.influence_score > b.influence_score)
if limit > 0 and limit < ranking.size():
ranking = ranking.slice(0, limit)
return ranking
## 添加连接
func _add_connection(from_character: String, to_character: String) -> void:
"""
添加角色连接到索引
@param from_character: 源角色ID
@param to_character: 目标角色ID
"""
if not character_connections.has(from_character):
character_connections[from_character] = []
var connections = character_connections[from_character]
if not to_character in connections:
connections.append(to_character)
## 获取关系键
func _get_relationship_key(from_character: String, to_character: String) -> String:
"""
生成关系键(确保一致性)
@param from_character: 源角色ID
@param to_character: 目标角色ID
@return: 关系键
"""
return from_character + ":" + to_character
## 保存网络数据
func save_network_data() -> void:
"""保存关系网络数据到本地文件"""
var data = {
"relationships": {},
"character_connections": character_connections,
"relationship_groups": relationship_groups,
"influence_scores": influence_scores
}
# 序列化关系数据
for relationship_key in relationships:
var relationship = relationships[relationship_key]
data.relationships[relationship_key] = {
"from_character": relationship.from_character,
"to_character": relationship.to_character,
"relationship_type": relationship.relationship_type,
"strength": relationship.strength,
"trust_level": relationship.trust_level,
"interaction_history": relationship.interaction_history,
"shared_experiences": relationship.shared_experiences,
"created_at": relationship.created_at,
"last_updated": relationship.last_updated,
"tags": relationship.tags
}
var file = FileAccess.open(network_file_path, FileAccess.WRITE)
if file:
var json_string = JSON.stringify(data)
file.store_string(json_string)
file.close()
print("Relationship network data saved")
else:
print("Failed to save relationship network data")
## 加载网络数据
func load_network_data() -> void:
"""从本地文件加载关系网络数据"""
if not FileAccess.file_exists(network_file_path):
print("No relationship network data file found, starting fresh")
return
var file = FileAccess.open(network_file_path, FileAccess.READ)
if file:
var json_string = file.get_as_text()
file.close()
var json = JSON.new()
var parse_result = json.parse(json_string)
if parse_result == OK:
var data = json.data
# 加载关系数据
if data.has("relationships"):
for relationship_key in data.relationships:
var rel_data = data.relationships[relationship_key]
var relationship = Relationship.new(
rel_data.get("from_character", ""),
rel_data.get("to_character", ""),
rel_data.get("relationship_type", RelationshipType.NEUTRAL)
)
relationship.strength = rel_data.get("strength", 0.0)
relationship.trust_level = rel_data.get("trust_level", 0.0)
# 正确处理类型化数组的赋值
var history_data = rel_data.get("interaction_history", [])
relationship.interaction_history.clear()
for item in history_data:
if item is Dictionary:
relationship.interaction_history.append(item)
var experiences_data = rel_data.get("shared_experiences", [])
relationship.shared_experiences.clear()
for item in experiences_data:
if item is String:
relationship.shared_experiences.append(item)
var tags_data = rel_data.get("tags", [])
relationship.tags.clear()
for item in tags_data:
if item is String:
relationship.tags.append(item)
relationship.created_at = rel_data.get("created_at", Time.get_unix_time_from_system())
relationship.last_updated = rel_data.get("last_updated", relationship.created_at)
relationships[relationship_key] = relationship
# 加载连接索引
if data.has("character_connections"):
character_connections = data.character_connections
# 加载群组数据
if data.has("relationship_groups"):
relationship_groups = data.relationship_groups
# 加载影响力分数
if data.has("influence_scores"):
influence_scores = data.influence_scores
print("Relationship network data loaded: ", relationships.size(), " relationships, ", relationship_groups.size(), " groups")
else:
print("Failed to parse relationship network data JSON")
else:
print("Failed to open relationship network data file")
## 获取统计信息
func get_statistics() -> Dictionary:
"""
获取关系网络统计信息
@return: 统计信息字典
"""
var type_counts = {}
var total_interactions = 0
for relationship_key in relationships:
var relationship = relationships[relationship_key]
var type_name = RelationshipType.keys()[relationship.relationship_type]
type_counts[type_name] = type_counts.get(type_name, 0) + 1
total_interactions += relationship.interaction_history.size()
return {
"total_relationships": relationships.size(),
"total_characters": character_connections.size(),
"total_groups": relationship_groups.size(),
"total_interactions": total_interactions,
"relationship_types": type_counts,
"average_connections": float(relationships.size()) / max(character_connections.size(), 1)
}