创建新工程

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,864 @@
extends Node
class_name CommunityEventSystem
## 社区活动和事件系统
## 管理社区活动、事件和集体互动
# 事件类型枚举
enum EventType {
SOCIAL_GATHERING, # 社交聚会
LEARNING_SESSION, # 学习会议
COMPETITION, # 竞赛活动
CELEBRATION, # 庆祝活动
WORKSHOP, # 工作坊
DISCUSSION, # 讨论会
GAME_ACTIVITY, # 游戏活动
COMMUNITY_PROJECT, # 社区项目
ANNOUNCEMENT, # 公告
MILESTONE # 里程碑事件
}
# 事件状态枚举
enum EventStatus {
PLANNED, # 计划中
ACTIVE, # 进行中
COMPLETED, # 已完成
CANCELLED # 已取消
}
# 事件数据结构
class CommunityEvent:
var event_id: String
var title: String
var description: String
var event_type: EventType
var status: EventStatus
var organizer_id: String
var participants: Array[String] = []
var max_participants: int = 0 # 0表示无限制
var start_time: float
var end_time: float
var location: String = "" # 游戏内位置
var rewards: Dictionary = {}
var requirements: Dictionary = {}
var created_at: float
var updated_at: float
var tags: Array[String] = []
var metadata: Dictionary = {}
func _init(id: String, event_title: String, type: EventType, organizer: String):
event_id = id
title = event_title
event_type = type
organizer_id = organizer
status = EventStatus.PLANNED
created_at = Time.get_unix_time_from_system()
updated_at = created_at
start_time = created_at + 3600 # 默认1小时后开始
end_time = start_time + 3600 # 默认持续1小时
# 活动数据存储
var events: Dictionary = {} # event_id -> CommunityEvent
var active_events: Array[String] = []
var user_events: Dictionary = {} # user_id -> Array[event_id]
var event_history: Array[Dictionary] = []
# 系统配置
var max_events_per_user: int = 10
var max_active_events: int = 20
var auto_cleanup_days: int = 30
# 关系网络引用
var relationship_network: RelationshipNetwork
# 数据持久化
var events_file_path: String = "user://community_events.json"
# 信号
signal event_created(event_id: String, title: String, organizer_id: String)
signal event_started(event_id: String, title: String)
signal event_completed(event_id: String, title: String, participants: Array[String])
signal event_cancelled(event_id: String, title: String, reason: String)
signal participant_joined(event_id: String, participant_id: String)
signal participant_left(event_id: String, participant_id: String)
signal event_reminder(event_id: String, title: String, minutes_until_start: int)
signal milestone_achieved(milestone_type: String, data: Dictionary)
func _ready():
"""初始化社区事件系统"""
load_events_data()
# 启动定时器检查事件状态
var timer = Timer.new()
timer.wait_time = 60.0 # 每分钟检查一次
timer.timeout.connect(_check_event_status)
timer.autostart = true
add_child(timer)
print("CommunityEventSystem initialized")
## 设置关系网络引用
func set_relationship_network(rn: RelationshipNetwork) -> void:
"""
设置关系网络引用
@param rn: 关系网络实例
"""
relationship_network = rn
## 创建事件
func create_event(title: String, description: String, event_type: EventType, organizer_id: String, start_time: float = 0.0, duration: float = 3600.0) -> String:
"""
创建新的社区事件
@param title: 事件标题
@param description: 事件描述
@param event_type: 事件类型
@param organizer_id: 组织者ID
@param start_time: 开始时间Unix时间戳0表示使用默认时间
@param duration: 持续时间(秒)
@return: 事件ID失败返回空字符串
"""
# 验证输入
if title.strip_edges().is_empty():
print("Event title cannot be empty")
return ""
if title.length() > 100:
print("Event title too long")
return ""
# 检查用户事件数量限制
var user_event_count = user_events.get(organizer_id, []).size()
if user_event_count >= max_events_per_user:
print("User has reached maximum events limit")
return ""
# 检查活跃事件数量限制
if active_events.size() >= max_active_events:
print("Maximum active events limit reached")
return ""
# 生成事件ID
var event_id = generate_event_id()
# 创建事件
var event = CommunityEvent.new(event_id, title.strip_edges(), event_type, organizer_id)
event.description = description.strip_edges()
if start_time > 0:
event.start_time = start_time
event.end_time = start_time + duration
# 组织者自动参与
event.participants.append(organizer_id)
# 存储事件
events[event_id] = event
active_events.append(event_id)
# 更新用户事件索引
_add_event_to_user_index(organizer_id, event_id)
# 保存数据
save_events_data()
# 发射信号
event_created.emit(event_id, title, organizer_id)
print("Event created: ", title, " (", event_id, ") by ", organizer_id)
return event_id
## 加入事件
func join_event(event_id: String, participant_id: String) -> bool:
"""
加入事件
@param event_id: 事件ID
@param participant_id: 参与者ID
@return: 是否成功加入
"""
if not events.has(event_id):
print("Event not found: ", event_id)
return false
var event = events[event_id]
# 检查事件状态
if event.status != EventStatus.PLANNED and event.status != EventStatus.ACTIVE:
print("Cannot join event: event is not active")
return false
# 检查是否已经参与
if participant_id in event.participants:
print("Already participating in event: ", event_id)
return true
# 检查参与者数量限制
if event.max_participants > 0 and event.participants.size() >= event.max_participants:
print("Event is full")
return false
# 检查参与要求
if not _check_event_requirements(event, participant_id):
print("Participant does not meet event requirements")
return false
# 加入事件
event.participants.append(participant_id)
event.updated_at = Time.get_unix_time_from_system()
# 更新用户事件索引
_add_event_to_user_index(participant_id, event_id)
# 记录关系网络互动
if relationship_network:
for other_participant in event.participants:
if other_participant != participant_id:
relationship_network.record_interaction(participant_id, other_participant, "community_event", {"event_id": event_id})
# 保存数据
save_events_data()
# 发射信号
participant_joined.emit(event_id, participant_id)
print("Participant ", participant_id, " joined event ", event_id)
return true
## 离开事件
func leave_event(event_id: String, participant_id: String) -> bool:
"""
离开事件
@param event_id: 事件ID
@param participant_id: 参与者ID
@return: 是否成功离开
"""
if not events.has(event_id):
print("Event not found: ", event_id)
return false
var event = events[event_id]
# 检查是否参与
if not participant_id in event.participants:
print("Not participating in event: ", event_id)
return false
# 组织者不能离开自己的事件
if participant_id == event.organizer_id:
print("Organizer cannot leave their own event")
return false
# 离开事件
event.participants.erase(participant_id)
event.updated_at = Time.get_unix_time_from_system()
# 更新用户事件索引
_remove_event_from_user_index(participant_id, event_id)
# 保存数据
save_events_data()
# 发射信号
participant_left.emit(event_id, participant_id)
print("Participant ", participant_id, " left event ", event_id)
return true
## 开始事件
func start_event(event_id: String) -> bool:
"""
开始事件
@param event_id: 事件ID
@return: 是否成功开始
"""
if not events.has(event_id):
print("Event not found: ", event_id)
return false
var event = events[event_id]
if event.status != EventStatus.PLANNED:
print("Event cannot be started: not in planned status")
return false
# 更新状态
event.status = EventStatus.ACTIVE
event.start_time = Time.get_unix_time_from_system()
event.updated_at = event.start_time
# 保存数据
save_events_data()
# 发射信号
event_started.emit(event_id, event.title)
print("Event started: ", event.title, " (", event_id, ")")
return true
## 完成事件
func complete_event(event_id: String, results: Dictionary = {}) -> bool:
"""
完成事件
@param event_id: 事件ID
@param results: 事件结果数据
@return: 是否成功完成
"""
if not events.has(event_id):
print("Event not found: ", event_id)
return false
var event = events[event_id]
if event.status != EventStatus.ACTIVE:
print("Event cannot be completed: not active")
return false
# 更新状态
event.status = EventStatus.COMPLETED
event.end_time = Time.get_unix_time_from_system()
event.updated_at = event.end_time
event.metadata["results"] = results
# 从活跃事件列表移除
active_events.erase(event_id)
# 添加到历史记录
_add_to_event_history(event)
# 分发奖励
_distribute_event_rewards(event)
# 记录关系网络互动
if relationship_network:
_record_event_relationships(event)
# 检查里程碑
_check_milestones(event)
# 保存数据
save_events_data()
# 发射信号
event_completed.emit(event_id, event.title, event.participants)
print("Event completed: ", event.title, " (", event_id, ") with ", event.participants.size(), " participants")
return true
## 取消事件
func cancel_event(event_id: String, reason: String = "") -> bool:
"""
取消事件
@param event_id: 事件ID
@param reason: 取消原因
@return: 是否成功取消
"""
if not events.has(event_id):
print("Event not found: ", event_id)
return false
var event = events[event_id]
if event.status == EventStatus.COMPLETED or event.status == EventStatus.CANCELLED:
print("Event cannot be cancelled: already completed or cancelled")
return false
# 更新状态
event.status = EventStatus.CANCELLED
event.updated_at = Time.get_unix_time_from_system()
event.metadata["cancel_reason"] = reason
# 从活跃事件列表移除
active_events.erase(event_id)
# 保存数据
save_events_data()
# 发射信号
event_cancelled.emit(event_id, event.title, reason)
print("Event cancelled: ", event.title, " (", event_id, ") - ", reason)
return true
## 获取事件列表
func get_events_list(filter_type: EventType = EventType.SOCIAL_GATHERING, filter_status: EventStatus = EventStatus.PLANNED, include_all_types: bool = true, include_all_statuses: bool = true) -> Array[Dictionary]:
"""
获取事件列表
@param filter_type: 过滤事件类型
@param filter_status: 过滤事件状态
@param include_all_types: 是否包含所有类型
@param include_all_statuses: 是否包含所有状态
@return: 事件信息数组
"""
var events_list = []
for event_id in events:
var event = events[event_id]
# 应用过滤器
if not include_all_types and event.event_type != filter_type:
continue
if not include_all_statuses and event.status != filter_status:
continue
events_list.append(_get_event_info(event))
# 按开始时间排序
events_list.sort_custom(func(a, b): return a.start_time < b.start_time)
return events_list
## 获取用户事件
func get_user_events(user_id: String) -> Array[Dictionary]:
"""
获取用户参与的事件
@param user_id: 用户ID
@return: 事件信息数组
"""
var user_event_ids = user_events.get(user_id, [])
var user_events_list = []
for event_id in user_event_ids:
if events.has(event_id):
user_events_list.append(_get_event_info(events[event_id]))
# 按开始时间排序
user_events_list.sort_custom(func(a, b): return a.start_time < b.start_time)
return user_events_list
## 搜索事件
func search_events(query: String, event_type: EventType = EventType.SOCIAL_GATHERING, include_all_types: bool = true) -> Array[Dictionary]:
"""
搜索事件
@param query: 搜索关键词
@param event_type: 事件类型过滤
@param include_all_types: 是否包含所有类型
@return: 匹配的事件信息数组
"""
var results = []
var search_query = query.to_lower()
for event_id in events:
var event = events[event_id]
# 类型过滤
if not include_all_types and event.event_type != event_type:
continue
# 搜索标题和描述
if event.title.to_lower().contains(search_query) or event.description.to_lower().contains(search_query):
results.append(_get_event_info(event))
# 搜索标签
else:
for tag in event.tags:
if tag.to_lower().contains(search_query):
results.append(_get_event_info(event))
break
return results
## 获取推荐事件
func get_recommended_events(user_id: String, limit: int = 5) -> Array[Dictionary]:
"""
获取推荐事件
@param user_id: 用户ID
@param limit: 限制返回数量
@return: 推荐事件信息数组
"""
var recommendations = []
var user_interests = _get_user_interests(user_id)
for event_id in events:
var event = events[event_id]
# 只推荐计划中的事件
if event.status != EventStatus.PLANNED:
continue
# 不推荐已参与的事件
if user_id in event.participants:
continue
var score = _calculate_recommendation_score(event, user_id, user_interests)
recommendations.append({
"event": _get_event_info(event),
"score": score
})
# 按推荐分数排序
recommendations.sort_custom(func(a, b): return a.score > b.score)
# 提取事件信息
var recommended_events = []
for i in range(min(limit, recommendations.size())):
recommended_events.append(recommendations[i].event)
return recommended_events
## 检查事件状态
func _check_event_status() -> void:
"""定期检查事件状态并处理自动转换"""
var current_time = Time.get_unix_time_from_system()
for event_id in active_events.duplicate(): # 使用副本避免修改时的问题
if not events.has(event_id):
active_events.erase(event_id)
continue
var event = events[event_id]
# 检查是否应该开始
if event.status == EventStatus.PLANNED and current_time >= event.start_time:
start_event(event_id)
# 检查是否应该结束
elif event.status == EventStatus.ACTIVE and current_time >= event.end_time:
complete_event(event_id)
# 发送提醒
elif event.status == EventStatus.PLANNED:
var minutes_until_start = (event.start_time - current_time) / 60.0
if minutes_until_start <= 15 and minutes_until_start > 14: # 15分钟提醒
event_reminder.emit(event_id, event.title, 15)
elif minutes_until_start <= 5 and minutes_until_start > 4: # 5分钟提醒
event_reminder.emit(event_id, event.title, 5)
## 检查事件要求
func _check_event_requirements(_event: CommunityEvent, _participant_id: String) -> bool:
"""
检查参与者是否满足事件要求
@param _event: 事件对象 (暂未使用)
@param _participant_id: 参与者ID (暂未使用)
@return: 是否满足要求
"""
# 这里可以添加各种要求检查,比如等级、成就、关系等
# 目前返回true表示没有特殊要求
return true
## 分发事件奖励
func _distribute_event_rewards(event: CommunityEvent) -> void:
"""
分发事件奖励
@param event: 事件对象
"""
if event.rewards.is_empty():
return
for participant_id in event.participants:
# 这里可以实现具体的奖励分发逻辑
# 比如经验值、成就、物品等
print("Distributing rewards to ", participant_id, " for event ", event.title)
## 记录事件关系
func _record_event_relationships(event: CommunityEvent) -> void:
"""
记录事件中的关系互动
@param event: 事件对象
"""
if not relationship_network:
return
# 为所有参与者之间记录互动
for i in range(event.participants.size()):
for j in range(i + 1, event.participants.size()):
var participant1 = event.participants[i]
var participant2 = event.participants[j]
var interaction_data = {
"event_id": event.event_id,
"event_type": EventType.keys()[event.event_type],
"event_title": event.title
}
relationship_network.record_interaction(participant1, participant2, "community_event", interaction_data)
relationship_network.record_interaction(participant2, participant1, "community_event", interaction_data)
## 检查里程碑
func _check_milestones(event: CommunityEvent) -> void:
"""
检查并触发里程碑事件
@param event: 完成的事件对象
"""
# 检查各种里程碑条件
var total_events = event_history.size()
# 事件数量里程碑
if total_events == 10:
milestone_achieved.emit("events_10", {"count": total_events})
elif total_events == 50:
milestone_achieved.emit("events_50", {"count": total_events})
elif total_events == 100:
milestone_achieved.emit("events_100", {"count": total_events})
# 参与者数量里程碑
if event.participants.size() >= 20:
milestone_achieved.emit("large_event", {"participants": event.participants.size(), "event_id": event.event_id})
## 获取用户兴趣
func _get_user_interests(user_id: String) -> Dictionary:
"""
获取用户兴趣(基于历史参与)
@param user_id: 用户ID
@return: 兴趣数据字典
"""
var interests = {}
var user_event_ids = user_events.get(user_id, [])
for event_id in user_event_ids:
if events.has(event_id):
var event = events[event_id]
var type_name = EventType.keys()[event.event_type]
interests[type_name] = interests.get(type_name, 0) + 1
return interests
## 计算推荐分数
func _calculate_recommendation_score(event: CommunityEvent, user_id: String, user_interests: Dictionary) -> float:
"""
计算事件推荐分数
@param event: 事件对象
@param user_id: 用户ID
@param user_interests: 用户兴趣数据
@return: 推荐分数
"""
var score = 0.0
# 基于用户兴趣
var type_name = EventType.keys()[event.event_type]
score += user_interests.get(type_name, 0) * 10.0
# 基于关系网络
if relationship_network:
var user_relationships = relationship_network.get_character_relationships(user_id)
for relationship in user_relationships:
if relationship.to_character in event.participants:
score += relationship.strength * 0.5
# 基于事件规模(适中规模更受欢迎)
var participant_count = event.participants.size()
if participant_count >= 3 and participant_count <= 10:
score += 5.0
# 基于时间(即将开始的事件更相关)
var time_until_start = event.start_time - Time.get_unix_time_from_system()
if time_until_start > 0 and time_until_start <= 86400: # 24小时内
score += 10.0 - (time_until_start / 8640.0) # 越近分数越高
return score
## 获取事件信息
func _get_event_info(event: CommunityEvent) -> Dictionary:
"""
获取事件信息字典
@param event: 事件对象
@return: 事件信息字典
"""
return {
"id": event.event_id,
"title": event.title,
"description": event.description,
"type": event.event_type,
"type_name": EventType.keys()[event.event_type],
"status": event.status,
"status_name": EventStatus.keys()[event.status],
"organizer_id": event.organizer_id,
"participants": event.participants.duplicate(),
"participant_count": event.participants.size(),
"max_participants": event.max_participants,
"start_time": event.start_time,
"end_time": event.end_time,
"location": event.location,
"rewards": event.rewards.duplicate(),
"requirements": event.requirements.duplicate(),
"created_at": event.created_at,
"updated_at": event.updated_at,
"tags": event.tags.duplicate(),
"metadata": event.metadata.duplicate()
}
## 添加到事件历史
func _add_to_event_history(event: CommunityEvent) -> void:
"""
添加事件到历史记录
@param event: 事件对象
"""
var history_entry = {
"event_id": event.event_id,
"title": event.title,
"type": event.event_type,
"organizer_id": event.organizer_id,
"participant_count": event.participants.size(),
"start_time": event.start_time,
"end_time": event.end_time,
"completed_at": Time.get_unix_time_from_system()
}
event_history.append(history_entry)
# 限制历史记录长度
if event_history.size() > 1000:
event_history.pop_front()
## 添加事件到用户索引
func _add_event_to_user_index(user_id: String, event_id: String) -> void:
"""
添加事件到用户索引
@param user_id: 用户ID
@param event_id: 事件ID
"""
if not user_events.has(user_id):
user_events[user_id] = []
var user_event_list = user_events[user_id]
if not event_id in user_event_list:
user_event_list.append(event_id)
## 从用户索引移除事件
func _remove_event_from_user_index(user_id: String, event_id: String) -> void:
"""
从用户索引移除事件
@param user_id: 用户ID
@param event_id: 事件ID
"""
if user_events.has(user_id):
var user_event_list = user_events[user_id]
user_event_list.erase(event_id)
## 生成事件ID
func generate_event_id() -> String:
"""生成唯一的事件ID"""
var timestamp = Time.get_unix_time_from_system()
var random = randi()
return "event_%d_%d" % [timestamp, random]
## 保存事件数据
func save_events_data() -> void:
"""保存事件数据到本地文件"""
var data = {
"events": {},
"active_events": active_events,
"user_events": user_events,
"event_history": event_history
}
# 序列化事件数据
for event_id in events:
var event = events[event_id]
data.events[event_id] = {
"title": event.title,
"description": event.description,
"event_type": event.event_type,
"status": event.status,
"organizer_id": event.organizer_id,
"participants": event.participants,
"max_participants": event.max_participants,
"start_time": event.start_time,
"end_time": event.end_time,
"location": event.location,
"rewards": event.rewards,
"requirements": event.requirements,
"created_at": event.created_at,
"updated_at": event.updated_at,
"tags": event.tags,
"metadata": event.metadata
}
var file = FileAccess.open(events_file_path, FileAccess.WRITE)
if file:
var json_string = JSON.stringify(data)
file.store_string(json_string)
file.close()
print("Community events data saved")
else:
print("Failed to save community events data")
## 加载事件数据
func load_events_data() -> void:
"""从本地文件加载事件数据"""
if not FileAccess.file_exists(events_file_path):
print("No community events data file found, starting fresh")
return
var file = FileAccess.open(events_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("events"):
for event_id in data.events:
var event_data = data.events[event_id]
var event = CommunityEvent.new(
event_id,
event_data.get("title", ""),
event_data.get("event_type", EventType.SOCIAL_GATHERING),
event_data.get("organizer_id", "")
)
event.description = event_data.get("description", "")
event.status = event_data.get("status", EventStatus.PLANNED)
event.participants = event_data.get("participants", [])
event.max_participants = event_data.get("max_participants", 0)
event.start_time = event_data.get("start_time", Time.get_unix_time_from_system())
event.end_time = event_data.get("end_time", event.start_time + 3600)
event.location = event_data.get("location", "")
event.rewards = event_data.get("rewards", {})
event.requirements = event_data.get("requirements", {})
event.created_at = event_data.get("created_at", Time.get_unix_time_from_system())
event.updated_at = event_data.get("updated_at", event.created_at)
event.tags = event_data.get("tags", [])
event.metadata = event_data.get("metadata", {})
events[event_id] = event
# 加载活跃事件列表
if data.has("active_events"):
active_events = data.active_events
# 加载用户事件索引
if data.has("user_events"):
user_events = data.user_events
# 加载事件历史
if data.has("event_history"):
event_history = data.event_history
print("Community events data loaded: ", events.size(), " events, ", active_events.size(), " active")
else:
print("Failed to parse community events data JSON")
else:
print("Failed to open community events data file")
## 获取统计信息
func get_statistics() -> Dictionary:
"""
获取社区事件系统统计信息
@return: 统计信息字典
"""
var type_counts = {}
var status_counts = {}
var total_participants = 0
for event_id in events:
var event = events[event_id]
var type_name = EventType.keys()[event.event_type]
var status_name = EventStatus.keys()[event.status]
type_counts[type_name] = type_counts.get(type_name, 0) + 1
status_counts[status_name] = status_counts.get(status_name, 0) + 1
total_participants += event.participants.size()
return {
"total_events": events.size(),
"active_events": active_events.size(),
"completed_events": event_history.size(),
"total_participants": total_participants,
"average_participants": float(total_participants) / max(events.size(), 1),
"event_types": type_counts,
"event_statuses": status_counts,
"max_events_per_user": max_events_per_user,
"max_active_events": max_active_events
}