1043 lines
36 KiB
PHP
1043 lines
36 KiB
PHP
<?php
|
|
|
|
namespace models;
|
|
|
|
require_once('mt/Hero.php');
|
|
require_once('mt/HeroLevelAttr.php');
|
|
require_once('mt/HeroLevel.php');
|
|
require_once('mt/AttrHelper.php');
|
|
require_once('mt/Item.php');
|
|
require_once('mt/BattleBasicAttribute.php');
|
|
require_once('mt/BattleRandAttribute.php');
|
|
require_once('mt/EconomyAttribute.php');
|
|
require_once('models/HeroSkin.php');
|
|
require_once('models/Chip.php');
|
|
require_once('models/User.php');
|
|
require_once('models/Avatar.php');
|
|
require_once('models/ChipPlugin.php');
|
|
require_once('models/ChipPage.php');
|
|
require_once('models/Nft.php');
|
|
require_once('services/NftService.php');
|
|
require_once('services/FormulaService.php');
|
|
|
|
|
|
use mt;
|
|
use phpcommon;
|
|
use phpcommon\SqlHelper;
|
|
use services\NftService;
|
|
use services\FormulaService;
|
|
|
|
|
|
class Hero extends BaseModel {
|
|
|
|
const GETED_STATE = 0;
|
|
const FREE_STATE = 1;
|
|
|
|
const SEAL_STATE = 1;
|
|
const UNSEAL_STATE = 0;
|
|
|
|
const NO_LOCK = 0;
|
|
const LEVEL_LOCK = 1;
|
|
const QUALITY_LOCK = 2;
|
|
const SEND_LOCK = 3;
|
|
const COST_LOCK = 4;
|
|
|
|
const HERO_QUALITY_MAX = 6;
|
|
|
|
public static function find($heroUniId)
|
|
{
|
|
return self::internalFind(myself()->_getAccountId(), myself()->_getAddress(), $heroUniId);
|
|
}
|
|
|
|
public static function findEx($heroUniId){
|
|
$row = SqlHelper::ormSelectOne(
|
|
myself()->_getMysql(myself()->_getAccountId()),
|
|
't_hero',
|
|
array(
|
|
'idx' => $heroUniId,
|
|
)
|
|
);
|
|
return $row;
|
|
}
|
|
|
|
public static function findByAccountId($accountId, $heroUniId)
|
|
{
|
|
return self::internalFind($accountId, User::findUserAddress($accountId), $heroUniId);
|
|
}
|
|
|
|
public static function findByAccountIdEx($accountId, $heroUniId)
|
|
{
|
|
$row = SqlHelper::ormSelectOne(
|
|
myself()->_getMysql($accountId),
|
|
't_hero',
|
|
array(
|
|
'idx' => $heroUniId,
|
|
'account_id' => $accountId,
|
|
)
|
|
);
|
|
if ($row) {
|
|
$row['hero_uniid'] = $row['idx'];
|
|
}
|
|
return $row;
|
|
}
|
|
|
|
public static function findByTokenId($tokenId)
|
|
{
|
|
$row = SqlHelper::ormSelectOne(
|
|
myself()->_getMysql($tokenId),
|
|
't_hero',
|
|
array(
|
|
'token_id' => $tokenId,
|
|
)
|
|
);
|
|
if ($row) {
|
|
$row['hero_uniid'] = $row['idx'];
|
|
if (!NftService::isHeroOwner(myself()->_getAddress(), $row['token_id'])) {
|
|
$row = null;
|
|
}
|
|
}
|
|
return $row;
|
|
}
|
|
|
|
public static function findByTokenId2($tokenId)
|
|
{
|
|
$row = SqlHelper::ormSelectOne(
|
|
myself()->_getMysql($tokenId),
|
|
't_hero',
|
|
array(
|
|
'token_id' => $tokenId,
|
|
)
|
|
);
|
|
return $row;
|
|
}
|
|
|
|
private static function internalFind($accountId, $address, $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 = $address;
|
|
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) {
|
|
$row['tags'] = '';
|
|
$cb($row);
|
|
}
|
|
);
|
|
foreach (NftService::getHeros(myself()->_getAddress()) as $nftDb) {
|
|
if (! $nftDb['deleted']){
|
|
$row = SqlHelper::ormSelectOne(
|
|
myself()->_getSelfMysql(),
|
|
't_hero',
|
|
array(
|
|
'token_id' => $nftDb['token_id'],
|
|
)
|
|
);
|
|
|
|
if ($row) {
|
|
$row['tags'] = $nftDb['tags'];
|
|
$cb($row);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static function listDto($row){
|
|
$attr = emptyReplace(json_decode($row['rand_attr'], true), array());
|
|
$userDb = myself()->_getOrmUserInfo();
|
|
$isSelect = 0;
|
|
if ($row['idx'] == $userDb['hero_id']){
|
|
$isSelect = 1;
|
|
}
|
|
$heroMeta = \mt\Item::get($row['hero_id']);
|
|
$heroAtteMeta = \mt\EconomyAttribute::findByGrade($heroMeta['relationship'],$row['quality']);
|
|
$unsealTime = $row['unseal_time'] ? $row['unseal_time'] : $row['createtime'];
|
|
$validTime = $unsealTime + 86400 * $heroAtteMeta['validTime'] ;
|
|
$skinDb = HeroSkin::find($row['skin_id']);
|
|
$dto = array(
|
|
'idx' => $row['idx'],
|
|
'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' => $skinDb?$skinDb['skin_id']:0,
|
|
'quality' => $row['quality'],
|
|
'skill_lv1' => $row['skill_lv1'],
|
|
'skill_lv2' => $row['skill_lv2'],
|
|
'rand_attr' => $attr,
|
|
'is_select' => $isSelect,
|
|
'lucky' => self::getHeroLucky($row),
|
|
'wealth' => self::getHeroWealth($row),
|
|
'seal_type' => $row['seal_type'],
|
|
'unseal_time' => $row['unseal_time'],
|
|
'valid_lefttime' => max(0,
|
|
$validTime - myself()->_getNowTime()),
|
|
'valid_time' => max(0,
|
|
86400 * $heroAtteMeta['validTime']),
|
|
'is_old' => $row['is_old'],
|
|
"current_times" => myself()->_getDailyV(TN_DAILY_GOLD_MODE_BATTLE_TIMES,$row['idx']),
|
|
"total_times" => $heroAtteMeta['roundPerDay'],
|
|
);
|
|
$dto['is_avatar'] = 0;
|
|
if (SERVER_ENV == _ONLINE) {
|
|
if ($dto['token_id'] > 6240603010001668 && $dto['token_id'] <= 6240603010002168){
|
|
$dto['is_avatar'] = 1;
|
|
}
|
|
}else{
|
|
if ($dto['token_id'] > 0){
|
|
$dto['is_avatar'] = 1;
|
|
}
|
|
}
|
|
return $dto;
|
|
}
|
|
|
|
public static function toDto($row)
|
|
{
|
|
$attr = emptyReplace(json_decode($row['rand_attr'], true), array());
|
|
if (!$attr){
|
|
$attr = self::getRandAttr($row['hero_id'],$row['quality']);
|
|
self::update($row['idx'],array(
|
|
'rand_attr'=>json_encode($attr)
|
|
));
|
|
}
|
|
// $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'];
|
|
}
|
|
|
|
$levelMeta = mt\HeroLevel::getByLevel($row['hero_lv']);
|
|
$todayGetGold = $row['today_get_gold'];
|
|
$lastGetGoldTime = $row['last_get_gold_time'];
|
|
if (myself()->_getDaySeconds($lastGetGoldTime) <
|
|
myself()->_getNowDaySeconds()) {
|
|
$todayGetGold = 0;
|
|
}
|
|
|
|
$userDb = myself()->_getOrmUserInfo();
|
|
$isSelect = 0;
|
|
if ($row['idx'] == $userDb['hero_id'] && self::findByAccountId(myself()->_getAccountId(),$userDb['hero_id'])){
|
|
$isSelect = 1;
|
|
}
|
|
$skinDb = HeroSkin::find($row['skin_id']);
|
|
// $attribute = self::celHeroWealthUpLimit($row);
|
|
{
|
|
$heroMeta = \mt\Item::get($row['hero_id']);
|
|
$heroAtteMeta = \mt\EconomyAttribute::findByGrade($heroMeta['relationship'],$row['quality']);
|
|
$unsealTime = $row['unseal_time'] ? $row['unseal_time'] : $row['createtime'];
|
|
$validTime = $unsealTime + 86400 * $heroAtteMeta['validTime'] ;
|
|
|
|
}
|
|
$baseAbility = self::abilityInfo($row);
|
|
$addAbility = self::abilityInfoAddition($baseAbility, $row);
|
|
$dto = array(
|
|
'idx' => $row['idx'],
|
|
'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' => $skinDb?$skinDb['skin_id']:0,
|
|
'skin_uniid' => $skinDb?$skinDb['idx']:0,
|
|
'quality' => $row['quality'],
|
|
'skill_lv1' => $row['skill_lv1'],
|
|
'skill_lv2' => $row['skill_lv2'],
|
|
'rand_attr' => $attr,
|
|
'try_count' => $row['try_count'],
|
|
'lock_type' => $lockType,
|
|
'unlock_time' => $unlockTime,
|
|
'unlock_lefttime' => max(0,
|
|
$unlockTime - myself()->_getNowTime()),
|
|
'current_get_gold' => $todayGetGold / 100,
|
|
'last_get_gold_time' => $lastGetGoldTime,
|
|
'gold_uplimit' => $levelMeta['gold_limit'],
|
|
'unlock_trade_time' => $row['unlock_trade_time'],
|
|
'advanced_count' => $row['advanced_count'],
|
|
'offer_reward_state' => 0,
|
|
'tags' => isset($row['tags'])?$row['tags']:'',
|
|
'is_select' => $isSelect,
|
|
'lucky' => self::getHeroLucky($row),
|
|
'lucky_base' => self::getHeroLuckyBase($row),
|
|
'wealth' => self::getHeroWealth($row),
|
|
'ability' => $baseAbility,
|
|
'ability_addition' => $addAbility,
|
|
'wealth_base' => self::getHeroWealthBase($row),
|
|
'seal_type' => $row['seal_type'],
|
|
'unseal_time' => $row['unseal_time'],
|
|
'valid_lefttime' => max(0,
|
|
$validTime - myself()->_getNowTime()),
|
|
'valid_time' => max(0,
|
|
86400 * $heroAtteMeta['validTime']),
|
|
'is_old' => $row['is_old'],
|
|
"current_times" => myself()->_getDailyV(TN_DAILY_GOLD_MODE_BATTLE_TIMES,$row['idx']),
|
|
"total_times" => $heroAtteMeta['roundPerDay'],
|
|
);
|
|
|
|
// $nft_address = '';
|
|
// $contract = ContractConfig::find(ContractConfig::ERC721);
|
|
// if ($row['token_id']){
|
|
// $nft_address = $contract ? $contract['hero'] : "";
|
|
// }
|
|
// $dto['nft_address'] = $nft_address;
|
|
$dto['is_avatar'] = 0;
|
|
if (SERVER_ENV == _ONLINE) {
|
|
if ($dto['token_id'] > 6240603010001668 && $dto['token_id'] <= 6240603010002168){
|
|
$dto['is_avatar'] = 1;
|
|
}
|
|
}else{
|
|
if ($dto['token_id'] > 0){
|
|
$dto['is_avatar'] = 1;
|
|
}
|
|
}
|
|
|
|
return $dto;
|
|
}
|
|
|
|
public static function mallInfo($row){
|
|
$attr = emptyReplace(json_decode($row['rand_attr'], true), array());
|
|
$heroMeta = \mt\Item::get($row['hero_id']);
|
|
$heroAtteMeta = \mt\EconomyAttribute::findByGrade($heroMeta['relationship'],$row['quality']);
|
|
return array(
|
|
'idx' => $row['idx'],
|
|
'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'],
|
|
'quality' => $row['quality'],
|
|
'skill_lv1' => $row['skill_lv1'],
|
|
'skill_lv2' => $row['skill_lv2'],
|
|
'rand_attr' => $attr,
|
|
'lucky' => self::getHeroLuckyBase($row),
|
|
'wealth' => self::getHeroWealthBase($row),
|
|
'ability' => self::abilityInfo($row),
|
|
'valid_time' => max(0,
|
|
86400 * $heroAtteMeta['validTime']),
|
|
"current_times" => myself()->_getDailyV(TN_DAILY_GOLD_MODE_BATTLE_TIMES,$row['idx']),
|
|
"total_times" => $heroAtteMeta['roundPerDay'],
|
|
);
|
|
}
|
|
private static function celHeroWealthBase($row){
|
|
|
|
//最大财富值和幸运值计算
|
|
$wealth = 0;
|
|
$wealth_rate = 0;
|
|
$lucky = 0;
|
|
$lucky_rate = 0;
|
|
$heroAttrs = emptyReplace(json_decode($row['wealth_attr'], true), array());
|
|
$heroResult = \mt\EconomyAttribute::getAttrValue($heroAttrs);
|
|
$wealth += $heroResult['wealth'];
|
|
$wealth_rate += $heroResult['wealth_rate'];
|
|
$lucky += $heroResult['lucky'];
|
|
$lucky_rate += $heroResult['lucky_rate'];
|
|
|
|
return array(
|
|
"wealth" => floor($wealth * (1+$wealth_rate)),
|
|
"lucky" => floor($lucky * (1+$lucky_rate)),
|
|
);
|
|
}
|
|
public static function getHeroWealthBase($row){
|
|
return self::celHeroWealthBase($row)["wealth"];
|
|
}
|
|
|
|
public static function getHeroLuckyBase($row){
|
|
return self::celHeroWealthBase($row)["lucky"];
|
|
}
|
|
|
|
private static function celHeroWealthUpLimit($row){
|
|
|
|
//最大财富值和幸运值计算
|
|
$wealth = 0;
|
|
$wealth_rate = 0;
|
|
$lucky = 0;
|
|
$lucky_rate = 0;
|
|
$heroAttrs = emptyReplace(json_decode($row['wealth_attr'], true), array());
|
|
$heroResult = \mt\EconomyAttribute::getAttrValue($heroAttrs);
|
|
$wealth += $heroResult['wealth'];
|
|
$wealth_rate += $heroResult['wealth_rate'];
|
|
$lucky += $heroResult['lucky'];
|
|
$lucky_rate += $heroResult['lucky_rate'];
|
|
$chipPageDb = ChipPage::find($row['idx']);
|
|
if ($row['quality'] > 1 && $chipPageDb){
|
|
$data = emptyReplace(json_decode($chipPageDb['data'], true), array());
|
|
foreach ($data as $value){
|
|
$chipDb = Chip::find($value['chip_id']);
|
|
if ( $chipDb ) {
|
|
$chipAttrs = emptyReplace(json_decode($chipDb['wealth_attr'], true), array());
|
|
$chipResult = \mt\EconomyAttribute::getAttrValue($chipAttrs);
|
|
$wealth += $chipResult['wealth'];
|
|
$wealth_rate += $chipResult['wealth_rate'];
|
|
$lucky += $chipResult['lucky'];
|
|
$lucky_rate += $chipResult['lucky_rate'];
|
|
}
|
|
}
|
|
}
|
|
if ($row['quality'] > 1 && $row['skin_id']){
|
|
$skinDb= HeroSkin::find($row['skin_id']);
|
|
$skinAttrs = emptyReplace(json_decode($skinDb['wealth_attr'], true), array());
|
|
$skinResult = \mt\EconomyAttribute::getAttrValue($skinAttrs);
|
|
$wealth += $skinResult['wealth'];
|
|
$wealth_rate += $skinResult['wealth_rate'];
|
|
$lucky += $skinResult['lucky'];
|
|
$lucky_rate += $skinResult['lucky_rate'];
|
|
}
|
|
return array(
|
|
"wealth" => floor($wealth * (1+$wealth_rate)),
|
|
"lucky" => floor($lucky * (1+$lucky_rate)),
|
|
);
|
|
}
|
|
|
|
public static function getHeroWealth($row){
|
|
return self::celHeroWealthUpLimit($row)["wealth"];
|
|
}
|
|
|
|
public static function getHeroLucky($row){
|
|
return self::celHeroWealthUpLimit($row)["lucky"];
|
|
}
|
|
|
|
public static function avatarInfo($row){
|
|
$avatarDbs = Avatar::getAvatarByHeroIdx($row['idx']);
|
|
$avatarInfos = array();
|
|
if ($avatarDbs){
|
|
foreach ($avatarDbs as $avatarDb){
|
|
array_push($avatarInfos,Avatar::toDto($avatarDb));
|
|
}
|
|
}
|
|
return $avatarInfos;
|
|
}
|
|
|
|
public static function abilityInfoAddition($baseAbility, $row){
|
|
$attr = array();
|
|
$chipPageDb = ChipPage::find($row['idx']);
|
|
if ($row['quality'] > 1 && $chipPageDb) {
|
|
$data = emptyReplace(json_decode($chipPageDb['data'], true), array());
|
|
foreach ($data as $value) {
|
|
$chipDb = Chip::find($value['chip_id']);
|
|
if (!empty($chipDb)) {
|
|
self::mergeAttr($attr, emptyReplace(json_decode($chipDb['rand_attr'], true), array()));
|
|
}
|
|
}
|
|
}
|
|
if ($row['quality'] > 1 && $row['skin_id']) {
|
|
$skinDb = HeroSkin::find($row['skin_id']);
|
|
if (!empty($skinDb)) {
|
|
self::mergeAttr($attr, emptyReplace(json_decode($skinDb['rand_attr'], true), array()));
|
|
}
|
|
}
|
|
$newAbility = self::calcAbility($row['hero_id'], $attr);
|
|
$addAbility = array(
|
|
'hp' => $newAbility['hp'] - $baseAbility['hp'],
|
|
'attack' => $newAbility['attack'] - $baseAbility['attack'],
|
|
'defence' => $newAbility['defence'] - $baseAbility['defence'],
|
|
'block' => $newAbility['block'] - $baseAbility['block'],
|
|
'critical' => $newAbility['critical'] - $baseAbility['critical'],
|
|
);
|
|
return $addAbility;
|
|
}
|
|
|
|
public static function mergeAttr(&$tarAttrs, $srcAttrs)
|
|
{
|
|
foreach ($srcAttrs as $srcAttr) {
|
|
$found = false;
|
|
foreach ($tarAttrs as &$tarAttr) {
|
|
if ($tarAttr['attr_id'] == $srcAttr['attr_id']) {
|
|
$tarAttr['val'] += $srcAttr['val'];
|
|
$found = true;
|
|
break;
|
|
}
|
|
}//end for tarAttrs
|
|
if (!$found) {
|
|
array_push($tarAttrs, $srcAttr);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function calcAbility($heroId, $attr) {
|
|
$info = array(
|
|
'hp' => 0,
|
|
'attack' => 0,
|
|
'defence' => 0,
|
|
'block' => 0,
|
|
'critical' => 0
|
|
);
|
|
$basicMeta = mt\BattleBasicAttribute::get($heroId);
|
|
if (!$basicMeta) {
|
|
return $info;
|
|
}
|
|
{
|
|
$pHealRateAm = 0;
|
|
$pHealthAm_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pHealthAm, 0);
|
|
$pHealRateAm += $pHealthAm_Add;
|
|
|
|
$pHealthRateSe = 0;
|
|
$pHealthRateSe_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pHealthRateSe, 0);
|
|
$pHealthRateSe += $pHealthRateSe_Add;
|
|
|
|
$pHealthRateIn = 0;
|
|
$pHealthRateIn_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pHealthRateIn, 0);
|
|
$pHealthRateIn = (1 + $pHealthRateIn) * (1 + $pHealthRateIn_Add) - 1;
|
|
|
|
$pHealth = ($basicMeta['pOrigHealth'] + $pHealRateAm) * (1 + $pHealthRateSe) * (1 + $pHealthRateIn);
|
|
|
|
$vHealthAm = 0;
|
|
$vHealthAm_Add = mt\AttrHelper::getAttrVal($attr, kHAT_vHealthAm, 0);
|
|
$vHealthAm += $vHealthAm_Add;
|
|
|
|
$vHealthRateSe = 0;
|
|
$vHealthRateSe_Add = mt\AttrHelper::getAttrVal($attr, kHAT_vHealthRateSe, 0);
|
|
$vHealthRateSe += $vHealthRateSe_Add;
|
|
|
|
$vHealthRateIn = 0;
|
|
$vHealthRateIn_Add = mt\AttrHelper::getAttrVal($attr, kHAT_vHealthRateIn, 0);
|
|
$vHealthRateIn = (1 + $vHealthRateIn) * (1 + $vHealthRateIn_Add) - 1;
|
|
|
|
$info['hp'] = ($basicMeta['vOrigHealth'] * (1 + $pHealth / $basicMeta['pBaseHealth'] + $vHealthAm)) *
|
|
(1 + $vHealthRateSe) * (1 + $vHealthRateIn);
|
|
}
|
|
{
|
|
$pAttackAm = 0;
|
|
$pAttackAm_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pAttackAm, 0);
|
|
$pAttackAm += $pAttackAm;
|
|
|
|
$pAttackRateSe = 0;
|
|
$pAttackRateSe_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pAttackRateSe, 0);
|
|
$pAttackRateSe += $pAttackRateSe_Add;
|
|
|
|
$pAttackRateIn = 0;
|
|
$pAttackRateIn_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pAttackRateIn, 0);
|
|
$pAttackRateIn = (1 + $pAttackRateIn) * (1 + $pAttackRateIn_Add) - 1;
|
|
|
|
$vAttackAm = 0;
|
|
$vAttackAm_Add = mt\AttrHelper::getAttrVal($attr, kHAT_vAttackAm, 0);
|
|
$vAttackAm += $vAttackAm_Add;
|
|
|
|
$vAttackRateSe = 0;
|
|
$vAttackRateSe_Add = mt\AttrHelper::getAttrVal($attr, kHAT_vAttackRateSe, 0);
|
|
$vAttackRateSe += $vAttackRateSe_Add;
|
|
|
|
$vAttackRateIn = 0;
|
|
$vAttackRateIn_Add = mt\AttrHelper::getAttrVal($attr, kHAT_vAttackRateIn, 0);
|
|
$vAttackRateIn = (1 + $vAttackRateIn) * (1 + $vAttackRateIn_Add) - 1;
|
|
|
|
$pAttack = 0;
|
|
$pAttack = ($basicMeta['pOrigAttack'] + $pAttackAm) * (1 + $pAttackRateSe) * (1 + $pAttackRateIn);
|
|
|
|
$info['attack'] = ($basicMeta['vOrigAttack'] * (1 + $pAttack / $basicMeta['pBaseAttack'] + $vAttackAm)) *
|
|
(1 + $vAttackRateSe) * (1 + $vAttackRateIn);
|
|
}
|
|
{
|
|
$pDefendAm = 0;
|
|
$pDefendAm_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pDefendAm, 0);
|
|
$pDefendAm += $pDefendAm_Add;
|
|
|
|
$pDefendRateSe = 0;
|
|
$pDefendRateSe_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pDefendRateSe, 0);
|
|
$pDefendRateSe += $pDefendRateSe_Add;
|
|
|
|
$pDefendRateIn = 0;
|
|
$pDefendRateIn_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pDefendRateIn, 0);
|
|
$pDefendRateIn = (1 + $pDefendRateIn) * (1 + $pDefendRateIn_Add) - 1;
|
|
|
|
$pDefend = ($basicMeta['pOrigDefend'] + $pDefendAm) *
|
|
(1 + $pDefendRateSe) * (1 + $pDefendRateIn);
|
|
|
|
$info['defence'] = 1 - (1 - $basicMeta['vOrigDefend']) / (1 + $pDefend / $basicMeta['pBaseDefend']);
|
|
}
|
|
{
|
|
$pBlockAm = 0;
|
|
$pBlockAm_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pBlockAm, 0);
|
|
$pBlockAm += $pBlockAm_Add;
|
|
|
|
$pBlockRateSe = 0;
|
|
$pBlockRateSe_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pBlockRateSe, 0);
|
|
$pBlockRateSe += $pBlockRateSe_Add;
|
|
|
|
$pBlockRateIn = 0;
|
|
$pBlockRateIn_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pBlockRateIn, 0);
|
|
$pBlockRateIn = (1 + $pBlockRateIn) * (1 + $pBlockRateIn_Add) - 1;
|
|
|
|
$pBlock = ($basicMeta['pOrigBlock'] + $pBlockAm) * (1 + $pBlockRateSe) * (1 + $pBlockRateIn);
|
|
|
|
$vBlock = 1 - (1 - $basicMeta['vOrigBlock']) / (1 + $pBlock / $basicMeta['pBaseBlock']);
|
|
|
|
$info['block'] = $vBlock;
|
|
}
|
|
{
|
|
$pCritAm = 0;
|
|
$pCritAm_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pCritAm, 0);
|
|
$pCritAm += $pCritAm_Add;
|
|
|
|
$pCritRateSe = 0;
|
|
$pCritRateSe_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pCritRateSe, 0);
|
|
$pCritRateSe += $pCritRateSe_Add;
|
|
|
|
$pCritRateIn = 0;
|
|
$pCritRateIn_Add = mt\AttrHelper::getAttrVal($attr, kHAT_pCritRateIn, 0);
|
|
$pCritRateIn = (1 - $pCritRateIn) * (1 + $pCritRateIn_Add) - 1;
|
|
|
|
$pCrit = 0;
|
|
$pCrit = ($basicMeta['pOrigCrit'] + $pCritAm) * (1 + $pCritRateSe) * (1 + $pCritRateIn);
|
|
|
|
$vCrit = 0;
|
|
$vCrit = (1 + $basicMeta['vOrigCrit']) * (1 + $pCrit / $basicMeta['pBaseCrit']) - 1;
|
|
$info['critical'] = $vCrit;
|
|
}
|
|
return $info;
|
|
}
|
|
|
|
public static function abilityInfo($row){
|
|
return self::calcAbility($row['hero_id'], array());
|
|
}
|
|
|
|
public static function addFreeHero($heroMeta)
|
|
{
|
|
return self::internalAddHero(
|
|
myself()->_getSelfMysql(),
|
|
$heroMeta,
|
|
myself()->_getAccountId(),
|
|
null
|
|
);
|
|
}
|
|
|
|
|
|
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 addSyntheticHero($heroMeta,$quality){
|
|
return self::internalAddHero(
|
|
myself()->_getSelfMysql(),
|
|
$heroMeta,
|
|
myself()->_getAccountId(),
|
|
null,
|
|
$quality
|
|
);
|
|
}
|
|
|
|
public static function internalAddHero($conn, $heroMeta, $accountId, $tokenId,$quality = 1)
|
|
{
|
|
|
|
$randAttr = self::getRandAttr($heroMeta['battleAttribute'],$quality) ;
|
|
$attribute = \mt\EconomyAttribute::getAttribute($heroMeta['economyAttribute'], $quality);
|
|
$seal_type = 0;
|
|
$unseal_time = 0;
|
|
if ($quality > 1){
|
|
$seal_type = 1;
|
|
$unseal_time = myself()->_getNowTime();
|
|
}
|
|
|
|
$fieldsKv = array(
|
|
'hero_id' => $heroMeta['id'],
|
|
'hero_lv' => 1,
|
|
'quality' => $quality,
|
|
'state' => self::FREE_STATE,
|
|
'skill_lv1' => 1,
|
|
'skill_lv2' => 1,
|
|
'rand_attr' => json_encode($randAttr),
|
|
'lock_type' => self::NO_LOCK,
|
|
'unlock_time' => 0,
|
|
'unlock_trade_time' => 0,
|
|
'activate' => 0,
|
|
'wealth_attr' => json_encode($attribute),
|
|
'seal_type' => $seal_type,
|
|
'unseal_time' => $unseal_time,
|
|
'createtime' => myself()->_getNowTime(),
|
|
'modifytime' => myself()->_getNowTime(),
|
|
|
|
);
|
|
if ($accountId) {
|
|
$fieldsKv['account_id'] = $accountId;
|
|
}
|
|
if ($tokenId) {
|
|
$fieldsKv['token_id'] = $tokenId;
|
|
}
|
|
|
|
SqlHelper::insert(
|
|
$conn,
|
|
't_hero',
|
|
$fieldsKv
|
|
);
|
|
myself()->_addTgLog("addHero",array(
|
|
'item_id'=>$heroMeta['id'],
|
|
'item_num'=>1,
|
|
));
|
|
$userInfo = myself()->_getOrmUserInfo();
|
|
if (!$userInfo['hero_id'] && $seal_type == self::UNSEAL_STATE){
|
|
$heroUnid = SqlHelper::getLastInsertId(myself()->_getSelfMysql());
|
|
User::Update(array(
|
|
'hero_id' => $heroUnid
|
|
));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
private static function getRandAttr($heroId,$quality){
|
|
$attr = array();
|
|
$basicMeta = mt\BattleBasicAttribute::get($heroId);
|
|
if ($basicMeta) {
|
|
$randMeta = mt\BattleRandAttribute::getByWeight($basicMeta['randomAttribute_Default'],$quality);
|
|
if ($randMeta) {
|
|
$attr = mt\BattleRandAttribute::getRandAttr($randMeta);
|
|
}
|
|
}
|
|
return $attr;
|
|
}
|
|
|
|
|
|
public static function update($heroUniId, $fieldsKv)
|
|
{
|
|
if (self::find($heroUniId)) {
|
|
SqlHelper::update
|
|
(myself()->_getSelfMysql(),
|
|
't_hero',
|
|
array(
|
|
'idx' => $heroUniId,
|
|
),
|
|
$fieldsKv
|
|
);
|
|
}
|
|
}
|
|
|
|
public static function safeUpdateTokenId($accountId, $heroUniId, $tokenId)
|
|
{
|
|
myself()->_getMysql($accountId)->execScript(
|
|
'UPDATE t_hero SET token_id=:token_id ' .
|
|
'WHERE idx=:idx AND account_id=:account_id AND token_id IS NULL;',
|
|
array(
|
|
':idx' => $heroUniId,
|
|
':account_id' => $accountId,
|
|
':token_id' => $tokenId,
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function updateByTokenId($tokenId, $fieldsKv)
|
|
{
|
|
if (self::findByTokenId($tokenId)) {
|
|
SqlHelper::update
|
|
(myself()->_getSelfMysql(),
|
|
't_hero',
|
|
array(
|
|
'token_id' => $tokenId,
|
|
),
|
|
$fieldsKv
|
|
);
|
|
}
|
|
}
|
|
|
|
public static function randHero(&$heroUniId, &$heroId)
|
|
{
|
|
$heroUniId = 0;
|
|
$heroId = 0;
|
|
|
|
$heroList = array();
|
|
Hero::getHeroList(function ($row) use($heroId, &$heroList) {
|
|
if ($row['seal_type'] == self::UNSEAL_STATE) {
|
|
array_push($heroList, Hero::toDto($row));
|
|
}
|
|
});
|
|
$key = null;
|
|
if (count($heroList)>0){
|
|
$key = array_rand($heroList, 1);
|
|
}
|
|
if (!is_null($key)) {
|
|
$heroUniId = $heroList[$key]['idx'];
|
|
$heroId = $heroList[$key]['hero_id'];
|
|
}
|
|
}
|
|
|
|
public static function recoverUsedTime($heroUniId)
|
|
{
|
|
self::update($heroUniId,
|
|
array(
|
|
"unseal_time" => myself()->_getNowTime()
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function gainGoldPvp($heroDto, $addGold)
|
|
{
|
|
$newGold = min($heroDto['gold_uplimit'],
|
|
$heroDto['current_get_gold'] + $addGold);
|
|
$finalyAddGold = max(0, $newGold - $heroDto['current_get_gold']);
|
|
// 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 gainGoldMission($heroDto, $addGold)
|
|
{
|
|
$newGold = min($heroDto['mission_ceg_uplimit'],
|
|
$heroDto['current_mission_get_ceg'] + $addGold);
|
|
$finalyAddGold = max(0, $newGold - $heroDto['current_mission_get_ceg']);
|
|
if ($finalyAddGold > 0) {
|
|
self::update($heroDto['hero_uniid'],
|
|
array(
|
|
'today_mission_get_ceg' => $newGold * 100,
|
|
'last_mission_get_ceg_time' => myself()->_getNowTime()
|
|
));
|
|
}
|
|
return $finalyAddGold;
|
|
}
|
|
|
|
public static function calcMissionGainGold($heroDto, $count)
|
|
{
|
|
if ($count <= 0) {
|
|
return 0;
|
|
}
|
|
$newGold = min($heroDto['mission_ceg_uplimit'],
|
|
$heroDto['current_mission_get_ceg'] +
|
|
$heroDto['mission_ceg_uplimit'] / $count);
|
|
$finalyAddGold = max(0, $newGold - $heroDto['current_mission_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;
|
|
}
|
|
|
|
public static function getFreeHero(){
|
|
$hero = array();
|
|
Hero::getHeroList(function ($row) use (&$hero) {
|
|
if (!$row['token_id']) {
|
|
$hero = $row;
|
|
}
|
|
});
|
|
return $hero;
|
|
}
|
|
|
|
public static function toDtoInfo($row){
|
|
$heroMeta = mt\Hero::get($row['hero_id']);
|
|
$attr = emptyReplace(json_decode($row['rand_attr'], true), array());
|
|
if ($attr){
|
|
foreach ($attr as &$value){
|
|
$value['val'] = floor($value['val']);
|
|
}
|
|
}else{
|
|
$attr = mt\Hero::getHeroAttr($heroMeta);
|
|
}
|
|
$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;
|
|
}
|
|
$info = array(
|
|
'idx' => $row['idx'],
|
|
'token_id' => $row['token_id'],
|
|
'hero_uniid' => $row['idx'],
|
|
'hero_name' => $heroMeta['name'],
|
|
'hero_id' => $row['hero_id'],
|
|
'hero_lv' => $row['hero_lv'],
|
|
'hero_tili' => $row['hero_tili'],
|
|
'quality' => $row['quality'],
|
|
'rand_attr' => $attr,
|
|
'current_pvp_get_ceg' => $todayGetGold / 100,
|
|
'current_pve_get_ceg' => $todayPveGetCeg / 100,
|
|
'advanced_count' => $row['advanced_count'],
|
|
);
|
|
|
|
return $info;
|
|
}
|
|
|
|
public static function getHeroByItemId($itemId){
|
|
$hero = array();
|
|
self::getHeroList(function ($row) use (&$hero,$itemId) {
|
|
if ($row['hero_id'] == $itemId) {
|
|
array_push($hero,$row);
|
|
}
|
|
});
|
|
return $hero;
|
|
}
|
|
|
|
public static function getAccountLucky($address){
|
|
$lucky = 0;
|
|
foreach (NftService::getHeros($address) as $nftDb) {
|
|
if (! $nftDb['deleted']){
|
|
$row = SqlHelper::ormSelectOne(
|
|
myself()->_getSelfMysql(),
|
|
't_hero',
|
|
array(
|
|
'token_id' => $nftDb['token_id'],
|
|
)
|
|
);
|
|
if ($row) {
|
|
$heroMeta = \mt\Item::get($row['hero_id']);
|
|
$heroAtteMeta = \mt\EconomyAttribute::findByGrade($heroMeta['relationship'],$row['quality']);
|
|
$currTime = $row['unseal_time'] ? $row['unseal_time'] : $row['createtime'];
|
|
if ($row['seal_type'] == 0 && $currTime + 86400 * $heroAtteMeta['validTime'] > myself()->_getNowTime()){
|
|
$lucky += self::getHeroLucky($row);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $lucky;
|
|
}
|
|
|
|
public static function getAccountLuckyTemp(){
|
|
$lucky = 0;
|
|
// $rows = SqlHelper::ormSelect(
|
|
// myself()->_getSelfMysql(),
|
|
// 't_hero',
|
|
// array(
|
|
// 'account_id' => myself()->_getAccountId(),
|
|
// )
|
|
// );
|
|
$rows = array();
|
|
self::getHeroList(function ($row) use(&$rows) {
|
|
array_push($rows, $row);
|
|
});
|
|
|
|
foreach ($rows as $row) {
|
|
$heroMeta = \mt\Item::get($row['hero_id']);
|
|
$heroAtteMeta = \mt\EconomyAttribute::findByGrade($heroMeta['relationship'],$row['quality']);
|
|
$currTime = $row['unseal_time'] ? $row['unseal_time'] : $row['createtime'];
|
|
if ($row['seal_type'] == 0 && $currTime + 86400 * $heroAtteMeta['validTime'] > myself()->_getNowTime()){
|
|
$lucky += self::getHeroLucky($row);
|
|
}
|
|
}
|
|
return $lucky;
|
|
}
|
|
|
|
public static function verifyValid($hero){
|
|
// if (empty($hero['token_id'])){
|
|
// return false;
|
|
// }
|
|
|
|
$heroMeta = \mt\Item::get($hero['hero_id']);
|
|
$heroAtteMeta = \mt\EconomyAttribute::findByGrade($heroMeta['relationship'],$hero['quality']);
|
|
$currTime = $hero['unseal_time'] ? $hero['unseal_time'] : $hero['createtime'];
|
|
if ($hero['seal_type'] == 0 && $currTime + 86400 * $heroAtteMeta['validTime'] > myself()->_getNowTime()){
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
}
|