增加任务逻辑
This commit is contained in:
27
Assets/Plugins/steam_api.dll.meta
Normal file
27
Assets/Plugins/steam_api.dll.meta
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f167045178ff20d45821bd7cb37231f7
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
27
Assets/Plugins/steam_api64.dll.meta
Normal file
27
Assets/Plugins/steam_api64.dll.meta
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 46713ca58de687b4db4d9684c7021923
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/TcgEngine/Docs.meta
Normal file
8
Assets/TcgEngine/Docs.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 08d1c1c6476cad04f97fb97cec8d0798
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
115
Assets/TcgEngine/Docs/TaskConfigurations.md
Normal file
115
Assets/TcgEngine/Docs/TaskConfigurations.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# 任务配置文件结构说明
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
任务配置文件定义了游戏中可用的各种任务。每个任务都有特定的条件和奖励。
|
||||||
|
|
||||||
|
## 配置字段说明
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 必需 | 描述 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| id | string | 是 | 任务唯一标识符 |
|
||||||
|
| name | string | 是 | 任务显示名称 |
|
||||||
|
| desc | string | 是 | 任务描述 |
|
||||||
|
| condition | int | 是 | 任务条件类型 (参考TaskConditionType枚举) |
|
||||||
|
| value1 | int | 是 | 任务目标值 |
|
||||||
|
| value2 | string | 否 | 条件参数2 (根据任务类型可能需要) |
|
||||||
|
| value3 | string | 否 | 条件参数3 (根据任务类型可能需要) |
|
||||||
|
| rewardTypes | int[] | 是 | 奖励类型数组 (参考TaskRewardType枚举) |
|
||||||
|
| rewardNums | int[] | 是 | 奖励数量数组 (与rewardTypes一一对应) |
|
||||||
|
| isDailyTask | boolean | 是 | 是否为每日任务 |
|
||||||
|
| durationHours | int | 是 | 任务持续时间(小时) |
|
||||||
|
|
||||||
|
## 任务类型详解
|
||||||
|
|
||||||
|
### 1. 登录任务 (LoginGame - 1)
|
||||||
|
- **描述**: 玩家登录游戏即可完成
|
||||||
|
- **value1**: 无意义 (通常为1)
|
||||||
|
- **value2/value3**: 不使用
|
||||||
|
|
||||||
|
### 2. 对战任务 (PlayGames - 2)
|
||||||
|
- **描述**: 完成指定场次的游戏对战
|
||||||
|
- **value1**: 需要完成的对战场次
|
||||||
|
- **value2/value3**: 不使用
|
||||||
|
|
||||||
|
### 3. 胜利任务 (WinGames - 3)
|
||||||
|
- **描述**: 获得指定场次的对战胜利
|
||||||
|
- **value1**: 需要获得胜利的场次
|
||||||
|
- **value2/value3**: 不使用
|
||||||
|
|
||||||
|
### 4. 击败英雄任务 (DefeatHeroWithAttributes - 4)
|
||||||
|
- **描述**: 击败指定阵营的英雄
|
||||||
|
- **value1**: 需要击败的英雄数量
|
||||||
|
- **value2**: 第一个目标阵营 (如 "YiYongJun")
|
||||||
|
- **value3**: 第二个目标阵营 (如 "DiGuoJun")
|
||||||
|
|
||||||
|
### 5. 召唤英雄任务 (SummonHeroWithAttributes - 5)
|
||||||
|
- **描述**: 召唤指定阵营的英雄
|
||||||
|
- **value1**: 需要召唤的英雄数量
|
||||||
|
- **value2**: 第一个目标阵营 (如 "WangGuoJun")
|
||||||
|
- **value3**: 第二个目标阵营 (如 "ZiYouRen")
|
||||||
|
|
||||||
|
### 6. 使用技能任务 (UseHeroSkillWithAttributes - 6)
|
||||||
|
- **描述**: 使用指定阵营英雄的技能
|
||||||
|
- **value1**: 需要使用的技能次数
|
||||||
|
- **value2**: 第一个目标阵营 (如 "ShouQun")
|
||||||
|
- **value3**: 第二个目标阵营 (如 "XieMo")
|
||||||
|
|
||||||
|
## 奖励类型
|
||||||
|
|
||||||
|
### 金币奖励 (Coins - 0)
|
||||||
|
- **描述**: 给予玩家指定数量的金币
|
||||||
|
- **rewardNums**: 金币数量
|
||||||
|
|
||||||
|
## 示例配置文件
|
||||||
|
|
||||||
|
### 登录任务示例
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "login_task_1",
|
||||||
|
"name": "每日登录",
|
||||||
|
"desc": "每日登录游戏",
|
||||||
|
"condition": 1,
|
||||||
|
"value1": 1,
|
||||||
|
"value2": "",
|
||||||
|
"value3": "",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [100],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 胜利任务示例
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "win_task_1",
|
||||||
|
"name": "胜利之路",
|
||||||
|
"desc": "获得3场对战胜利",
|
||||||
|
"condition": 3,
|
||||||
|
"value1": 3,
|
||||||
|
"value2": "",
|
||||||
|
"value3": "",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [200],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 击败英雄任务示例
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "defeat_hero_task_1",
|
||||||
|
"name": "阵营克星",
|
||||||
|
"desc": "击败5个义勇军或帝国军英雄",
|
||||||
|
"condition": 4,
|
||||||
|
"value1": 5,
|
||||||
|
"value2": "YiYongJun",
|
||||||
|
"value3": "DiGuoJun",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [300],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
|
```
|
||||||
7
Assets/TcgEngine/Docs/TaskConfigurations.md.meta
Normal file
7
Assets/TcgEngine/Docs/TaskConfigurations.md.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c0a30614928943b46853e32be2a29fb0
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
119
Assets/TcgEngine/Docs/TaskSystemAPI.md
Normal file
119
Assets/TcgEngine/Docs/TaskSystemAPI.md
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# 任务系统接口文档
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
任务系统允许玩家完成各种游戏内任务以获得奖励。系统支持多种任务类型,包括日常任务、成就任务等。
|
||||||
|
|
||||||
|
## API端点
|
||||||
|
|
||||||
|
### 获取所有任务配置
|
||||||
|
```
|
||||||
|
GET /api/tasks
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "login_task_1",
|
||||||
|
"name": "每日登录",
|
||||||
|
"desc": "每日登录游戏",
|
||||||
|
"condition": 1,
|
||||||
|
"value1": 1,
|
||||||
|
"value2": "",
|
||||||
|
"value3": "",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [100],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "win_task_1",
|
||||||
|
"name": "胜利之路",
|
||||||
|
"desc": "获得3场对战胜利",
|
||||||
|
"condition": 3,
|
||||||
|
"value1": 3,
|
||||||
|
"value2": "",
|
||||||
|
"value3": "",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [200],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 获取玩家任务数据
|
||||||
|
```
|
||||||
|
GET /api/users/{userId}/tasks
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"taskId": "login_task_1",
|
||||||
|
"assignedTime": 16409952000000000,
|
||||||
|
"expireTime": 16410816000000000,
|
||||||
|
"status": 1,
|
||||||
|
"progress": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastDailyTaskAssigned": 16409952000000000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 保存玩家任务数据
|
||||||
|
```
|
||||||
|
POST /api/users/{userId}/tasks
|
||||||
|
```
|
||||||
|
|
||||||
|
**请求体**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"taskId": "login_task_1",
|
||||||
|
"assignedTime": 16409952000000000,
|
||||||
|
"expireTime": 16410816000000000,
|
||||||
|
"status": 1,
|
||||||
|
"progress": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastDailyTaskAssigned": 16409952000000000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"error": ""
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 枚举值定义
|
||||||
|
|
||||||
|
### 任务条件类型 (TaskConditionType)
|
||||||
|
| 值 | 名称 | 描述 |
|
||||||
|
|---|------|------|
|
||||||
|
| 1 | LoginGame | 登入游戏 |
|
||||||
|
| 2 | PlayGames | 进行X场对战 |
|
||||||
|
| 3 | WinGames | 胜利X场 |
|
||||||
|
| 4 | DefeatHeroWithAttributes | 击败Y属性和Z属性的英雄X次 |
|
||||||
|
| 5 | SummonHeroWithAttributes | 召唤Y属性和Z属性的英雄X次 |
|
||||||
|
| 6 | UseHeroSkillWithAttributes | 使用Y属性和Z属性英雄的技能X次 |
|
||||||
|
|
||||||
|
### 任务奖励类型 (TaskRewardType)
|
||||||
|
| 值 | 名称 | 描述 |
|
||||||
|
|---|------|------|
|
||||||
|
| 0 | Coins | 金币 |
|
||||||
|
|
||||||
|
### 任务状态 (TaskStatus)
|
||||||
|
| 值 | 名称 | 描述 |
|
||||||
|
|---|------|------|
|
||||||
|
| 0 | Active | 激活 |
|
||||||
|
| 1 | Completed | 完成 |
|
||||||
|
| 2 | Expired | 过期 |
|
||||||
|
| 3 | Claimed | 已领取 |
|
||||||
7
Assets/TcgEngine/Docs/TaskSystemAPI.md.meta
Normal file
7
Assets/TcgEngine/Docs/TaskSystemAPI.md.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 33e4d9d92f851d04ea1362bf1570a671
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
101
Assets/TcgEngine/Docs/TaskSystemUserGuide.md
Normal file
101
Assets/TcgEngine/Docs/TaskSystemUserGuide.md
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
# 任务系统使用说明
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
任务系统为玩家提供游戏目标和奖励机制。系统每天为玩家分配一个随机任务,玩家完成任务后可获得奖励。
|
||||||
|
|
||||||
|
## 系统架构
|
||||||
|
|
||||||
|
任务系统由以下几个核心组件构成:
|
||||||
|
|
||||||
|
1. **TaskData**: 任务配置数据结构
|
||||||
|
2. **TaskManager**: 任务管理器,负责任务逻辑处理
|
||||||
|
3. **GameClientTaskIntegration**: 游戏客户端集成组件
|
||||||
|
4. **API接口**: 与服务器通信的接口
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
### 1. 任务分配
|
||||||
|
- 每日0点为每个玩家随机分配一个任务
|
||||||
|
- 玩家最多同时持有5个任务
|
||||||
|
- 任务过期时间为24小时
|
||||||
|
|
||||||
|
### 2. 任务类型
|
||||||
|
系统支持以下6种任务类型:
|
||||||
|
1. 登录任务
|
||||||
|
2. 对战任务
|
||||||
|
3. 胜利任务
|
||||||
|
4. 击败特定阵营英雄任务
|
||||||
|
5. 召唤特定阵营英雄任务
|
||||||
|
6. 使用特定阵营英雄技能任务
|
||||||
|
|
||||||
|
### 3. 任务状态
|
||||||
|
任务具有以下4种状态:
|
||||||
|
1. **Active**: 激活状态,玩家正在进行中
|
||||||
|
2. **Completed**: 完成状态,条件已满足但奖励未领取
|
||||||
|
3. **Expired**: 过期状态,任务已超时
|
||||||
|
4. **Claimed**: 已领取,奖励已发放
|
||||||
|
|
||||||
|
### 4. 奖励机制
|
||||||
|
当前版本仅支持金币奖励,未来可扩展支持:
|
||||||
|
- 卡牌包
|
||||||
|
- 稀有卡牌
|
||||||
|
- 经验值
|
||||||
|
- 其他游戏内物品
|
||||||
|
|
||||||
|
## 集成指南
|
||||||
|
|
||||||
|
### 1. 客户端集成
|
||||||
|
在游戏客户端中,通过以下方式集成任务系统:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// 在游戏启动时初始化任务系统
|
||||||
|
TaskManager taskManager = TaskManager.Instance;
|
||||||
|
taskManager.OnPlayerLogin(); // 玩家登录时检查任务
|
||||||
|
|
||||||
|
// 在游戏过程中自动追踪任务进度
|
||||||
|
// 系统会自动监听游戏事件并更新任务进度
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 服务器集成
|
||||||
|
服务器需要提供以下API接口:
|
||||||
|
|
||||||
|
1. `GET /tasks` - 获取所有任务配置
|
||||||
|
2. `GET /users/{userId}/tasks` - 获取玩家任务数据
|
||||||
|
3. `POST /users/{userId}/tasks` - 保存玩家任务数据
|
||||||
|
|
||||||
|
## 扩展开发
|
||||||
|
|
||||||
|
### 添加新的任务类型
|
||||||
|
1. 在`TaskConditionType`枚举中添加新的任务类型
|
||||||
|
2. 在`TaskManager.UpdateTaskProgress`方法中添加相应的条件判断
|
||||||
|
3. 在服务器端添加对应的任务处理逻辑
|
||||||
|
|
||||||
|
### 添加新的奖励类型
|
||||||
|
1. 在`TaskRewardType`枚举中添加新的奖励类型
|
||||||
|
2. 在`TaskManager.GiveReward`方法中添加奖励发放逻辑
|
||||||
|
3. 在服务器端添加对应的奖励处理逻辑
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
### 性能优化
|
||||||
|
1. 使用本地缓存减少API调用频率
|
||||||
|
2. 对任务数据进行批处理更新
|
||||||
|
3. 实现合理的错误重试机制
|
||||||
|
|
||||||
|
### 用户体验
|
||||||
|
1. 及时通知玩家任务完成状态
|
||||||
|
2. 提供清晰的任务进度显示
|
||||||
|
3. 确保奖励发放的可靠性
|
||||||
|
|
||||||
|
## 故障排除
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
1. **任务无法加载**: 检查网络连接和API接口状态
|
||||||
|
2. **任务进度不更新**: 检查事件监听是否正常注册
|
||||||
|
3. **奖励未发放**: 检查奖励发放逻辑和用户数据同步
|
||||||
|
|
||||||
|
### 调试建议
|
||||||
|
1. 使用日志输出追踪任务状态变化
|
||||||
|
2. 验证API响应数据的正确性
|
||||||
|
3. 检查时间戳和过期逻辑
|
||||||
7
Assets/TcgEngine/Docs/TaskSystemUserGuide.md.meta
Normal file
7
Assets/TcgEngine/Docs/TaskSystemUserGuide.md.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3f085404f2be13947a04ab677c3025cd
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/TcgEngine/Resources/Tasks.meta
Normal file
8
Assets/TcgEngine/Resources/Tasks.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8afae310ab2fb8843a6c162db7030919
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
13
Assets/TcgEngine/Resources/Tasks/DefeatHeroTask.asset
Normal file
13
Assets/TcgEngine/Resources/Tasks/DefeatHeroTask.asset
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "defeat_hero_task_1",
|
||||||
|
"name": "阵营克星",
|
||||||
|
"desc": "击败5个义勇军或帝国军英雄",
|
||||||
|
"condition": 4,
|
||||||
|
"value1": 5,
|
||||||
|
"value2": "YiYongJun",
|
||||||
|
"value3": "DiGuoJun",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [300],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 10df7503b6489e7479a8239f15197785
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
13
Assets/TcgEngine/Resources/Tasks/LoginTask.asset
Normal file
13
Assets/TcgEngine/Resources/Tasks/LoginTask.asset
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "login_task_1",
|
||||||
|
"name": "每日登录",
|
||||||
|
"desc": "每日登录游戏",
|
||||||
|
"condition": 1,
|
||||||
|
"value1": 1,
|
||||||
|
"value2": "",
|
||||||
|
"value3": "",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [100],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
8
Assets/TcgEngine/Resources/Tasks/LoginTask.asset.meta
Normal file
8
Assets/TcgEngine/Resources/Tasks/LoginTask.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e36474881d2ea304fa5667f767a9044a
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
13
Assets/TcgEngine/Resources/Tasks/SummonHeroTask.asset
Normal file
13
Assets/TcgEngine/Resources/Tasks/SummonHeroTask.asset
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "summon_hero_task_1",
|
||||||
|
"name": "召唤大师",
|
||||||
|
"desc": "召唤10个王国军或自由人英雄",
|
||||||
|
"condition": 5,
|
||||||
|
"value1": 10,
|
||||||
|
"value2": "WangGuoJun",
|
||||||
|
"value3": "ZiYouRen",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [250],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0b19400c7b189e64eaf33fbdb02e0347
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
13
Assets/TcgEngine/Resources/Tasks/UseSkillTask.asset
Normal file
13
Assets/TcgEngine/Resources/Tasks/UseSkillTask.asset
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "use_skill_task_1",
|
||||||
|
"name": "技能专家",
|
||||||
|
"desc": "使用5次兽群或邪魔英雄的技能",
|
||||||
|
"condition": 6,
|
||||||
|
"value1": 5,
|
||||||
|
"value2": "ShouQun",
|
||||||
|
"value3": "XieMo",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [150],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
8
Assets/TcgEngine/Resources/Tasks/UseSkillTask.asset.meta
Normal file
8
Assets/TcgEngine/Resources/Tasks/UseSkillTask.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c82472e555797d94db11f2f7228eb10e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
13
Assets/TcgEngine/Resources/Tasks/WinTask.asset
Normal file
13
Assets/TcgEngine/Resources/Tasks/WinTask.asset
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "win_task_1",
|
||||||
|
"name": "胜利之路",
|
||||||
|
"desc": "获得3场对战胜利",
|
||||||
|
"condition": 3,
|
||||||
|
"value1": 3,
|
||||||
|
"value2": "",
|
||||||
|
"value3": "",
|
||||||
|
"rewardTypes": [0],
|
||||||
|
"rewardNums": [200],
|
||||||
|
"isDailyTask": true,
|
||||||
|
"durationHours": 24
|
||||||
|
}
|
||||||
8
Assets/TcgEngine/Resources/Tasks/WinTask.asset.meta
Normal file
8
Assets/TcgEngine/Resources/Tasks/WinTask.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 80ca1990d6330be49b5e0be31b9b171b
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace TcgEngine
|
namespace TcgEngine
|
||||||
@@ -208,4 +208,45 @@ namespace TcgEngine
|
|||||||
public string last_online_time;
|
public string last_online_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 任务相关请求和响应结构
|
||||||
|
[Serializable]
|
||||||
|
public struct TaskDataResponse
|
||||||
|
{
|
||||||
|
public string id;
|
||||||
|
public string name;
|
||||||
|
public string desc;
|
||||||
|
public int condition;
|
||||||
|
public int value1;
|
||||||
|
public string value2;
|
||||||
|
public string value3;
|
||||||
|
public int[] rewardTypes;
|
||||||
|
public int[] rewardNums;
|
||||||
|
public bool isDailyTask;
|
||||||
|
public int durationHours;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct PlayerTaskResponse
|
||||||
|
{
|
||||||
|
public string taskId;
|
||||||
|
public long assignedTime;
|
||||||
|
public long expireTime;
|
||||||
|
public int status;
|
||||||
|
public int progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct PlayerTasksResponse
|
||||||
|
{
|
||||||
|
public PlayerTaskResponse[] tasks;
|
||||||
|
public long lastDailyTaskAssigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct PlayerTaskSaveRequest
|
||||||
|
{
|
||||||
|
public PlayerTaskResponse[] tasks;
|
||||||
|
public long lastDailyTaskAssigned;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
116
Assets/TcgEngine/Scripts/Data/TaskData.cs
Normal file
116
Assets/TcgEngine/Scripts/Data/TaskData.cs
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TcgEngine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 任务配置数据,用于定义各种任务的属性和条件
|
||||||
|
/// </summary>
|
||||||
|
[CreateAssetMenu(fileName = "TaskData", menuName = "TcgEngine/TaskData")]
|
||||||
|
public class TaskData : ScriptableObject
|
||||||
|
{
|
||||||
|
public string id;
|
||||||
|
public string name;
|
||||||
|
public string desc;
|
||||||
|
public TaskConditionType condition;
|
||||||
|
public int value1; // 任务进度上限
|
||||||
|
public string value2; // 边界条件1
|
||||||
|
public string value3; // 边界条件2
|
||||||
|
public TaskRewardType[] rewardTypes;
|
||||||
|
public int[] rewardNums;
|
||||||
|
public bool isDailyTask = true; // 是否为每日任务
|
||||||
|
public int durationHours = 24; // 任务有效期(小时)
|
||||||
|
|
||||||
|
// 从服务器响应数据创建任务配置
|
||||||
|
public static TaskData CreateFromResponse(TaskDataResponse response)
|
||||||
|
{
|
||||||
|
TaskData taskData = ScriptableObject.CreateInstance<TaskData>();
|
||||||
|
taskData.id = response.id;
|
||||||
|
taskData.name = response.name;
|
||||||
|
taskData.desc = response.desc;
|
||||||
|
taskData.condition = (TaskConditionType)response.condition;
|
||||||
|
taskData.value1 = response.value1;
|
||||||
|
taskData.value2 = response.value2;
|
||||||
|
taskData.value3 = response.value3;
|
||||||
|
|
||||||
|
// 转换奖励类型数组
|
||||||
|
taskData.rewardTypes = new TaskRewardType[response.rewardTypes.Length];
|
||||||
|
for (int i = 0; i < response.rewardTypes.Length; i++)
|
||||||
|
{
|
||||||
|
taskData.rewardTypes[i] = (TaskRewardType)response.rewardTypes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
taskData.rewardNums = response.rewardNums;
|
||||||
|
taskData.isDailyTask = response.isDailyTask;
|
||||||
|
taskData.durationHours = response.durationHours;
|
||||||
|
|
||||||
|
return taskData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TaskConditionType
|
||||||
|
{
|
||||||
|
LoginGame = 1, // 登入游戏
|
||||||
|
PlayGames = 2, // 进行X场对战
|
||||||
|
WinGames = 3, // 胜利X场
|
||||||
|
DefeatHeroWithAttributes = 4, // 击败Y属性和Z属性的英雄X次
|
||||||
|
SummonHeroWithAttributes = 5, // 召唤Y属性和Z属性的英雄X次
|
||||||
|
UseHeroSkillWithAttributes = 6 // 使用Y属性和Z属性英雄的技能X次
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TaskRewardType
|
||||||
|
{
|
||||||
|
Coins = 0, // 金币
|
||||||
|
// 后续可扩展其他奖励类型
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class PlayerTask
|
||||||
|
{
|
||||||
|
public string taskId;
|
||||||
|
public DateTime assignedTime;
|
||||||
|
public DateTime expireTime;
|
||||||
|
public TaskStatus status;
|
||||||
|
public int progress; // 当前进度
|
||||||
|
|
||||||
|
public PlayerTask(TaskData taskConfig)
|
||||||
|
{
|
||||||
|
taskId = taskConfig.id;
|
||||||
|
assignedTime = DateTime.Now;
|
||||||
|
expireTime = assignedTime.AddHours(taskConfig.durationHours);
|
||||||
|
status = TaskStatus.Active;
|
||||||
|
progress = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从服务器响应数据创建玩家任务
|
||||||
|
public PlayerTask(PlayerTaskResponse response)
|
||||||
|
{
|
||||||
|
taskId = response.taskId;
|
||||||
|
assignedTime = new DateTime(response.assignedTime);
|
||||||
|
expireTime = new DateTime(response.expireTime);
|
||||||
|
status = (TaskStatus)response.status;
|
||||||
|
progress = response.progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为服务器响应数据
|
||||||
|
public PlayerTaskResponse ToResponse()
|
||||||
|
{
|
||||||
|
PlayerTaskResponse response = new PlayerTaskResponse();
|
||||||
|
response.taskId = taskId;
|
||||||
|
response.assignedTime = assignedTime.Ticks;
|
||||||
|
response.expireTime = expireTime.Ticks;
|
||||||
|
response.status = (int)status;
|
||||||
|
response.progress = progress;
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TaskStatus
|
||||||
|
{
|
||||||
|
Active = 0, // 激活
|
||||||
|
Completed = 1, // 完成
|
||||||
|
Expired = 2, // 过期
|
||||||
|
Claimed = 3 // 已领取
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/TcgEngine/Scripts/Data/TaskData.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Data/TaskData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 951a52e8fe4069e41963e049a390811f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using TcgEngine.Client;
|
||||||
|
using TcgEngine.Gameplay;
|
||||||
|
|
||||||
|
namespace TcgEngine.Client
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏客户端任务集成,用于将任务系统集成到游戏客户端中
|
||||||
|
/// </summary>
|
||||||
|
public class GameClientTaskIntegration : MonoBehaviour
|
||||||
|
{
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
// 在游戏客户端启动时初始化任务系统
|
||||||
|
GameClient client = GameClient.Get();
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
// 玩家连接到游戏服务器时触发任务检查
|
||||||
|
client.onConnectServer += OnConnectToServer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
// 取消订阅事件
|
||||||
|
GameClient client = GameClient.Get();
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
client.onConnectServer -= OnConnectToServer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnConnectToServer()
|
||||||
|
{
|
||||||
|
// 玩家登录时检查任务
|
||||||
|
TaskManager taskManager = TaskManager.Instance;
|
||||||
|
if (taskManager != null)
|
||||||
|
{
|
||||||
|
taskManager.OnPlayerLogin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 222f46c5f21da1d47a9d2fed11d3d48c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
553
Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs
Normal file
553
Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs
Normal file
@@ -0,0 +1,553 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using TcgEngine;
|
||||||
|
using TcgEngine.Gameplay;
|
||||||
|
using TcgEngine.Client;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TcgEngine.Gameplay
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 任务管理器,负责任务的分配、进度追踪和奖励发放等功能
|
||||||
|
/// </summary>
|
||||||
|
public class TaskManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static TaskManager Instance;
|
||||||
|
|
||||||
|
[Header("Player Data")]
|
||||||
|
public List<PlayerTask> playerTasks = new List<PlayerTask>();
|
||||||
|
public DateTime lastDailyTaskAssigned;
|
||||||
|
public int maxTasks = 5; // 玩家最多持有任务数
|
||||||
|
|
||||||
|
private GameLogic gameLogic;
|
||||||
|
private System.Random random = new System.Random();
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (Instance == null)
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
LoadTasks();
|
||||||
|
LoadPlayerData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
// 订阅游戏事件
|
||||||
|
GameClient client = GameClient.Get();
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
client.onGameStart += OnGameStart;
|
||||||
|
client.onGameEnd += OnGameEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除对GameLogic.Instance的错误引用,改为检查gameLogic变量
|
||||||
|
if (gameLogic != null)
|
||||||
|
{
|
||||||
|
SubscribeToGameEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
// 取消订阅游戏事件
|
||||||
|
GameClient client = GameClient.Get();
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
client.onGameStart -= OnGameStart;
|
||||||
|
client.onGameEnd -= OnGameEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除对GameLogic.Instance的错误引用,改为检查gameLogic变量
|
||||||
|
if (gameLogic != null)
|
||||||
|
{
|
||||||
|
UnsubscribeFromGameEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetGameLogic(GameLogic logic)
|
||||||
|
{
|
||||||
|
gameLogic = logic;
|
||||||
|
SubscribeToGameEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeToGameEvents()
|
||||||
|
{
|
||||||
|
if (gameLogic != null)
|
||||||
|
{
|
||||||
|
gameLogic.onCardPlayed += OnCardPlayed;
|
||||||
|
gameLogic.onCardSummoned += OnCardSummoned;
|
||||||
|
gameLogic.onAbilityStart += OnAbilityUsed;
|
||||||
|
gameLogic.onCardDiscarded += OnCardDiscarded; // 用于检测击败英雄
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnsubscribeFromGameEvents()
|
||||||
|
{
|
||||||
|
if (gameLogic != null)
|
||||||
|
{
|
||||||
|
gameLogic.onCardPlayed -= OnCardPlayed;
|
||||||
|
gameLogic.onCardSummoned -= OnCardSummoned;
|
||||||
|
gameLogic.onAbilityStart -= OnAbilityUsed;
|
||||||
|
gameLogic.onCardDiscarded -= OnCardDiscarded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void LoadTasks()
|
||||||
|
{
|
||||||
|
// 从服务器加载所有任务配置
|
||||||
|
await LoadTasksFromServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadTasksFromServer()
|
||||||
|
{
|
||||||
|
if (ApiClient.Get() != null && ApiClient.Get().IsLoggedIn())
|
||||||
|
{
|
||||||
|
// 从服务器API获取任务配置
|
||||||
|
string url = ApiClient.ServerURL + "/tasks";
|
||||||
|
WebResponse res = await ApiClient.Get().SendGetRequest(url);
|
||||||
|
|
||||||
|
if (res.success)
|
||||||
|
{
|
||||||
|
// 解析任务配置数据
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskDataResponse[] taskResponses = ApiTool.JsonToObject<TaskDataResponse[]>(res.data);
|
||||||
|
Debug.Log("Loaded " + taskResponses.Length + " tasks from server");
|
||||||
|
// 在实际项目中,这里应该将服务器数据转换为TaskData对象并存储在内存中
|
||||||
|
// 供后续使用,而不是每次都从Resources加载
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError("Failed to parse task data from server: " + e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Failed to load tasks from server: " + res.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果无法从服务器加载,则使用本地Resources作为后备
|
||||||
|
TaskData[] localTasks = Resources.LoadAll<TaskData>("Tasks");
|
||||||
|
Debug.Log("Loaded " + localTasks.Length + " tasks from local resources as fallback");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void LoadPlayerData()
|
||||||
|
{
|
||||||
|
// 从服务器加载玩家任务数据
|
||||||
|
await LoadPlayerTasksFromServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadPlayerTasksFromServer()
|
||||||
|
{
|
||||||
|
if (ApiClient.Get() != null && ApiClient.Get().IsLoggedIn())
|
||||||
|
{
|
||||||
|
// 从服务器获取玩家任务数据
|
||||||
|
string url = ApiClient.ServerURL + "/users/" + ApiClient.Get().UserID + "/tasks";
|
||||||
|
WebResponse res = await ApiClient.Get().SendGetRequest(url);
|
||||||
|
|
||||||
|
if (res.success)
|
||||||
|
{
|
||||||
|
// 解析玩家任务数据
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PlayerTasksResponse response = ApiTool.JsonToObject<PlayerTasksResponse>(res.data);
|
||||||
|
lastDailyTaskAssigned = new DateTime(response.lastDailyTaskAssigned);
|
||||||
|
|
||||||
|
// 清除现有任务
|
||||||
|
playerTasks.Clear();
|
||||||
|
|
||||||
|
// 转换并添加任务
|
||||||
|
foreach (var taskResponse in response.tasks)
|
||||||
|
{
|
||||||
|
PlayerTask playerTask = new PlayerTask(taskResponse);
|
||||||
|
playerTasks.Add(playerTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log("Player tasks loaded from server: " + playerTasks.Count + " tasks");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError("Failed to parse player tasks from server: " + e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Failed to load player tasks from server: " + res.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 简化处理,首次登录时分配任务
|
||||||
|
if (playerTasks.Count == 0)
|
||||||
|
{
|
||||||
|
AssignDailyTaskIfNeeded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void SavePlayerData()
|
||||||
|
{
|
||||||
|
// 将玩家任务数据保存到服务器
|
||||||
|
if (ApiClient.Get() != null && ApiClient.Get().IsLoggedIn())
|
||||||
|
{
|
||||||
|
// 准备要发送的数据
|
||||||
|
PlayerTasksResponse saveData = new PlayerTasksResponse();
|
||||||
|
|
||||||
|
// 转换任务数据
|
||||||
|
PlayerTaskResponse[] taskResponses = new PlayerTaskResponse[playerTasks.Count];
|
||||||
|
for (int i = 0; i < playerTasks.Count; i++)
|
||||||
|
{
|
||||||
|
taskResponses[i] = playerTasks[i].ToResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
saveData.tasks = taskResponses;
|
||||||
|
saveData.lastDailyTaskAssigned = lastDailyTaskAssigned.Ticks;
|
||||||
|
|
||||||
|
string json = ApiTool.ToJson(saveData);
|
||||||
|
string url = ApiClient.ServerURL + "/users/" + ApiClient.Get().UserID + "/tasks";
|
||||||
|
WebResponse res = await ApiClient.Get().SendPostRequest(url, json);
|
||||||
|
|
||||||
|
if (res.success)
|
||||||
|
{
|
||||||
|
Debug.Log("Player tasks saved to server");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Failed to save player tasks to server: " + res.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每日任务分配
|
||||||
|
public void AssignDailyTaskIfNeeded()
|
||||||
|
{
|
||||||
|
// 检查是否应该分配新任务(每日一次)
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
if ((now - lastDailyTaskAssigned).TotalHours < 24)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 检查玩家是否已达到最大任务数
|
||||||
|
if (playerTasks.Count >= maxTasks)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 获取所有每日任务
|
||||||
|
TaskData[] allTasks = Resources.LoadAll<TaskData>("Tasks");
|
||||||
|
var dailyTasks = allTasks
|
||||||
|
.Where(t => t.isDailyTask &&
|
||||||
|
t.condition != 0 &&
|
||||||
|
!string.IsNullOrEmpty(t.id))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (dailyTasks.Length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 避免重复分配相同任务
|
||||||
|
int maxRetries = 3;
|
||||||
|
TaskData selectedTask = null;
|
||||||
|
HashSet<string> triedTasks = new HashSet<string>();
|
||||||
|
|
||||||
|
while (maxRetries-- > 0 && selectedTask == null)
|
||||||
|
{
|
||||||
|
// 随机选择一个任务
|
||||||
|
TaskData candidateTask = dailyTasks[random.Next(dailyTasks.Length)];
|
||||||
|
|
||||||
|
// 如果任务已经尝试过则跳过
|
||||||
|
if (triedTasks.Contains(candidateTask.id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
triedTasks.Add(candidateTask.id);
|
||||||
|
|
||||||
|
// 检查任务是否有效(未被玩家完成过或未在进度中)
|
||||||
|
if (!playerTasks.Any(pt => pt.taskId == candidateTask.id))
|
||||||
|
{
|
||||||
|
selectedTask = candidateTask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有找到合适的任务则返回
|
||||||
|
if (selectedTask == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Failed to assign daily task after multiple retries");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建玩家任务实例
|
||||||
|
PlayerTask playerTask = new PlayerTask(selectedTask);
|
||||||
|
playerTasks.Add(playerTask);
|
||||||
|
|
||||||
|
lastDailyTaskAssigned = now;
|
||||||
|
SavePlayerData();
|
||||||
|
|
||||||
|
Debug.Log($"Assigned daily task: {selectedTask.name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查并更新过期任务
|
||||||
|
public void CheckExpiredTasks()
|
||||||
|
{
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
foreach (var task in playerTasks)
|
||||||
|
{
|
||||||
|
if (task.status == TaskStatus.Active && now > task.expireTime)
|
||||||
|
{
|
||||||
|
task.status = TaskStatus.Expired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查任务是否完成
|
||||||
|
public bool CheckTaskCompletion(PlayerTask task)
|
||||||
|
{
|
||||||
|
TaskData taskConfig = GetTaskConfig(task.taskId);
|
||||||
|
if (taskConfig == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return task.progress >= taskConfig.value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 领取任务奖励
|
||||||
|
public bool ClaimTaskReward(PlayerTask task)
|
||||||
|
{
|
||||||
|
if (task.status != TaskStatus.Completed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TaskData taskConfig = GetTaskConfig(task.taskId);
|
||||||
|
if (taskConfig == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 发放奖励
|
||||||
|
for (int i = 0; i < taskConfig.rewardTypes.Length && i < taskConfig.rewardNums.Length; i++)
|
||||||
|
{
|
||||||
|
GiveReward(taskConfig.rewardTypes[i], taskConfig.rewardNums[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
task.status = TaskStatus.Claimed;
|
||||||
|
SavePlayerData();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GiveReward(TaskRewardType rewardType, int amount)
|
||||||
|
{
|
||||||
|
// 根据奖励类型发放奖励
|
||||||
|
switch (rewardType)
|
||||||
|
{
|
||||||
|
case TaskRewardType.Coins:
|
||||||
|
// 增加金币(需要与游戏现有金币系统集成)
|
||||||
|
UserData userData = Authenticator.Get().UserData;
|
||||||
|
if (userData != null)
|
||||||
|
{
|
||||||
|
userData.coins += amount;
|
||||||
|
Debug.Log($"Gave {amount} coins as reward");
|
||||||
|
|
||||||
|
// 保存用户数据更新
|
||||||
|
if (ApiClient.Get() != null && ApiClient.Get().IsLoggedIn())
|
||||||
|
{
|
||||||
|
Authenticator.Get().SaveUserData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskData GetTaskConfig(string taskId)
|
||||||
|
{
|
||||||
|
TaskData[] allTasks = Resources.LoadAll<TaskData>("Tasks");
|
||||||
|
return allTasks.FirstOrDefault(t => t.id == taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新任务进度
|
||||||
|
private void UpdateTaskProgress(TaskConditionType conditionType, string parameter1 = null, string parameter2 = null)
|
||||||
|
{
|
||||||
|
bool progressUpdated = false;
|
||||||
|
|
||||||
|
foreach (var task in playerTasks)
|
||||||
|
{
|
||||||
|
if (task.status != TaskStatus.Active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TaskData taskConfig = GetTaskConfig(task.taskId);
|
||||||
|
if (taskConfig == null || taskConfig.condition != conditionType)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool shouldUpdate = false;
|
||||||
|
|
||||||
|
// 根据任务类型检查条件
|
||||||
|
switch (conditionType)
|
||||||
|
{
|
||||||
|
case TaskConditionType.LoginGame:
|
||||||
|
case TaskConditionType.PlayGames:
|
||||||
|
case TaskConditionType.WinGames:
|
||||||
|
// 这些任务类型直接增加进度
|
||||||
|
shouldUpdate = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TaskConditionType.DefeatHeroWithAttributes:
|
||||||
|
case TaskConditionType.SummonHeroWithAttributes:
|
||||||
|
case TaskConditionType.UseHeroSkillWithAttributes:
|
||||||
|
// 检查参数是否匹配(支持多个参数匹配)
|
||||||
|
if (!string.IsNullOrEmpty(parameter1) &&
|
||||||
|
(!string.IsNullOrEmpty(taskConfig.value2) && taskConfig.value2 == parameter1 ||
|
||||||
|
!string.IsNullOrEmpty(taskConfig.value3) && taskConfig.value3 == parameter1))
|
||||||
|
{
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrEmpty(parameter2) &&
|
||||||
|
(!string.IsNullOrEmpty(taskConfig.value2) && taskConfig.value2 == parameter2 ||
|
||||||
|
!string.IsNullOrEmpty(taskConfig.value3) && taskConfig.value3 == parameter2))
|
||||||
|
{
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldUpdate && task.progress < taskConfig.value1)
|
||||||
|
{
|
||||||
|
task.progress++;
|
||||||
|
progressUpdated = true;
|
||||||
|
|
||||||
|
// 检查任务是否完成
|
||||||
|
if (CheckTaskCompletion(task))
|
||||||
|
{
|
||||||
|
task.status = TaskStatus.Completed;
|
||||||
|
Debug.Log($"Task completed: {taskConfig.name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progressUpdated)
|
||||||
|
{
|
||||||
|
SavePlayerData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 事件处理方法
|
||||||
|
private void OnGameStart()
|
||||||
|
{
|
||||||
|
// 进行对战任务进度+1
|
||||||
|
UpdateTaskProgress(TaskConditionType.PlayGames);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGameEnd(int winner)
|
||||||
|
{
|
||||||
|
int player_id = GameClient.Get().GetPlayerID();
|
||||||
|
|
||||||
|
// 胜利任务进度+1
|
||||||
|
if (winner == player_id)
|
||||||
|
{
|
||||||
|
UpdateTaskProgress(TaskConditionType.WinGames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有任务完成并自动领取奖励
|
||||||
|
CheckAndClaimCompletedTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCardPlayed(Card card, Slot slot)
|
||||||
|
{
|
||||||
|
// 召唤特定属性英雄任务
|
||||||
|
if (card.CardData.type == CardType.Character)
|
||||||
|
{
|
||||||
|
string cardCamp = card.CardData.camp.ToString();
|
||||||
|
UpdateTaskProgress(TaskConditionType.SummonHeroWithAttributes, cardCamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCardSummoned(Card card, Slot slot)
|
||||||
|
{
|
||||||
|
// 召唤特定属性英雄任务
|
||||||
|
if (card.CardData.type == CardType.Character)
|
||||||
|
{
|
||||||
|
string cardCamp = card.CardData.camp.ToString();
|
||||||
|
UpdateTaskProgress(TaskConditionType.SummonHeroWithAttributes, cardCamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAbilityUsed(AbilityData ability, Card caster)
|
||||||
|
{
|
||||||
|
// 使用特定属性英雄技能任务
|
||||||
|
string cardCamp = caster.CardData.camp.ToString();
|
||||||
|
UpdateTaskProgress(TaskConditionType.UseHeroSkillWithAttributes, cardCamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCardDiscarded(Card card)
|
||||||
|
{
|
||||||
|
// 击败特定属性英雄任务
|
||||||
|
if (card.CardData.type == CardType.Character)
|
||||||
|
{
|
||||||
|
string cardCamp = card.CardData.camp.ToString();
|
||||||
|
UpdateTaskProgress(TaskConditionType.DefeatHeroWithAttributes, cardCamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查并自动领取已完成任务的奖励
|
||||||
|
public void CheckAndClaimCompletedTasks()
|
||||||
|
{
|
||||||
|
bool claimedAny = false;
|
||||||
|
foreach (var task in playerTasks)
|
||||||
|
{
|
||||||
|
if (task.status == TaskStatus.Completed)
|
||||||
|
{
|
||||||
|
if (ClaimTaskReward(task))
|
||||||
|
{
|
||||||
|
claimedAny = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (claimedAny)
|
||||||
|
{
|
||||||
|
SavePlayerData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 玩家登录时检查任务
|
||||||
|
public void OnPlayerLogin()
|
||||||
|
{
|
||||||
|
// 登录任务完成
|
||||||
|
UpdateTaskProgress(TaskConditionType.LoginGame);
|
||||||
|
|
||||||
|
// 检查是否有任务完成并自动领取奖励
|
||||||
|
CheckAndClaimCompletedTasks();
|
||||||
|
|
||||||
|
// 分配每日任务(如果需要)
|
||||||
|
AssignDailyTaskIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取活跃任务
|
||||||
|
public List<PlayerTask> GetActiveTasks()
|
||||||
|
{
|
||||||
|
return playerTasks.Where(t => t.status == TaskStatus.Active).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取已完成任务
|
||||||
|
public List<PlayerTask> GetCompletedTasks()
|
||||||
|
{
|
||||||
|
return playerTasks.Where(t => t.status == TaskStatus.Completed).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有任务
|
||||||
|
public List<PlayerTask> GetAllTasks()
|
||||||
|
{
|
||||||
|
return playerTasks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 玩家任务保存数据结构
|
||||||
|
[Serializable]
|
||||||
|
public struct PlayerTaskSaveData
|
||||||
|
{
|
||||||
|
public PlayerTask[] tasks;
|
||||||
|
public DateTime lastDailyTaskAssigned;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 37abf64a943e2bb43a818a56f330d168
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Reference in New Issue
Block a user