<?php

namespace loyalsoft;

/// <summary>
///  英雄属性
/// </summary>
class EHeroProperties extends Enum {

    /// <summary>
    /// 生命值
    /// </summary>
    const HP = 0;
    /// <summary>
    /// 能量值
    /// </summary>
    const NENGLIANGZHI = 1;
    /// <summary>
    /// 物理攻击
    /// </summary>
    const WULIGONGJI = 2;
    /// <summary>
    /// 防御护甲
    /// </summary>
    const FANGYUHUJIA = 3;
    /// <summary>
    /// 敏捷
    /// </summary>
    const GONGJISUDU = 4;
    /// <summary>
    /// 暴击
    /// </summary>
    const CRICITAL = 5;
    /// <summary>
    /// 法术强度
    /// </summary>
    const FASHUQIANGDU = 6;
    /// <summary>
    /// 魔法抗性
    /// </summary>       
    const MOFAKANGXING = 7;

}

/**
 * 玩家的英雄的实体数据
 */
class Ins_UserHero extends Object_ext {

    /**
     * 唯一的英雄ID
     * @var  string
     */
    public $uid;

    /**
     * 英雄的模板ID
     * @var string
     */
    public $typeId;

    /**
     * 英雄的当前等级
     * @var  int
     */
    public $level;

    /**
     * 英雄当前等阶 
     * @var string
     */
    public $grade;

    /**
     * 英雄的收集的当前等级满级的累计经验值
     * @var  int
     */
    public $maxXp;

    /**
     * 英雄的当前总经验值
     * @var  int
     */
    public $xp;

    /**
     * 当前等阶 默认是0.
     * 0= 绿 1=蓝  2= 红   3=  紫  4= 橙  5
     * @var  int
     * @deprecated since version 0
     */
    public $strengthLevel;

    /**
     * 当前星级 默认是0星
     * @var  int
     * @deprecated since version 0
     */
    public $curStar;

    /**
     * 当前神血的 血脉等级 默认是0
     * @var  int
     * @deprecated since version 0
     */
    public $curBloodId;

    /**
     * 当前卡牌的锁定状态
     * true = 锁定
     * @var  bool
     * @deprecated since version 0
     */
    public $isLocked;

    /**
     * 技能数据
     * @var object
     * @deprecated since version 0
     */
    public $skills;

    /**
     * 子技能列表(已解锁子技能id)
     * @var dic<int,[]int> 
     */
    public $subSkills;

    /**
     * 装备
     * @var object
     */
    public $equip;

    /**
     * 言灵
     * @var {}
     */
    public $yanling;

    /**
     * 当前主线的好感度进度
     * @var object
     * @deprecated since version 0
     */
    public $curMainFavor;

    /**
     * 所有的已经拥有的好感度进度
     * @var array
     * @deprecated since version 0
     */
    public $favors;

    /**
     *
     * 构造函数
     */
    public function __construct($arg = null) {
        if (null != $arg) {
            parent::__construct($arg);
        } else {
            $this->level = 1;
            $this->xp = 0;
            $this->maxXp = 0;
            $this->strengthLevel = 0;
            $this->curBloodId = 0;
            $this->curStar = 0;
            $this->isLocked = false;
            $this->curMainFavor = 'E';
            $this->favors = ArrayInit();
            $this->favors[] = 'E';
            $this->grade = "D";
//-----------初始化技能的默认数据
            $temp = ObjectInit();
            $temp->normalSkill = JsonUtil::decode('{"level":1}');
            $temp->manuSkill1 = JsonUtil::decode('{"level":1}');
            $temp->manuSkill2 = JsonUtil::decode('{"level":1}');
            $temp->manuSkill3 = JsonUtil::decode('{"level":1}');
            $temp->passiveSkill = JsonUtil::decode('{"level":1}');
            $temp->captainSkill = JsonUtil::decode('{"level":1}');
            $this->skills = $temp;
            $this->subSkills = ObjectInit();

//----初始化装备的默认数据
            $this->equip = ObjectInit();
            $tempEq = ObjectInit();
            $tempEq->weapon = JsonUtil::decode('{"itemuid":0}');
            $tempEq->armor = JsonUtil::decode('{"itemuid":0}');
            $tempEq->ring = JsonUtil::decode('{"itemuid":0}');

            $this->equip = $tempEq;
// ------初始化言灵的默认数据
            $this->yanling = JsonUtil::decode('{"1":{"itemuid":0},"2":{"itemuid":0},"3":{"itemuid":0}}');
        }
    }

    /**
     * 判断技能是否可升级
     * @param type $mainSkillId
     * @param type $subSkillId Description
     * @return type
     */
    public function IsSkillUpdateAble($mainSkillId, $subSkillId) {
        $sarr = array("D" => 1, "C" => 2, "B" => 3, "A" => 4, "S" => 5);
        $isOk = false;
        if (CommUtil::isPropertyExists($this->subSkills, $mainSkillId)) {
            if (CommUtil::isPropertyExists($this->subSkills->$mainSkillId, $subSkillId)) {
                $sm = GameConfig::subSkill_getItem($subSkillId);
                switch ($sm->upgradeConditionType) {
                    case 1:                               // 角色等级
                        $isOk = $this->level >= int($sm->upgradeParameter);
                        break;
                    case 2:                               // 角色品阶
                        $cur = (array_key_exists($this->grade, $sarr) ? $sarr[$this->grade] : 0);
                        $require = (array_key_exists($sm->upgradeParameter, $sarr) ? $sarr[$sm->upgradeParameter] : 0);
                        $isOk = $cur >= $require;
                        break;
                    default:
                        break;
                }
            }
        }
        return $isOk;
    }

    /**
     * 判断技能是否可解锁
     * @param type $mainSkillId
     * @param type $subSkillId Description
     * @return type
     */
    public function IsSkillUnlockAble($mainSkillId, $subSkillId) {
        $sarr = array("D" => 1, "C" => 2, "B" => 3, "A" => 4, "S" => 5);
        $isOk = false;
        if (CommUtil::isPropertyExists($this->subSkills, $mainSkillId)) {
            if (CommUtil::isPropertyExists($this->subSkills->$mainSkillId, $subSkillId)) {
                $sm = GameConfig::subSkill_getItem($subSkillId);
                switch ($sm->unlockConditionType) {
                    case 1:                               // 角色等级
                        $isOk = $this->level >= int($sm->unlockParameter);
                        break;
                    case 2:                               // 角色品阶
                        $cur = (array_key_exists($this->grade, $sarr) ? $sarr[$this->grade] : 0);
                        $require = (array_key_exists($sm->unlockParameter, $sarr) ? $sarr[$sm->unlockParameter] : 0);
                        $isOk = $cur >= $require;
                        break;
                    default:
                        break;
                }
            }
        }
        return $isOk;
    }

    /**
     * 是否可继续升级(指挥官等级限制 + 全局限制)
     * @return bool
     */
    public function HeroCanLevelUp() {
        $maxLevel = glc()->Hero_Upgrade_BasicMaxLevel;                          # 全局设置限制了当前英雄的最高等级
        $playerLimit = GameConfig::playerlevel_getItem(ctx()->base()->level)->hero_max_level;
        return $this->level < min($maxLevel, $playerLimit);
    }

    /**
     * 获取该角色战斗力数值
     * 生命值+物理攻击*4+魔法强度*4+护甲*5+魔抗*5
     * @return type
     */
    public function GetPower() {
        return (int) ($this->getHpForBattle() * 1.0                                    //
                + $this->getNengLiangZhiJiForBattle() * 0                              //
                + $this->getWuLiGongJiForBattle() * 4                                  //
                + $this->getFaShuQiangDuForBattle() * 4                                //
                + $this->getFangYuHuJiaForBattle() * 5                                 //
                + $this->getMoFaKangXingForBattle() * 5                                //
                );
    }

//
// <editor-fold defaultstate="collapsed" desc="辅助方法">

    /**
     * 获得角色装备的 物品提供的属性加成
     * @param type $attribute
     * @return type
     */
    public function getEquipExtraProperty($attribute) {
        $result = 0;
        $player = req()->userInfo->game;
        $equipUID = $this->equip->weapon->itemuid;

        if (CommUtil::isPropertyExists($player->store->equipment, $equipUID)) {
            $equip = $player->store->equipment->$equipUID;
            $itemId = my_null_default($equip->typeId, 0);
            $wp = GameConfig::item_weapon_getItem($itemId);
            my_Assert(null != $wp, ErrCode::err_const_no);
            switch ($attribute) {
                case EHeroProperties::WULIGONGJI:
                    $result += $wp->phyAtk;
                    break;
                case EHeroProperties :: FASHUQIANGDU:
                    $result += $wp->fashuqiangdu;
                    break;
                case EHeroProperties :: CRICITAL:
                    $result += $wp->crit;
                    break;
            }
        }

        return $result;
    }

    /**
     * 获得角色装备的言灵提供的属性加成
     * @param type $attribute
     * @return type
     */
    public function getYanlingExtraProperty($attribute) {
        $result = 0;
        $player = req()->userInfo->game;
        foreach ($this->yanling as $item) {
            $itemUID = $item->itemuid;
            if ($itemUID > 0) {
                $itemId = $player->store->yanling->$itemUID->typeId;
                $mo = GameConfig::item_yanling_getItem($itemId);
                my_Assert(null != $mo, ErrCode::err_const_no);                  # 言灵常量找不到
                switch ($attribute) {
                    case EHeroProperties ::HP:
                        $result += $mo->hp;
                        break;
                    case EHeroProperties :: WULIGONGJI:
                        $result += $mo->phyAtk;
                        break;
                    case EHeroProperties :: FASHUQIANGDU:
                        $result += $mo->fashuqiangdu;
                        break;
                    case EHeroProperties :: CRICITAL:
                        $result += $mo->crit;
                        break;
                    case EHeroProperties ::FANGYUHUJIA:
                        $result += $mo->phyDef;
                        break;
                    case EHeroProperties ::MOFAKANGXING:
                        $result += $mo->mofakangxing;
                        break;
                    default:
                        break;
                }
            }
        }

        return $result;
    }

    /**
     * 获得  角色某个等级 等阶 状态下的属性值
     * @param type $modelId moID
     * @param type $attType 
     * @param type $level 等级
     * @param type $gradeLevel 品阶(SABCD)
     * @return type
     */
    public function getHeroProperty($modelId, $attType, $level, $gradeLevel) {
        $result = 0;                                                            # 结果
        $gradeF = 0;                                                            # 品阶加成    
        /* 角色成长公式					
          生命=初始生命+生命成长*（角色等级-1））+武器加成+言灵加成
          言能=初始言能+言能成长*（角色等级-1））
          物攻=初始物攻+物攻成长*（角色等级-1））+武器加成+言灵加成
          护甲=初始护甲+护甲成长*（角色等级-1））+武器加成+言灵加成
          言攻=初始言攻+言攻成长*（角色等级-1））+武器加成+言灵加成
          言抗=初始言抗+言抗成长*（角色等级-1））+武器加成+言灵加成
          暴击=初始暴击+暴击成长*（角色等级-1））+武器加成+言灵加成
          暴击率=暴击/(75+角色等级*5)
         */
        // 武器成长 和 言灵成长都是直接数值, 所以放到外面再做加法也可以. Ps. 放外面了
        $heroMo = GameConfig::hero_getItem($modelId);
        my_Assert($heroMo != null, ErrCode::hero_const_no_err);                 # 找不到英雄模板数据
        $gradeLevelMo = GameConfig::heroextra_level_getItem($heroMo->heroId, $gradeLevel); # 等阶加成配置
        my_Assert(null != $gradeLevelMo, ErrCode::err_const_no);                # 找不到常量
//
////第一步， 根据玩家的等阶，来找出，对应的等阶，的各个属性成长的曲线类型，也就是说0阶的时候， 各个属性的成长系数是SABCD的哪搞一个。
////然后 根据  SABCD的类型以及 想查找的属性， 找出对应的 这个属性的成长系数
//
// <editor-fold defaultstate="collapsed" desc="属性成长">
        switch ($attType) {                                                     # 属性类型
            case EHeroProperties::HP:
                $gradeF = $gradeLevelMo->hp;
                break;
            case EHeroProperties :: MOFAKANGXING:
                $gradeF = $gradeLevelMo->mofakangxing;
                break;
            case EHeroProperties ::FASHUQIANGDU:
                $gradeF = $gradeLevelMo->fashuqiangdu;
                break;
            case EHeroProperties ::WULIGONGJI:
                $gradeF = $gradeLevelMo->wuligongji;
                break;
            case EHeroProperties ::FANGYUHUJIA:
                $gradeF = $gradeLevelMo->fangyuhujia;
                break;
            case EHeroProperties :: NENGLIANGZHI:
                $gradeF = $gradeLevelMo->nengliangzhi;
                break;
            case EHeroProperties :: GONGJISUDU:
                $gradeF = $gradeLevelMo->gongjisudu;
                break;
            case EHeroProperties ::CRICITAL:
                $gradeF = 0;
                break;
        }
//
// </editor-fold>
// 
// <editor-fold defaultstate="collapsed" desc="叠加加成后的结果"> 
        switch ($attType) {
            case EHeroProperties :: HP:
                $result += $heroMo->hp + $gradeF * ($level - 1);
                break;
            case EHeroProperties ::NENGLIANGZHI:
                $result += $heroMo->nengliangzhi + $gradeF * ($level - 1);
                break;
            case EHeroProperties ::WULIGONGJI:
                $result += $heroMo->wuligongji + $gradeF * ($level - 1);
                break;
            case EHeroProperties ::FANGYUHUJIA:
                $result += $heroMo->fangyuhujia + $gradeF * ($level - 1);
                break;
            case EHeroProperties :: FASHUQIANGDU:
                $result += $heroMo->fashuqiangdu + $gradeF * ($level - 1);
                break;
            case EHeroProperties :: MOFAKANGXING:
                $result += $heroMo->mofakangxing + $gradeF * ($level - 1);
                break;
            case EHeroProperties :: GONGJISUDU:
                $result += $heroMo->gongjisudu + $gradeF * ($level - 1);
                break;
            case EHeroProperties :: CRICITAL:
                $result += $heroMo->baoji / (75 + $level * 5);
                break;
        }

// </editor-fold>
//        
        return $result;
    }

// <editor-fold defaultstate="collapsed" desc="基础(等级+品阶)属性值">

    /**
     * 基础(等级+品阶) 血量
     * @return type
     */
    function getHp() {
        return $this->getHeroProperty($this->typeId, EHeroProperties ::HP, $this->level, $this->grade);
    }

    /**
     * 基础(等级+品阶)能量值
     * @return type
     */
    function getNengLiangZhi() {
        return $this->getHeroProperty($this->typeId, EHeroProperties ::NENGLIANGZHI, $this->level, $this->grade);
    }

    /**
     *  基础(等级+品阶)物理攻击
     * @return type
     */
    function getWuLiGongJi() {
        return $this->getHeroProperty($this->typeId, EHeroProperties ::WULIGONGJI, $this->level, $this->grade);
    }

    /**
     *  基础(等级+品阶)法术强度
     * @return type
     */
    function getFaShuQiangDu() {
        return $this->getHeroProperty($this->typeId, EHeroProperties ::FASHUQIANGDU, $this->level, $this->grade);
    }

    /**
     *  基础(等级+品阶)防御护甲
     * @return type
     */
    function getFangYuHuJia() {
        return $this->getHeroProperty($this->typeId, EHeroProperties ::FANGYUHUJIA, $this->level, $this->grade);
    }

    /**
     *  基础(等级+品阶)魔法抗性
     * @return type
     */
    function getMoFaKangXing() {
        return $this->getHeroProperty($this->typeId, EHeroProperties ::MOFAKANGXING, $this->level, $this->grade);
    }

// </editor-fold>
// 

    /**
     * 战场血量 = 基础血量 + 武器和言灵加成
     * @return type
     */
    public function getHpForBattle() {
        return (int) ($this->getHp()                                            // 英雄数据
                + $this->getEquipExtraProperty(EHeroProperties ::HP)            // 武器加成
                + $this->getYanlingExtraProperty(EHeroProperties :: HP)         // 言灵加成
                );
    }

    /**
     * 战场能量值 = 基础能量值 + 武器和言灵加成
     * @return type
     */
    public function getNengLiangZhiJiForBattle() {
        return (int) ($this->getNengLiangZhi()                                  // 英雄本身
                + $this->getEquipExtraProperty(EHeroProperties :: NENGLIANGZHI) // + 武器加成
                + $this->getYanlingExtraProperty(EHeroProperties::NENGLIANGZHI) // + 言灵加成
                );
    }

    public function getWuLiGongJiForBattle() {
        return (int) ($this->getWuLiGongJi()                                            // 英雄数据
                + $this->getEquipExtraProperty(EHeroProperties ::WULIGONGJI)            // 武器加成
                + $this->getYanlingExtraProperty(EHeroProperties :: WULIGONGJI)         // 言灵加成
                );
    }

    function getFaShuQiangDuForBattle() {
        return (int) ($this->getFaShuQiangDu()                                            // 英雄数据
                + $this->getEquipExtraProperty(EHeroProperties ::FASHUQIANGDU)            // 武器加成
                + $this->getYanlingExtraProperty(EHeroProperties :: FASHUQIANGDU)         // 言灵加成
                );
    }

    function getFangYuHuJiaForBattle() {
        return (int) ($this->getFangYuHuJia()                                            // 英雄数据
                + $this->getEquipExtraProperty(EHeroProperties ::FANGYUHUJIA)            // 武器加成
                + $this->getYanlingExtraProperty(EHeroProperties :: FANGYUHUJIA)         // 言灵加成
                );
    }

    function getMoFaKangXingForBattle() {
        return (int) ($this->getMoFaKangXing()                                            // 英雄数据
                + $this->getEquipExtraProperty(EHeroProperties ::MOFAKANGXING)            // 武器加成
                + $this->getYanlingExtraProperty(EHeroProperties :: MOFAKANGXING)         // 言灵加成
                );
    }

// 
// </editor-fold>
// 
}
