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.
307 lines
11 KiB
307 lines
11 KiB
1 month ago
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using ProtoCSStruct;
|
||
|
using Sog;
|
||
|
|
||
|
namespace Game
|
||
|
{
|
||
|
public abstract class AbstractActivity
|
||
|
{
|
||
|
private static readonly Dictionary<ActivityType, AbstractActivity> ActivityTypes = new();
|
||
|
|
||
|
public static Dictionary<ActivityType, AbstractActivity> GetAllActivityTypes()
|
||
|
{
|
||
|
return ActivityTypes;
|
||
|
}
|
||
|
|
||
|
public static void Register()
|
||
|
{
|
||
|
ActivityTypes[ActivityType.Question] = new QuestionnaireSvc();
|
||
|
ActivityTypes[ActivityType.LoopSign] = new SignLoopAct();
|
||
|
ActivityTypes[ActivityType.Sign] = new SignAct();
|
||
|
ActivityTypes[ActivityType.MonthlyCard] = new LongEmptyActivity();
|
||
|
ActivityTypes[ActivityType.PowerPass] = new PowerPassAct();
|
||
|
ActivityTypes[ActivityType.ChapterPass] = new ChapterPassAct();
|
||
|
ActivityTypes[ActivityType.HandBook] = new HandBookAct();
|
||
|
ActivityTypes[ActivityType.AdventurePass] = new AdventurePassAct();
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//所有的活动应该都要关注这几件事情:1玩家进入游戏时候;2活动状态改变的时候;3系统解锁的时候;4新的一天(可能是某个时候)的时候
|
||
|
public abstract void OnRoleEnter(PlayerOnGame player);
|
||
|
protected abstract void OnStateChange(PlayerOnGame player, int actId, ActivityState state);
|
||
|
public abstract void OnSystemUnlock(PlayerOnGame player, int sysId);
|
||
|
protected abstract void OnDailyRefresh(PlayerOnGame player, ref DBActInfo activityInfo);
|
||
|
|
||
|
|
||
|
public static void TickAll(PlayerOnGame player)
|
||
|
{
|
||
|
var notifyClient = false;
|
||
|
foreach (var kv in ActivityTypes)
|
||
|
{
|
||
|
kv.Value.OnTick(player, kv.Key, out var change);
|
||
|
if (change)
|
||
|
{
|
||
|
notifyClient = true;
|
||
|
}
|
||
|
kv.Value.OnTickCheck(player);
|
||
|
}
|
||
|
|
||
|
if (notifyClient)
|
||
|
{
|
||
|
player.MakeDirty();
|
||
|
SyncActivity(player);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
///通用tick逻辑:以活动类型做分组tick,当前此类型的活动可以同时存在一个或者多个,互不影响,
|
||
|
///根据配置的时间开放,活动开始时候自动添加数据到活动db,抛出状态改变事件,活动状态改变后,也会抛出状态改变事件,
|
||
|
///若某个类型的活动之间相互有别的特殊逻辑,请在自己的活动类型种复写此方法,切勿修改此函数。
|
||
|
///!!!不要在这儿加入任何具体活动相关的逻辑,以便于分离活动类型和时间相关的逻辑
|
||
|
/// </summary>
|
||
|
/// <param name="player"></param>
|
||
|
/// <param name="activityType"></param>
|
||
|
/// <param name="changed">活动是否有变化</param>
|
||
|
protected virtual void OnTick(PlayerOnGame player, ActivityType activityType, out bool changed)
|
||
|
{
|
||
|
var now = GameServerUtils.GetTimeSecond();
|
||
|
|
||
|
changed = false;
|
||
|
var groups = ActivityDescMgr.Instance.GetActivityDescByType(activityType);
|
||
|
if (groups == null)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ref var activityData = ref player.RoleData.ActivityInfo;
|
||
|
foreach (var desc in groups)
|
||
|
{
|
||
|
var index = -1;
|
||
|
for (var i = 0; i < activityData.Count; i++)
|
||
|
{
|
||
|
if (activityData[i].ActID == desc.id)
|
||
|
{
|
||
|
index = i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var state = ActivitySvc.GetActivityState(player, desc.id);
|
||
|
if (state == ActivityState.ActivityNotStarted)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
//活动状态发生改变,
|
||
|
if (index >= 0 && activityData[index].State != (int)state)
|
||
|
{
|
||
|
//活动状态发生改变,
|
||
|
OnStateChange(player, desc.id, state);
|
||
|
activityData[index].State = (int)state; //更新活动状态
|
||
|
//当活动结束之后,所有后续处理都需要在这个之前,否则任务数据没了
|
||
|
if (state == ActivityState.ActivityEnded)
|
||
|
{
|
||
|
RemoveTask(player, desc.activityTask);
|
||
|
RemoveTask(player, desc.activityDailyTask);
|
||
|
RemoveTask(player, desc.activityWeekTask);
|
||
|
}
|
||
|
|
||
|
changed = true;
|
||
|
}
|
||
|
|
||
|
//新活动开始
|
||
|
if (index < 0 && state == ActivityState.InProgress)
|
||
|
{
|
||
|
AddActivity(player, desc.id, (int)ActivityState.InProgress);
|
||
|
OnStateChange(player, desc.id, state);
|
||
|
changed = true;
|
||
|
}
|
||
|
|
||
|
//活动在有效期内
|
||
|
if (index >= 0 && state == ActivityState.InProgress)
|
||
|
{
|
||
|
ref var info = ref activityData[index];
|
||
|
if (!AppTime.IsSameDay(info.RefreshTime, now))
|
||
|
{
|
||
|
RefreshDaily(player, ref info);
|
||
|
info.RefreshTime = now;
|
||
|
changed = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//玩法结束
|
||
|
if (index >= 0 && state == ActivityState.GameplayEnded)
|
||
|
{
|
||
|
activityData.RemoveAt(index);
|
||
|
changed = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected virtual void OnTickCheck(PlayerOnGame player)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
//添加一个新活动
|
||
|
protected static void AddActivity(PlayerOnGame player, int actId, int state)
|
||
|
{
|
||
|
var desc = ActivityDescMgr.Instance.GetConfig(actId);
|
||
|
for (var i = 0; i < player.RoleData.ActivityInfo.Count; i++)
|
||
|
{
|
||
|
if (player.RoleData.ActivityInfo[i].ActID == actId)
|
||
|
{
|
||
|
player.Error("AbstractActivity.AddActivity activity exist uid={0},actId={1}", player.UserID, actId);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (player.RoleData.ActivityInfo.Count == player.RoleData.ActivityInfo.GetMaxCount())
|
||
|
{
|
||
|
player.Error("AbstractActivity.AddActivity in processing activity overflow uid={0},actId={1}",
|
||
|
player.UserID, actId);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var info = new DBActInfo
|
||
|
{
|
||
|
ActID = desc.id,
|
||
|
State = (int)state,
|
||
|
OpenTime = ActivitySvc.GetActOpenTimeDate(player, desc.id),
|
||
|
EndTime = ActivitySvc.GetLastTimeToEnd(player, desc.id),
|
||
|
RefreshTime = GameServerUtils.GetTimeSecond(),
|
||
|
};
|
||
|
player.RoleData.ActivityInfo.Add(info);
|
||
|
AddTask(player, desc.activityTask);
|
||
|
AddTask(player, desc.activityDailyTask);
|
||
|
AddTask(player, desc.activityWeekTask);
|
||
|
}
|
||
|
|
||
|
|
||
|
public static void SyncActivity(PlayerOnGame player)
|
||
|
{
|
||
|
CSActivityInfoSync sync = new CSActivityInfoSync();
|
||
|
sync.ActivityInfo.CopyFrom(ref player.RoleData.ActivityInfo);
|
||
|
player.SendToClient((int)CSGameMsgID.ActivitySncInfo, ref sync);
|
||
|
}
|
||
|
|
||
|
|
||
|
public static void AddTask(PlayerOnGame player, int[] tasks)
|
||
|
{
|
||
|
if (tasks.Length == 0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int index;
|
||
|
CSTaskEXAcceptTaskRes taskRes = new CSTaskEXAcceptTaskRes();
|
||
|
foreach (var taskId in tasks)
|
||
|
{
|
||
|
if (taskId == 0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
taskRes.TaskId = taskId;
|
||
|
taskRes.Ret = TaskEXSvc.ProcessAcceptTask(player, taskId, true, out index);
|
||
|
if (taskRes.Ret == CSErrCode.None)
|
||
|
{
|
||
|
taskRes.Taskdata.CopyFrom(ref TaskEXSvc.GetTaskByIndex(player, index));
|
||
|
TaskEXEvent.ProcessCheckNotifyClient(taskRes.TaskId, player);
|
||
|
}
|
||
|
|
||
|
player.SendToClient((int)CSGameMsgID.TaskexAcceptTaskRes, ref taskRes);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
public static void RemoveTask(PlayerOnGame player, int[] tasks)
|
||
|
{
|
||
|
if (tasks.Length == 0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var delNotify = new CSTaskEXDeleteNotify();
|
||
|
foreach (var id in tasks)
|
||
|
{
|
||
|
if (id == 0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
|
||
|
var ret = TaskEXSvc.ProcessGiveupTask2(player, id, out int index);
|
||
|
if (ret == CSErrCode.None)
|
||
|
{
|
||
|
delNotify.DelTaskIDList.Add(id);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TraceLog.Error("AbstractActivity.RemoveTask ,delete task error Ret is " + ret + "taskId = " + id);
|
||
|
}
|
||
|
|
||
|
if (delNotify.DelTaskIDList.Count >= delNotify.DelTaskIDList.GetMaxCount())
|
||
|
{
|
||
|
player.SendToClient<CSTaskEXDeleteNotify>((int)CSGameMsgID.TaskexDeleteNotify, ref delNotify);
|
||
|
delNotify.Clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (delNotify.DelTaskIDList.Count > 0)
|
||
|
{
|
||
|
player.SendToClient((int)CSGameMsgID.TaskexDeleteNotify, ref delNotify);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
protected void RefreshDaily(PlayerOnGame player, ref DBActInfo activityInfo)
|
||
|
{
|
||
|
OnDailyRefresh(player, ref activityInfo); //处理完一天干的事情后,再去重制任务数据
|
||
|
RefreshTask(player, ref activityInfo);
|
||
|
}
|
||
|
|
||
|
private static void RefreshTask(PlayerOnGame player, ref DBActInfo activityInfo)
|
||
|
{
|
||
|
//刷新任务
|
||
|
var desc = ActivityDescMgr.Instance.GetConfig(activityInfo.ActID);
|
||
|
RemoveTask(player, desc.activityDailyTask);
|
||
|
AddTask(player, desc.activityDailyTask);
|
||
|
if (!AppTime.IsSameWeek127(activityInfo.RefreshTime, GameServerUtils.GetTimeSecond()))
|
||
|
{
|
||
|
RemoveTask(player, desc.activityWeekTask);
|
||
|
AddTask(player, desc.activityWeekTask);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected static void DeleteActPayItemData(PlayerOnGame player, int actId)
|
||
|
{
|
||
|
var desc = ActivityDescMgr.Instance.GetConfig(actId);
|
||
|
var payDiamondIds = desc.payDiamondId;
|
||
|
var change = false;
|
||
|
foreach (var payDiamondId in payDiamondIds)
|
||
|
{
|
||
|
ref var record = ref player.RoleData.PayData.PayItemRecord;
|
||
|
|
||
|
for (var j = 0; j < record.Count; j++)
|
||
|
{
|
||
|
if (payDiamondId != record[j].ItemId)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
player.RoleData.PayData.PayItemRecord.RemoveAt(j);
|
||
|
change = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (change)
|
||
|
{
|
||
|
PlayerNotify.NotifyPlayerPayDataChange(player);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|