<?php

namespace loyalsoft;

/**
 * 战斗模块
 * @author c'y'zhao
 */
class FightProc {

    /**
     * 逻辑分发
     * 所有的Proc中必须有这样一个方法
     * @param Req $req
     */
    public static function procMain($req) {
        switch ($req->cmd) {
            case CmdCode::fight_settle:                                         # 6801 主线战斗结算
                return FightProc::Settle();
            case CmdCode::fight_passGateTsPrizeReceive:                         # 6802 章节宝箱的领取
                return FightProc::PassGateTsPrizeReceive();
            case CmdCode::fight_allGateBoxReceive:                              # 6831 章节宝箱的一键领取
                return FightProc::AllGateBoxReceive();

            case CmdCode::fight_selectGate:                                     # 6803 主线剧情关卡选择
                return FightProc::SelectGate();
            case CmdCode::fight_gateChallengeRewards:                           # 6804 挑战关卡: 领取奖励
                return FightProc::GateChallengeRewards();
            case CmdCode::fihgt_reliveCost:                                     # 6805 战斗: 复活花费
                return FightProc::ReliveCost();
            case CmdCode::fight_plotSav:                                        # 6806 主线剧情(已播放)回存
                return FightProc::PlotSav();
            case CmdCode::fight_sweep:                                          # 6807 主线扫荡
                return FightProc::FightSweep();
            case CmdCode::fight_startFight:                                     # 6808 主线剧情关卡开始挑战
                return self::StartFight();
            case CmdCode::fight_tower_RefreshSkills:                            # 6809 挑战关卡: 刷新初始技能
                return self::TowerRefreshSkills();
            case CmdCode::fight_tower_updatelocklist:                           # 6810 挑战关卡: 更新技能锁定列表
                return self::TowerUpdateLockskillList();
            case CmdCode::fight_rankInfo:                                       # 6811 获取主线关卡排行榜信息
                return self::GetRankInfo();
            case CmdCode::fight_rank_uidEquipInfo:                              # 6812 获取主线关卡榜内玩家的装备信息
                return self::GetUidEquipInfo_Rank();
            case CmdCode::fight_rank_GetMainGateRankRewardInfo:                 # 6813 获取通关荣誉榜信息
                return self::GetmainGate_RankRewardInfo();
            case CmdCode::fight_rank_GetFightPowerRankRewardInfo:               # 6814 获取战力荣誉榜信息
                return self::GetFightPower_RankRewardInfo();
            case CmdCode::fight_rank_ReceiveRankReward_MainGate:                # 6815 领取通关荣誉榜奖励
                return self::ReceiveRankReward_MainGate();
            case CmdCode::fight_rank_ReceiveRankReward_FightPower:              # 6816 领取战力荣誉榜奖励
                return self::ReceiveRankReward_FightPower();
            case CmdCode::fight_rank_IsExistRankReward:                         # 6817 是否存在未领取的荣誉榜奖励
                return self::IsExistRankReward();
            case CmdCode::fight_evolveUnlock:                                   # 6818 启灵解锁
                return self::EvolveUnlock();
            case CmdCode::fight_MainTZPass:                                     # 6819 主线挑战--通关
                return self::MainTZPass();
            case CmdCode::fight_MainTZGetReward:                                # 6820 主线挑战--领取奖励
                return self::MainTZGetReward();
            case CmdCode::fight_ResetChallange_RedMask:                         # 6821 每天重置挑战红点
                return self::ResetChallange_RedMask();
            case CmdCode::fight_lockSkill:                                      # 6822 封印/解封技能
                return self::LockSkill();
            case CmdCode::fight_buyLockSkillCount:                              # 6823 购买更多封印数量
                return self::BuySkillLockCount();
            case CmdCode::fight_rank_ReceiveRankReward:                         # 6824 排行奖励一键领取
                return self::ReceiveRankReward();
            case CmdCode::fight_PVP_match:                                      # 6825 PVP 匹配一个对手
                return self::PvpMatchPlayer();

            case CmdCode::fight_WorldBoss_rankInfo:                             # 6826 世界boss的排名信息
                return self::GetWorldBoss_RankInfo();
            case CmdCode::fight_WorldBoss_getRankDamageVal:                     # 6827 当前轮次下 自己的最高伤害值
                return self::GetWorldBoss_RankDamageVal();
            case CmdCode::fight_WorldBoss_getSelfRank:                          # 6828 获取自己的排名信息
                return self::GetWorldBoss_GetSelfRank();
            case CmdCode::fight_WorldBoss_claimRewards:                         # 6829 领取奖励
                return self::GetWorldBoss_ClaimRewards();
            case CmdCode::fight_WorldBoss_settle:                               # 6830 世界boss结算
                return self::WorldBoss_settle();
            default:
                Err(ErrCode::cmd_err);
        }
    }

    /**
     * 6825 pvp 匹配一个对手
     * @return Resp
     */
    static function PvpMatchPlayer() {
        // 先从排行榜上随机取一个玩家的数据返回 -gwang 2024.10.30
//        $uid = req()->uid;
        $memKey = MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid);
        $mem = gMem();
        $length = $mem->zlen($memKey);
        if ($length > glc()->Rank_FightPower_OnListRank) {
            $length = glc()->Rank_FightPower_OnListRank;
        }
        $arr = $mem->zrange($memKey, 0, $length - 1);

        $uid = $arr[array_rand($arr)];                                          # 这里是否应该去掉自己呢? 算了不用,自己打自己也是一种挑战

        $pvpPlayer = UserProc::getUserGame(req()->zoneid, $uid);

        return Resp::ok($pvpPlayer);
    }

    /**
     * 6823 购买更多技能封印数量
     */
    static function BuySkillLockCount() {
        list($n) = req()->paras;                                                # 解锁数量
        my_Assert($n > ctx()->privateData()->skillLockerNumber, ErrCode::paras_err); # 参数异常
        $amt = 0;
        foreach (explode(",", glc()->Skill_LockBtn_BuyCount_Cost) as $str) {
            list($cnt, $cost) = explode(':', $str);
            if ($cnt == $n) {
                $amt = $cost;
                break;
            }
        }
        my_Assert($amt > 0, "消耗元宝数量配置出错!");
        my_Assert(ctx()->base(true)->Consume_Cash($amt), ErrCode::notenough_cash_msg);
        ctx()->privateData(true)->skillLockerNumber = $cnt;
        UserProc::updateUserInfo();
        return Resp::ok();
    }

    /**
     * 6822 封印/解封技能
     */
    static function LockSkill() {
        list($skillTypeId) = req()->paras;                                      # 技能类型ID
        $pri = ctx()->privateData(true);
//        my_Assert(in_array($skillTypeId, $pri->skillUnlockRecord), "技能尚未解锁!");
        if (in_array($skillTypeId, $pri->skillReLocked)) {                      # 解封
            StlUtil::arrayRemove($pri->skillReLocked, $skillTypeId);
        } else {                                                                # 封印
            my_Assert(count($pri->skillReLocked) < $pri->skillLockerNumber, "超出封印上限!");
            $pri->skillReLocked[] = $skillTypeId;
            TaskProc::OnCloseSkill();
        }
        return Resp::ok(array("task" => ctx()->task,));
    }

    /**
     * 6821 每天重置挑战红点
     */
    static function ResetChallange_RedMask() {

        ctx()->privateData(true)->challange_RedMask = 1;
        UserProc::updateUserInfo();
        return Resp::ok();
    }

    /**
     * 6819 主线挑战 -- 通关
     */
    static function MainTZPass() {
        list($gateId, $index, $killMonsterNum, $killBossNum) = req()->paras;                                   # 关卡id, 通关难度索引(1/2/3)
        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
//        isEditor() && $gateInfo = new Ins_GateInfo();
        $gateInfo = ctx()->gates->GateList->$gateId;
        my_Assert($gateInfo->pass, ErrCode::gate_GateNoUnlock);                 # 通关后解锁难度1
//        my_Assert($gateInfo->tz_state + 1 >= $index, ErrCode::gate_GateNoUnlock); # 通关上一难度解锁当前难度

        FightProc::funUnlock_mainChallengeGate_State(true, $gateId, $index);
        $gateInfo->tz_state = $index;

        TaskProc::OnPassMainChallengeGate_X_Num($gateId, $index);
        TaskProc::OnKillCommonNumMonster($killMonsterNum);
        TaskProc::OnKillleaderNumMonster($killBossNum);

        //TaskProc::Day7TaskReset();
        UserProc::updateUserInfo();
        return Resp::ok(array("task" => ctx()->task,
                    'privateState' => ctx()->privateState,
                        // 'funUnlockRecord' => ctx()->privateState->funUnlockRecord,
                        // 'funUnlockRecord_2' => ctx()->privateState->funUnlockRecord_2,
        ));
    }

    /**
     * 6820 主线挑战 -- 领取奖励
     */
    static function MainTZGetReward() {
        list($gateId, $index) = req()->paras;                                   # 关卡id, 通关难度索引(1/2/3)
        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
//        isEditor() && $gateInfo = new Ins_GateInfo();
        $gateInfo = ctx()->gates->GateList->$gateId;
        my_Assert($gateInfo->pass, ErrCode::gate_GateNoUnlock);                 # 通关后解锁难度1
        my_Assert($gateInfo->tz_state >= $index, ErrCode::gate_GateNoUnlock);   # 已解锁当前难度
        my_Assert(Bits::GetBitValue($gateInfo->tz_rewards, $index - 1) == false, ErrCode::gate_GatePriceHasReceive);
        $gateInfo->tz_rewards = Bits::SetBitValue($gateInfo->tz_rewards, $index - 1, true); # 更新领取记录

        $prize = "tz_reward" . $index;
        $mo = GameConfig::gate_getItem($gateId);
        StoreProc::AddMultiItemInStore($mo->$prize);
        UserProc::updateUserInfo();
        return Resp::ok(array(
                    'gold' => ctx()->baseInfo->gold,
                    'cash' => ctx()->baseInfo->cash,
                    'store' => ctx()->store,
                    'reward' => StoreProc::$reward,
                    'reward_Gem' => StoreProc::$reward_Gem,
                    'reward_equip' => StoreProc::$reward_equip,
        ));
    }

    /**
     * 6818 启灵解锁
     * @return type
     */
    public static function EvolveUnlock() {
        list($type, $id) = req()->paras; //$id废弃 因为玩家可能不安顺序点

        if ($type == 1) {
            $nextId = ctx()->gates->evolveMaxId_left + 1;
            my_Assert($id == $nextId, ErrCode::err_const_no);

            $mo = GameConfig::evolve_getItem($nextId);
            my_Assert($mo != null, ErrCode::err_const_no);
            my_Assert(ctx()->baseInfo->level >= $mo->level, ErrCode::evolve_canotUnlock_levelLimit);
            my_Assert(ctx()->baseInfo->gold >= $mo->needGold_unlock, ErrCode::notenough_gold_msg);

            ctx()->baseInfo->Consume_Gold($mo->needGold_unlock);
            ctx()->gates->evolveMaxId_left = $nextId;

            GuideProc::Shop_Guide_Trigger(ctx()->gates->evolveMaxId_left);

            TaskProc::OnCompleteNumQiLing();
        } else {
            $nextId = ctx()->gates->evolveMaxId_right + 1;
            my_Assert($id == $nextId, ErrCode::err_const_no);

            $dic = GameConfig::evolve();
            foreach ($dic as $key => $value) {
                if ($value->specificEvolveId == $nextId) {
                    $mo = $value;
                }
            }

            my_Assert(ctx()->baseInfo->level >= $mo->level, ErrCode::evolve_canotUnlock_levelLimit);
            my_Assert($mo != null, ErrCode::err_const_no);
            if ($mo->specificEvolveCost != null) {
                $cost = explode(',', $mo->specificEvolveCost);
                $costId = $cost[0];
                $costNum = $cost[1];
                my_Assert(StlUtil::dictHasProperty(ctx()->store->items, $costId) && ctx()->store->items->$costId >= $costNum, ErrCode::notenough_item);
                ctx()->store->removeItem($costId, $costNum);
            }
            ctx()->gates->evolveMaxId_right = $id;
            TaskProc::OnCompleteNumSpecialQiLing();
        }
        FightProc::Ranking_FightPower();
        UserProc::updateUserInfo();
        $ret = array(
            'task' => ctx()->task,
            'gold' => ctx()->baseInfo->gold,
            'items' => ctx()->store->items,
            'evolveMaxId_right' => ctx()->gates->evolveMaxId_right,
            'evolveMaxId_left' => ctx()->gates->evolveMaxId_left,
        );
        return Resp::ok($ret);
    }

    /**
     * 6807 扫荡
     * @return type
     */
    public static function FightSweep() {
        //list($gateId) = req()->paras;
// 2024.12.17 扫荡修改: 前3次免费, 后面可以一直看广告免费.(特权月卡可以免广告, 结合到一起, 特权月卡就可以一直刷了.)

        $passGateId = ctx()->gates->maxPassGateId();                            # 最高通关关卡id
        my_Assert($passGateId != 0, ErrCode::gate_NoSweep);                     # 还没有通关关卡
        $mo = GameConfig::gate_getItem($passGateId);                            # 关卡配置数据
        my_Assert(null != $mo, ErrCode::err_const_no);                          # 防御: 关卡配置找不到
        $gateName = $mo->gateName;
        $costTili = glc()->sweep_cost_tili;
        $curTili = ctx()->baseInfo->CurTili();
        my_Assert($curTili >= $costTili, ErrCode::notenough_tili);              # 检查: 体力不足
        # 2024.12.17 去掉了次数限制, 故这段废弃
//        if (ctx()->privateState->honourCardShop_ts == 0) {
//            $max = glc()->sweepMaxNum;
//            my_Assert(ctx()->gates->fightSweepNum < $max, ErrCode::gate_SweepMaxNum_limit);
//        }
        if (ctx()->gates->fightSweepNum < glc()->sweepMaxNum) {
            ctx()->gates->fightSweepTs = now();                                 # 前三次无冷却
        } else {
            ctx()->gates->fightSweepTs = now(60);                               # 下次扫荡时间戳(广告时需要间隔)
        }
        ctx()->gates->fightSweepNum += 1;                                       # 增加扫荡次数记录
        ctx()->baseInfo->Consume_tili($costTili);                               # 扣除体力
        ctx()->privateData(true)->battlePass_tili += $costTili;                 # 增加体力消耗记录
# 发放扫荡奖励↓
        $wavesArr = GameConfig::waves_getItemArray($passGateId);
        $count = count($wavesArr);
        $wavesMo = $wavesArr[$count - 1];

        $gold = $wavesMo->rewardGold;
        StoreProc::AddMultiItemInStore("1," . $gold);

        $oldLevel = ctx()->baseInfo->level;
        $exp = $wavesMo->rewardExp;
        StoreProc::AddMultiItemInStore("4," . $exp);
        $newLevel = ctx()->baseInfo->level;
        if ($wavesMo->rewardTuZhi != null) {
            $tuzhi = explode('-', $wavesMo->rewardTuZhi);
            $n = rand($tuzhi[0], $tuzhi[1]);
            $tuzhiArr = array();
            $item = GameConfig::item();
            foreach ($item as $id => $mo) {
                if ($mo->itemType == 100) {
                    $tuzhiArr[] = $id;
                }
            }
            for ($i = 0; $i < $n; $i++) {
                $index = rand(0, count($tuzhiArr) - 1);
                $goodsStr = $tuzhiArr[$index] . ',' . 1;
                $prizeArr[] = $goodsStr;
                StoreProc::AddMultiItemInStore($goodsStr);
            }
        }

        if ($wavesMo->rewardItem != null) {
            $reward = StoreProc::Distribute_Rewards($wavesMo->rewardItem);
            StoreProc::AddMultiItemInStore($reward);
        }

        if ($wavesMo->rewardGem != null) {
            $goodsStr = self::sweepRandReward($wavesMo->rewardGem);
            $str = explode(';', $goodsStr);
            $dic = GameConfig::gem();
            foreach ($str as $value) {
                $list = explode(',', $value);
                $posId = rand(1, 6);
                $qual = $list[0];
                foreach ($dic as $key => $gemMo) {
                    if ($gemMo->qual == $qual && $gemMo->position == $posId && $gemMo->isfixed_predicateId == 0) {
                        $gemStr = $gemMo->typeId . ',' . $list[1];

                        SystemProc::GetGem_GreaterOrangeQual_SweepMainGateIndex(req()->zoneid, ctx()->baseInfo->name, Ins_GateInfo::gateNum($passGateId), $gateName, $gemMo->typeId);
                        //StoreProc::PutGemInStore($gemMo->typeId, $list[1]);
                        StoreProc::AddMultiItemInStore($gemStr);
                        break;
                    }
                }
            }
        }
# 奖励逻辑结束.

        TaskProc::OnFightSweepGate();
        UserProc::updateUserInfo();
        $ret = array(
            'gold' => ctx()->baseInfo->gold,
            'cash' => ctx()->baseInfo->cash,
            'tili' => ctx()->baseInfo->tili,
            'tili_ts' => ctx()->baseInfo->tili_ts,
            'xp' => ctx()->baseInfo->xp,
            'maxXp' => ctx()->baseInfo->maxXp,
            'level' => ctx()->baseInfo->level,
            'fightSweepNum' => ctx()->gates->fightSweepNum,
            'fightSweepTs' => ctx()->gates->fightSweepTs,
            //'prizeArr' => $prizeArr,
            'store' => ctx()->store,
            'task' => ctx()->task,
            'reward' => StoreProc::$reward,
            'reward_Gem' => StoreProc::$reward_Gem,
            'reward_equip' => StoreProc::$reward_equip,
            'oldLevel' => $oldLevel,
            'newLevel' => $newLevel,
        );
        return Resp::ok($ret);
    }

    static function sweepRandReward($rewardStr) {
        $ctxArr = explode(';', $rewardStr);
        $numArr = explode('-', $ctxArr[0]);
        $num = rand($numArr[0], $numArr[1]);

        $rand = 0;
        $itemArr = explode(',', $ctxArr[1]);
        foreach ($itemArr as $value) {
            $arr = explode(':', $value);
            $itemId = $arr[0];
            $per = $arr[1];

            $rand += $per;
        }

        $res = "";
        for ($i = 0; $i < $num; $i++) {
            $start = 0;
            $end = 0;
            $randNum = rand(1, $rand);
            $id = 0;
            foreach ($itemArr as $str) {
                $arr = explode(':', $str);
                $itemId = $arr[0];
                $per = $arr[1];

                $end += $per;
                if ($randNum > $start && $randNum <= $end) {
                    $id = $itemId;
                    break;
                }
                $start = $end;
            }

            if ($id != 0) {
                $str = $id . ',1';
                if ($res == "") {
                    $res = $str;
                } else {
                    $res = $res . ';' . $str;
                }
            }
        }

        return $res;
    }

    /**
     * 6808 开始挑战 (主线关卡:扣除体力, 挑战关卡: 增加次数)
     */
    private static function StartFight() {
        list($gateId, $layerNum) = req()->paras;
        my_Assert($gateId > 0, ErrCode::paras_err);
        $mo = GameConfig::gate_getItem($gateId);
        my_Assert(null != $mo, ErrCode::err_const_no);

        if (Ints::Slice($gateId, 0, 1) == 9) {                                  # 爬塔模式
//            list($layerNum) = req()->paras;
            if ($layerNum != ctx()->gates()->TowerGateInfo()->CurLayer) {       # --起始层数校验
                Err(ErrCode::tower_layerNum);
            }
            if (ctx()->gates()->TowerGateInfo()->TodayChanNum < 1) {            # --剩余次数校验
                Err(ErrCode::tower_timeNo);
            }
            ctx()->gates()->TowerGateInfo()->TodayChanNum--;                    # --增加次数
        } else if (Ints::Slice($gateId, 0, 1) == 8) {                           # 兔羊模式
            // nothing todo 临时
        } else {                                                                # 主线剧情
            my_Assert(ctx()->base(true)->Consume_tili($mo->cost_tili), ErrCode::notenough_tili);
            ctx()->privateData(true)->battlePass_tili += $mo->cost_tili;
        }
        ctx()->gates()->lastStartFightTs = now();                               # 记录下开始战斗的时间戳(状态变量,用于校验战斗用时,排除作弊)
        UserProc::updateUserInfo();
        return Resp::ok(array("tili" => ctx()->baseInfo->tili, "tili_ts" => ctx()->baseInfo->tili_ts));
    }

    /**
     * 战斗模块 - 每日清理变量
     */
    public static function FightDailyClear() {
        //ctx()->gates->xunluo_quick_buyRecord = 0;
        ctx()->gates->fightSweepNum = 0;
        ctx()->gates->fightSweepTs = now();
        ctx()->gates()->TowerGateInfo()->RefreshSkillTimes = 0;
        ctx()->gates()->TowerGateInfo()->TodayChanNum = glc()->tower_daily_chanceNum;

        ctx()->privateState->challange_RedMask = 0;
    }

    /**
     * 6806 剧情回存
     * @return type
     */
    public static function PlotSav() {
        list($gateId) = req()->paras;

        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::err_const_no);
        ctx()->gates->GateList->$gateId->plotStart = 1;

        UserProc::updateUserInfo();
        $ret = array(
            'ok' => 1,
        );
        return Resp::ok($ret);
    }

// <editor-fold defaultstate="collapsed" desc="挑战模块">

    /**
     * 6810 挑战关卡: 更新锁定技能列表
     */
    public static function TowerUpdateLockskillList() {
        list($li_zd, $li_bd, $li_zds, $li_bds) = req()->paras;                  # 参数解析
        $t = ctx()->gates()->TowerGateInfo();                                   # 记忆技能刷新结果
        $t->skill_zhudong = $li_zd;
        $t->skill_beidong = $li_bd;
        $t->skill_zhudong_lockState = $li_zds;
        $t->skill_beidong_lockState = $li_bds;
        UserProc::updateUserInfo();
        return Resp::ok();
    }

    /**
     * 6809 挑战关卡: 刷新初始技能(扣除免费次数/cost)
     */
    public static function TowerRefreshSkills() {
        list($isFree, $li_zd, $li_bd, $li_zds, $li_bds) = req()->paras;         # 参数解析
        if ($isFree) {
            if (ctx()->gates()->TowerGateInfo()->RefreshSkillTimes > glc()->tower_daily_refreshChanceNum) {
                Err(ErrCode::tower_refreshNo);                                  # 免费次数不足
            }
        } else {
            list($type, $num) = explode(':', glc()->tower_refreshCost);         # 二级货币类型(1:金币,2:元宝):数量
            if ($type == 1) {                                                   # 金币
                my_Assert(ctx()->base(true)->Consume_Gold($num), ErrCode::notenough_gold_msg);
            } else if ($type == 2) {                                            # 元宝
                my_Assert(ctx()->base(true)->Consume_Cash($num), ErrCode::notenough_cash_msg);
            } else {
                Err(ErrCode::err_const_no, "检查刷新扣费配置信息!");
            }
        }
        $t = ctx()->gates()->TowerGateInfo();                                   # 记忆技能刷新结果
        $t->RefreshSkillTimes++;
        $t->skill_zhudong = $li_zd;
        $t->skill_beidong = $li_bd;
        $t->skill_zhudong_lockState = $li_zds;
        $t->skill_beidong_lockState = $li_bds;
        UserProc::updateUserInfo();

        $ret = array(
            'task' => ctx()->task,
        );
        return Resp::ok($ret);
    }

    /**
     * 6805 战斗: 复活花费
     * @return type
     * @version 2024年5月17日 重整利用为复活扣除消耗功能
     */
    public static function ReliveCost() {
        // 复活可以扣除复活币(暂无)或者元宝,(客户端看广告复活不需要跟服务器通讯)
        list($reliveNum) = req()->paras;
        $arr = explode(',', glc()->Relive_cost);
        my_Assert($reliveNum >= 0 && $reliveNum <= Count($arr), ErrCode::paras_err); # 参数范围>0
        $amt = $arr[$reliveNum];
        my_Assert(ctx()->base(true)->Consume_Cash($amt), ErrCode::notenought_yuanbao);
        UserProc::updateUserInfo();
        return Resp::ok();
    }

    /**
     * 6804 挑战关卡: 奖励领取
     * @return type
     */
    public static function GateChallengeRewards() {
        list($finalLayer, $killedMonster, $killedBoss) = req()->paras;          # 战斗结束时的层数

        $lastLayer = ctx()->gates()->TowerGateInfo()->CurLayer;
        $arr = GameConfig::waves_getItemArray(glc()->TowerGateId);
        TaskProc::OnFightNumChallengeGate();
        TaskProc::OnKillCommonNumMonster($killedMonster);
        TaskProc::OnKillleaderNumMonster($killedBoss);

        if ($finalLayer > $lastLayer) {
            foreach ($arr as $layerId => $layerMo) {
                if ($layerMo->waveId >= $lastLayer && $layerMo->waveId < $finalLayer) {
                    my_Assert($layerMo != null, ErrCode::err_const_no);
                    StoreProc::AddMultiItemInStore($layerMo->rewards);              # 发放奖励
                }
            }

            ctx()->gates()->TowerGateInfo()->CurLayer = $finalLayer;

            TaskProc::OnPassLayer_ChallengeGate($finalLayer - 1);
            UserProc::updateUserInfo();
            $ret = array(
                'store' => ctx()->store,
                'gold' => ctx()->base()->gold,
                'cash' => ctx()->base()->cash,
                'task' => ctx()->task,
            );
            return Resp::ok($ret);
        } else if ($finalLayer == $lastLayer) {
            $ret = array(
                'store' => ctx()->store,
                'gold' => ctx()->base()->gold,
                'cash' => ctx()->base()->cash,
                'task' => ctx()->task,
            );
            return Resp::ok($ret);
        }
        return Resp::err(ErrCode::tower_rewardNo);                              # 没有奖励
    }

// </editor-fold>

    /**
     * 6803 关卡选择
     * @return type
     */
    public static function SelectGate() {
        list($gateId) = req()->paras;

        ctx()->gates->CurrentGateId = $gateId;

        UserProc::updateUserInfo();
        $ret = array(
            'gates' => ctx()->gates,
        );
        return Resp::ok($ret);
    }

    /**
     * 6831 关卡宝箱一键领取
     * @return type
     */
    public static function AllGateBoxReceive() {
        //list() = req()->paras;

        $dic = ctx()->gates->GateList;
        foreach ($dic as $gateId => $item) {
            $ins_gateInfo = new Ins_GateInfo($item);
            $gateMo = GameConfig::gate_getItem($ins_gateInfo->GateId);
            $ts1 = $gateMo->first_ts1 * 60;
            if ($ins_gateInfo->MaxSeconds >= $ts1 && !in_array(1, $ins_gateInfo->FirstReward)) {
                $ins_gateInfo->FirstReward[] = 1;
                GuideProc::HeroChange_Guide_Trigger($gateId, 1);
                StoreProc::AddMultiItemInStore($gateMo->first_reward1);
            }
            
            $ts2 = $gateMo->first_ts2 * 60;
            if ($ins_gateInfo->MaxSeconds >= $ts2 && !in_array(2, $ins_gateInfo->FirstReward)) {
                $ins_gateInfo->FirstReward[] = 2;
                GuideProc::HeroChange_Guide_Trigger($gateId, 2);
                StoreProc::AddMultiItemInStore($gateMo->first_reward2);
            }
                      
            if ($ins_gateInfo->pass > 0 && !in_array(3, $ins_gateInfo->FirstReward)) {
                $ins_gateInfo->FirstReward[] = 3;
                GuideProc::HeroChange_Guide_Trigger($gateId, 3);
                StoreProc::AddMultiItemInStore($gateMo->first_reward3);
            }
           ctx()->gates->GateList->$gateId = $ins_gateInfo;
        }


        UserProc::updateUserInfo();
        $ret = array(
            'gates' => ctx()->gates,
            'store' => ctx()->store,
            'task' => ctx()->task,
            'gold' => ctx()->baseInfo->gold,
            'cash' => ctx()->baseInfo->cash,
            'reward' => StoreProc::$reward,
            'reward_Gem' => StoreProc::$reward_Gem,
            'reward_equip' => StoreProc::$reward_equip,
            'heros' => ctx()->heros,
            'funUnlockRecord' => ctx()->privateState->funUnlockRecord,
            'funUnlockRecord_2' => ctx()->privateState->funUnlockRecord_2,
            'funUnlockRecord_3' => ctx()->privateState->funUnlockRecord_3,
        );
        return Resp::ok($ret);
    }

    /**
     * 6802 章节宝箱的领取
     * @return type
     */
    public static function PassGateTsPrizeReceive() {
        list($gateId, $index) = req()->paras;

        $gateMo = GameConfig::gate_getItem($gateId);
        my_Assert($gateMo != null, ErrCode::err_const_no);

        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
        $gateInfo = ctx()->gates->GateList->$gateId;

        $tag = false;
        $prize = "";
        $mask = 0;
        switch ($index) {
            case 1:
                $ts = $gateMo->first_ts1 * 60;
                if ($gateInfo->MaxSeconds >= $ts || $gateInfo->pass > 0) {
                    $tag = true;
                }
                $mask = 1;
                $prize = $gateMo->first_reward1;
                break;
            case 2:
                $ts = $gateMo->first_ts2 * 60;
                if ($gateInfo->MaxSeconds >= $ts || $gateInfo->pass > 0) {
                    $tag = true;
                }
                $mask = 2;
                $prize = $gateMo->first_reward2;
                break;
            case 3:
                if ($gateInfo->pass > 0) {
                    $tag = true;
                }
                $mask = 3;
                $prize = $gateMo->first_reward3;
                break;
            default:
                break;
        }

        if ($tag) {
            my_Assert(!in_array($mask, $gateInfo->FirstReward), ErrCode::gate_GatePriceHasReceive);
            $gateInfo->FirstReward[] = $mask;
            GuideProc::HeroChange_Guide_Trigger($gateId, $index);

            StoreProc::AddMultiItemInStore($prize);
        }
        ctx()->gates->GateList->$gateId = $gateInfo;
        TaskProc::OnReceiveGateBoxReward();

        UserProc::updateUserInfo();
        $ret = array(
            'gates' => ctx()->gates,
            'store' => ctx()->store,
            'task' => ctx()->task,
            'gold' => ctx()->baseInfo->gold,
            'cash' => ctx()->baseInfo->cash,
            'reward' => StoreProc::$reward,
            'reward_Gem' => StoreProc::$reward_Gem,
            'reward_equip' => StoreProc::$reward_equip,
            'heros' => ctx()->heros,
            'funUnlockRecord' => ctx()->privateState->funUnlockRecord,
            'funUnlockRecord_2' => ctx()->privateState->funUnlockRecord_2,
            'funUnlockRecord_3' => ctx()->privateState->funUnlockRecord_3,
        );
        return Resp::ok($ret);
    }

    /**
     * [6801]关卡战斗结算
     * @return type
     */
    public static function Settle() {
        list($resultType, $gateId, $gold, $curTs, $pickups,
                $finalLayer, $finalHpPercent, $killMonsterNum, $killBossNum,
                $finalLevel, $reliveNum) = req()->paras;
        # 客户端需要增加参数: killmonserNum,killBosssNum, finalHpPercent(最终血量百分比)
        $gateMo = GameConfig::gate_getItem($gateId);
        my_Assert($gateMo != null, ErrCode::err_const_no);
        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
        $gateInfo = ctx()->gates->GateList->$gateId;
        $ts = $gateInfo->MaxSeconds;
        if ($curTs >= $ts) {
            $gateInfo->MaxSeconds = $curTs;
        }

        self::funUnlock_Gate($resultType, $gateId); //备注：这个接口的位置不能动 里面有关卡第一次胜利解锁的功能提示校验
        //self::subFunUnlock($resultType, $gateId);
        if ($resultType) {                                                      # 胜利
            self::skillUnlock_gate($resultType, $gateId); //备注 这个接口位置不能动
            GuideProc::GateBoxReceived_Guide_Trigger($gateId, 1);

            if (ctx()->gates->GateList->$gateId->pass == 0) {
                ctx()->gates->GateList->$gateId->pass = 1;

                $maxGateId = ctx()->gates->maxPassGateNumId();

                if ($maxGateId > 0) {
                    self::Ranking_MainGateIndex($maxGateId);
                    self::IsAchievedMainGate_PassReward($maxGateId);
                }
            }

            TaskProc::OnPassGate_X($gateId);                                    # 刷新任务进度: 通关第X关
            TaskProc::OnPassGate_X_state($gateId);
            if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {
                ctx()->gates()->UnlockNextPlotGate($gateId);                    # 解锁下一主线关卡
//                ctx()->gates()->UnlockMainChallengeGate($gateId);              # 挑战关卡解锁逻辑. -gwang 2024年4月15日
            } else {                                                            # 不是主线关卡, 暂时没有其他逻辑
            }
//            StoreProc::AddMultiItemInStore($gateMo->reward_win);                # 发放胜利奖励(2024.5.30 过期)
        } else {
            ctx()->gates->GateList->$gateId->fightNum_fail += 1;
            self::skillUnlock_fightNum($resultType); //这个接口位置不能动
        }
//        else {                                                                # 失败
////            StoreProc::AddMultiItemInStore($gateMo->reward_fail);               # 发放失败奖励(2024.5.30 过期)
//        }

        StoreProc::AddMultiItemInStore($pickups);                               # 战场拾取道具直接入背包
        //ctx()->base()->Add_Gold($gold);                                         # 战场拾取的金币直接入背包
        //ctx()->base()->Add_Exp($exp);
        $waveMo = GameConfig::waveItem_getItem($gateId, $finalLayer);
        my_Assert(null != $waveMo, ErrCode::err_const_no);
        my_Assert(now() - ctx()->gates->lastStartFightTs > $waveMo->minTs, ErrCode::err_opTimeTooShort); # todo:校验战斗耗时 2025年4月10日16:29:46
        $oldLevel = ctx()->baseInfo->level;
        StoreProc::AddMultiItemInStore('4,' . $waveMo->rewardExp);
        //ctx()->base()->Add_Exp($waveMo->rewardExp);                             # 指挥官经验
        $newLevel = ctx()->baseInfo->level;
        if ($oldLevel != $newLevel) {
            ctx()->privateData(true)->oldLevel = $oldLevel;
            ctx()->privateData(true)->upLevel = $newLevel;
        }

        //ctx()->base()->Add_Gold($waveMo->rewardGold);                           # 金币奖励
        //$pickups .= ";1," . $gold + $waveMo->rewardGold;

        $str = "1," . $gold + $waveMo->rewardGold;
        StoreProc::AddMultiItemInStore($str);

        if ($waveMo->rewardItem != null) {
            $reward = StoreProc::Distribute_Rewards($waveMo->rewardItem);
            StoreProc::AddMultiItemInStore($reward);

//            if(count(StoreProc::$reward_equip) > 0){
//                self::funUnlock_equip_firstTime();
//            }
        }

        # 图纸奖励: 数量min-max, 部位随机
        if (strlen($waveMo->rewardTuZhi) > 0 && str_contains($waveMo->rewardTuZhi, '-')) {
            list($tz_min, $tz_max) = explode('-', $waveMo->rewardTuZhi);        # 图纸数量
            $tz_n = rand($tz_min, $tz_max);
            # 图纸部位数据源 1001, 1002, 1003, 1004, 1005, 1006
            for ($i = 0; $i < $tz_n; $i++) {
                $id = 1000 + rand(1, 6);
                StoreProc::AddMultiItemInStore("$id,1");                        # 获得图纸
                //$pickups .= ";$id,1";
            }
        }
        # 宝石奖励: 数量min-max;品质:权重,品质:权重...
        if (strlen($waveMo->rewardGem) > 0) {
            //self::funUnlock_Gem();

            list($gs_num, $gs_props) = explode(';', $waveMo->rewardGem);
            list($gem_min, $gem_max) = explode('-', $gs_num);                   # 宝石数量
            $gem_n = rand($gem_min, $gem_max);
            $arr = explode(",", $gs_props);
            $pool = array();
            $n = 0;
            foreach ($arr as $str) {
                list($qual, $props) = explode(':', $str);
                $pool[] = array('q' => $qual, 'p' => $props);
                $n += $props;
            }
            for ($i = 0; $i < $gem_n; $i++) {                                   # 随机n块宝石
                $r = rand(1, $n);                                                  # 投色子
                $l = 0;
                foreach ($pool as $item) {
                    if ($r <= ($l + $item['p'])) {
                        $gemId = $item['q'] * 100000 + rand(1, 6) * 1000;
                        SystemProc::GetGem_GreaterOrangeQual_MainGate(req()->zoneid, ctx()->baseInfo->name, Ins_GateInfo::gateNum($gateId), $gateMo->gateName, $gemId); //广播
                        //StoreProc::PutGemInStore($gemId);                       # 发放宝石并退出本次投色子
                        //$pickups .= ";$gemId,1";
                        StoreProc::AddMultiItemInStore("$gemId,1");

                        break;
                    }
                    $l += $item['p'];                                             # 累计到下一段
                }
            }
        }

        ctx()->gates->GateList->$gateId->fightNum += 1;

        GuideProc::MainTaskRewardReceived_Guide_Trigger($gateId, ctx()->gates->GateList->$gateId->fightNum);

        //TaskProc::Day7TaskReset();
        TaskProc::OnFightNumMainGate();
        TaskProc::OnKillCommonNumMonster($killMonsterNum);
        TaskProc::OnKillleaderNumMonster($killBossNum);
        TaskProc::OnFightGate_X($gateId);

        if ($gateId == 11000) {
            ctx()->gates()->UnlockNextPlotGate(11000);
            ctx()->gates(true)->CurrentGateId = 11001;
            StlUtil::dictRemove(ctx()->gates->GateList, 11000);
            ctx()->baseInfo->animation = 1;
        }

        UserProc::updateUserInfo();
        $ret = array(
            'gates' => ctx()->gates,
            'store' => ctx()->store,
            'task' => ctx()->task,
            'baseInfo' => ctx()->base(),
            'gold' => $gold + $waveMo->rewardGold,
            'exp' => $waveMo->rewardExp,
            //'rewardStr' => $pickups
            'reward' => StoreProc::$reward,
            'reward_Gem' => StoreProc::$reward_Gem,
            'reward_equip' => StoreProc::$reward_equip,
            'oldLevel' => $oldLevel,
            'newLevel' => $newLevel,
            //'funUnlockRecord' => ctx()->privateState->funUnlockRecord,
            //'funUnlockRecord_2' => ctx()->privateState->funUnlockRecord_2,
            //'LoginDays'=> ctx()->privateState->LoginDays,            
            //'skillUnlockRecord' => ctx()->privateState->skillUnlockRecord,
            'heros' => ctx()->heros,
            'privateState' => ctx()->privateState,
        );
        return Resp::ok($ret);
    }

    /**
     * 装备概率结算
     * @param type $equipStr
     */
    private static function EquipSettle($equipStr) {
        StoreProc::DistributeItemsBox($itemId);
    }

// <editor-fold defaultstate="collapsed" desc="功能解锁">

    /**
     * 检测功能解锁的 关卡
     * @param type $resultType
     * @param type $gateId
     * @return type
     */
    static function funUnlock_Gate($resultType, $gateId) {
        $dic = GameConfig::fun_unlock();
        foreach ($dic as $id => $mo) {
            if ($mo->unlockTip == 1) {//$mo->unlockGateId == $gateId
                $tag = false;
                if ($mo->unlockType1 != null) {
                    //1:参与战斗结束即可  2战斗胜利  3某场战斗参加N次数才行
                    switch ($mo->unlockType1) {
                        case Enum_FunUnlockType::battle_Gate:
                            if ($mo->unlockParas1 == $gateId && ctx()->gates->GateList->$gateId->fightNum == 0) {
                                $tag = true;
                            }
                            break;
                        case Enum_FunUnlockType::passBattle_Gate:
                            if ($resultType == true && $mo->unlockParas1 == $gateId && ctx()->gates->GateList->$gateId->pass == 0) {
                                $tag = true;
                            }

                            break;
                        default:
                            break;
                    }
                }

                if ($mo->unlockType2 != null) {
                    //1:参与战斗结束即可  2战斗胜利  3某场战斗参加N次数才行
                    switch ($mo->unlockType2) {
                        case Enum_FunUnlockType::battle_Gate:
                            if ($mo->unlockParas2 == $gateId && ctx()->gates->GateList->$gateId->fightNum == 0) {
                                $tag = true;
                            }
                            break;
                        case Enum_FunUnlockType::passBattle_Gate:
                            if ($resultType == true && $mo->unlockParas2 == $gateId && ctx()->gates->GateList->$gateId->pass == 0) {
                                $tag = true;
                            }

                            break;
                        default:
                            break;
                    }
                }

                if ($tag && !in_array($id, ctx()->privateState->funUnlockRecord_2)) {
                    ctx()->privateData(true)->funUnlockRecord[] = $id;
                    ctx()->privateData(true)->funUnlockRecord_2[] = $id;
                    if ($id == 13 || $id == 16 || $id == 14) {
                        self::unlockGuideType($id);
                        //ctx()->privateData(true)->funUnlockRecord_3[] = 
                    }
                    self::SubFunDateInit_FunUnlock($id);
                }
            }
        }
    }

    public static function unlockGuideType($id) {
        GuideProc::Qingling_EquipWear_Guide_Trigger($id);
//        $type = 0;
//        switch ($id) {           
//            case 16://启灵
//                $type = E_GuideTypeState::Qingling_Guide;
//                break;
//            case 14://装备 首次获得装备 装备功能解锁 同时开启装备穿戴引导 
//                $type = E_GuideTypeState::EquipWear_Guide;
//                break;                     
//            default:
//                break;
//        }
//        
//        if($type >0 && !in_array($type,ctx()->privateData(true)->funUnlockRecord_3)){
//            ctx()->privateData(true)->funUnlockRecord_3[] = $type;
//        }
        //return $type;
    }

    /**
     *  初次得到装备 功能解锁
     */
    static function funUnlock_equip_firstTime() {
        $dic = GameConfig::fun_unlock();
        foreach ($dic as $id => $mo) {
            $tag = false;
            if ($mo->unlockTip == 1) {//$mo->unlockGateId == $gateId
                if ($mo->unlockType1 != null && $mo->unlockType1 == Enum_FunUnlockType::equip_firstTime && count(StlUtil::dictToArray(ctx()->store->equip)) == 0) {
                    $tag = true;
                }

                if ($mo->unlockType2 != null && $mo->unlockType2 == Enum_FunUnlockType::equip_firstTime && count(StlUtil::dictToArray(ctx()->store->equip)) == 0) {
                    $tag = true;
                }
            }

            if ($tag && !in_array($id, ctx()->privateState->funUnlockRecord_2)) {
                ctx()->privateData(true)->funUnlockRecord[] = $id;
                ctx()->privateData(true)->funUnlockRecord_2[] = $id;

                if ($id == 13 || $id == 16 || $id == 14) {
                    self::unlockGuideType($id);
                    //ctx()->privateData(true)->funUnlockRecord_3[] = 
                }
                self::SubFunDateInit_FunUnlock($id);
            }
        }
    }

    /**
     *  玩家等级要求 功能解锁
     */
    static function funUnlock_userLv($level) {
        $dic = GameConfig::fun_unlock();
        foreach ($dic as $id => $mo) {
            $tag = false;
            if ($mo->unlockTip == 1) {//$mo->unlockGateId == $gateId
                if ($mo->unlockType1 != null && $mo->unlockType1 == Enum_FunUnlockType::userLv && $mo->unlockParas1 == $level) {
                    $tag = true;
                }

                if ($mo->unlockType2 != null && $mo->unlockType2 == Enum_FunUnlockType::userLv && $mo->unlockParas2 == $level) {
                    $tag = true;
                }
            }
            if ($tag && !in_array($id, ctx()->privateState->funUnlockRecord_2)) {
                ctx()->privateData(true)->funUnlockRecord[] = $id;
                ctx()->privateData(true)->funUnlockRecord_2[] = $id;
                if ($id == 13 || $id == 16 || $id == 14) {
                    self::unlockGuideType($id);
                    //ctx()->privateData(true)->funUnlockRecord_3[] = self::unlockGuideType($id);
                }
                self::SubFunDateInit_FunUnlock($id);
            }
        }
    }

    /**
     *  主线挑战 功能解锁
     */
    static function funUnlock_mainChallengeGate_State($result, $gateId, $state) {
        $dic = GameConfig::fun_unlock();
        foreach ($dic as $id => $mo) {
            $tag = false;
            if ($mo->unlockTip == 1) {//$mo->unlockGateId == $gateId
                if ($mo->unlockType1 != null && $result = true && $mo->unlockType1 == Enum_FunUnlockType::mainChallengeGate_State) {
                    $str = explode(',', $mo->unlockParas1);
                    $uGateId = $str[0];
                    $gateState = $str[1];

                    if ($uGateId == $gateId && StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId) && ctx()->gates->GateList->$gateId->tz_state == $gateState - 1) {
                        $tag = true;
                    }
                }

                if ($mo->unlockType2 != null && $result = true && $mo->unlockType2 == Enum_FunUnlockType::mainChallengeGate_State) {
                    $str = explode(',', $mo->unlockParas2);
                    $uGateId = $str[0];
                    $gateState = $str[1];
                    if ($uGateId == $gateId && StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId) && ctx()->gates->GateList->$gateId->tz_state == $gateState - 1) {
                        $tag = true;
                    }
                }
            }

            if ($tag && !in_array($id, ctx()->privateState->funUnlockRecord_2)) {
                ctx()->privateData(true)->funUnlockRecord[] = $id;
                ctx()->privateData(true)->funUnlockRecord_2[] = $id;
                if ($id == 13 || $id == 16 || $id == 14) {
                    self::unlockGuideType($id);
                    //ctx()->privateData(true)->funUnlockRecord_3[] = self::unlockGuideType($id);
                }
                self::SubFunDateInit_FunUnlock($id);
            }
        }
    }

    /**
     * 查看某功能是否解锁
     * @param type $id
     */
    static function isFunUnlock($id) {
        $funMo = GameConfig::fun_unlock_getItem($id);
        if ($funMo->unlockType1 != null && self::unlockCondition($funMo->unlockType1, $funMo->unlockParas1)) {
            return true;
        }

        if ($funMo->unlockType2 != null && self::unlockCondition($funMo->unlockType2, $funMo->unlockParas2)) {
            return true;
        }
        return false;
    }

    /**
     * 解锁条件id
     * @param type $conditionId
     */
    static function unlockCondition($conditionId, $paras) {
        $funUnlock = false;
        switch ($conditionId) {
            case Enum_FunUnlockType::battle_Gate:
                $gateId = $paras;
                if (ctx()->gates->GateList->$gateId->fightNum > 0) {
                    $funUnlock = true;
                }
                break;
            case Enum_FunUnlockType::passBattle_Gate:
                $gateId = $paras;
                if (ctx()->gates->GateList->$gateId->pass >= 1) {
                    $funUnlock = true;
                }

                break;
            case Enum_FunUnlockType::equip_firstTime:
                if (ctx()->store->equip != null) {
                    $funUnlock = true;
                }

                break;
            case Enum_FunUnlockType::userLv:
                if (ctx()->baseInfo->level >= $paras) {
                    $funUnlock = true;
                }

                break;
            case Enum_FunUnlockType::mainChallengeGate_State:
                $str = explode(',', $paras);
                $uGateId = $str[0];
                $gateState = $str[1];

                if (StlUtil::dictHasProperty(ctx()->gates->GateList, $uGateId) && ctx()->gates->GateList->$uGateId->tz_state >= $gateState) {
                    $funUnlock = true;
                }

                break;
            default:
                break;
        }
        return $funUnlock;
    }

    /**
     * 次级功能解锁数据初始化
     */
    static function SubFunDateInit_FunUnlock($type) {
        $dic = GameConfig::subfun_unlock();
        foreach ($dic as $id => $mo) {
            if ($mo->funTypeId != $type) {
                continue;
            }

            if ($mo->funTypeId == 6 && $mo->id == Enum_SubFunType::Day7_Happy) {
                TaskProc::Day7TaskReset();
            }
            if ($mo->funTypeId == 5 && $mo->id == Enum_SubFunType::DailyTask) {
                TaskProc::DailyTaskReset(true);
            }

            if ($mo->funTypeId == 5 && $mo->id == Enum_SubFunType::WeekTask) {
                TaskProc::WeekTaskReset(true);
            }

            if ($mo->funTypeId == 5 && $mo->id == Enum_SubFunType::Day7_Sign) {
                ActiveProc::DailyResetDay7Task(true);
            }

            if ($mo->funTypeId == 21 && $mo->id == Enum_SubFunType::Day7_Sign_NewPlayer) {
                ActiveProc::InitDay7_Sign_NewPlayer(true);
                ctx()->privateState->day7_drawed_newPlayer_startTs = now();
            }
        }
    }

    /**
     * 次级功能解锁数据初始化
     */
    static function SubFunDateInit_Config() {
        $dic = GameConfig::subfun_unlock();
        foreach ($dic as $id => $mo) {
            if ($mo->type == 3 && $mo->id == Enum_SubFunType::LimitTsSale && ctx()->privateState->nextDayLogin == 0 && now() >= $mo->startTs) {
                ActiveProc::ResetLimitTsBuy();
            }

            if ($mo->type == 3 && $mo->id == Enum_SubFunType::ActivePoint_BattlePass && ctx()->privateState->battlePass_activePoint_refersh_ts == 0 && now() >= $mo->startTs) {
                ctx()->privateState->battlePass_activePoint_refersh_ts = TimeUtil::getNextDayTs($mo->startTs, $mo->ts);
                ctx()->privateData(true)->battlePass_activePoint_cost_ts = 0;
                ctx()->privateData(true)->battlePass_taskPoint = 0;
                ActiveProc::ResetBattlePassReward(Enum_SubFunType::ActivePoint_BattlePass);
            }
            if ($mo->type == 3 && $mo->id == Enum_SubFunType::Tili_BattleBass && ctx()->privateState->battlePass_tili_refersh_ts == 0 && now() >= $mo->startTs) {
                ctx()->privateState->battlePass_tili_refersh_ts = TimeUtil::getNextDayTs($mo->startTs, $mo->ts);
                ctx()->privateData(true)->battlePass_tili_cost_ts = 0;
                ctx()->privateData(true)->battlePass_tili = 0;
                ActiveProc::ResetBattlePassReward(Enum_SubFunType::Tili_BattleBass);
            }
        }
    }

// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="技能解锁">

    /**
     * 检测技能解锁的 1 关卡解锁，游玩到一定关卡解锁技能
     * @param type $resultType
     * @param type $gateId
     * @return type
     */
    static function skillUnlock_gate($resultType, $gateId) {
        $dic = GameConfig::skills();

        $gateIndex = Ins_GateInfo::gateNum($gateId);
        foreach ($dic as $id => $mo) {
            if ($mo->unlock_acc_id_new == null) {
                continue;
            }
            $strList = explode(':', $mo->unlock_acc_id_new);
            $unlockType = $strList[0];
            $unlockId = $strList[1];

            if ($unlockType == 1 && $unlockId == $gateIndex && $resultType == true && ctx()->gates->GateList->$gateId->pass == 0 && !in_array($mo->typeId, ctx()->privateState->skillUnlockRecord)) {
                ctx()->privateData(true)->skillUnlockRecord[] = $mo->typeId;
            }
        }
    }

    /**
     * 检测技能解锁的 2://皮肤解锁，获取到人物解锁后对应皮肤技能
     * @param type $resultType
     * @param type $gateId
     * @return type
     */
    static function skillUnlock_heroUnlock($heroId) {
        $dic = GameConfig::skills();
        foreach ($dic as $id => $mo) {
            if ($mo->unlock_acc_id_new == null) {
                continue;
            }

            $strList = explode(':', $mo->unlock_acc_id_new);
            $unlockType = $strList[0];
            $unlockId = $strList[1];

            if ($unlockType != 2) {
                continue;
            }

            $heroMo = GameConfig::hero_getItem($heroId);
            $heroTypeId = $heroMo->typeID;
            $isUnlock = ctx()->heros->Dic->$heroId->isUnlock;

            if ($unlockId == $heroTypeId && $isUnlock == 0 && !in_array($mo->typeId, ctx()->privateState->skillUnlockRecord)) {
                ctx()->privateData(true)->skillUnlockRecord[] = $mo->typeId;
            }
        }
    }

    /**
     * 检测技能解锁的  3://玩家失败X次后解锁
     * @param type $resultType
     * @param type $gateId
     * @return type
     */
    static function skillUnlock_fightNum($resultType) {

        if ($resultType) {
            return;
        }

        $GateList = ctx()->gates->GateList;
        $num = 0;
        foreach ($GateList as $gateId => $Ins_GateInfo) {
            $num += $Ins_GateInfo->fightNum_fail;
        }

        $dic = GameConfig::skills();
        foreach ($dic as $id => $mo) {
            if ($mo->unlock_acc_id_new == null) {
                continue;
            }

            $strList = explode(':', $mo->unlock_acc_id_new);
            $unlockType = $strList[0];
            $unlockId = $strList[1];

            if ($unlockType != 3) {
                continue;
            }

            if ($num == $unlockId && !in_array($mo->typeId, ctx()->privateState->skillUnlockRecord)) {
                ctx()->privateData(true)->skillUnlockRecord[] = $mo->typeId;
            }
        }
    }

    /**
     * 玩家等级解锁技能
     * @param type $curLevel
     */
    static function skillUnlock_userLevel($curLevel) {
        $dic = GameConfig::skills();
        foreach ($dic as $id => $mo) {
            if ($mo->unlock_acc_id_new == null) {
                continue;
            }

            $strList = explode(':', $mo->unlock_acc_id_new);
            $unlockType = $strList[0];
            $unlockId = $strList[1];

            if ($unlockType != 5) {                                             // 玩家等级
                continue;
            }
            if ($unlockId == $curLevel && !in_array($mo->typeId, ctx()->privateState->skillUnlockRecord)) {
                ctx()->privateData(true)->skillUnlockRecord[] = $mo->typeId;
            }
        }
    }

// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="排行榜">

    /**
     * 参与主线关卡排行榜
     * @param type $gateIndex
     */
    public static function Ranking_MainGateIndex($maxGateIndex) {
        $memKey = MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid);
        $mem = gMem();

        $uid = req()->uid;
        $score = self::GetRankScoreUid($uid, 1);
        if ($maxGateIndex > $score) {
            $arr = array();
            $arr["$uid"] = self::createScore($maxGateIndex);
            $mem->zadd($memKey, $arr);
        }

        $length = $mem->zlen($memKey);
        if ($length > glc()->Rank_MainGateIndex_OnListRank) {
            $num = $length - glc()->Rank_MainGateIndex_OnListRank;
            $mem->zremrangebyrank($memKey, 0, $num - 1);
        }
    }

    public static function createScore($score) {
        if ($score > 0) {
            $newScore = $score . '.' . (9999999999 - now());
            return $newScore;
        }
        return 0;
    }

    /**
     * 战力榜
     * @param type $gateIndex
     */
    public static function Ranking_FightPower() {
        $memKey = MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid);
        $mem = gMem();

        $uid = req()->uid;

        $score = self::GetRankScoreUid($uid, 2);
        //$power = self::countUserFightPower();
        $power = FightPower_Calculate::GetFightPower();
        $arr = array();
        $arr["$uid"] = self::createScore($power);
        $mem->zadd($memKey, $arr);
        if ($power >= $score) {
            self::IsAchievedFightPower_PassReward($power);
        }

        $length = $mem->zlen($memKey);
        if ($length > glc()->Rank_FightPower_OnListRank) {
            $num = $length - glc()->Rank_FightPower_OnListRank;
            $mem->zremrangebyrank($memKey, 0, $num - 1);
        }
    }

    public static function GetRankScoreUid($uid_rank, $type) {
        if ($type == 1) {
            $score = gMem()->zscore(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), $uid_rank);
        } else {
            $score = gMem()->zscore(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), $uid_rank);
        }

        if ($score == null) {
            $score = 0;
        }

        return intval($score);
    }

    /**
     * 6811 获取主线关卡排行榜信息
     * @return type
     */
    public static function GetRankInfo() {
        list($type) = req()->paras;

        $selfIsHasRank = 0; //本人是否上榜 0未上榜没有排名 1上榜则selfRank就是排名
        $selfExtraInfo = 0;
        $isExistFinishReward = 0;
        $isExistFinishReward_other = 0;
        if ($type == 1) {
            $list = gMem()->zrevrange(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
            $selfExtraInfo = ctx()->gates->maxPassGateNumId();

            $isExistFinishReward = self::isExistNoDrawed_MainGate();
            $isExistFinishReward_other = self::isExistNoDrawed_FightPower();
        } else {
            $list = gMem()->zrevrange(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
            //$selfExtraInfo = self::countUserFightPower();
            $selfExtraInfo = FightPower_Calculate::GetFightPower();

            $isExistFinishReward = self::isExistNoDrawed_FightPower();
            $isExistFinishReward_other = self::isExistNoDrawed_MainGate();
        }

        if ($isExistFinishReward == 1) {
            $isExistFinishReward = true;
        } else {
            $isExistFinishReward = false;
        }

        if ($isExistFinishReward_other == 1) {
            $isExistFinishReward_other = true;
        } else {
            $isExistFinishReward_other = false;
        }

        $selfRank = null;
        $retArr = array();
        if (count($list) > 0) {
            foreach ($list as $uid => $score) {
                $rankInfo = self::initOtherUidRankInfo($uid, $score, $type);
                if ($rankInfo->uid == req()->uid) {
                    $selfIsHasRank = 1;
                    $selfRank = $rankInfo;
                }

                $retArr[] = $rankInfo;
            }
        }

        if ($selfRank == null) {
            $selfRank = self::initOtherUidRankInfo(req()->uid, $selfExtraInfo, $type);
        }

        UserProc::updateUserInfo();
        $ret = array(
            'rankInfo' => $retArr,
            'selfRank' => $selfRank,
            'selfIsHasRank' => $selfIsHasRank,
            'isExistFinishReward' => $isExistFinishReward,
            'isExistFinishReward_other' => $isExistFinishReward_other,
        );
        return Resp::ok($ret);
    }

    /**
     * 初始化玩家rank
     * @param type $uid
     * @param type $score
     * @return \loyalsoft\Ins_rank
     */
    static function initOtherUidRankInfo($uid, $score, $type = null) {
        $ins_rank = new Ins_rank();

        if ($type == 1) {
            $lv = gMem()->zrevrank(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), $uid);
        } else if ($type == 2) {
            $lv = gMem()->zrevrank(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), $uid);
        } elseif ($type == 3) {
            $memKey = self::GetWorldBoss_DamageMemKey();
            $lv = gMem()->zrevrank($memKey, $uid);
        }

        if ($lv === null) {
            $lv = -1;
        }

        $ins_rank->rank = $lv + 1;
        $ins_rank->uid = $uid;
        $userInfo = UserProc::getUserGame(req()->zoneid, $uid);
        $ins_rank->name = $userInfo->baseInfo->name;
        $ins_rank->headImg = $userInfo->baseInfo->headImg;
        $ins_rank->score = intval($score);
        return $ins_rank;
    }

    /**
     * 6812 获取排行榜内玩家的装备信息
     * @return type
     */
    public static function GetUidEquipInfo_Rank() {
        list($uid) = req()->paras;
        $userInfo = UserProc::getUserGame(req()->zoneid, $uid);

        $store = $userInfo->store;
        $heros = $userInfo->heros;
        $gates = $userInfo->gates;

        UserProc::updateUserInfo();
        $ret = array(
            'store' => $store,
            'heros' => $heros,
            'gates' => $gates,
        );
        return Resp::ok($ret);
    }

    /**
     * 通关奖励是否达成
     * @param type $maxGateIndex
     */
    public static function IsAchievedMainGate_PassReward($maxGateIndex) {
        $rewards = GameConfig::rank_passgatereward();

        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        foreach ($rewards as $passGateId => $mo) {
            if ($passGateId == $maxGateIndex && !gMem()->hexists($memKey, $maxGateIndex)) {
                $ins_rank = new Ins_rank();
                $ins_rank->uid = req()->uid;
                $ins_rank->name = ctx()->baseInfo->name;
                $ins_rank->headImg = ctx()->baseInfo->headImg;
                $ins_rank->score = $passGateId;
                gMem()->hset($memKey, $maxGateIndex, $ins_rank);
                break;
            }
        }
    }

    /*
     * 战力奖励是否达成
     */

    public static function IsAchievedFightPower_PassReward($power) {
        $rewards = GameConfig::rank_fightpowerreward();

        $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        foreach ($rewards as $fightPower => $mo) {
            if ($power >= $fightPower && !gMem()->hexists($memKey, $fightPower)) {
                $ins_rank = new Ins_rank();
                $ins_rank->uid = req()->uid;
                $ins_rank->name = ctx()->baseInfo->name;
                $ins_rank->headImg = ctx()->baseInfo->headImg;
                $ins_rank->score = $fightPower;
                gMem()->hset($memKey, $fightPower, $ins_rank);
            }
        }
    }

    public static function isExistNoDrawed_MainGate() {
        $isExistFinishReward = 0;
        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);
        foreach ($dic as $gateId => $ins_rank) {
            if (!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate)) {
                $isExistFinishReward = 1;
                break;
            }
        }

        ctx()->privateData(true)->redTip_RewardMainGateRank = $isExistFinishReward;
        return $isExistFinishReward;
    }

    public static function isExistNoDrawed_FightPower() {
        $isExistFinishReward = 0;
        $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);
        foreach ($dic as $fightPower => $ins_rank) {
            if (!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower)) {
                $isExistFinishReward = 1;
                break;
            }
        }

        ctx()->privateData(true)->redTip_RewardFightPowerRank = $isExistFinishReward;
        return $isExistFinishReward;
    }

    /**
     * 6813
     * @return type
     */
    public static function GetmainGate_RankRewardInfo() {
        //list($type) = req()->paras;

        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);

        if ($dic == null) {
            $dic = new \stdClass();
        }

        UserProc::updateUserInfo();
        $ret = array(
            'rankReward' => $dic,
        );
        return Resp::ok($ret);
    }

    /**
     * 6814
     * @return type
     */
    public static function GetFightPower_RankRewardInfo() {
        //list($type) = req()->paras;

        $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);

        if ($dic == null) {
            $dic = new \stdClass();
        }

        UserProc::updateUserInfo();
        $ret = array(
            'rankReward' => $dic,
        );
        return Resp::ok($ret);
    }

    /**
     * 6815 领取通关荣誉榜奖励
     * @return type
     */
    public static function ReceiveRankReward_MainGate() {
        list($gateId) = req()->paras;

        my_Assert(!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate), ErrCode::rankReward_HasReceive);

        $mo = GameConfig::rank_passgatereward_getItem($gateId);
        my_Assert($mo != null, ErrCode::err_const_no);

        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        if (gMem()->hexists($memKey, $gateId)) {
            StoreProc::AddMultiItemInStore($mo->reward);
            ctx()->privateData(true)->rankReward_drawed_MainGate[] = $gateId;

            TaskProc::OnRankPrize_Num();
        }

        $tag = self::isExistNoDrawed_MainGate();
        UserProc::updateUserInfo();
        $ret = array('redTip' => $tag, 'task' => ctx()->task, 'store' => ctx()->store, 'cash' => ctx()->baseInfo->cash, 'reward' => StoreProc::$reward);
        return Resp::ok($ret);
    }

    /**
     * 6816 领取战力荣誉榜奖励
     * @return type
     */
    public static function ReceiveRankReward_FightPower() {
        list($fightPower) = req()->paras;

        my_Assert(!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower), ErrCode::rankReward_HasReceive);

        $mo = GameConfig::rank_fightpowerreward_getItem($fightPower);
        my_Assert($mo != null, ErrCode::err_const_no);

        $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        if (gMem()->hexists($memKey, $fightPower)) {
            StoreProc::AddMultiItemInStore($mo->reward);
            ctx()->privateData(true)->rankReward_drawed_fightPower[] = $fightPower;
            TaskProc::OnFightRankPrize_Num();
        }

        $tag = self::isExistNoDrawed_FightPower();

        UserProc::updateUserInfo();
        $ret = array('redTip' => $tag, 'task' => ctx()->task, 'store' => ctx()->store, 'cash' => ctx()->baseInfo->cash, 'reward' => StoreProc::$reward);
        return Resp::ok($ret);
    }

    /**
     * 6824 排行奖励一键领取
     */
    static function ReceiveRankReward() {
        list($type) = req()->paras;                                                # 解锁数量
        if ($type == 1) {
            $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
            $dic = gMem()->hgetall($memKey);
            foreach ($dic as $gateId => $ins_rank) {
                if (!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate)) {
                    $mo = GameConfig::rank_passgatereward_getItem($gateId);
                    StoreProc::AddMultiItemInStore($mo->reward);
                    ctx()->privateData(true)->rankReward_drawed_MainGate[] = $gateId;
                    TaskProc::OnRankPrize_Num();
                }
            }
        } else {
            $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
            $dic2 = gMem()->hgetall($memKey2);
            foreach ($dic2 as $fightPower => $ins_rank) {
                if (!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower)) {
                    $mo = GameConfig::rank_fightpowerreward_getItem($fightPower);
                    StoreProc::AddMultiItemInStore($mo->reward);
                    ctx()->privateData(true)->rankReward_drawed_fightPower[] = $fightPower;
                    TaskProc::OnFightRankPrize_Num();
                }
            }
        }

        UserProc::updateUserInfo();
        $ret = array('redTip' => 0,
            'task' => ctx()->task,
            'store' => ctx()->store,
            'cash' => ctx()->baseInfo->cash,
            'reward' => StoreProc::$reward,
            'rankReward_drawed_fightPower' => ctx()->privateState->rankReward_drawed_fightPower,
            'rankReward_drawed_MainGate' => ctx()->privateState->rankReward_drawed_MainGate,
        );
        return Resp::ok($ret);
    }

    /**
     * 6817
     */
    public static function IsExistRankReward() {
        //list($type) = req()->paras;

        $type = 0;
        $isExistFinishReward = false;
        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);
        foreach ($dic as $gateId => $ins_rank) {
            if (!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate)) {
                $isExistFinishReward = true;
                $type = 1;
                break;
            }
        }

        $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic2 = gMem()->hgetall($memKey2);
        foreach ($dic2 as $fightPower => $ins_rank) {
            if (!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower)) {
                $isExistFinishReward = true;
                $type = 2;
                break;
            }
        }

        UserProc::updateUserInfo();
        $ret = array(
            'isExistFinishReward' => $isExistFinishReward,
            'type' => $type,
        );
        return Resp::ok($ret);
    }

    /*
     * 删除排行榜内注销账号的玩家
     */

    public static function DeleteRankInvalidUser($uid2) {
        $dic1 = gMem()->zrevrange(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
        foreach ($dic1 as $uid => $score) {
            if ($uid == $uid2) {
                gMem()->zrem(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), $uid);
                break;
            }
        }

        $dic2 = gMem()->zrevrange(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
        foreach ($dic2 as $uid => $score) {
            if ($uid == $uid2) {
                gMem()->zrem(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), $uid);
                break;
            }
        }

        self::DeleteWorldBossRankInvalidUser($uid2);
    }

    /*
     * 删除世界boss排行榜内注销账号的玩家
     */

    public static function DeleteWorldBossRankInvalidUser($uid2) {
        $rankKey = self::GetWorldBoss_DamageMemKey();
        $score = gMem()->zscore($rankKey, $uid2);
        if ($score > 0) {
            gMem()->zrem($rankKey, $uid2);
        }
    }

    /*
     * 排行玩家修改昵称
     */

    public static function UpdateRankUserName($uid, $newName) {
        $memKey1 = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey1);
        foreach ($dic as $gateId => $ins_rank) {
            if ($ins_rank->uid == $uid) {
                $ins_rank->name = $newName;
                gMem()->hset($memKey1, $gateId, $ins_rank);
            }
        }

        $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic2 = gMem()->hgetall($memKey2);
        foreach ($dic2 as $fightPower => $ins_rank) {
            if ($ins_rank->uid == $uid) {
                $ins_rank->name = $newName;
                gMem()->hset($memKey2, $fightPower, $ins_rank);
            }
        }
    }

    /*
     * 排行玩家头像变动
     */

    public static function UpdateRankUserHeadImg($uid, $headImg) {
        $memKey1 = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey1);
        foreach ($dic as $gateId => $ins_rank) {
            if ($ins_rank->uid == $uid) {
                $ins_rank->headImg = $headImg;
                gMem()->hset($memKey1, $gateId, $ins_rank);
            }
        }

        $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic2 = gMem()->hgetall($memKey2);
        foreach ($dic2 as $fightPower => $ins_rank) {
            if ($ins_rank->uid == $uid) {
                $ins_rank->headImg = $headImg;
                gMem()->hset($memKey2, $fightPower, $ins_rank);
            }
        }
    }

    /*
     * 统计战力 战斗力=攻击x（生命-伤害减免值）x（1+暴击率/100x（暴击伤害倍率-1））改为 //战斗力=攻击x（生命-伤害减免值）x（1+暴击率 x（暴击伤害倍率-1））2024-8-30
     */

    public static function countUserFightPower() {
        $CurrentHeroId = ctx()->heros->CurrentHeroId;
        //$hero = ctx()->heros->Dic->$CurrentHeroId;

        list($addHp, $addAtk, $addDecDamage, $addEatFood) = ctx()->gates()->GetEnvovleBuffs(); // 启灵加成

        $mo = GameConfig::hero_getItem($CurrentHeroId);
        my_Assert($mo != null, ErrCode::err_const_no);

        $heroBashAttack = $mo->attack;
        $heroBashHp = $mo->hp;

        $attck = 0;
        $hp = 0;
        $equipDic = ctx()->store->equipLocation;
        foreach ($equipDic as $index => $equipUid) {
            $ins_Equip = new Ins_Equip(ctx()->store->equip->$equipUid);
            if ($ins_Equip->mo()->position % 2 == 1) {
                $attck += GameConfig::equip_levelupgrade_getItem($ins_Equip->mo()->rarity, $ins_Equip->qual, $ins_Equip->mo()->position, $ins_Equip->level)->attckNum;
            } elseif ($ins_Equip->mo()->position % 2 == 0) {
                $hp += GameConfig::equip_levelupgrade_getItem($ins_Equip->mo()->rarity, $ins_Equip->qual, $ins_Equip->mo()->position, $ins_Equip->level)->hpNum;
            }
        }


//        $equipDic = ctx()->store->equipPosition;
//        $attck = 0;
//        $hp = 0;
//        foreach ($equipDic as $index => $ins_equip) {
//            $Ins_Equip = new Ins_EquipPosition($ins_equip);
//            if ($Ins_Equip->mo()->upgradeType == 1) {//攻击力
//                $attck += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->attckNum;
//            } elseif ($Ins_Equip->mo()->upgradeType == 2) {
//                $hp += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->hpNum;
//            } else {
//                $attck += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->attckNum;
//                $hp += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->hpNum;
//            }
//        }

        $heroAttck = $heroBashAttack + $attck + $addAtk;                        # 英雄基础攻击力+装备宝石词条攻击力+启灵攻击力
        $heroHp = $heroBashHp + $hp + $addHp;                                   # 英雄基础hp + 装备宝石词条hp + 启灵hp

        $pag = ctx()->store->equipPag;
        $gemDic = ctx()->store->gemEquip->$pag; //Dictionary<E_EquipPosition, Dictionary<int, Ins_Gem>>
        $per = 0;
        $parasVal = 0;

        $per_hp = 0;
        $parasVal_hp = 0;
        foreach ($equipDic as $index => $ins_equip) {
            if (StlUtil::dictHasProperty($gemDic, $index)) {
                $dic = $gemDic->$index;
                foreach ($dic as $k => $gem) {
                    $ins_Gem = new Ins_Gem($gem);
                    if ($ins_Gem->predicateMo()->actionType == "mulDamage") {
                        $per += $ins_Gem->predicateMo()->actionParam1;
                    } elseif ($ins_Gem->predicateMo()->actionType == "addDamage") {
                        $parasVal += $ins_Gem->predicateMo()->actionParam1;
                    } elseif ($ins_Gem->predicateMo()->actionType == "mulHp") {
                        $per_hp += $ins_Gem->predicateMo()->actionParam1;
                    } elseif ($ins_Gem->predicateMo()->actionType == "addHp") {
                        $parasVal_hp += $ins_Gem->predicateMo()->actionParam1;
                    }
                }
            }
        }

        if ($per != 0) {
            $heroAttck = round($heroAttck + $heroAttck * $per);
        }
        if ($parasVal != 0) {
            $heroAttck += $parasVal;
        }

        if ($per_hp != 0) {
            $heroHp = round($heroHp + $heroHp * $per_hp);
        }
        if ($parasVal_hp != 0) {
            $heroHp += $parasVal_hp;
        }

        $dec_demage = $mo->dec_demage + $addDecDamage;                          # 英雄基础减伤 + 启灵减伤
        $bigHit_Val = $mo->bigHit_Val;
        $bigHit_rate = $mo->bigHit_rate;

        $val = $heroAttck * ($heroHp - $dec_demage) * (1 + $bigHit_rate * ($bigHit_Val - 1));

        return intval($val);
    }

    // </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" 世界boss 排行榜">  

    /**
     * 结算世界boss排行奖励[定时发放奖励接口]
     */
    public static function triggerSettleRankReward_worldBoss() {
        //校验下是否处在发放奖励信息的时间点 【每个轮次最后一天的最后10分钟】                             
        $mo = GameConfig::subfun_unlock_getItem(Enum_SubFunType::WorldBoss);

        if ($mo == null) {
            return;
        }
        if (now() < $mo->startTs) {
            return;
        }

        echo '----发放世界boss的排行奖励程序开始运行-----';

        $curDay = TimeUtil::totalDays();
        $turnNum = self::GetCurTurnNum();
        $turnnumMo = GameConfig::worldboss_turnnum_getItem($turnNum);
        if ($turnnumMo != null) {
            $lastDay = TimeUtil::totalDays($turnnumMo->endTs);
            if ($curDay == $lastDay && $turnnumMo->endTs - now() < 600) {
                $damageMemKey = self::GetWorldBoss_DamageMemKey();
                echo '发放奖励的menkey===============:';
                echo "$damageMemKey";
                $mem = gMem();
                if ($mem->exists($damageMemKey)) {
                    FightProc::settleRankReward_worldBoss();
                }
            }
        }

        echo '----世界boss的排行奖励-发放完成----';
    }

    public static function settleRankReward_worldBoss() {
        echo '----开始发放世界boss的排行奖励-----';
        $dic = GameConfig::worldboss_rankreward();
        if ($dic == null) {
            return;
        }

        $turnNum = self::GetCurTurnNum();
        $turnnumMo = GameConfig::worldboss_turnnum_getItem($turnNum);
        $orderId = $turnnumMo->orderId;
        $gateMo = GameConfig::gate_getItem($turnnumMo->gateId);
        if ($gateMo == null) {
            return;
        }
        $name = $gateMo->gateName;

        $memKey = self::GetWorldBoss_DamageMemKey();
        $index = 0;
        foreach ($dic as $id => $mo) {
            $list = gMem()->zrevrange($memKey, $mo->rank_start - 1, $mo->rank_end - 1, true);

            if (count($list) == 0) {
                continue;
            }

            foreach ($list as $uid => $score) {
                $index += 1;
                self::settleDamageReward_worldBoss($name, $orderId, $uid, $score);
                EmailProc::SendWorldBossRewardMail(req()->zoneid, $uid, $mo->reward, $index, $name);
            }
        }

        gMem()->delete($memKey);
//        $list = gMem()->zrevrange($memKey, 0, GameConfig::glc2()->WorldBoss_RankRewardStatistics, true);       
//        if (count($list) <= 0) {
//            
//        }
    }

    public static function settleDamageReward_worldBoss($name, $orderId, $uid, $demageVal) {
        $demageList = GameConfig::worldboss_demagereward_getItemArray($orderId);
        $strkey = MemKey_User::Info_hash(req()->zoneid, $uid);
        if (!gMem()->exists($strkey)) {
            return;
        }

        $userInfo = UserProc::getUserGame(req()->zoneid, $uid);
        $worldBoss_received = $userInfo->privateState->worldBoss_received;
        $dic = new \stdClass();
        foreach ($demageList as $dMo) {
            if ($demageVal >= $dMo->demageValId && !in_array($dMo->demageValId, $worldBoss_received)) {
                if ($dMo->reward != null) {
                    $list = explode(';', $dMo->reward);
                    foreach ($list as $value) {
                        $arr = explode(',', $value);
                        $rewardId = $arr[0];
                        $rewardNum = $arr[1];
                        if (StlUtil::dictHasProperty($dic, $rewardId)) {
                            $dic->$rewardId += $rewardNum;
                        } else {
                            $dic->$rewardId = $rewardNum;
                        }
                    }
                }
            }
        }

        $str = '';
        foreach ($dic as $k => $val) {
            $s = $k . ',' . $val;
            if ($str == '') {
                $str = $s;
            } else {
                $str = $str . ';' . $s;
            }
        }

        if ($str != null) {
            EmailProc::SendWorldBossDamageRewardMail(req()->zoneid, $uid, $str, $name);
        }
    }

    /**
     * 重置每个赛季的开始时间 一个重置每个赛季的开始时间赛季完成后  排名数据清理掉  同时轮次要改变 [定时接口]----废弃
     */
    public static function ResetWorldBossRank_StartTs() {
        return;
//        $mo = GameConfig::subfun_unlock_getItem(Enum_SubFunType::WorldBoss);
//        if ($mo == null) {
//            return;
//        }
//        if (now() < $mo->startTs) {
//            return;
//        }
//        echo '赛季的开始时间重置程序开始运行**********';
//        $memKey = MemKey_GameRun::WorldBoss_StartTs(req()->zoneid);
//        $mem = gMem();
//
//        $ts = $mem->get($memKey);
//        $durationTs = $mo->ts * 24 * 60 * 60;
//        if ($ts == null && now() - $mo->startTs < $durationTs) {
//            $mem->set($memKey, $mo->startTs);
//            $ts = $mo->startTs;
//        }
//
//        if (now() - $ts > $durationTs) {
//            $nextTs = TimeUtil::getNextDayTs($ts, $mo->ts);
//            $mem->set($memKey, $nextTs); //下一轮赛季的开始时间回存   
//            echo '完成重置下一个赛季的开始时间';
//            //清理排行榜
//            self::ClearWorldBossRank();
//        }
    }

    /**
     * 清理世界boss排行榜数据 
     */
    public static function ClearWorldBossRank() {
        $mem = gMem();
        $arr = array();
        for ($i = 1; $i <= 9; $i++) {
            $memKey = MemKey_GameRun::WorldBoss_Rank($i, req()->zoneid);
            $arr[] = $memKey;
        }
        $mem->deleteMulti($arr);
    }

    /**
     * 每天登录的时候 检测轮次变化
     */
    public static function ResetTurnNum() {
        if (!FightProc::isFunUnlock(25)) {
            return;
        }

        $subMo = GameConfig::subfun_unlock_getItem(Enum_SubFunType::WorldBoss);
        if (ctx()->privateState->worldBoss_turnNum < 0) {
            ctx()->privateState->worldBoss_turnNum = 0;
        }

        if (now() < $subMo->startTs) {
            return;
        }

        $num = self::GetCurTurnNum();
        if ($num != ctx()->privateState->worldBoss_turnNum) {
            ctx()->privateState->worldBoss_turnNum = $num;
            ctx()->privateState->worldBoss_received = array();
        }
    }

    /**
     * 当前所在世界boss 的轮次 //当前轮次可以算出来
     */
    public static function GetCurTurnNum() {
        $dic = GameConfig::worldboss_turnnum();
        foreach ($dic as $turnId => $mo) {
            if (now() >= $mo->startTs && now() < $mo->endTs) {
                return $turnId;
            }
        }
        return 0;

//        $memKey = MemKey_GameRun::WorldBoss_StartTs(req()->zoneid);
//        $mem = gMem();
//        $ts = $mem->get($memKey);
//
//        $curDay = TimeUtil::totalDays(now());
//        $lastDay = TimeUtil::totalDays($ts);
//
//        $val = $curDay - $lastDay;
//        $num = intval($val / 3);
//
//        return $num + 1;
    }

    /**
     * 世界boss排名榜 memkey
     * @return type
     */
    public static function GetWorldBoss_DamageMemKey() {
        $num = self::GetCurTurnNum();
        $memKey = MemKey_GameRun::WorldBoss_Rank($num, req()->zoneid);
        return $memKey;
    }

    /**
     * 世界boss榜  伤害值入榜
     * @param type $gateIndex
     */
    public static function Ranking_DamageVal($damageVal) {
        //$num = self::GetCurTurnNum();
        $memKey = self::GetWorldBoss_DamageMemKey(); // MemKey_GameRun::WorldBoss_Rank($num, req()->zoneid);
        $mem = gMem();

        $uid = req()->uid;
        $val = gMem()->zscore($memKey, $uid);
        if ($damageVal > $val) {
            $arr = array();
            $arr["$uid"] = self::createScore($damageVal);
            $mem->zadd($memKey, $arr);
        }

        $length = $mem->zlen($memKey);
        if ($length > GameConfig::glc2()->WorldBoss_RankRewardStatistics) {
            $num = $length - GameConfig::glc2()->WorldBoss_RankRewardStatistics;
            $mem->zremrangebyrank($memKey, 0, $num - 1);
        }
    }

    /**
     *  6826 世界boss的排名信息
     * @return type
     */
    public static function GetWorldBoss_RankInfo() {
        //list() = req()->paras;

        $selfIsHasRank = 0; //本人是否上榜 0未上榜没有排名 1上榜则selfRank就是排名
        //$num = self::GetCurTurnNum();
        //$memKey =  MemKey_GameRun::WorldBoss_Rank($num, req()->zoneid);
        $memKey = self::GetWorldBoss_DamageMemKey();
        $list = gMem()->zrevrange($memKey, 0, GameConfig::glc2()->WorldBoss_RankRewardStatistics, true);

        $rankStatistics = GameConfig::glc2()->WorldBoss_RankStatistics;

        $selfRank = null;
        $retArr = array();
        $index = 0;
        if (count($list) > 0) {
            foreach ($list as $uid => $score) {
                $index += 1;
                $rankInfo = self::initOtherUidRankInfo($uid, $score, 3);
                if ($rankInfo->uid == req()->uid && $index <= $rankStatistics) {
                    $selfIsHasRank = 1;
                    $selfRank = $rankInfo;
                }

                $retArr[] = $rankInfo;
            }
        }

        if ($selfRank == null) {
            $selfRank = self::initOtherUidRankInfo(req()->uid, 0);
        }

        UserProc::updateUserInfo();
        $ret = array(
            'rankInfo' => $retArr,
            'selfRank' => $selfRank,
            'selfIsHasRank' => $selfIsHasRank,
        );
        return Resp::ok($ret);
    }

    /**
     * 6827 当前轮次下 自己的最高伤害值
     * @return type
     */
    public static function GetWorldBoss_RankDamageVal() {
        $val = gMem()->zscore(self::GetWorldBoss_DamageMemKey(), req()->uid);
        if ($val == null) {
            $val = 0;
        }
        UserProc::updateUserInfo();
        $ret = array(
            'DamageVal' => intval($val),
        );
        return Resp::ok($ret);
    }

    /**
     * 6828 获取自己的排名信息
     * @return type
     */
    public static function GetWorldBoss_GetSelfRank() {
//        $lv = gMem()->zrevrank(self::GetWorldBoss_DamageMemKey(), req()->uid);
//        if($lv == null){
//            $lv = 0;
//        }
        $damageval = gMem()->zscore(self::GetWorldBoss_DamageMemKey(), req()->uid);
        if ($damageval == null) {
            $damageval = 0;
        }
        $ins_rank = self::initOtherUidRankInfo(req()->uid, $damageval, 3);

        //$tsMemKey = MemKey_GameRun::WorldBoss_StartTs(req()->zoneid);
        //$ts = gMem()->get($tsMemKey);
        //ctx()->privateState->worldBoss_startTs = $ts;

        UserProc::updateUserInfo();
        $ret = array(
            'selfRank' => $ins_rank,
        );
        return Resp::ok($ret);
    }

    /**
     * 6829 领取世界boss奖励
     * @return type
     */
    public static function GetWorldBoss_ClaimRewards() {
        list($damageValId) = req()->paras;

        my_Assert(!in_array($damageValId, ctx()->privateState->worldBoss_received), ErrCode::active_hasgetted);

        $val = gMem()->zscore(self::GetWorldBoss_DamageMemKey(), req()->uid);
        if ($val == null) {
            $val = 0;
        }
        my_Assert($damageValId <= $val, ErrCode::active_worldBoss_notClaimRewards);

        $turnNum = self::GetCurTurnNum();
        $turnnumMo = GameConfig::worldboss_turnnum_getItem($turnNum);
        my_Assert($turnnumMo != null, ErrCode::err_const_no);

        $list = GameConfig::worldboss_demagereward_getItemArray($turnnumMo->orderId);
        foreach ($list as $key => $mo) {
            if ($mo->demageValId == $damageValId && $mo->orderId == $turnnumMo->orderId) {
                StoreProc::AddMultiItemInStore($mo->reward);
                break;
            }
        }
        ctx()->privateState->worldBoss_received[] = $damageValId;

        UserProc::updateUserInfo();
        $ret = array(
            'store' => ctx()->store,
            'cash' => ctx()->baseInfo->cash,
            'reward' => StoreProc::$reward,
            'reward_Gem' => StoreProc::$reward_Gem,
            'reward_equip' => StoreProc::$reward_equip,
        );
        return Resp::ok($ret);
    }

    /**
     * 6830 世界boss结算
     */
    public static function WorldBoss_settle() {
        list($damageNum) = req()->paras; //战斗结束伤害值      
        //校验每个轮次最后10分钟， 不能战斗
        my_Assert(FightProc::isFunUnlock(25), ErrCode::active_funUnlock);
        $tag = true;

        $curDay = TimeUtil::totalDays();
        $turnNum = self::GetCurTurnNum();
        $turnnumMo = GameConfig::worldboss_turnnum_getItem($turnNum);
        if ($turnnumMo != null) {
            $lastDay = TimeUtil::totalDays($turnnumMo->endTs);
            if ($curDay == $lastDay && $turnnumMo->endTs - now() < 600) {
                $tag = false;
            }
        }

        if (ctx()->privateState->worldBoss_turnNum == 0) {
            ctx()->privateState->worldBoss_turnNum = $turnNum;
        }

        if (ctx()->privateState->worldBoss_turnNum != $turnNum) {
            ctx()->privateState->worldBoss_turnNum = $turnNum;
            ctx()->privateState->worldBoss_received = array();
            $tag = false;
        }

        if ($tag) {
            self::Ranking_DamageVal($damageNum);
        }

        UserProc::updateUserInfo();
        return Resp::ok(array());
    }

// </editor-fold>    
}
