This commit is contained in:
aozhiwei 2022-09-19 20:39:37 +08:00
commit 20c85abfd5
3 changed files with 284 additions and 86 deletions

View File

@ -9,23 +9,93 @@ class FragmentPool extends BaseModel {
public static function dropHero()
{
$rows = SqlHelper::ormSelect
(myself()->_getMysql($targetId),
't_fragment_pool',
array(
'fragment_type' => 0,
'alloc_time' => 0,
)
);
if ($rows) {
$items = self::internalGet(0);
if (count($items)) {
$idx = array_rand($items, 1);
$fragmentId = $items[$idx]['fragment_id'];
self::decNum($fragmentId);
return $fragmentId;
}
return null;
return 0;
}
public static function dropGun()
{
$items = self::internalGet(1);
if (count($items)) {
$idx = array_rand($items, 1);
$fragmentId = $items[$idx]['fragment_id'];
self::decNum($fragmentId);
return $fragmentId;
}
return 0;
}
public static function getHeroNum()
{
$items = self::internalGet(0);
$num = 0;
foreach ($items as $item) {
$num += $item['fragment_num'];
}
return $num;
}
public static function getGunNum()
{
$items = self::internalGet(1);
$num = 0;
foreach ($items as $item) {
$num += $item['fragment_num'];
}
return $num;
}
private static function internalGet($type)
{
$allocTime = self::getAllocTime();
$rows = SqlHelper::ormSelect
(myself()->_getMysql($targetId),
't_fragment_pool',
array(
'fragment_type' => $type,
'alloc_time' => $allocTime,
)
);
$items = array();
if ($rows) {
foreach ($rows as $row) {
if ($row['fragment_num'] > 0) {
array_push($items, $row);
}
}
}
return $items;
}
private static function decNum($itemId)
{
$allocTime = self::getAllocTime();
SqlHelper::update
(myself()->_getMysql($targetId),
't_fragment_pool',
array(
'fragment_id' => $itemId,
'alloc_time' => $allocTime,
),
array(
'fragment_num' => function () {
return 'GREATEST(0, fragment_num - 1)';
},
)
);
}
private static function getAllocTime()
{
$allocTime = myself()->_getNowDaySeconds() +
intval((myself()->_getNowTime() - myself()->_getNowDaySeconds()) / 3600) * 3600;
return $allocTime;
}
}

View File

@ -34,10 +34,17 @@ use models\Bag;
use models\Hero;
use models\Gun;
use models\RealtimeData;
use models\FragmentPool;
use services\FormulaService;
class BattleDataService extends BaseService {
const MAX_DROP_NUM = 2;
const MATCH_MODE_PVP = 0;
const MATCH_MODE_MATCH = 1;
const MATCH_MODE_PVE = 2;
private $seasonDb = array();
private $heroDto = null;
private $heroMeta = null;
@ -79,7 +86,8 @@ class BattleDataService extends BaseService {
return false;
}
$this->reward['hero']['hero_uniid'] = $this->heroDto['hero_uniid'];
$this->reward['hero']['ceg_uplimit'] = $matchMode == 2 ? $this->heroDto['pve_ceg_uplimit'] : $this->heroDto['pvp_ceg_uplimit'];
$this->reward['hero']['ceg_uplimit'] = $matchMode == self::MATCH_MODE_PVE ?
$this->heroDto['pve_ceg_uplimit'] : $this->heroDto['pvp_ceg_uplimit'];
}
{
$weaponUuid1 = getReqVal('weapon_uuid1', '');
@ -90,7 +98,8 @@ class BattleDataService extends BaseService {
}
$this->weapon1Dto = Gun::toDto($weaponDb);
$this->reward['weapon1']['gun_uniid'] = $this->weapon1Dto['gun_uniid'];
$this->reward['weapon1']['ceg_uplimit'] = $matchMode == 2 ? $this->weapon1Dto['pve_ceg_uplimit'] : $this->weapon1Dto['pvp_ceg_uplimit'];
$this->reward['weapon1']['ceg_uplimit'] = $matchMode == self::MATCH_MODE_PVE ?
$this->weapon1Dto['pve_ceg_uplimit'] : $this->weapon1Dto['pvp_ceg_uplimit'];
}
}
{
@ -102,11 +111,12 @@ class BattleDataService extends BaseService {
}
$this->weapon2Dto = Gun::toDto($weaponDb);
$this->reward['weapon2']['gun_uniid'] = $this->weapon2Dto['gun_uniid'];
$this->reward['weapon2']['ceg_uplimit'] = $matchMode == 2 ? $this->weapon2Dto['pve_ceg_uplimit'] : $this->weapon2Dto['pvp_ceg_uplimit'];
$this->reward['weapon2']['ceg_uplimit'] = $matchMode == self::MATCH_MODE_PVE ?
$this->weapon2Dto['pve_ceg_uplimit'] : $this->weapon2Dto['pvp_ceg_uplimit'];
}
}
switch ($matchMode) {
case 0:
case self::MATCH_MODE_PVP:
{
//匹配赛模式
$this->updatePvpData();
@ -115,12 +125,12 @@ class BattleDataService extends BaseService {
$this->_incDailyV(TN_DAILY_PVP_BATTLE_TIMES, 1);
}
break;
case 1:
case self::MATCH_MODE_MATCH:
{
//排位赛
}
break;
case 2:
case self::MATCH_MODE_PVE:
{
//pve
$this>updatePveData();
@ -487,87 +497,79 @@ class BattleDataService extends BaseService {
private function rewardFragmentPvp()
{
$todayPvpBattleTimes = $this->_getDailyV(TN_DAILY_PVP_BATTLE_TIMES, 0);
$todayPveGetFragmentNum = $this->_getDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0);
$todayPvpGetFragmentNum = $this->_getDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 0);
if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum > 2) {
return;
if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum < self::MAX_DROP_NUM) {
$todayPvpBattleTimes = $this->_getDailyV(TN_DAILY_PVP_BATTLE_TIMES, 0);
$onlineNum = RealtimeData::getOnline();
$heroFragmentNum = FragmentPool::getHeroNum();
$gunFragmentNum = FragmentPool::getGunNum();
$heroProbability = FormulaService::calcHeroFragmentProbabilityPvp
($_REQUEST,
$onlineNum,
$heroFragmentNum,
$todayPvpBattleTimes);
$gunProbability = FormulaService::calcGunFragmentProbabilityPvp
($_REQUEST,
$onlineNum,
$gunFragmentNum,
$todayPvpBattleTimes);
$emptyProbability = max(1 - $heroProbability - $gunProbability, 0);
$dropIdx = $this->randWeight(array($heroProbability, $gunProbability, $emptyProbability));
$this->procDrop($dropIdx);
}
$onlineNum = RealtimeData::getOnline();
$rankedTopX= getXVal($params, 'ranked_topx');
$meta = mt\FormulaPvp::getByRanked($rankedTopX);
if (!$meta) {
return;
}
$heroProbability = min($heroFragment[$now].total / $onlineNum *
5 *
(
0.5*$meta['ranked_topx'] +
0.25*$meta['kills_topx'] +
0.15*$meta['hero_topx'] +
0.05*$meta['weapon_topx']
) *
pow(2, ($todayPvpBattleTimes % 10) - 1), 1);
$gunProbability = min($gunFragment[$now].total / $onlineNum *
5 *
(
0.5*$meta['ranked_topx'] +
0.25*$meta['kills_topx'] +
0.15*$meta['hero_topx'] +
0.05*$meta['weapon_topx']
) *
pow(2, ($todayPvpBattleTimes % 10) - 1), 1);
$heroProbability = max($heroProbability, 0);
$gunProbability = max($gunProbability, 0);
$emptyProbability = max(1 - $heroProbability - $gunProbability, 0);
$dropIdx = $this->randWeight(array($heroProbability, $gunProbability, $emptyProbability));
if ($dropIdx < 0 || $dropIdx == 2) {
return;
}
}
private function rewardFragmentPve()
{
$pveRankScore = getReqVal('pve_rank_score', 0);
$todayPveBattleTimes = $this->_getDailyV(TN_DAILY_PVE_BATTLE_TIMES, 0);
$todayPveGetFragmentNum = $this->_getDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0);
$todayPvpGetFragmentNum = $this->_getDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 0);
if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum > 2) {
return;
if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum < self::MAX_DROP_NUM) {
$onlineNum = RealtimeData::getOnline();
$heroFragmentNum = FragmentPool::getHeroNum();
$gunFragmentNum = FragmentPool::getGunNum();
$instanceLevel = $this->pveGeminiMeta['gemini_lv'];
$instanceRank = $this->instanceRank;
$instanceRankRate = $this->getInstanceRankRate();
$bossReward = getReqVal('pve_kill_boss', 0) ? 1 : 0;
$heroQuality = $this->heroDto['quality'];
$heroProbability = FormulaService::calcHeroFragmentProbabilityPve
(
$heroQuality,
$onlineNum,
$heroFragmentNum,
$todayPveBattleTimes,
$instanceLevel,
$instanceRank,
$instanceRankRate,
$bossReward,
$todayPveGetFragmentNum
);
$gunProbability = FormulaService::calcWeaponFragmentProbabilityPve
(
$heroQuality,
$onlineNum,
$gunFragmentNum,
$todayPveBattleTimes,
$instanceLevel,
$instanceRank,
$instanceRankRate,
$bossReward,
$todayPveGetFragmentNum
);
$emptyProbability = max(1 - $heroProbability - $gunProbability, 0);
$dropIdx = $this->randWeight(array($heroProbability, $gunProbability, $emptyProbability));
$this->procDrop($dropIdx);
}
$onlineNum = RealtimeData::getOnline();
$instanceLevel = $this->pveGeminiMeta['gemini_lv'];
$instanceRank = $this->instanceRank;
$instanceRankRate = $this->getInstanceRankRate();
$bossReward = getReqVal('pve_kill_boss', 0) ? 1 : 0;
$heroQuality = $this->heroDto['quality'];
$dropRate = max(1.15 - ($heroQuality - $instanceLevel) * 0.25, 0);
$dropMul = 0.8 - ($instanceRank - 1) * 0.25 + $bossReward * 0.2;
$heroProbability = min($heroFragment[$now].total / $onlineNum * $dropRate * ($instanceRankRate + $bossReward*0.2) * pow(2, $todayPveBattleTimes - $todayPveGetFragmentNum -1), 1);
$gunProbability = min($gunFragment[$now].total / $onlineNum * $dropRate * ($instanceRankRate + $bossReward*0.2) * pow(2, $todayPveBattleTimes - $todayPveGetFragmentNum -1), 1);
$heroProbability = max($heroProbability, 0);
$gunProbability = max($gunProbability, 0);
$emptyProbability = max(1 - $heroProbability - $gunProbability, 0);
$dropIdx = $this->randWeight(array($heroProbability, $gunProbability, $emptyProbability));
if ($dropIdx < 0 || $dropIdx == 2) {
return;
}
}
private function rewardCegPvp()
@ -709,4 +711,38 @@ class BattleDataService extends BaseService {
}
}
private function procDrop($dropIdx)
{
$matchMode = getReqVal('match_mode');
if ($dropIdx == 0) {
$itemId = FragmentPool::dropHero();
if ($itemId) {
array_push($this->reward['items'],
array(
'item_id' => $itemId,
'item_num' => 1
));
if ($matchMode == self::MATCH_MODE_PVE) {
$this->_incDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 1);
} else {
$this->_incDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 1);
}
}
} else if ($dropIdx == 1) {
$itemId = FragmentPool::dropGun();
if ($itemId) {
array_push($this->reward['items'],
array(
'item_id' => $itemId,
'item_num' => 1
));
if ($matchMode == self::MATCH_MODE_PVE) {
$this->_incDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 1);
} else {
$this->_incDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 1);
}
}
}
}
}

View File

@ -20,7 +20,7 @@ class FormulaService extends BaseService {
$kills = getXVal($params, 'kills');
$aliveTime = getXVal($params, 'alive_time');
$rankedTopX= getXVal($params, 'ranked_topx');
$rankedTopX = getXVal($params, 'ranked_topx');
$killsTopX = getXVal($params, 'kills_topx');
$heroTopX = getXVal($params, 'hero_topx');
$weaponTopX = getXVal($params, 'weapon_topx');
@ -96,6 +96,98 @@ class FormulaService extends BaseService {
return round(ceg);
}
public static function calcHeroFragmentProbabilityPvp($params,
$onlineNum,
$heroFragmentNum,
$todayPvpBattleTimes)
{
$rankedTopX = getXVal($params, 'ranked_topx');
$killsTopX = getXVal($params, 'kills_topx');
$heroTopX = getXVal($params, 'hero_topx');
$weaponTopX = getXVal($params, 'weapon_topx');
$survivalTopX = getXVal($params, 'survival_topx');
$meta = mt\FormulaPvp::getByRanked($rankedTopX);
if (!$meta) {
return 0;
}
$heroProbability = min($heroFragmentNum / $onlineNum *
5 *
(
0.5 * $rankedTopX * $meta['ranked_topx'] +
0.25 * $killsTopX * $meta['kills_topx'] +
0.15 * $heroTopX * $meta['hero_topx'] +
0.05 * $weaponTopX * $meta['weapon_topx'] +
0.05 * $survivalTopX * $meta['survival_topx']
) *
pow(2, ($todayPvpBattleTimes % 10) - 1), 1);
return max(0, $heroProbability);
}
public static function calcWeaponFragmentProbabilityPvp($params,
$onlineNum,
$weaponFragmentNum,
$todayPvpBattleTimes)
{
$rankedTopX = getXVal($params, 'ranked_topx');
$killsTopX = getXVal($params, 'kills_topx');
$heroTopX = getXVal($params, 'hero_topx');
$weaponTopX = getXVal($params, 'weapon_topx');
$survivalTopX = getXVal($params, 'survival_topx');
$meta = mt\FormulaPvp::getByRanked($rankedTopX);
if (!$meta) {
return 0;
}
$weaponProbability = min($FragmentNum / $onlineNum *
5 *
(
0.5 * $rankedTopX * $meta['ranked_topx'] +
0.25 * $killsTopX * $meta['kills_topx'] +
0.15 * $heroTopX * $meta['hero_topx'] +
0.05 * $weaponTopX * $meta['weapon_topx'] +
0.05 * $survivalTopX * $meta['survival_topx']
) *
pow(2, ($todayPvpBattleTimes % 10) - 1), 1);
return max(0, $weaponProbability);
}
public static function calcHeroFragmentProbabilityPve($heroQuality,
$onlineNum,
$heroFragmentNum,
$todayPvpBattleTimes,
$instanceLevel,
$instanceRank,
$instanceRankRate,
$bossReward,
$todayPveGetFragmentNum)
{
$dropRate = max(1.15 - ($heroQuality - $instanceLevel) * 0.25, 0);
$dropMul = 0.8 - ($instanceRank - 1) * 0.25 + $bossReward * 0.2;
$heroProbability = min($heroFragmentNum / $onlineNum *
$dropRate * ($instanceRankRate + $bossReward*0.2) *
pow(2, $todayPveBattleTimes - $todayPveGetFragmentNum - 1), 1);
return max(0, $heroProbability);
}
public static function calcWeaponFragmentProbabilityPve($heroQuality,
$onlineNum,
$gunFragmentNum,
$todayPvpBattleTimes,
$instanceLevel,
$instanceRank,
$instanceRankRate,
$bossReward,
$todayPveGetFragmentNum)
{
$dropRate = max(1.15 - ($heroQuality - $instanceLevel) * 0.25, 0);
$dropMul = 0.8 - ($instanceRank - 1) * 0.25 + $bossReward * 0.2;
$gunProbability = min($gunFragmentNum / $onlineNum *
$dropRate * ($instanceRankRate + $bossReward*0.2) *
pow(2, $todayPveBattleTimes - $todayPveGetFragmentNum - 1), 1);
return max(0, $gunProbability);
}
public static function getHeroPvpTiliTotalValue($heroDb)
{
//ROUND((0.0241*角色NFT阶数^3-0.5675*角色NFT阶数^2+7.1798*角色NFT阶数+2.4114)+(0.0161*角色幸运值^3-1.2943*角色幸运值^2+36.5664*角色幸运值-336.144),0)+系统参数