From 947fd83ca6d2d6ec591f27520c84423d0a3c9264 Mon Sep 17 00:00:00 2001 From: hujiabin Date: Wed, 8 Mar 2023 17:12:06 +0800 Subject: [PATCH] =?UTF-8?q?pve=E7=A2=8E=E7=89=87=E4=BA=A7=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/_common.py | 2 + sql/gamedb.sql | 19 ++ webapp/bootstrap/constant.php | 2 + webapp/models/FragmentRecord.php | 53 +++++ webapp/services/BattleDataService.php | 282 +++++++++++++------------- webapp/services/FormulaService.php | 9 +- 6 files changed, 229 insertions(+), 138 deletions(-) create mode 100644 webapp/models/FragmentRecord.php diff --git a/doc/_common.py b/doc/_common.py index fd68a533..8cdef054 100644 --- a/doc/_common.py +++ b/doc/_common.py @@ -1024,5 +1024,7 @@ class HeroPreset(object): ['skill_id', 0, '技能item id'], ['weapon_uid1', 0, '武器1唯一id'], ['weapon_uid2', 0, '武器2唯一id'], + ['gun_id1', 0, '武器1 item id'], + ['gun_id2', 0, '武器2 item id'], ['chip_page', 0, '芯片页id'], ] \ No newline at end of file diff --git a/sql/gamedb.sql b/sql/gamedb.sql index e8712281..9f657746 100644 --- a/sql/gamedb.sql +++ b/sql/gamedb.sql @@ -622,6 +622,25 @@ CREATE TABLE `t_fragment_pool` ( ) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `t_fragment_record` +-- + +DROP TABLE IF EXISTS `t_fragment_record`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t_fragment_record` ( + `idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', + `account_id` varchar(60) NOT NULL DEFAULT '' COMMENT '账号id', + `param` int(11) NOT NULL DEFAULT '0' COMMENT 'param', + `value` int(11) NOT NULL DEFAULT '0' COMMENT '有效场次', + `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', + `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', + PRIMARY KEY (`idx`), + KEY `account_param` (`account_id`, `param`) +) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `t_realtime_data` -- diff --git a/webapp/bootstrap/constant.php b/webapp/bootstrap/constant.php index 5fa3a7a3..26cf74e5 100644 --- a/webapp/bootstrap/constant.php +++ b/webapp/bootstrap/constant.php @@ -41,6 +41,8 @@ define('TN_DAILY_PVP_GET_FRAGMENT_NUM', 9009); define('TN_DAILY_PVE_LAST_GET_FRAGMENT_BATTLE', 9010); define('TN_DAILY_RANK_BATTLE_TIMES', 9011); define('TN_DAILY_END', 9011); +define('TN_DAILY_PVE_GET_HERO_FRAGMENT_NUM', 9012); +define('TN_DAILY_PVE_GET_GUN_FRAGMENT_NUM', 9013); define('TN_WEEKLY_BEGIN', 10001); define('TN_WEEKLY_ACTIVE', 10002); diff --git a/webapp/models/FragmentRecord.php b/webapp/models/FragmentRecord.php new file mode 100644 index 00000000..6875a4a9 --- /dev/null +++ b/webapp/models/FragmentRecord.php @@ -0,0 +1,53 @@ +_getSelfMysql(), + 't_fragment_record', + array( + 'account_id' => myself()->_getAccountId(), + 'param' => $param, + ) + ); + $num = 0; + if ($row) { + $num = $row['value']; + } + return $num; + } + + public static function upsertGamesNum($param,$value){ + SqlHelper::upsert + (myself()->_getSelfMysql(), + 't_fragment_record', + array( + 'account_id' => myself()->_getAccountId(), + 'param' => $param + ), + array( + 'value' => $value, + 'modifytime' => myself()->_getNowDaySeconds() + ), + array( + 'account_id' => myself()->_getAccountId(), + 'param' => $param, + 'value' => 1, + 'createtime' => myself()->_getNowTime(), + 'modifytime' => myself()->_getNowDaySeconds() + ) + ); + } + +} \ No newline at end of file diff --git a/webapp/services/BattleDataService.php b/webapp/services/BattleDataService.php index 38f77b75..2e358814 100644 --- a/webapp/services/BattleDataService.php +++ b/webapp/services/BattleDataService.php @@ -28,6 +28,7 @@ require_once('models/FragmentPool.php'); require_once('models/RealtimeData.php'); require_once('models/BattleHistory.php'); require_once('models/NftActive.php'); +require_once('models/FragmentRecord.php'); require_once('services/RankActivityService.php'); require_once('services/FormulaService.php'); @@ -37,6 +38,7 @@ require_once('services/LogService.php'); use models\Chip; +use models\FragmentRecord; use models\Nft; use models\NftActive; use models\User; @@ -79,17 +81,6 @@ class BattleDataService extends BaseService { 'obtain_ceg' => 0, 'curr_ceg' => 0, ), - 'weapon1' => array( - 'gun_uniid' => '', - 'ceg_uplimit' => 0, - 'obtain_ceg' => 0, - ), - 'weapon2' => array( - 'gun_uniid' => '', - 'ceg_uplimit' => 0, - 'obtain_ceg' => 0, - 'curr_ceg' => 0, - ), 'total_ceg' => 0, 'items' => array(), 'lvInfo' => array() @@ -126,32 +117,7 @@ class BattleDataService extends BaseService { $this->reward['hero']['ceg_uplimit'] = $matchMode == self::MATCH_MODE_PVE ? $this->heroDto['pve_ceg_uplimit'] : $this->heroDto['pvp_ceg_uplimit']; } - { - $weaponUuid1 = getReqVal('weapon_uuid1', ''); - if ($weaponUuid1) { - $weaponDb = Gun::find($weaponUuid1); - if (!$weaponDb) { - return false; - } - $this->weapon1Dto = Gun::toDto($weaponDb); - $this->reward['weapon1']['gun_uniid'] = $this->weapon1Dto['gun_uniid']; - $this->reward['weapon1']['ceg_uplimit'] = $matchMode == self::MATCH_MODE_PVE ? - $this->weapon1Dto['pve_ceg_uplimit'] : $this->weapon1Dto['pvp_ceg_uplimit']; - } - } - { - $weaponUuid2 = getReqVal('weapon_uuid2', ''); - if ($weaponUuid2) { - $weaponDb = Gun::find($weaponUuid2); - if (!$weaponDb) { - return false; - } - $this->weapon2Dto = Gun::toDto($weaponDb); - $this->reward['weapon2']['gun_uniid'] = $this->weapon2Dto['gun_uniid']; - $this->reward['weapon2']['ceg_uplimit'] = $matchMode == self::MATCH_MODE_PVE ? - $this->weapon2Dto['pve_ceg_uplimit'] : $this->weapon2Dto['pvp_ceg_uplimit']; - } - } + //录入战斗记录 $this->saveBattleHistory(); @@ -162,7 +128,6 @@ class BattleDataService extends BaseService { //匹配赛模式 $this->updatePvpData(); $this->rewardCegPvp(); - $this->rewardFragmentPvp(); myself()->_incDailyV(TN_DAILY_PVP_BATTLE_TIMES, 0, 1); } break; @@ -179,7 +144,6 @@ class BattleDataService extends BaseService { $this->updatePveData(); if ($this->pveGeminiMeta && $this->pveGeminiModeMeta) { - $this->rewardCegPve(); $this->rewardFragmentPve(); } myself()->_incDailyV(TN_DAILY_PVE_BATTLE_TIMES, 0, 1); @@ -809,54 +773,151 @@ class BattleDataService extends BaseService { private function rewardFragmentPve() { - if ($this->instanceRank < 1) { + $bossReward = getReqVal('pve_kill_boss', 0) ? 1 : 0; + if ($this->instanceRank < 1 || !$bossReward) { return; } - $todayPveBattleTimes = myself()->_getDailyV(TN_DAILY_PVE_BATTLE_TIMES, 0); - $todayPveLastGetFragmentBattle = myself()->_getDailyV(TN_DAILY_PVE_LAST_GET_FRAGMENT_BATTLE, 0); - $todayPveGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0); - $todayPvpGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 0); + $dropRate = $this->pveGeminiMeta['drop_rate']; + $todayPveGetHeroFragmentNum = myself()->_getDailyV(TN_DAILY_PVE_GET_HERO_FRAGMENT_NUM, 0); + $todayPveGetGunFragmentNum = myself()->_getDailyV(TN_DAILY_PVE_GET_GUN_FRAGMENT_NUM, 0); + if ($todayPveGetHeroFragmentNum < self::MAX_DROP_NUM) { + $gamesNum = FragmentRecord::getGamesNum(FragmentRecord::HERO_FRAGMENT); + $rate = $dropRate*($gamesNum+1); + if (rand(1,100) < $rate*100){ + $dropHeroFragmentId = $this->randWeight2(1); + $this->drop($dropHeroFragmentId,1); + FragmentRecord::upsertGamesNum(FragmentRecord::HERO_FRAGMENT,0); + }else{ + FragmentRecord::upsertGamesNum(FragmentRecord::HERO_FRAGMENT,$gamesNum+1); + } - if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum < self::MAX_DROP_NUM) { - $onlineNum = RealtimeData::getOnline(); - $heroFragmentNum = FragmentPool::getHeroNum(1); - $gunFragmentNum = FragmentPool::getGunNum(1); - - $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, - $todayPveLastGetFragmentBattle - ); - $gunProbability = FormulaService::calcWeaponFragmentProbabilityPve - ( - $heroQuality, - $onlineNum, - $gunFragmentNum, - $todayPveBattleTimes, - $instanceLevel, - $instanceRank, - $instanceRankRate, - $bossReward, - $todayPveLastGetFragmentBattle - ); - $emptyProbability = max(1 - $heroProbability - $gunProbability, 0); - - $dropIdx = $this->randWeight(array($heroProbability, $gunProbability, $emptyProbability)); - $this->procDrop($dropIdx); } + if ($todayPveGetGunFragmentNum < self::MAX_DROP_NUM) { + $gamesNum = FragmentRecord::getGamesNum(FragmentRecord::GUN_FRAGMENT); + $rate = $dropRate*($gamesNum+1); + if (rand(1,100) < $rate*100){ + $dropGunFragmentId = $this->randWeight2(2); + $this->drop($dropGunFragmentId,2); + FragmentRecord::upsertGamesNum(FragmentRecord::GUN_FRAGMENT,0); + }else{ + FragmentRecord::upsertGamesNum(FragmentRecord::GUN_FRAGMENT,$gamesNum+1); + } + + } + +// $todayPveBattleTimes = myself()->_getDailyV(TN_DAILY_PVE_BATTLE_TIMES, 0); +// $todayPveLastGetFragmentBattle = myself()->_getDailyV(TN_DAILY_PVE_LAST_GET_FRAGMENT_BATTLE, 0); +// $todayPveGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVE_GET_FRAGMENT_NUM, 0); +// $todayPvpGetFragmentNum = myself()->_getDailyV(TN_DAILY_PVP_GET_FRAGMENT_NUM, 0); +// +// if ($todayPveGetFragmentNum + $todayPvpGetFragmentNum < self::MAX_DROP_NUM) { +// $onlineNum = RealtimeData::getOnline(); +// $heroFragmentNum = FragmentPool::getHeroNum(1); +// $gunFragmentNum = FragmentPool::getGunNum(1); +// +// $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, +// $todayPveLastGetFragmentBattle +// ); +// $gunProbability = FormulaService::calcWeaponFragmentProbabilityPve +// ( +// $heroQuality, +// $onlineNum, +// $gunFragmentNum, +// $todayPveBattleTimes, +// $instanceLevel, +// $instanceRank, +// $instanceRankRate, +// $bossReward, +// $todayPveLastGetFragmentBattle +// ); +// $emptyProbability = max(1 - $heroProbability - $gunProbability, 0); +// +// $dropIdx = $this->randWeight(array($heroProbability, $gunProbability, $emptyProbability)); +// $this->procDrop($dropIdx); +// } + } + + private function randWeight2($type){ + $itemMeta = mt\Item::getMetaListByType(mt\Item::FRAGMENT_TYPE); + $heroFragment = array(); + $gunFragment = array(); + foreach ($itemMeta as $meta){ + if ($meta['sub_type'] == 3 || $meta['sub_type'] == 1){ + array_push($heroFragment,$meta['id']); + } + if ($meta['sub_type'] == 4 || $meta['sub_type'] == 2){ + array_push($gunFragment,$meta['id']); + } + } + $weightRate = array( + array(0,4), + array(1,12), + array(2,12), + array(3,12), + array(4,12), + array(5,12), + array(6,12), + array(7,12), + array(8,12), + ); + $weight = 0; + $tempData = array (); + foreach ($weightRate as $one) { + $weight += $one[1]; + for ($i = 0; $i < $one[1]; $i++) { + $tempData[] = $one; + + } + } + $key = $tempData[rand(0, $weight -1)][0]; + switch ($type){ + case 1:return $heroFragment[$key]; + case 2:return $gunFragment[$key]; + default:return null; + } + } + + private function drop($itemId,$type){ + $itemMeta = mt\Item::get($itemId); + if ($itemMeta){ + $propertyChgService = new services\PropertyChgService(); + $awardService = new services\AwardService(); + array_push($this->reward['items'], + array( + 'item_id' => $itemId, + 'item_num' => 1 + )); + myself()->_addItems( + array( + array( + 'item_id' => $itemId, + 'item_num' => 1 + )), + $awardService, + $propertyChgService + ); + switch ($type){ + case 1:myself()->_incDailyV(TN_DAILY_PVE_GET_HERO_FRAGMENT_NUM, 0, 1);break; + case 2:myself()->_incDailyV(TN_DAILY_PVE_GET_GUN_FRAGMENT_NUM, 0, 1);break; + } + + } + } private function rewardCegPvp() @@ -878,22 +939,11 @@ class BattleDataService extends BaseService { } } $heroPvpCeg = FormulaService::calcHeroPvpCeg($this->heroDto, $_REQUEST); - $weaponPvpCeg1 = 0; - $weaponPvpCeg2 = 0; - if ($this->weapon1Dto) { - $weaponPvpCeg1 = FormulaService::calcWeaponPvpCeg($this->weapon1Dto, $_REQUEST); - } - if ($this->weapon2Dto) { - $weaponPvpCeg2 = FormulaService::calcWeaponPvpCeg($this->weapon2Dto, $_REQUEST); - } error_log(json_encode(array( 'heroPvpCeg' => $heroPvpCeg, - 'weaponPvpCeg1' => $weaponPvpCeg1, - 'weaponPvpCeg2' => $weaponPvpCeg2, ))); if ($heroPvpCeg > 0) { $heroPvpCeg = Hero::gainGoldPvp($this->heroDto, $heroPvpCeg); - { //埋点 $event = [ @@ -907,56 +957,14 @@ class BattleDataService extends BaseService { $this->reward['hero']['obtain_ceg'] = '' . ($this->heroDto['current_pvp_get_ceg'] + $heroPvpCeg); $this->reward['total_ceg'] += $heroPvpCeg; } - if ($weaponPvpCeg1 > 0) { - $weaponPvpCeg1 = Gun::gainGoldPvp($this->weapon1Dto, $weaponPvpCeg1); - { - //埋点 - $event = [ - 'name' => LogService::BATTLE_AWARD_PVP, - 'val' => $weaponPvpCeg1 - ]; - LogService::productCEG($event,$this->weapon1Dto,$log_param); - } - - $this->reward['weapon1']['curr_ceg'] = '' . ($this->weapon1Dto['current_pvp_get_ceg'] + $weaponPvpCeg1); - $this->reward['weapon1']['obtain_ceg'] = '' . ($this->weapon1Dto['current_pvp_get_ceg'] + $weaponPvpCeg1); - $this->reward['total_ceg'] += $weaponPvpCeg1; - } - if ($weaponPvpCeg2 > 0) { - $weaponPvpCeg2 = Gun::gainGoldPvp($this->weapon2Dto, $weaponPvpCeg2); - - { - //埋点 - $event = [ - 'name' => LogService::BATTLE_AWARD_PVP, - 'val' => $weaponPvpCeg2 - ]; - LogService::productCEG($event,$this->weapon2Dto,$log_param); - } - - $this->reward['weapon2']['curr_ceg'] = '' . ($this->weapon2Dto['current_pvp_get_ceg'] + $weaponPvpCeg2); - $this->reward['weapon2']['obtain_ceg'] = '' . ($this->weapon2Dto['current_pvp_get_ceg'] + $weaponPvpCeg2); - $this->reward['total_ceg'] += $weaponPvpCeg2; - } $this->reward['total_ceg'] .= ''; error_log(json_encode(array( 'new_heroPvpCeg' => $heroPvpCeg, - 'new_weaponPvpCeg1' => $weaponPvpCeg1, - 'new_weaponPvpCeg2' => $weaponPvpCeg2, ))); - $gold = $heroPvpCeg + $weaponPvpCeg1 + $weaponPvpCeg2; + $gold = $heroPvpCeg; error_log('updateBattleData1'); $this->rankActivityService->updateBattleData($gold); - if ($heroPvpCeg>0){ - NftService::addNftActive($this->heroDto,1); - } - if ($weaponPvpCeg1>0){ - NftService::addNftActive($this->weapon1Dto,2); - } - if ($weaponPvpCeg2>0){ - NftService::addNftActive($this->weapon2Dto,2); - } if ($gold > 0) { myself()->_addVirtualItem(V_ITEM_GOLD, $gold); } diff --git a/webapp/services/FormulaService.php b/webapp/services/FormulaService.php index 0dbfb5d4..fc25f7d3 100644 --- a/webapp/services/FormulaService.php +++ b/webapp/services/FormulaService.php @@ -17,10 +17,17 @@ use mt; class FormulaService extends BaseService { + public static function calcHeroPvpGold($heroDto, $params) + { +// GOLD = Min(英雄每天gold上限*10%,标准值) * (f(队伍排名) + g(队伍击杀数)) +// f(队伍排名) = round(1-(队伍排名-1)/10 ,1) +// g(队伍击杀数)= Min(队伍击杀数*0.1 ,2) + } + public static function calcHeroPvpCeg($heroDto, $params) { //每局实际收益=10%PVP收益*5*(50%*[每局排名TopX%对应比例]+25%*[每局PK人数排名TopX%对应比例]+15%*[每局英雄属性排名TopX%对应比例]+5%*[每局武器属性排名TopX%对应比例]+5%*[每局存活时间排名TopX%对应比例]) - $upLimit = $heroDto['pvp_ceg_uplimit']; + $upLimit = $heroDto['gold_uplimit']; $ranked = getXVal($params, 'ranked'); $kills = getXVal($params, 'kills'); $aliveTime = getXVal($params, 'alive_time');