_getAccountId(), $heroUniId); } public static function findByAccountId($accountId, $heroUniId) { return self::internalFind($accountId, $heroUniId); } private static function internalFind($accountId, $heroUniId) { $row = SqlHelper::ormSelectOne( myself()->_getMysql($accountId), 't_hero', array( 'idx' => $heroUniId, ) ); if ($row) { $row['hero_uniid'] = $row['idx']; if ($row['account_id'] != $accountId) { $openId = phpcommon\extractOpenId($accountId); if (!NftService::isHeroOwner($openId, $row['token_id'])) { $row = null; } } } return $row; } public static function getValidHero($heroId) { $heroList = array(); Hero::getHeroList(function ($row) use($heroId, &$heroList) { if ($row['hero_id'] == $heroId && $row['state'] == self::GETED_STATE) { array_push($heroList, Hero::toDto($row)); } }); return !empty($heroList) ? $heroList[0] : null; } public static function getRawPveCegUpLimit() { $cegUpLimit = 0; self::getHeroList(function ($row) use(&$cegUpLimit) { $heroDto = self::toDto($row); $cegUpLimit += $heroDto['raw_pve_ceg_uplimit']; }); return $cegUpLimit; } public static function getHeroList($cb) { SqlHelper::ormSelect( myself()->_getSelfMysql(), 't_hero', array( 'account_id' => myself()->_getAccountId() ), function ($row) use($cb) { $cb($row); } ); foreach (NftService::getHeros(myself()->_getOpenId()) as $nftDb) { if (! $nftDb['deleted']){ $row = SqlHelper::ormSelectOne( myself()->_getSelfMysql(), 't_hero', array( 'token_id' => $nftDb['token_id'], ) ); if (!$row) { $itemMeta = mt\Item::get($nftDb['item_id']); if ($itemMeta) { self::addNftHero($itemMeta, $nftDb['token_id']); $row = SqlHelper::ormSelectOne( myself()->_getSelfMysql(), 't_hero', array( 'token_id' => $nftDb['token_id'], ) ); } } if ($row) { $cb($row); } } } } public static function toDto($row) { $attr = emptyReplace(json_decode($row['rand_attr'], true), array()); $lockType = 0; $unlockTime = 0; /*if ($row['lock_type'] != 0 && $row['unlock_time'] - myself()->_getNowTime() > 0) { $lockType = $row['lock_type']; $unlockTime = $row['unlock_time']; }*/ { $lockType = $row['lock_type']; $unlockTime = $row['unlock_time']; } $qualityMeta = mt\HeroQuality::getByQuality($row['quality']); $todayGetGold = $row['today_get_gold']; $lastGetGoldTime = $row['last_get_gold_time']; if (myself()->_getDaySeconds($lastGetGoldTime) < myself()->_getNowDaySeconds()) { $todayGetGold = 0; } $todayPveGetCeg = $row['today_pve_get_ceg']; $lastPveGetCegTime = $row['last_pve_get_ceg_time']; if (myself()->_getDaySeconds($lastPveGetCegTime) < myself()->_getNowDaySeconds()) { $todayPveGetCeg = 0; } $baseAttr=[]; $attrPro=[]; $heroMeta = mt\Hero::get($row['hero_id']); if ($heroMeta) { $baseAttr = mt\Hero::getHeroAttr($heroMeta); $attrPro1=[]; if ($row['hero_lv']>1){ $attrPro1 = self::getAttrProByLevel($row,$baseAttr,$attr); } $attrPro2=[]; if ($row['quality']>1){ $attrPro2 = self::getAttrProByQuality($row,$baseAttr); } $attrPro = self::mergeAttrPro($baseAttr,$attrPro1,$attrPro2); } //print_r($attr);die; $skill_common = explode("|",$row['skill_common']); $attr_skill = []; foreach ($skill_common as $val){ $item = mt\SkillCommon::getAttrBySkillCommon($val); if ($item){ array_push($attr_skill,$item); } } $heroLucky = \services\FormulaService::Hero_Advanced_Lucky_Value($row['quality']); $dto = array( 'token_id' => $row['token_id'], 'hero_uniid' => $row['idx'], 'hero_id' => $row['hero_id'], 'hero_lv' => $row['hero_lv'], 'hero_tili' => $row['hero_tili'], 'state' => $row['state'], 'skin_id' => $row['skin_id'], 'quality' => $row['quality'], 'skill_lv1' => $row['skill_lv1'], 'skill_lv2' => $row['skill_lv2'], 'attr_base' => $baseAttr, 'attr_pro' => $attrPro, 'attr_skill' => $attr_skill, 'attr_chip' => Chip::getChipAttr($row['chip_ids'])['attr_chip'], 'chip_core' => Chip::getChipAttr($row['chip_ids'])['chip_core'], 'try_count' => $row['try_count'], 'lock_type' => $lockType, 'unlock_time' => $unlockTime, 'unlock_lefttime' => max(0, $unlockTime - myself()->_getNowTime()), 'current_pvp_get_ceg' => $todayGetGold / 100, 'last_pvp_get_ceg_time' => $lastGetGoldTime, 'current_pve_get_ceg' => $todayPveGetCeg / 100, 'last_pve_get_ceg_time' => $lastPveGetCegTime, 'unlock_trade_time' => $row['unlock_trade_time'], 'advanced_count' => $row['advanced_count'], 'lucky' => $heroLucky, 'chip_ids' => $row['chip_ids'], 'chip_strength_sum' => strval(Chip::getChipMaxStrength($row['chip_ids'],1)), //计算ceg上限所需参数 'skill_common' => $skill_common, 'skill_points' => $row['skill_points'], 'offer_reward_state' => 0, ); $dto['hero_tili_max'] = strval(round(FormulaService::Hero_NFT_Maximum_Physical_Strength($dto['quality'],$dto['lucky']),3)); $dto['pvp_ceg_uplimit'] =strval( round(FormulaService::getHeroPvpDailyCegUpLimit($dto),2) ); $dto['pve_ceg_uplimit'] = strval( round(FormulaService::getHeroPveDailyCegUpLimit($dto),2) ); return $dto; } public static function addHero($heroMeta) { return self::internalAddHero( myself()->_getSelfMysql(), $heroMeta, myself()->_getAccountId(), null); } public static function addNftHero($heroMeta, $tokenId) { return self::internalAddHero( myself()->_getMysql($tokenId), $heroMeta, null, $tokenId); } public static function internalAddHero($conn, $heroMeta, $accountId, $tokenId) { $realHeroMeta = mt\Hero::get($heroMeta['id']); $randAttr = array(); $fieldsKv = array( 'hero_id' => $heroMeta['id'], 'hero_lv' => 1, 'quality' => 1, 'hero_tili' => FormulaService::Hero_NFT_Maximum_Physical_Strength(1,FormulaService::Hero_Advanced_Lucky_Value(1)), 'state' => self::GETED_STATE, 'skill_lv1' => 1, 'skill_lv2' => 1, 'rand_attr' => json_encode($randAttr), 'lock_type' => self::NO_LOCK, 'unlock_time' => 0, 'unlock_trade_time' => 0, 'skill_points' => 0, 'createtime' => myself()->_getNowTime(), 'modifytime' => myself()->_getNowTime() ); if ($accountId) { $fieldsKv['account_id'] = $accountId; } if ($tokenId) { $fieldsKv['token_id'] = $tokenId; } SqlHelper::insert( myself()->_getSelfMysql(), 't_hero', $fieldsKv ); } public static function addTryHero($heroMeta, $tryCount) { $realHeroMeta = mt\Hero::get($heroMeta['id']); $randAttr = array(); { $initQualityMeta = mt\HeroQuality::getByQuality(1); if ($initQualityMeta) { $randAttr = mt\HeroQuality::getRandAttr($initQualityMeta); } } SqlHelper::upsert( myself()->_getSelfMysql(), 't_hero', array( 'account_id' => myself()->_getAccountId(), 'hero_id' => $heroMeta['id'] ), array( ), array( 'account_id' => myself()->_getAccountId(), 'hero_id' => $heroMeta['id'], 'hero_lv' => 1, 'quality' => 1, 'hero_tili' => $realHeroMeta ? $realHeroMeta['tili'] : 0, 'state' => self::TRY_STATE, 'try_count' => $tryCount, 'skill_lv1' => 1, 'skill_lv2' => 1, 'rand_attr' => json_encode($randAttr), 'lock_type' => self::NO_LOCK, 'unlock_time' => 0, 'unlock_trade_time' => 0, 'createtime' => myself()->_getNowTime(), 'modifytime' => myself()->_getNowTime() ) ); } public static function takeonSkin($heroUniId, $skinId) { self::update($heroUniId, array( 'skin_id' => $skinId, 'modifytime' => myself()->_getNowTime() )); } public static function upgradeSkill($heroUniId, $skillIdx) { if (!in_array($skillIdx, array(0, 1))) { return; } $fieldName = 'skill_lv' . ($skillIdx + 1); self::update($heroUniId, array( $fieldName => function () use($fieldName) { return "${fieldName} + 1"; }, 'modifytime' => myself()->_getNowTime() )); } public static function update($heroUniId, $fieldsKv) { if (self::find($heroUniId)) { SqlHelper::update (myself()->_getSelfMysql(), 't_hero', array( 'idx' => $heroUniId, ), $fieldsKv ); } } public static function randHero(&$heroUniId, &$heroId) { $heroUniId = 0; $heroId = 0; $heroList = array(); Hero::getHeroList(function ($row) use($heroId, &$heroList) { if ($row['state'] == self::GETED_STATE) { array_push($heroList, Hero::toDto($row)); } }); $key = array_rand($heroList, 1); if (!is_null($key)) { $heroUniId = $heroList[$key]['idx']; $heroId = $heroList[$key]['hero_id']; } } public static function addTili($heroUniId, $tili) { self::update($heroUniId, array( 'hero_tili' => function () use($tili) { return "hero_tili + ${tili}"; }, )); } public static function gainGoldPvp($heroDto, $addGold) { $newGold = min($heroDto['pvp_ceg_uplimit'], $heroDto['current_pvp_get_ceg'] + $addGold); $finalyAddGold = max(0, $newGold - $heroDto['current_pvp_get_ceg']); if ($finalyAddGold > 0) { self::update($heroDto['hero_uniid'], array( 'today_get_gold' => $newGold * 100, 'last_get_gold_time' => myself()->_getNowTime() )); } return $finalyAddGold; } public static function gainGoldPve($heroDto, $addGold) { $newGold = min($heroDto['pve_ceg_uplimit'], $heroDto['current_pve_get_ceg'] + $addGold); $finalyAddGold = max(0, $newGold - $heroDto['current_pve_get_ceg']); if ($finalyAddGold > 0) { self::update($heroDto['hero_uniid'], array( 'today_pve_get_ceg' => $newGold * 100, 'last_pve_get_ceg_time' => myself()->_getNowTime() )); } return $finalyAddGold; } public static function calcPveGainGold($heroDto, $count) { if ($count <= 0) { return 0; } $newGold = min($heroDto['pve_ceg_uplimit'], $heroDto['today_pve_get_ceg'] + round($heroDto['pve_ceg_uplimit'] / $count)); $finalyAddGold = max(0, $newGold - $heroDto['today_pve_get_ceg']); return $finalyAddGold; } public static function heroIsLocking($heroDto) { if ($heroDto['lock_type']) { return true; } $locking = false; $heroUniId = !empty($heroDto['hero_uniid']) ? $heroDto['hero_uniid'] : $heroDto['idx']; { $idx = 0; for ($i = 0; $i < kMaxHeroUpQualityNum; ++$i) { $upHeroUniId = myself()->_getV(TN_HERO_QUALITY_UP, $i); if ($upHeroUniId == $heroUniId) { $idx = $i; $locking = true; break; } } } if (!$locking) { $idx = 0; for ($i = 0; $i < kMaxHeroUpLevelNum; ++$i) { $upHeroUniId = myself()->_getV(TN_HERO_LEVEL_UP, $i); if ($upHeroUniId == $heroUniId) { $idx = $i; $locking = true; break; } } } return $locking; } private static function mergeAttrPro($baseAttr,$attrPro1,$attrPro2){ $newAttr = []; $newAttrPro = []; if ($attrPro1 && !$attrPro2){ $newAttrPro = $attrPro1; } if (!$attrPro1 && $attrPro2){ $newAttrPro = $attrPro2; } if ($attrPro1 && $attrPro2){ foreach ($attrPro1 as $value){ foreach ($attrPro2 as $val){ if ($value['attr_id'] == $val['attr_id']){ array_push($newAttr, [ 'attr_id' => $value['attr_id'], 'type' => $value['type'], 'val' => $value['val']+$val['val'], ]); } } } if ($newAttr){ foreach ($baseAttr as $value){ foreach ($newAttr as $val){ if ($value['attr_id'] == $val['attr_id']){ array_push($newAttrPro, [ 'attr_id' => $value['attr_id'], 'type' => $value['type'], 'val' => strval($val['val']-$value['val']), ]); } } } } } return $newAttrPro; } private static function getAttrProByLevel($row,$baseAttr,$attr){ $attrPro1 = []; $coefficient_level = mt\HeroLevelAttr::getCoefficientByLevel($row['hero_lv'],$row['hero_id']); foreach ($baseAttr as $val){ $coef_level = mt\HeroLevelAttr::getByCoefficient($coefficient_level,$val['attr_id']); foreach ($attr as $v){ if ($val['attr_id'] == $v['attr_id'] && $val['attr_id'] == kHAT_Atk){ //18 //18.941564456287 //20.847692307692 array_push($attrPro1,[ 'attr_id' => $val['attr_id'], 'type'=> $val['type'], 'val' => strval($val['val']*$v['val']+$v['val']/$coef_level['val']*100-100/$coef_level['val']), ]); } if ($val['attr_id'] == $v['attr_id'] && $val['attr_id'] != kHAT_Atk){ array_push($attrPro1,[ 'attr_id' => $val['attr_id'], 'type'=> $val['type'], 'val' => strval($val['val']*pow($v['val'],$coef_level['val'])), ]); } } } return $attrPro1; } private static function getAttrProByQuality($row,$baseAttr){ $attrPro2 = []; $qualityMeta = mt\HeroQuality::getByQuality($row['quality']); $coefficient_quality = mt\HeroQuality::getCoefficientByQuality($row['quality'],$row['hero_id']); foreach ($baseAttr as $val){ $coef_quality = mt\HeroQuality::getByCoefficient($coefficient_quality,$val['attr_id']); if ($coef_quality){ if ($val['attr_id'] == kHAT_Atk){ array_push($attrPro2,[ 'attr_id' => $val['attr_id'], 'type'=> $val['type'], 'val' => strval($val['val']*$qualityMeta['promote_val']+$qualityMeta['promote_val']/$coef_quality['val']*100-100/$coef_quality['val']), ]); } if ($val['attr_id'] != kHAT_Atk) { array_push($attrPro2, [ 'attr_id' => $val['attr_id'], 'type' => $val['type'], 'val' => strval($val['val'] * pow($qualityMeta['promote_val'], $coef_quality['val'])), ]); } } } return $attrPro2; } }