<?php

namespace loyalsoft;

/**
 * 玩家任务数据
 * @author wanggangzero@qq.com
 * @version 1.0.0 2020.7.8 created by gwang
 */
class Info_UserTask extends Object_ext {

    /**
     * 当前任务节点id
     * @var int
     */
    public $curTaskNode;

    /**
     * 当前关注任务id
     * @var int
     */
    public $curTaskId;

    /**
     * 剧情任务实例列表 {id:{progress:0.4,rewardgeted:0}...}
     * @var dict
     */
    public $taskListPlot;

    /**
     * 每日任务实例列表 {id:{progress:0.4,rewardgeted:0}...}
     * @var dict
     */
    public $taskListDaily;

    /**
     * @var int 每日重置记录
     */
    public $dailyResetTs = 0;

    /**
     * @var int 每日活跃点数
     */
    public $dailyActivePoint = 0;

    /**
     * @var array 日常任务活跃度阶段奖励领取记录
     */
    public $dailyActiveGetedRewardArr = array();

    public function __construct($args = null) {
        parent::__construct($args);
        if (null == $args) {
            $this->curTaskNode = 4000001;
            $this->curTaskId = 0;
            $this->taskListDaily = ObjectInit();
            $this->taskListPlot = ObjectInit();
        }
    }

    public function initialize() {
        $nodeCfg = GameConfig::task_node_getItem($this->curTaskNode);
        $taskArr = explode(',', $nodeCfg->taskList);
        $this->curTaskId = $taskArr[0];
        foreach ($taskArr as $tid) {
            $this->AddPlotTask($tid);
        }
        $this->AfterInit();
    }

    public function resetDailyTask() {
        if (tsDay($this->dailyResetTs - 18000) < tsDay() || $this->dailyResetTs <= 0) { # 每天5点
            $dts = GameConfig::task_daily();
            $this->taskListDaily = ObjectInit();
            foreach ($dts as $tid => $t) {
                $task = new Ins_TaskInfo();
                $task->taskId = $tid;
                $this->taskListDaily->$tid = $task;
            }
            $this->dailyActivePoint = 0;
            $this->dailyActiveGetedRewardArr = array();
            $this->dailyResetTs = now();                                        # 更新刷新时间
        }
    }

    function AddPlotTask($taskId) {
        $tmo = GameConfig::task_getItem($taskId);
        my_Assert(null != $tmo, ErrCode::err_const_no);
        switch ($tmo->ban) {    // 每日,剧情...
        }
        $task = new Ins_TaskInfo();
        $task->taskId = $taskId;
        $this->taskListPlot->$taskId = $task;
    }

    function AfterInit() {
        foreach ($this->taskListPlot as $taskId => &$task) {
            $tmo = GameConfig::task_getItem($taskId);
            $task = new Ins_TaskInfo($task);
            my_Assert(null != $tmo, ErrCode::err_const_no);
            switch ($tmo->tasktype) {                                               # 有可能添加任务的时候, 任务就已经完成了. 所以这里需要直接做一个检查...
                case Enum_TaskCmdType::CommanderLevelUpTo:
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::CommanderLevelUpTo, ctx()->base(false)->level);
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::HeroLevelUpTo:
                    $heroMoId = $tmo->canshu1;
                    $userHeros = ctx()->heros(false);
                    $hero = $userHeros->GetHeroByMoID($heroMoId);
                    $level = 0;
                    if ($hero != null) {
                        $level = $hero->level;
                    }
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::HeroLevelUpTo, $hero->typeId, $hero->level);
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::HeroGradeUpTo:
                    $heroMoId = $tmo->canshu1;
                    $userHeros = ctx()->heros(false);
                    $hero = $userHeros->GetHeroByMoID($heroMoId);
                    $level = 0;
                    if ($hero != null) {
                        $level = $hero->grade;
                    }
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::HeroLevelUpTo, $heroMoId, $level);
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::HeroSegmentNumberTo:
                    $segId = $tmo->canshu1;
                    $store = ctx()->store(false);
                    $num = $store->GetItemCount($segId);
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::HeroSegmentNumberTo, $segId, $num);
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::HeroSkillUnlock:
                    $heroMoId = $tmo->canshu1;
                    $userHeros = ctx()->heros(false);
                    $hero = $userHeros->GetHeroByMoID($heroMoId);
                    $subSkillMo = GameConfig::subSkill_getItem($tmo->canshu2);
                    my_Assert(null != $subSkillMo, ErrCode::err_const_no);
                    $mSkillId = $subSkillMo->mainSkillId;
                    $subSkillId = 0;
                    if ($hero != null && in_array($tmo->canshu2, $hero->subSkills->$mSkillId)) {
                        $subSkillId = $tmo->canshu2;
                    }
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::HeroSkillUnlock, $heroMoId, $subSkillId);
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::PassGateN:
                    $gateId = $tmo->canshu1;
                    $diffculty = $tmo->canshu2;
                    $gates = ctx()->gates(false)->normal;
                    switch ($diffculty) {
                        case 0:
                            $gates = ctx()->gates(false)->normal;
                            break;
                        case 1:
                            $gates = ctx()->gates(false)->hard;
                            break;
                        case 2:
                            $gates = ctx()->gates(false)->elite;
                            break;
                        default :
                            $gates = ctx()->gates(false)->normal;
                            break;
                    }
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::PassGateN, $gates->highest, $diffculty);
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::passCarbonN:
                    break;
                case Enum_TaskCmdType::PvPWinNumberTo:
                    $pvp = ctx()->pvp(false);                                   # 设计玩家pvp数据结构
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::PvPWinNumberTo, $pvp->totalWin); # 任务参数
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::PvPScoreTo:
                    $uid = req()->uid;                                                         # 快速访问UID
                    $zoneid = req()->zoneid;                                                   # 快速访问zoneid
                    $seasonId = PVPProc::GetCurSeasonID();                                     # 当前赛季ID
                    $key = MemKey_GameRun::Game_PVPScoreByZoneSeason_zset($zoneid, $seasonId); # 积分总榜
                    $score = self::_getScore_by_uid($uid, $key);                               # 玩家积分
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::PvPScoreTo, $score);             # 任务参数
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::UserPowerTo:
                    $key = MemKey_GameRun::Game_FightPowerRank_zset(req()->zoneid);            # redis key 
                    $power = gMem()->zscore($key, req()->uid);                                 # 查询战斗力
                    $taskParam = new Ins_TaskParams(Enum_TaskCmdType::UserPowerTo, $power);
                    $task->bCheckProgress($taskParam);
                    break;
                case Enum_TaskCmdType::UserCollectScoreTo:
                    break;
            }
        }
    }

    /**
     * 判断是否当前所有剧情任务全部完成并且领取奖励了
     * @return boolean
     */
    function IsAllPlotTaskOver() {
        $bYes = true;
        foreach ($this->taskListPlot as $tid => $task) {
            isEditor() and $task = new Ins_TaskInfo($task);
            if (!$task->rewardGeted) {
                $bYes = false;
                break;
            }
        }
        return $bYes;
    }

}
