You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1701 lines
61 KiB
1701 lines
61 KiB
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ProtoCSStruct;
|
|
using Sog;
|
|
|
|
namespace Game
|
|
{
|
|
/// <summary>
|
|
///主线章节系统
|
|
///</summary>
|
|
public static class ChapterSvc
|
|
{
|
|
//进入游戏 检测上次战斗数据
|
|
public static void OnEnter(PlayerOnGame player)
|
|
{
|
|
OnBattleEnd(player);
|
|
player.RoleData.ChapterData.CanJoinBattle = true;
|
|
player.MakeDirty();
|
|
}
|
|
|
|
//下线清理数据
|
|
public static void OnOffline(PlayerOnGame player)
|
|
{
|
|
// OnBattleEnd(player);//客户端战斗过程中长时间且后台运行,会导致战斗结束,这里不清理
|
|
player.MakeDirty();
|
|
}
|
|
|
|
//重连得话需要同步数据
|
|
public static void OnReEnter(PlayerOnGame player)
|
|
{
|
|
player.RoleData.ChapterData.CanJoinBattle = true;
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
return;
|
|
}
|
|
//player.RoleData.IsInBattle = false;
|
|
OffsetBattleTime(ref player.RoleData.BattleRecord);
|
|
SyncChapterInfo(player);
|
|
}
|
|
|
|
public static void OnPlayerBorn(PlayerOnGame player)
|
|
{
|
|
ref var chapterData = ref player.RoleData.ChapterData;
|
|
var chapterId = CommParamDescMgr.Instance.MainLandFirstId.int_val;
|
|
var desc = ChapterDescMgr.Instance.GetConfig(chapterId);
|
|
if (desc == null)
|
|
{
|
|
TraceLog.Error("ChapterSvc.OnPlayerBorn init chapter id desc not found id= {0}", chapterId);
|
|
}
|
|
else
|
|
{
|
|
chapterData.ChapterId = desc.chapterId;
|
|
}
|
|
|
|
chapterData.CanJoinBattle = true;
|
|
chapterData.BattleId = 0;
|
|
InitRecords(ref chapterData.EffectiveStage);
|
|
InitRecords(ref chapterData.PerfectIds);
|
|
InitRecords(ref chapterData.EffectiveRewardRecord);
|
|
InitRecords(ref chapterData.PerfectRewardRecord);
|
|
|
|
player.MakeDirty();
|
|
SyncChapterInfo(player);
|
|
}
|
|
|
|
private static void InitRecords(ref RepeatedRecord data)
|
|
{
|
|
for (var i = 0; i < data.Records.GetMaxCount(); i++)
|
|
{
|
|
var one = new RepeatedRecordOne();
|
|
for (var j = 0; j < one.Record.GetMaxCount(); j++)
|
|
{
|
|
one.Record.Add(0);
|
|
}
|
|
|
|
data.Records.Add(one);
|
|
}
|
|
}
|
|
|
|
public static void OnBattleBegin(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnBattleBeginReq>();
|
|
//Thread.Sleep(2000);
|
|
var isGm = req.IsGm;
|
|
isGm = false;
|
|
|
|
ref var res = ref OnBattleBeginRes.Parser.GetMessageClear();
|
|
|
|
var resCmd = (int)CSGameMsgID.BattleBeginRes;
|
|
|
|
var chapterId = req.ChapterId;
|
|
var battleId = req.BattleId;
|
|
if (!player.RoleData.ChapterData.CanJoinBattle)
|
|
{
|
|
res.Ret = (int)CSErrCode.CanJoinBattleFail;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
if (player.RoleData.IsInBattle)
|
|
{
|
|
//结算上一场战斗
|
|
OnBattleEnd(player);
|
|
TraceLog.Error("ChapterSvc.OnBattleBegin player is in battle,uid={0},chapterId={1},battleId={2}",
|
|
player.UserID, chapterId, battleId);
|
|
// res.Ret = (int)CSErrCode.Fail;
|
|
// player.SendToClient(resCmd, ref res);
|
|
// return;
|
|
}
|
|
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (battleDesc == null)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
switch (battleDesc.chapterBattleType)
|
|
{
|
|
case ChapterBattleType.RewardBattle:
|
|
BeginRewardBattle(player, isGm, battleId);
|
|
break;
|
|
case ChapterBattleType.MainBattle:
|
|
BeginMainBattle(player, isGm, chapterId, battleId);
|
|
break;
|
|
case ChapterBattleType.GuideBattle:
|
|
BeginGuideBattle(player, isGm, battleId);
|
|
break;
|
|
default:
|
|
TraceLog.Error("ChapterSvc.OnBattleBegin battle type not found");
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static void BeginGuideBattle(PlayerOnGame player, bool isGm, int battleId)
|
|
{
|
|
ref var res = ref OnBattleBeginRes.Parser.GetMessageClear();
|
|
|
|
var resCmd = (int)CSGameMsgID.BattleBeginRes;
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (battleDesc == null)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var now = GameServerUtils.GetTimeSecond();
|
|
|
|
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
record.Clear();
|
|
|
|
record.BattleBeginTime = now;
|
|
record.BeginTime = now;
|
|
record.BattleData.BattleId = battleId;
|
|
record.BattleData.BattleStatus = BattleStatus.NONE;
|
|
|
|
InitBuildMonsterInfo(player, battleId);
|
|
player.RoleData.IsInBattle = true;
|
|
player.MakeDirty();
|
|
|
|
res.Ret = (int)CSErrCode.None;
|
|
res.BattleData.CopyFrom(ref record.BattleData);
|
|
player.SendToClient(resCmd, ref res);
|
|
//SyncChapterInfo(player);
|
|
}
|
|
|
|
private static void BeginRewardBattle(PlayerOnGame player, bool isGm, int battleId)
|
|
{
|
|
ref var res = ref OnBattleBeginRes.Parser.GetMessageClear();
|
|
ref var chapter = ref player.RoleData.ChapterData;
|
|
var resCmd = (int)CSGameMsgID.BattleBeginRes;
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (battleDesc == null)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var now = GameServerUtils.GetTimeSecond();
|
|
|
|
if (chapter.RewardBattleData.BattleId == 0 || chapter.RewardBattleData.BattleId != battleId)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
if (chapter.RewardBattleData.LoseTime < now)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var power = PlayerDataSvc.ClcPower(player);
|
|
if (power < battleDesc.chapterBattleCost && !isGm)
|
|
{
|
|
//体力不够呀
|
|
res.Ret = (int)CSErrCode.TargetNotExist;
|
|
player.SendToClient(resCmd, ref res);
|
|
PlayerDataSvc.SyncPower(player); //主动同步一下体力,防止客户端显示不对
|
|
return;
|
|
}
|
|
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
player.RoleData.ChapterData.CanJoinBattle = false;
|
|
record.Clear();
|
|
|
|
|
|
record.BattleBeginTime = now;
|
|
record.BeginTime = now;
|
|
record.BattleData.BattleId = battleId;
|
|
record.BattleData.BattleStatus = BattleStatus.NONE;
|
|
|
|
InitBuildMonsterInfo(player, battleId);
|
|
player.RoleData.IsInBattle = true;
|
|
player.MakeDirty();
|
|
|
|
res.Ret = (int)CSErrCode.None;
|
|
res.BattleData.CopyFrom(ref record.BattleData);
|
|
player.SendToClient(resCmd, ref res);
|
|
SyncChapterInfo(player);
|
|
}
|
|
|
|
private static void BeginMainBattle(PlayerOnGame player, bool isGm, int chapterId, int battleId)
|
|
{
|
|
ref var res = ref OnBattleBeginRes.Parser.GetMessageClear();
|
|
ref var chapter = ref player.RoleData.ChapterData;
|
|
var resCmd = (int)CSGameMsgID.BattleBeginRes;
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (battleDesc == null)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var desc = ChapterDescMgr.Instance.GetConfig(chapterId);
|
|
if (desc == null)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
if (!desc.battleList.Contains(battleId))
|
|
{
|
|
//是这个章节关卡么
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var power = PlayerDataSvc.ClcPower(player);
|
|
if (power < battleDesc.chapterBattleCost && !isGm)
|
|
{
|
|
//体力不够呀
|
|
res.Ret = (int)CSErrCode.PayConsumeItemLimit;
|
|
player.SendToClient(resCmd, ref res);
|
|
PlayerDataSvc.SyncPower(player); //主动同步一下体力,防止客户端显示不对
|
|
return;
|
|
}
|
|
if(chapter.BattleId != 0 && chapter.ChapterId == chapterId && chapter.BattleId + 1 < battleId)
|
|
{
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(resCmd, ref res);
|
|
TraceLog.Error("ChapterSvc.BeginMainBattle BattleId not +1,uid={0},chapterId={1},battleId={2}, databattleid={3}",
|
|
player.UserID, chapterId, battleId, chapter.BattleId);
|
|
return;
|
|
}
|
|
|
|
if (chapter.ChapterId != 0 && chapter.ChapterId < chapterId) //新的一章
|
|
{
|
|
if (chapter.BattleId != 0) //上一章没有打完,不可以打下一章的
|
|
{
|
|
var nowc = chapter.BattleId / 1000;//1010->1
|
|
if (nowc + 1 != chapterId % 1000)//1005->5
|
|
{
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(resCmd, ref res);
|
|
TraceLog.Error("ChapterSvc.BeginMainBattle chapterId not match,uid={0},chapterId={1},battleId={2}, databattleid={3}",
|
|
player.UserID, chapterId, battleId, chapter.BattleId);
|
|
return;
|
|
}
|
|
var winBattleDesc = ChapterBattleDescMgr.Instance.GetConfig(chapter.BattleId);
|
|
if (winBattleDesc == null)
|
|
{
|
|
res.Ret = (int)CSErrCode.DescNotFound;
|
|
player.Error("not found battle desc id={0}", chapter.BattleId);
|
|
player.SendToClient(resCmd, ref res);
|
|
return;
|
|
}
|
|
|
|
if (winBattleDesc.nextChapterBattleId != 0)
|
|
{
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(resCmd, ref res);
|
|
TraceLog.Error("ChapterSvc.BeginMainBattle2 chapterId not match,uid={0},chapterId={1},battleId={2}, databattleid={3}",
|
|
player.UserID, chapterId, battleId, chapter.BattleId);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
player.RoleData.ChapterData.CanJoinBattle = false;
|
|
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
record.Clear();
|
|
|
|
var now = GameServerUtils.GetTimeSecond();
|
|
|
|
record.BattleBeginTime = now;
|
|
record.BeginTime = now;
|
|
record.BattleData.BattleId = battleId;
|
|
record.BattleData.BattleStatus = BattleStatus.NONE;
|
|
|
|
chapter.LastBattleId = battleId;
|
|
chapter.LastChapterId = chapterId;
|
|
|
|
|
|
InitBuildMonsterInfo(player, battleId);
|
|
player.RoleData.IsInBattle = true;
|
|
player.MakeDirty();
|
|
|
|
res.Ret = (int)CSErrCode.None;
|
|
res.BattleData.CopyFrom(ref record.BattleData);
|
|
player.SendToClient(resCmd, ref res);
|
|
SyncChapterInfo(player);
|
|
}
|
|
|
|
|
|
public static void InitBuildMonsterInfo(PlayerOnGame player, int battleId, int initStageId = 0)
|
|
{
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
|
|
if(initStageId == 0)
|
|
{
|
|
initStageId = battleDesc.firstChapterBattleStageId;
|
|
}
|
|
var battleStageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(initStageId);
|
|
if (battleStageDesc == null)
|
|
{
|
|
TraceLog.Error("ChapterSvc.InitBuildMonsterInfo not found stage desc id={0}", initStageId);
|
|
return;
|
|
}
|
|
|
|
ref var stageInfo = ref record.StageInfo;
|
|
|
|
var nextStageId = battleStageDesc.stageId;
|
|
while (nextStageId != 0)
|
|
{
|
|
var desc = ChapterBattleStageDescMgr.Instance.GetConfig(nextStageId);
|
|
|
|
var stage = new MonsterStage()
|
|
{
|
|
StageId = nextStageId,
|
|
};
|
|
var monster = desc.monster;
|
|
|
|
var list = new List<IDValue32>();
|
|
foreach (var mon in monster)
|
|
{
|
|
for (var i = 0; i < mon.List.Length; i++)
|
|
{
|
|
GenericUtils.Merge(list, mon.List[i], mon.Num[i]);
|
|
}
|
|
}
|
|
|
|
foreach (var idv in list)
|
|
{
|
|
stage.AllNum += idv.Value;
|
|
stage.MonsterInfo.Add(idv);
|
|
}
|
|
|
|
stageInfo.Add(stage);
|
|
nextStageId = desc.nextStageId;
|
|
}
|
|
}
|
|
|
|
|
|
public static void OnBattleOption(PlayerOnGame player, StructPacket packet, bool isAdv = false)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnBattleOptionReq>();
|
|
ref var res = ref OnBattleOptionRes.Parser.GetMessageClear();
|
|
switch (req.Option)
|
|
{
|
|
case ChapterOption.ActiveMonster:
|
|
OnActiveNextStage(player);
|
|
break;
|
|
case ChapterOption.SuspendBattle:
|
|
OnSuspendBattle(player);
|
|
break;
|
|
case ChapterOption.ContinueBattle:
|
|
OnContinueBattle(player);
|
|
break;
|
|
case ChapterOption.ResurrectionBattle:
|
|
OnResurrectionBattle(player, isAdv);
|
|
break;
|
|
case ChapterOption.DefeatBattle:
|
|
res.Ret = (int)OnBattleDefeat(player);
|
|
break;
|
|
case ChapterOption.EndBattle:
|
|
OnBattleEnd(player);
|
|
SyncChapterInfo(player);
|
|
break;
|
|
case ChapterOption.None:
|
|
default:
|
|
TraceLog.Error("ChapterSvc.OnBattleOption command not supported,uid={0}", player.UserID);
|
|
break;
|
|
}
|
|
|
|
player.MakeDirty();
|
|
res.Option = req.Option;
|
|
res.BattleData.CopyFrom(ref player.RoleData.BattleRecord.BattleData);
|
|
player.SendToClient((int)CSGameMsgID.BattleOptionRes, ref res);
|
|
}
|
|
|
|
|
|
//激活波次
|
|
private static void OnActiveNextStage(PlayerOnGame player)
|
|
{
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ref var chapterBattleData = ref player.RoleData.BattleRecord;
|
|
var stageId = chapterBattleData.MonsterStageId;
|
|
int nextStageId;
|
|
if (stageId == 0)
|
|
{
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(chapterBattleData.BattleData.BattleId);
|
|
stageId = desc.firstChapterBattleStageId;
|
|
nextStageId = stageId;
|
|
}
|
|
else
|
|
{
|
|
var stageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(stageId);
|
|
nextStageId = stageDesc.nextStageId;
|
|
}
|
|
|
|
if (nextStageId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var nextStageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(nextStageId);
|
|
if (nextStageDesc == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
var now = GameServerUtils.GetTimeSecond();
|
|
chapterBattleData.MonsterStageId = nextStageId;
|
|
chapterBattleData.MonsterBeginTime = now;
|
|
chapterBattleData.MonsterActiveTime = now;
|
|
chapterBattleData.MonsterTimeDuration = 0;
|
|
}
|
|
|
|
|
|
// 由客户端触发产出一批怪,祭坛
|
|
public static void OnTickBattleEntity(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnTickBattleEntityReq>();
|
|
var type = req.Type;
|
|
ref var res = ref OnTickBattleEntityRes.Parser.GetMessageClear();
|
|
res.Seq = req.Seq;
|
|
res.MsgSeq = req.MsgSeq;
|
|
const int cmd = (int)CSGameMsgID.OntickBattleEntityRes;
|
|
|
|
switch (type)
|
|
{
|
|
case 0:
|
|
// {
|
|
// ref var chapter = ref player.RoleData.BattleRecord;
|
|
//
|
|
// ref var stageInfo = ref chapter.StageInfo;
|
|
// var index = -1;
|
|
// for (int i = 0; i < stageInfo.Count; i++)
|
|
// {
|
|
// if (stageInfo[i].StageId == req.StageId)
|
|
// {
|
|
// index = i;
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// ref var stage = ref stageInfo[index];
|
|
// var stageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(stage.StageId);
|
|
//
|
|
// var maxNum = 0;
|
|
// foreach (var m in stageDesc.monster)
|
|
// {
|
|
// for (int i = 0; i < m.List.Length; i++)
|
|
// {
|
|
// if (m.List[i] == req.EntityId)
|
|
// {
|
|
// maxNum = m.Num[i];
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// if (req.EntityNum > maxNum)
|
|
// {
|
|
// res.Ret = (int)CSErrCode.SendLimit;
|
|
// player.SendToClient(cmd, ref res);
|
|
// return;
|
|
// }
|
|
//
|
|
// ref var monster = ref stage.MonsterInfo;
|
|
// index = -1;
|
|
// for (var i = 0; i < monster.Count; i++)
|
|
// {
|
|
// if (monster[i].Id == req.EntityId)
|
|
// {
|
|
// index = i;
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// if (index == -1)
|
|
// {
|
|
// monster.Add(new IDValue32() { Id = req.EntityId, Value = req.EntityNum });
|
|
// }
|
|
// else
|
|
// {
|
|
// var num = monster[index].Value + req.EntityNum;
|
|
// if (num > maxNum)
|
|
// {
|
|
// //超过数量
|
|
// res.Ret = (int)CSErrCode.SendLimit;
|
|
// player.SendToClient(cmd, ref res);
|
|
// return;
|
|
// }
|
|
//
|
|
// monster[index].Value += req.EntityNum;
|
|
// }
|
|
// }
|
|
break;
|
|
case 1: //刷一个祭坛出来
|
|
{
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
var index = -1;
|
|
for (int i = 0; i < record.AltarInfo.Count; i++)
|
|
{
|
|
if (record.AltarInfo[i].Id == req.EntityId)
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (index < 0)
|
|
{
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(record.BattleData.BattleId);
|
|
var alterIds = battleDesc.altarId;
|
|
var entityId = req.EntityId;
|
|
|
|
var exist = alterIds.Any(alterId => alterId == entityId);
|
|
|
|
if (exist)
|
|
{
|
|
record.AltarInfo.Add(new IDValue32() { Id = req.EntityId, Value = 1 });
|
|
player.MakeDirty();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
player.SendToClient(cmd, ref res);
|
|
}
|
|
|
|
//拾取击杀怪物发送奖励
|
|
public static void OnKilledMonsterReq(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnKilledMonsterReq>();
|
|
|
|
var monsterId = req.MonsterId;
|
|
var stageId = req.StageId;
|
|
|
|
var monsterPropDesc = MonsterPropDescMgr.Instance.GetConfig(monsterId);
|
|
var cmd = (int)CSGameMsgID.KilledMonsterRes;
|
|
ref var res = ref OnKilledMonsterRes.Parser.GetMessageClear();
|
|
res.DropInfo.Seq = req.Seq;
|
|
res.MsgSeq = req.MsgSeq;
|
|
|
|
if (monsterPropDesc == null)
|
|
{
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var stageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(stageId);
|
|
if (stageDesc == null)
|
|
{
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(monsterPropDesc.dropConfig))
|
|
{
|
|
OnBattleWin(player, stageDesc.stageType);
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
var stageInfo = record.StageInfo;
|
|
var maxNum = 0; //当前波次这儿怪的最大数量
|
|
for (var i = 0; i < stageInfo.Count; i++)
|
|
{
|
|
if (stageInfo[i].StageId == stageId)
|
|
{
|
|
for (int j = 0; j < stageInfo[i].MonsterInfo.Count; j++)
|
|
{
|
|
var id = stageInfo[i].MonsterInfo[j].Id;
|
|
if (id == monsterId)
|
|
{
|
|
maxNum = stageInfo[i].MonsterInfo[j].Value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (maxNum == 0) //召唤怪
|
|
{
|
|
OnBattleWin(player, stageDesc.stageType);
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
ref var killedMonsters = ref record.KilledMonsters;
|
|
|
|
var killNum = 0;
|
|
var indexi = -1;
|
|
var indexj = -1;
|
|
for (var i = 0; i < killedMonsters.Count; i++)
|
|
{
|
|
if (killedMonsters[i].StageId == stageId)
|
|
{
|
|
for (var j = 0; j < killedMonsters[i].MonsterInfo.Count; j++)
|
|
{
|
|
if (killedMonsters[i].MonsterInfo[j].Id == monsterId)
|
|
{
|
|
killNum = killedMonsters[i].MonsterInfo[j].Value; //当前波次这个怪的击杀数量
|
|
indexj = j;
|
|
break;
|
|
}
|
|
}
|
|
|
|
indexi = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (maxNum > 0 && killNum > 0 && maxNum <= killNum)
|
|
{
|
|
OnBattleWin(player, stageDesc.stageType);
|
|
player.SendToClient(cmd, ref res); //击杀到最大值
|
|
return;
|
|
}
|
|
|
|
|
|
var dropRewardId = monsterPropDesc.dropConfig;
|
|
if (string.IsNullOrEmpty(dropRewardId))
|
|
{
|
|
OnBattleWin(player, stageDesc.stageType);
|
|
player.SendToClient(cmd, ref res); //没有奖励的怪物不计入
|
|
return;
|
|
}
|
|
|
|
|
|
var dropInfo = new MonsterDrop
|
|
{
|
|
Seq = req.Seq
|
|
};
|
|
var dropReward = new List<TypeIDValue32>();
|
|
BuildDropReward(player, dropRewardId, dropReward, ref dropInfo);
|
|
|
|
res.DropInfo.CopyFrom(ref dropInfo);
|
|
|
|
|
|
if (indexi > -1)
|
|
{
|
|
if (indexj > -1)
|
|
{
|
|
killedMonsters[indexi].MonsterInfo[indexj].Value += 1;
|
|
}
|
|
else
|
|
{
|
|
killedMonsters[indexi].MonsterInfo.Add(new IDValue32() { Id = monsterId, Value = 1 });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var killInfo = new KillMonsterInfo();
|
|
killInfo.MonsterInfo.Add(new IDValue32() { Id = monsterId, Value = 1 });
|
|
killInfo.StageId = stageId;
|
|
killedMonsters.Add(killInfo);
|
|
indexi = killedMonsters.Count - 1;
|
|
}
|
|
|
|
var quickPassed =
|
|
IsCanSendQuickPassReward(player, ref record, stageId); //是否速通
|
|
if (quickPassed)
|
|
{
|
|
killedMonsters[indexi].Effective = true;
|
|
var stageRewardId = stageDesc.stageReward;
|
|
var list = ChapterHelper.ConvRewardInternal(player, stageRewardId);
|
|
if (list.Count > 0)
|
|
{
|
|
ref var sync = ref SyncExtDropRewardData.Parser.GetMessageClear();
|
|
foreach (var v in list)
|
|
{
|
|
sync.Rewards.Add(v);
|
|
}
|
|
|
|
TaskEXEvent.TriggerGetStageRwdN(player);
|
|
player.SendToClient((int)CSGameMsgID.OnSyncExtDropRewardData, ref sync);
|
|
}
|
|
else
|
|
{
|
|
TraceLog.Trace(
|
|
"Chapter.OnKilledMonsterReq not found quick kill monster reward stage={0} ,rewardCfg={1}",
|
|
stageId, stageRewardId);
|
|
}
|
|
|
|
dropReward.AddRange(list); //添加到记录里面
|
|
AppendChapterDataEffectiveStage(player, stageId);
|
|
if (player.RoleData.ChapterData.BattleId >= record.BattleData.BattleId)
|
|
{
|
|
IsPerfectPass(player, ref record);
|
|
}
|
|
}
|
|
|
|
AppendDropReward(ref record, dropReward);
|
|
var exp = monsterPropDesc.exp;
|
|
LevelUtils.AddExp(player, exp, "Chapter");
|
|
|
|
OnBattleWin(player, stageDesc.stageType);
|
|
|
|
player.MakeDirty();
|
|
player.SendToClient(cmd, ref res);
|
|
}
|
|
|
|
|
|
private static void OnBattleWin(PlayerOnGame player, ChapterBattleStageType stageType)
|
|
{
|
|
if (stageType != ChapterBattleStageType.Boss)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ref var res = ref OnChapterBattleWinSync.Parser.GetMessageClear();
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
ref var chapterData = ref player.RoleData.ChapterData;
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(record.BattleData.BattleId);
|
|
if (battleDesc == null)
|
|
{
|
|
player.SendToClient((int)CSGameMsgID.OnSyncChapterBattleWin, ref res);
|
|
return;
|
|
}
|
|
if (battleDesc.chapterBattleType == ChapterBattleType.ContinueBattle)
|
|
{
|
|
//player.SendToClient((int)CSGameMsgID.OnSyncChapterBattleWin, ref res);
|
|
return;
|
|
}
|
|
if (record.BattleData.BattleStatus == BattleStatus.DEFEAT)
|
|
{
|
|
return;
|
|
}
|
|
if(record.BattleData.BattleStatus == BattleStatus.WIN)
|
|
{
|
|
player.SendToClient((int)CSGameMsgID.OnSyncChapterBattleWin, ref res);
|
|
return;
|
|
}
|
|
var upBattle = false;
|
|
var cost = battleDesc.chapterBattleCost;
|
|
PlayerDataSvc.CostPower(player, cost, true); //扣体力
|
|
switch (battleDesc.chapterBattleType)
|
|
{
|
|
case ChapterBattleType.MainBattle:
|
|
IsPerfectPass(player, ref record);
|
|
record.BattleData.BattleStatus = BattleStatus.WIN;
|
|
if (chapterData.LastChapterId > chapterData.ChapterId)
|
|
{
|
|
chapterData.ChapterId = chapterData.LastChapterId;
|
|
}
|
|
|
|
if (chapterData.LastBattleId > chapterData.BattleId)
|
|
{
|
|
ClcBattleTime(ref record, true);
|
|
chapterData.BattleId = chapterData.LastBattleId;
|
|
upBattle = true;
|
|
//新关卡,重置
|
|
var nextChapterBattleId = battleDesc.nextChapterBattleId;
|
|
var nextChapterId = chapterData.ChapterId;
|
|
if (nextChapterBattleId == 0)
|
|
{
|
|
var chapterDesc = ChapterDescMgr.Instance.GetConfig(chapterData.ChapterId);
|
|
nextChapterId = chapterDesc.nextChapterId;
|
|
var nextChapterDesc = ChapterDescMgr.Instance.GetConfig(nextChapterId);
|
|
nextChapterBattleId = nextChapterDesc.firstChapterBattleId;
|
|
}
|
|
|
|
if (nextChapterBattleId != 0)
|
|
{
|
|
chapterData.LastChapterId = nextChapterId;
|
|
chapterData.LastBattleId = nextChapterBattleId;
|
|
}
|
|
}
|
|
|
|
RandomRewardBattleChapter(player, battleDesc);
|
|
TaskEXEvent.TriggerChapterBattle(player, record.BattleData.BattleId);
|
|
TaskEXEvent.PassChapterBattle(player);
|
|
break;
|
|
case ChapterBattleType.RewardBattle:
|
|
player.RoleData.ChapterData.RewardBattleData.Clear();
|
|
record.BattleData.BattleStatus = BattleStatus.WIN;
|
|
break;
|
|
case ChapterBattleType.GuideBattle:
|
|
record.BattleData.BattleStatus = BattleStatus.WIN;
|
|
break;
|
|
case ChapterBattleType.ContinueBattle:
|
|
record.BattleData.BattleStatus = BattleStatus.WIN;
|
|
break;
|
|
}
|
|
|
|
SyncChapterInfo(player);
|
|
SystemUnlockEvent.OnLevelChange(player);
|
|
player.SendToClient((int)CSGameMsgID.OnSyncChapterBattleWin, ref res);
|
|
if (upBattle)
|
|
{
|
|
RankSvc.UpdateRankScore(player, 1, chapterData.BattleId, record.BattleTimeDuration);
|
|
}
|
|
PopPackageSvc.TriggerPopPackage(player,PackPopType.LevelStage);
|
|
}
|
|
|
|
public static void OnGainStageReward(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnGainBattleRewardReq>();
|
|
var res = OnGainBattleRewardRes.Parser.GetMessageClear();
|
|
res.StageId = req.StageId;
|
|
var stageId = req.StageId;
|
|
var cmd = (int)CSGameMsgID.OnGainBattleRewardRes;
|
|
|
|
if (stageId == 0)
|
|
{
|
|
res.Ret = CSErrCode.Fail;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var desc = ChapterBattleStageDescMgr.Instance.GetConfig(stageId);
|
|
if (desc == null)
|
|
{
|
|
res.Ret = CSErrCode.DescNotFound;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var effect = ChapterHelper.IsEffectiveStage(player, desc.stageIndex);
|
|
if (!effect)
|
|
{
|
|
res.Ret = CSErrCode.RecvLimit;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var isGain = ChapterHelper.IsGainEffectiveReward(player, desc.stageIndex);
|
|
if (isGain)
|
|
{
|
|
res.Ret = CSErrCode.RecvLimit;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var rewardId = desc.stageManualReward;
|
|
if (string.IsNullOrEmpty(rewardId))
|
|
{
|
|
res.Ret = CSErrCode.DescNotFound;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
RewardSvc.Reward(player, rewardId, true, true);
|
|
ChapterHelper.SetGainEffectiveReward(player, desc.stageIndex);
|
|
SyncChapterInfo(player);
|
|
player.MakeDirty();
|
|
player.SendToClient(cmd, ref res);
|
|
}
|
|
|
|
//领取当前关卡得所有波次奖励
|
|
public static void OnGainAllStageReward(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnGainAllBattleRewardReq>();
|
|
var chapterDesc = ChapterDescMgr.Instance.GetConfig(req.ChapterId);
|
|
ref var res = ref OnGainAllBattleRewardRes.Parser.GetMessageClear();
|
|
var cmd = (int)CSGameMsgID.OnGainAllBattleRewardRes;
|
|
if (chapterDesc == null)
|
|
{
|
|
res.Ret = CSErrCode.DescNotFound;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var battleId = chapterDesc.firstChapterBattleId;
|
|
var rewardList = new List<TypeIDValueString>();
|
|
while (battleId != 0)
|
|
{
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (desc == null)
|
|
{
|
|
break;
|
|
}
|
|
battleId = desc.nextChapterBattleId;
|
|
var stageId = desc.firstChapterBattleStageId;
|
|
while (stageId != 0)
|
|
{
|
|
var stageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(stageId);
|
|
if (stageDesc == null)
|
|
{
|
|
break;
|
|
}
|
|
|
|
stageId = stageDesc.nextStageId;
|
|
if (!ChapterHelper.IsEffectiveStage(player, stageDesc.stageIndex))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (ChapterHelper.IsGainEffectiveReward(player, stageDesc.stageIndex))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var rewardId = stageDesc.stageManualReward;
|
|
if (string.IsNullOrEmpty(rewardId))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var list = RewardSvc.Reward(player, rewardId, false, false);
|
|
foreach (var item in list)
|
|
{
|
|
var reward = new TypeIDValueString
|
|
{
|
|
Type = item.type,
|
|
Value = (int)item.amount
|
|
};
|
|
reward.Id.SetString(item.code);
|
|
GenericUtils.Merge(rewardList, reward);
|
|
}
|
|
|
|
ChapterHelper.SetGainEffectiveReward(player, stageDesc.stageIndex);
|
|
}
|
|
|
|
if (ChapterHelper.IsPerfectPass(player, desc.chapterIndex) &&
|
|
!ChapterHelper.IsGainPerfectPassReward(player, desc.chapterIndex))
|
|
{
|
|
var rewardId = desc.manualReward;
|
|
|
|
if (string.IsNullOrEmpty(rewardId))
|
|
{
|
|
continue;
|
|
}
|
|
ChapterHelper.SetGainPerfectPassReward(player,desc.chapterIndex);
|
|
var list = RewardSvc.Reward(player, rewardId, false, false);
|
|
foreach (var item in list)
|
|
{
|
|
var reward = new TypeIDValueString
|
|
{
|
|
Type = item.type,
|
|
Value = (int)item.amount
|
|
};
|
|
reward.Id.SetString(item.code);
|
|
GenericUtils.Merge(rewardList, reward);
|
|
}
|
|
}
|
|
}
|
|
|
|
var unifyOp = new UnifyOp(player, BillChangeItemReason.CHAPTER);
|
|
foreach (var reward in rewardList)
|
|
{
|
|
unifyOp.AddGoods(reward.Type, reward.Id.GetString(), reward.Value);
|
|
}
|
|
|
|
unifyOp.DoOp(sendGetItemMsg: true);
|
|
SyncChapterInfo(player);
|
|
player.MakeDirty();
|
|
player.SendToClient(cmd, ref res);
|
|
}
|
|
|
|
|
|
private static void RandomRewardBattleChapter(PlayerOnGame player, ChapterBattleDesc currentBattleDesc)
|
|
{
|
|
if (!SystemUnlockSvc.IsUnlockSys(player, SystemUnlockId.RwdChapter))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (currentBattleDesc.chapterBattleType != ChapterBattleType.MainBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var rewardId = CommParamDescMgr.Instance.RwdChapterRwd.str_val;
|
|
|
|
if (MonthlyCardSvc.IsActive(player, (int)MonthlyCardId.VIP_CARD_PLUS))
|
|
{
|
|
var vipDesc = MonthlyCardDescMgr.Instance.GetConfig((int)MonthlyCardId.VIP_CARD_PLUS);
|
|
if (vipDesc != null && !string.IsNullOrEmpty(vipDesc.rwdBattleCondUp))
|
|
{
|
|
rewardId = vipDesc.rwdBattleCondUp;
|
|
}
|
|
}
|
|
|
|
var reward = RewardSvc.Reward(player, rewardId, false);
|
|
if (reward == null || reward.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var rd = reward[0];
|
|
var type = rd.type;
|
|
if (type != (int)GoodsType.BattleReward) //type=6 is character battle id;
|
|
{
|
|
return;
|
|
}
|
|
|
|
int.TryParse(rd.code, out var battleId);
|
|
if (battleId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var duration = CommParamDescMgr.Instance.RwdChapterTime.int_val;
|
|
player.RoleData.ChapterData.RewardBattleData.LoseTime = GameServerUtils.GetTimeSecond() + duration;
|
|
player.RoleData.ChapterData.RewardBattleData.BattleId = battleId;
|
|
player.RoleData.ChapterData.RewardBattleData.Level = player.GetLevel();
|
|
}
|
|
|
|
|
|
private static void BuildDropReward(PlayerOnGame player, string rewardId, List<TypeIDValue32> collect,
|
|
ref MonsterDrop dropInfo)
|
|
{
|
|
var list = ChapterHelper.ConvRewardInternal(player, rewardId);
|
|
foreach (var reward in list)
|
|
{
|
|
collect.Add(reward);
|
|
dropInfo.Rewards.Add(reward);
|
|
}
|
|
}
|
|
|
|
public static bool IsCanSendQuickPassReward(PlayerOnGame player,
|
|
ref ChapterDataRecord record,
|
|
int stageId)
|
|
{
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(record.BattleData.BattleId);
|
|
var isPerfect = ChapterHelper.IsPerfectPass(player, desc.chapterIndex);
|
|
if (isPerfect) //已经完美通关那必定已经发过完美通关奖励了
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var battleId = record.BattleData.BattleId;
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(battleId); //奖励关卡不速通
|
|
if (battleDesc.chapterBattleType == ChapterBattleType.RewardBattle)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var stageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(stageId);
|
|
|
|
var isEffectiveStage = ChapterHelper.IsEffectiveStage(player, stageDesc.stageIndex);
|
|
if (isEffectiveStage)
|
|
{
|
|
return false; //以发过了
|
|
}
|
|
|
|
var timeLimit = stageDesc.stageRewardLimitTime;
|
|
if (record.MonsterStageId != stageId)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!IsKillOneStage(ref record, stageId))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ClcBattleTime(ref record, true);
|
|
return record.MonsterTimeDuration < timeLimit;
|
|
}
|
|
|
|
|
|
private static void AppendChapterDataEffectiveStage(PlayerOnGame player, int stageId)
|
|
{
|
|
var stageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(stageId);
|
|
|
|
var effectiveStage = ChapterHelper.IsEffectiveStage(player, stageDesc.stageIndex);
|
|
if (effectiveStage)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ChapterHelper.SetEffectiveStage(player, stageDesc.stageIndex);
|
|
}
|
|
|
|
//完美通关判定
|
|
private static void IsPerfectPass(PlayerOnGame player, ref ChapterDataRecord record)
|
|
{
|
|
var battleId = record.BattleData.BattleId;
|
|
if (battleId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (desc == null || desc.chapterBattleType == ChapterBattleType.RewardBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (ChapterHelper.IsPerfectPass(player, desc.chapterIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var stageId = desc.firstChapterBattleStageId;
|
|
var perfectPass = true;
|
|
while (stageId != 0)
|
|
{
|
|
var stageDesc = ChapterBattleStageDescMgr.Instance.GetConfig(stageId);
|
|
stageId = stageDesc.nextStageId;
|
|
if (stageDesc.stageType == ChapterBattleStageType.Boss)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
perfectPass &= ChapterHelper.IsEffectiveStage(player, stageDesc.stageIndex);
|
|
}
|
|
|
|
if (perfectPass)
|
|
{
|
|
//完美通关
|
|
ChapterHelper.SetPerfectPass(player, desc.chapterIndex);
|
|
}
|
|
|
|
SyncChapterInfo(player);
|
|
}
|
|
|
|
//当前波怪物是否杀完
|
|
private static bool IsKillOneStage(ref ChapterDataRecord record, int stageId)
|
|
{
|
|
var index = -1;
|
|
for (int i = 0; i < record.KilledMonsters.Count; i++)
|
|
{
|
|
if (record.KilledMonsters[i].StageId == stageId)
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (index < 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var killNum = 0;
|
|
var monsterInfo = record.KilledMonsters[index].MonsterInfo;
|
|
for (int i = 0; i < monsterInfo.Count; i++)
|
|
{
|
|
killNum += monsterInfo[i].Value;
|
|
}
|
|
|
|
for (var i = 0; i < record.StageInfo.Count; i++)
|
|
{
|
|
if (record.StageInfo[i].StageId != stageId) continue;
|
|
if (killNum >= record.StageInfo[i].AllNum)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void AppendDropReward(ref ChapterDataRecord record, List<TypeIDValue32> reward)
|
|
{
|
|
if (reward.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var dropReward = record.DropReward;
|
|
for (var i = 0; i < dropReward.Count; i++)
|
|
{
|
|
reward.Add(dropReward[i]);
|
|
}
|
|
|
|
var rw = GenericUtils.MergedDuplicates(reward);
|
|
record.DropReward.Clear();
|
|
foreach (var t in rw)
|
|
{
|
|
record.DropReward.Add(t);
|
|
}
|
|
}
|
|
|
|
public static void OnPickupMonsterReward(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnPickupMonsterRewardReq>();
|
|
|
|
ref var record = ref player.RoleData.BattleRecord;
|
|
ref var res = ref OnPickupMonsterRewardRes.Parser.GetMessageClear();
|
|
var battleDesc = ChapterBattleDescMgr.Instance.GetConfig(record.BattleData.BattleId);
|
|
if (battleDesc == null || battleDesc.chapterBattleType == ChapterBattleType.ContinueBattle)
|
|
{//boss连战单独处理
|
|
return;
|
|
}
|
|
ref var reward = ref record.DropReward;
|
|
var index = -1;
|
|
for (int i = 0; i < reward.Count; i++)
|
|
{
|
|
if (reward[i].Id == req.Id && reward[i].Type == req.Type)
|
|
{
|
|
index = i;
|
|
}
|
|
}
|
|
|
|
if (index < 0)
|
|
{
|
|
player.SendToClient((int)CSGameMsgID.OnPickupMonsterRewardRes, ref res);
|
|
return;
|
|
}
|
|
|
|
var id = reward[index].Id;
|
|
var type = reward[index].Type;
|
|
var value = reward[index].Value;
|
|
reward.RemoveAt(index);
|
|
if (value <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var unifyOp = new UnifyOp(player, BillChangeItemReason.CHAPTER);
|
|
unifyOp.AddGoods(type, id, value);
|
|
unifyOp.DoOp();
|
|
player.MakeDirty();
|
|
player.SendToClient((int)CSGameMsgID.OnPickupMonsterRewardRes, ref res);
|
|
}
|
|
|
|
|
|
//暂停(失败也会)
|
|
private static void OnSuspendBattle(PlayerOnGame player)
|
|
{
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ref var chapterBattleData = ref player.RoleData.BattleRecord;
|
|
if (chapterBattleData.BattleData.BattleId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (chapterBattleData.BattleData.BattleStatus != BattleStatus.NONE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ClcBattleTime(ref chapterBattleData, true);
|
|
chapterBattleData.BattleData.BattleStatus = BattleStatus.SUSPEND; //暂停
|
|
}
|
|
|
|
|
|
//继续
|
|
private static void OnContinueBattle(PlayerOnGame player)
|
|
{
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ref var chapterBattleData = ref player.RoleData.BattleRecord;
|
|
if (chapterBattleData.BattleData.BattleId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (chapterBattleData.BattleData.BattleStatus == (int)BattleStatus.NONE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsBattleWin(ref chapterBattleData))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ClcBattleTime(ref chapterBattleData);
|
|
chapterBattleData.BattleData.BattleStatus = (int)BattleStatus.NONE;
|
|
}
|
|
|
|
//复活
|
|
private static void OnResurrectionBattle(PlayerOnGame player, bool isAdv = false)
|
|
{
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ref var chapterBattleData = ref player.RoleData.BattleRecord;
|
|
if (chapterBattleData.BattleData.BattleId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(chapterBattleData.BattleData.BattleId);
|
|
if (desc.isRevive == ReviveType.FALSE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var status = chapterBattleData.BattleData.BattleStatus;
|
|
|
|
if (status is BattleStatus.NONE or BattleStatus.WIN)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsBattleWin(ref chapterBattleData))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (isAdv)
|
|
{
|
|
chapterBattleData.BattleData.ReviveNum++;
|
|
}
|
|
|
|
ClcBattleTime(ref chapterBattleData);
|
|
chapterBattleData.BattleData.BattleStatus = (int)BattleStatus.NONE;
|
|
}
|
|
|
|
|
|
private static bool IsBattleWin(ref ChapterDataRecord chapterDataRecord)
|
|
{
|
|
return chapterDataRecord.BattleData.BattleStatus == BattleStatus.WIN;
|
|
}
|
|
|
|
//激活祭坛
|
|
public static void OnActiveAltar(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
// ref var req = ref packet.GetMessage<OnActiveAltarReq>();
|
|
// var altarId = req.AltarId;
|
|
// var res = new OnActiveAltarRes();
|
|
// var cmd = (int)CSGameMsgID.BattleActiveAltarRes;
|
|
//
|
|
// ref var chapterData = ref player.RoleData.ChapterData;
|
|
// if (!chapterData.IsInBattle)
|
|
// {
|
|
// res.Ret = (int)CSErrCode.Fail;
|
|
// player.SendToClient(cmd, ref res);
|
|
// return;
|
|
// }
|
|
//
|
|
// ref var chapterBattleData = ref player.RoleData.ChapterBattleData;
|
|
// if (chapterBattleData.BattleId == 0)
|
|
// {
|
|
// res.Ret = (int)CSErrCode.DescNotFound;
|
|
// player.SendToClient(cmd, ref res);
|
|
// return;
|
|
// }
|
|
//
|
|
// ref var lateAltarInfo = ref chapterBattleData.AltarInfo;
|
|
// var index = -1;
|
|
// for (int i = 0; i < lateAltarInfo.Count; i++)
|
|
// {
|
|
// if (lateAltarInfo[i].AlterId == altarId)
|
|
// {
|
|
// index = i;
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// if (index == -1)
|
|
// {
|
|
// res.Ret = (int)CSErrCode.DescNotFound;
|
|
// player.SendToClient(cmd, ref res);
|
|
// return;
|
|
// }
|
|
//
|
|
// ref var info = ref lateAltarInfo[index];
|
|
// if (info.IsUse)
|
|
// {
|
|
// res.Ret = (int)CSErrCode.Fail;
|
|
// player.SendToClient(cmd, ref res);
|
|
// return;
|
|
// }
|
|
//
|
|
// info.IsUse = true;
|
|
// var desc = AltarDescMgr.Instance.GetConfig(info.AlterId);
|
|
// var altarEffect = desc.altarEffect;
|
|
// if (altarEffect != 0)
|
|
// {
|
|
// //刷新buff
|
|
// }
|
|
//
|
|
// player.MakeDirty();
|
|
// res.Ret = (int)CSErrCode.None;
|
|
// player.SendToClient(cmd, ref res);
|
|
}
|
|
|
|
|
|
public static void OnBattleDefeat(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnBattleDefeatReq>();
|
|
var ret = OnBattleDefeat(player);
|
|
ref var res = ref OnBattleDefeatRes.Parser.GetMessageClear();
|
|
res.Ret = ret;
|
|
res.DefType = req.DefType;
|
|
res.BattleId = req.BattleId;
|
|
player.SendToClient((int)CSGameMsgID.OnBattleDefeatRes, ref res);
|
|
}
|
|
|
|
//失败等待复活
|
|
private static CSErrCode OnBattleDefeat(PlayerOnGame player)
|
|
{
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
return CSErrCode.None;
|
|
}
|
|
ref var chapterBattleData = ref player.RoleData.BattleRecord;
|
|
if (chapterBattleData.BattleData.BattleId == 0)
|
|
{
|
|
ref var res = ref OnChapterBattleWinSync.Parser.GetMessageClear();
|
|
player.SendToClient((int)CSGameMsgID.OnSyncChapterBattleWin, ref res);
|
|
return CSErrCode.BattleDefeatFail;
|
|
}
|
|
|
|
if (IsBattleWin(ref chapterBattleData))
|
|
{
|
|
ref var res = ref OnChapterBattleWinSync.Parser.GetMessageClear();
|
|
player.SendToClient((int)CSGameMsgID.OnSyncChapterBattleWin, ref res);
|
|
return CSErrCode.BattleDefeatFail;
|
|
}
|
|
|
|
if (chapterBattleData.BattleData.BattleStatus == BattleStatus.DEFEAT)
|
|
{
|
|
return CSErrCode.None;
|
|
}
|
|
|
|
OnSuspendBattle(player);
|
|
chapterBattleData.BattleData.BattleStatus = BattleStatus.DEFEAT; //失败等待复活
|
|
return CSErrCode.None;
|
|
}
|
|
|
|
|
|
//战斗结束
|
|
private static void OnBattleEnd(PlayerOnGame player)
|
|
{
|
|
if (!player.RoleData.IsInBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
player.RoleData.ChapterData.CanJoinBattle = true;
|
|
player.RoleData.IsInBattle = false;
|
|
ref var chapterBattleData = ref player.RoleData.BattleRecord;
|
|
if (chapterBattleData.BattleData.BattleId == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (player.RoleData.BattleRecord.BattleData.BattleStatus != BattleStatus.WIN) //并没有击杀boss中途退出
|
|
{
|
|
var battleId = player.RoleData.BattleRecord.BattleData.BattleId;
|
|
var battleStageDesc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (battleStageDesc != null)
|
|
{
|
|
if (chapterBattleData.MonsterStageId != 0) //==0 没有进入战斗场景,不扣体力
|
|
{
|
|
var cost = battleStageDesc.chapterBattleCost - battleStageDesc.chapterBattleFailReturn;
|
|
PlayerDataSvc.CostPower(player, cost, true);
|
|
}
|
|
|
|
if (battleStageDesc.chapterBattleType == ChapterBattleType.RewardBattle)
|
|
{
|
|
player.RoleData.ChapterData.RewardBattleData.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
player.Error("Chapter.OnBattleEnd not found battle stage desc id={0}", battleId);
|
|
}
|
|
}
|
|
|
|
var battleData = player.RoleData.BattleRecord.BattleData;
|
|
|
|
GameTALogUtils.ChapterBattleEnd(player, player.RoleData.ChapterData.LastChapterId,
|
|
battleData.BattleId, battleData.BattleStatus == BattleStatus.WIN ? 1 : 0,
|
|
player.RoleData.BattleRecord.BattleTimeDuration, chapterBattleData.MonsterStageId,
|
|
player.RoleData.BattleRecord.PropVal);
|
|
|
|
SendAllBattleReward(player);
|
|
player.RoleData.BattleRecord.Clear();
|
|
player.RoleData.IsInBattle = false;
|
|
}
|
|
|
|
|
|
private static void SendAllBattleReward(PlayerOnGame player)
|
|
{
|
|
ref var dropReward = ref player.RoleData.BattleRecord.DropReward;
|
|
if (dropReward.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var op = new UnifyOp(player, BillChangeItemReason.CHAPTER);
|
|
for (var i = 0; i < dropReward.Count; i++)
|
|
{
|
|
var rd = dropReward[i];
|
|
op.AddGoods(rd.Type, rd.Id, rd.Value);
|
|
}
|
|
|
|
op.DoOp();
|
|
dropReward.Clear();
|
|
}
|
|
|
|
|
|
//是否战斗超时
|
|
private static bool IsBattleTimeout(ref ChapterDataRecord chapterBattleData)
|
|
{
|
|
var battleId = chapterBattleData.BattleData.BattleId;
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (desc == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
ClcBattleTime(ref chapterBattleData, true);
|
|
return chapterBattleData.BattleTimeDuration > desc.chapterBattleLimitedTime;
|
|
}
|
|
|
|
|
|
//统计结算战斗耗时
|
|
private static void ClcBattleTime(ref ChapterDataRecord chapterDataRecord, bool calculate = false)
|
|
{
|
|
var now = GameServerUtils.GetTimeSecond();
|
|
if (calculate)
|
|
{
|
|
var duration = now - chapterDataRecord.BattleBeginTime;
|
|
chapterDataRecord.BattleTimeDuration += (int)duration;
|
|
|
|
duration = now - chapterDataRecord.MonsterBeginTime;
|
|
chapterDataRecord.MonsterTimeDuration += (int)duration; //计算真正耗时
|
|
}
|
|
|
|
chapterDataRecord.BattleBeginTime = now;
|
|
chapterDataRecord.MonsterBeginTime = now;
|
|
}
|
|
|
|
private static void OffsetBattleTime(ref ChapterDataRecord chapterDataRecord)
|
|
{
|
|
var now = GameServerUtils.GetTimeSecond();
|
|
chapterDataRecord.BattleBeginTime = now;
|
|
chapterDataRecord.MonsterBeginTime = now;
|
|
}
|
|
|
|
|
|
//同步客户端信息
|
|
public static void SyncChapterInfo(PlayerOnGame player)
|
|
{
|
|
ref var sync = ref SyncChapterData.Parser.GetMessageClear();
|
|
sync.ChapterData.CopyFrom(ref player.RoleData.ChapterData);
|
|
sync.ChapterBattleData.CopyFrom(ref player.RoleData.BattleRecord.BattleData);
|
|
player.SendToClient((int)CSGameMsgID.BattleSyncData, ref sync);
|
|
}
|
|
|
|
//扫荡
|
|
public static void OnMopUp(PlayerOnGame player, bool isAdv = false)
|
|
{
|
|
var cmd = (int)CSGameMsgID.MopUpRes;
|
|
ref var res = ref MopUpRes.Parser.GetMessageClear();
|
|
var canMopUpNum = GetMopUpNum(player);
|
|
if (!isAdv && canMopUpNum <= 0)
|
|
{
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var battleId = player.RoleData.ChapterData.BattleId;
|
|
if (battleId == 0)
|
|
{
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (desc == null)
|
|
{
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
var costPower = desc.chapterBattleCost;
|
|
var ret = PlayerDataSvc.CostPower(player, costPower);
|
|
if (!ret)
|
|
{
|
|
res.Ret = (int)CSErrCode.Fail;
|
|
player.SendToClient(cmd, ref res);
|
|
return;
|
|
}
|
|
|
|
if (!isAdv)
|
|
{
|
|
player.RoleData.PowerPointData.MopTimes++;
|
|
}
|
|
|
|
PlayerDataSvc.SyncPower(player);
|
|
//扫荡时设置当前关卡为最大关卡
|
|
player.RoleData.ChapterData.LastBattleId = player.RoleData.ChapterData.BattleId;
|
|
var rewards = RewardSvc.Reward(player, desc.sweepReward, false, false);
|
|
var unifyOp = new UnifyOp(player, BillChangeItemReason.Mop, "" + desc.chapterBattleId);
|
|
foreach (var reward in rewards)
|
|
{
|
|
unifyOp.AddGoods(reward.type, reward.code, reward.amount);
|
|
}
|
|
|
|
var list = new List<CSItemChgInfo>();
|
|
unifyOp.DoOp(retList: list);
|
|
foreach (var info in list)
|
|
{
|
|
if (info.ChgCount <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
res.Rewards.Add(info);
|
|
}
|
|
|
|
player.SendToClient(cmd, ref res);
|
|
player.MakeDirty();
|
|
}
|
|
|
|
//战斗中是否可以改变天赋或者切换武器
|
|
public static bool CanChangeTalentOrEquip(PlayerOnGame player)
|
|
{
|
|
if (player.RoleData.ChapterData.CanJoinBattle)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
var battleId = player.RoleData.BattleRecord.BattleData.BattleId;
|
|
var desc = ChapterBattleDescMgr.Instance.GetConfig(battleId);
|
|
if (desc == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return desc.isChange == Bool.TRUE;
|
|
}
|
|
|
|
private static int GetMopUpNum(PlayerOnGame player)
|
|
{
|
|
var data = player.RoleData.PowerPointData;
|
|
var baseNum = CommParamDescMgr.Instance.SweepTimes.int_val;
|
|
baseNum += player.RoleData.PowerPointData.ExtMopTimes;
|
|
return baseNum - data.MopTimes;
|
|
}
|
|
|
|
public static void PushProp(PlayerOnGame player, StructPacket packet)
|
|
{
|
|
ref var req = ref packet.GetMessage<OnBattlePushClientPropReq>();
|
|
player.RoleData.BattleRecord.PropVal.CopyFrom(ref req.PropVal);
|
|
var res = new OnBattlePushClientPropRes();
|
|
player.SendToClient((int)CSGameMsgID.OnBattlePushPropDataRes, ref res);
|
|
}
|
|
}
|
|
}
|