diff --git a/sql/gamedb.sql b/sql/gamedb.sql index ce5dbfbf..e14de11b 100644 --- a/sql/gamedb.sql +++ b/sql/gamedb.sql @@ -615,7 +615,7 @@ CREATE TABLE `t_fragment_pool` ( `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', PRIMARY KEY (`idx`), - KEY `alloc_time_fragment_type` (`alloc_time`, `fragment_type`), + KEY `alloc_time_fragment_type` (`alloc_time`, `fragment_type`) ) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/webapp/controller/BattleController.class.php b/webapp/controller/BattleController.class.php index d32340dc..4da151dc 100644 --- a/webapp/controller/BattleController.class.php +++ b/webapp/controller/BattleController.class.php @@ -38,7 +38,7 @@ class BattleController extends BaseAuthedController { 'modifytime' => $this->_getNowTime(), ) ); - $this->_rspOk(); + $this->_rspData($battleDataService->getReward()); } public function battleReportNew() diff --git a/webapp/models/DynData.php b/webapp/models/DynData.php index 1aa4d4d5..82e1e9d2 100644 --- a/webapp/models/DynData.php +++ b/webapp/models/DynData.php @@ -159,7 +159,7 @@ class DynData extends BaseModel { private static function internalGetV($x, $y, $defVal = 0) { $key = self::calcKey($x, $y); - if (self::$dynData) { + if (!is_null(self::$dynData)) { if (isset(self::$dynData[$key])) { return self::$dynData[$key]; } else { @@ -172,7 +172,7 @@ class DynData extends BaseModel { ++self::$hitCount; if (self::$hitCount > 5 && is_null(self::$dynData)) { self::preload(); - return self::getV($x, $y, $defVal); + return self::internalGetV($x, $y, $defVal); } else { $row = SqlHelper::ormSelectOne( myself()->_getSelfMysql(), diff --git a/webapp/models/FragmentPool.php b/webapp/models/FragmentPool.php index 7e4599cd..df6a18b1 100644 --- a/webapp/models/FragmentPool.php +++ b/webapp/models/FragmentPool.php @@ -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()->_getSelfMysql(), + '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()->_getSelfMysql(), + '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; } } diff --git a/webapp/models/Hero.php b/webapp/models/Hero.php index 2ab7de20..c2a70119 100644 --- a/webapp/models/Hero.php +++ b/webapp/models/Hero.php @@ -384,8 +384,8 @@ class Hero extends BaseModel { if ($finalyAddGold > 0) { self::update($heroDto['hero_uniid'], array( - 'current_pvp_get_ceg' => $newGold, - 'last_pvp_get_ceg_time' => myself()->_getNowTime() + 'today_get_gold' => $newGold, + 'last_get_gold_time' => myself()->_getNowTime() )); } return $finalyAddGold; @@ -399,7 +399,7 @@ class Hero extends BaseModel { if ($finalyAddGold > 0) { self::update($heroDto['hero_uniid'], array( - 'current_pve_get_ceg' => $newGold, + 'today_pve_get_ceg' => $newGold, 'last_pve_get_ceg_time' => myself()->_getNowTime() )); } diff --git a/webapp/models/RealtimeData.php b/webapp/models/RealtimeData.php index 6753fb1a..5c3e00cb 100644 --- a/webapp/models/RealtimeData.php +++ b/webapp/models/RealtimeData.php @@ -17,7 +17,7 @@ class RealtimeData extends BaseModel { private static function internalGet($name) { $row = SqlHelper::ormSelectOne - (myself()->_getMysql($targetId), + (myself()->_getSelfMysql(), 't_realtime_data', array( 'name' => $name diff --git a/webapp/services/BattleDataService.php b/webapp/services/BattleDataService.php index 7baa4843..da25bd42 100644 --- a/webapp/services/BattleDataService.php +++ b/webapp/services/BattleDataService.php @@ -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; @@ -64,7 +71,7 @@ class BattleDataService extends BaseService { public function updateBattleData() { error_log(json_encode($_REQUEST)); - $matchMode = getReqVal('match_mode'); + $matchMode = getReqVal('match_mode', 0); { $heroDb = Hero::find(getReqVal('hero_uniid', 0)); if (!$heroDb) { @@ -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,25 +111,26 @@ 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(); $this->rewardCegPvp(); $this->rewardFragmentPvp(); - $this->_incDailyV(TN_DAILY_PVP_BATTLE_TIMES, 1); + myself()->_incDailyV(TN_DAILY_PVP_BATTLE_TIMES, 0, 1); } break; - case 1: + case self::MATCH_MODE_MATCH: { //排位赛 } break; - case 2: + case self::MATCH_MODE_PVE: { //pve $this>updatePveData(); @@ -129,7 +139,7 @@ class BattleDataService extends BaseService { $this->rewardCegPve(); $this->rewardFragmentPve(); } - $this->_incDailyV(TN_DAILY_PVE_BATTLE_TIMES, 1); + myself()->_incDailyV(TN_DAILY_PVE_BATTLE_TIMES, 0, 1); } break; default: @@ -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); + $todayPveGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0); + $todayPvpGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 0); - if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum > 2) { - return; + if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum < self::MAX_DROP_NUM) { + $todayPvpBattleTimes = myself()->_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::calcWeaponFragmentProbabilityPvp + ($_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 = myself()->_getDailyV(TN_DAILY_PVE_BATTLE_TIMES, 0); + $todayPveGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0); + $todayPvpGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 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 < self::MAX_DROP_NUM) { + $onlineNum = RealtimeData::getOnline(); + $heroFragmentNum = FragmentPool::getHeroNum(); + $gunFragmentNum = FragmentPool::getGunNum(); - if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum > 2) { - return; + $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() @@ -576,10 +578,10 @@ class BattleDataService extends BaseService { $ranked = getReqVal('ranked', 0); $kills = getReqVal('kills', 0); $aliveTime = getReqVal('alive_time', 0); - $cond = (1 - ($ranked > 30 ? 1 : 0)) * - ($kills > 1 ? 1 : 0) * - ($aliveTime > 30 ? 1 : 0); - if ($cond) { + $cond = (1 - ($ranked >= 30 ? 1 : 0)) * + ($kills >= 1 ? 1 : 0) * + ($aliveTime >= 30 ? 1 : 0); + if (!$cond) { return; } } @@ -709,4 +711,38 @@ class BattleDataService extends BaseService { } } + private function procDrop($dropIdx) + { + $matchMode = getReqVal('match_mode', 0); + 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) { + myself()->_incDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0, 1); + } else { + myself()->_incDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 0, 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) { + myself()->_incDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0, 1); + } else { + myself()->_incDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 0, 1); + } + } + } + } + } diff --git a/webapp/services/FormulaService.php b/webapp/services/FormulaService.php index e02b889c..f93648ab 100644 --- a/webapp/services/FormulaService.php +++ b/webapp/services/FormulaService.php @@ -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'); @@ -37,9 +37,9 @@ class FormulaService extends BaseService { (0.5 * $weaponTopX * $meta['weapon_topx']) + (0.5 * $survivalTopX * $meta['survival_topx']) ) * - (1 - ($ranked > 30 ? 1 : 0)) * - ($kills > 1 ? 1 : 0) * - ($aliveTime > 30 ? 1 : 0); + (1 - ($ranked >= 30 ? 1 : 0)) * + ($kills >= 1 ? 1 : 0) * + ($aliveTime >= 30 ? 1 : 0); return round($ceg); } @@ -77,9 +77,9 @@ class FormulaService extends BaseService { (0.5 * $weaponTopX * $meta['weapon_topx']) + (0.5 * $survivalTopX * $meta['survival_topx']) ) * - (1 - ($ranked > 30 ? 1 : 0)) * - ($kills > 1 ? 1 : 0) * - ($aliveTime > 30 ? 1 : 0); + (1 - ($ranked >= 30 ? 1 : 0)) * + ($kills >= 1 ? 1 : 0) * + ($aliveTime >= 30 ? 1 : 0); return round($ceg); } @@ -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($weaponFragmentNum / $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)+系统参数