FightProc.php 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. <?php
  2. namespace loyalsoft;
  3. /**
  4. * 战斗模块
  5. * @author c'y'zhao
  6. */
  7. class FightProc {
  8. public const TowerGateId = 940011999;
  9. /**
  10. * 逻辑分发
  11. * 所有的Proc中必须有这样一个方法
  12. * @param Req $req
  13. */
  14. public static function procMain($req) {
  15. switch ($req->cmd) {
  16. case CmdCode::fight_settle: # 6801 主线战斗结算
  17. return FightProc::Settle();
  18. case CmdCode::fight_PassGateTsPrizeReceive: # 6802 章节宝箱的领取
  19. return FightProc::PassGateTsPrizeReceive();
  20. case CmdCode::fight_selectGate: # 6803 主线剧情关卡选择
  21. return FightProc::SelectGate();
  22. case CmdCode::fight_gateChallengeRewards: # 6804 挑战关卡: 领取奖励
  23. return FightProc::GateChallengeRewards();
  24. case CmdCode::fihgt_towerStart: # 6805 挑战关卡: 开始挑战
  25. return FightProc::ChallengeGateStartFight();
  26. case CmdCode::fight_plotSav: # 6806 主线剧情(已播放)回存
  27. return FightProc::PlotSav();
  28. case CmdCode::fight_sweep: # 6807 主线扫荡
  29. return FightProc::FightSweep();
  30. case CmdCode::fight_startFight: # 6808 主线剧情关卡开始挑战
  31. return self::StartFight();
  32. case CmdCode::fight_tower_RefreshSkills: # 6809 挑战关卡: 刷新初始技能
  33. return self::TowerRefreshSkills();
  34. case CmdCode::fight_tower_updatelocklist: # 6810 挑战关卡: 更新技能锁定列表
  35. return self::TowerUpdateLockskillList();
  36. case CmdCode::fight_rankInfo: # 6811 获取主线关卡排行榜信息
  37. return self::GetRankInfo();
  38. case CmdCode::fight_rank_uidEquipInfo: # 6812 获取主线关卡榜内玩家的装备信息
  39. return self::GetUidEquipInfo_Rank();
  40. case CmdCode::fight_rank_GetMainGateRankRewardInfo: # 6813 获取通关荣誉榜信息
  41. return self::GetmainGate_RankRewardInfo();
  42. case CmdCode::fight_rank_GetFightPowerRankRewardInfo: # 6814 获取战力荣誉榜信息
  43. return self::GetFightPower_RankRewardInfo();
  44. case CmdCode::fight_rank_ReceiveRankReward_MainGate: # 6815 领取通关荣誉榜奖励
  45. return self::ReceiveRankReward_MainGate();
  46. case CmdCode::fight_rank_ReceiveRankReward_FightPower: # 6816 领取战力荣誉榜奖励
  47. return self::ReceiveRankReward_FightPower();
  48. case CmdCode::fight_rank_IsExistRankReward: #6817 是否存在未领取的荣誉榜奖励
  49. return self::IsExistRankReward();
  50. default:
  51. Err(ErrCode::cmd_err);
  52. }
  53. }
  54. /**
  55. * 6807 扫荡
  56. * @return type
  57. */
  58. public static function FightSweep() {
  59. //list($gateId) = req()->paras;
  60. $passGateId = ctx()->gates->maxPassGateId();
  61. my_Assert($passGateId != 0, ErrCode::gate_NoSweep);
  62. //$mo = GameConfig::gate_getItem(ctx()->gates->UnlockedGatesMaxId);
  63. $costTili = glc()->sweep_cost_tili;
  64. my_Assert(ctx()->baseInfo->tili >= $costTili, ErrCode::notenough_tili);
  65. $max = glc()->sweepMaxNum;
  66. my_Assert(ctx()->gates->fightSweepNum < $max, ErrCode::gate_SweepMaxNum_limit);
  67. ctx()->gates->fightSweepNum += 1;
  68. ctx()->baseInfo->Consume_tili($costTili);
  69. $prizeArr = array();
  70. $wavesArr = GameConfig::waves_getItemArray($passGateId);
  71. $count = count($wavesArr);
  72. $wavesMo = $wavesArr[$count - 1];
  73. ctx()->baseInfo->Add_Gold($wavesMo->rewardGold);
  74. $gold = $wavesMo->rewardGold;
  75. $prizeArr[] = "1," . $gold;
  76. ctx()->baseInfo->Add_Gold($gold);
  77. $exp = $wavesMo->rewardExp;
  78. $prizeArr[] = "4," . $exp;
  79. ctx()->baseInfo->Add_Exp($exp);
  80. if ($wavesMo->rewardTuZhi != null) {
  81. $tuzhi = explode('-', $wavesMo->rewardTuZhi);
  82. $n = rand($tuzhi[0], $tuzhi[1]);
  83. $tuzhiArr = array();
  84. $item = GameConfig::item();
  85. foreach ($item as $id => $mo) {
  86. if ($mo->itemType == 100) {
  87. $tuzhiArr[] = $id;
  88. }
  89. }
  90. $index = rand(0, count($tuzhiArr) - 1);
  91. $goodsStr = $tuzhiArr[$index] . ',' . $n;
  92. $prizeArr[] = $goodsStr;
  93. StoreProc::AddMultiItemInStore($goodsStr);
  94. }
  95. if ($wavesMo->rewardGem != null) {
  96. $goodsStr = self::sweepRandReward($wavesMo->rewardGem);
  97. $str = explode(';', $goodsStr);
  98. $dic = GameConfig::gem();
  99. foreach ($str as $value) {
  100. $list = explode(',', $value);
  101. $posId = rand(1, 6);
  102. $qual = $list[0];
  103. foreach ($dic as $key => $gemMo) {
  104. if ($gemMo->qual == $qual && $gemMo->position == $posId) {
  105. $prizeArr[] = $gemMo->typeId . ',' . $list[1];
  106. StoreProc::PutGemInStore($gemMo->typeId, $list[1]);
  107. break;
  108. }
  109. }
  110. }
  111. }
  112. UserProc::updateUserInfo();
  113. $ret = array(
  114. 'tili' => ctx()->baseInfo->tili,
  115. 'fightSweepNum' => ctx()->gates->fightSweepNum,
  116. 'prizeArr' => $prizeArr,
  117. 'store' => ctx()->store,
  118. 'task' => ctx()->task,
  119. );
  120. return Resp::ok($ret);
  121. }
  122. static function sweepRandReward($rewardStr) {
  123. $ctxArr = explode(';', $rewardStr);
  124. $numArr = explode('-', $ctxArr[0]);
  125. $num = rand($numArr[0], $numArr[1]);
  126. $rand = 0;
  127. $itemArr = explode(',', $ctxArr[1]);
  128. foreach ($itemArr as $value) {
  129. $arr = explode(':', $value);
  130. $itemId = $arr[0];
  131. $per = $arr[1];
  132. $rand += $per;
  133. }
  134. $res = "";
  135. for ($i = 0; $i < $num; $i++) {
  136. $start = 0;
  137. $end = 0;
  138. $randNum = rand(1, $rand);
  139. $id = 0;
  140. foreach ($itemArr as $str) {
  141. $arr = explode(':', $str);
  142. $itemId = $arr[0];
  143. $per = $arr[1];
  144. $end += $per;
  145. if ($randNum > $start && $randNum <= $end) {
  146. $id = $itemId;
  147. break;
  148. }
  149. $start = $end;
  150. }
  151. if ($id != 0) {
  152. $str = $id . ',1';
  153. if ($res == "") {
  154. $res = $str;
  155. } else {
  156. $res = $res . ';' . $str;
  157. }
  158. }
  159. }
  160. return $res;
  161. }
  162. /**
  163. * 6808 开始挑战 (主线关卡:扣除体力, 挑战关卡: 增加次数)
  164. */
  165. private static function StartFight() {
  166. list($gateId, $layerNum) = req()->paras;
  167. my_Assert($gateId > 0, ErrCode::paras_err);
  168. $mo = GameConfig::gate_getItem($gateId);
  169. my_Assert(null != $mo, ErrCode::err_const_no);
  170. if (Ints::Slice($gateId, 0, 1) == 9) { # 爬塔模式
  171. // list($layerNum) = req()->paras;
  172. if ($layerNum != ctx()->gates()->TowerGateInfo()->CurLayer) { # 起始层数校验
  173. Err(ErrCode::tower_layerNum);
  174. }
  175. if (ctx()->gates()->TowerGateInfo()->TodayChanNum < 1) { # 剩余次数校验
  176. Err(ErrCode::tower_timeNo);
  177. }
  178. ctx()->gates()->TowerGateInfo()->TodayChanNum--; # 增加次数
  179. } else { # 主线剧情
  180. my_Assert(ctx()->base()->Consume_tili($mo->cost_tili), ErrCode::notenough_tili);
  181. }
  182. UserProc::updateUserInfo();
  183. return Resp::ok(array("tili" => ctx()->baseInfo->tili, "tili_ts" => ctx()->baseInfo->tili_ts));
  184. }
  185. public static function FightDailyClear() {
  186. //ctx()->gates->xunluo_quick_buyRecord = 0;
  187. ctx()->gates->fightSweepNum = 0;
  188. ctx()->gates()->TowerGateInfo()->RefreshSkillTimes = 0;
  189. ctx()->gates()->TowerGateInfo()->TodayChanNum = glc()->tower_daily_chanceNum;
  190. }
  191. /**
  192. * 6806 剧情回存
  193. * @return type
  194. */
  195. public static function PlotSav() {
  196. list($gateId) = req()->paras;
  197. my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::err_const_no);
  198. ctx()->gates->GateList->$gateId->plotStart = 1;
  199. UserProc::updateUserInfo();
  200. $ret = array(
  201. 'ok' => 1,
  202. );
  203. return Resp::ok($ret);
  204. }
  205. // <editor-fold defaultstate="collapsed" desc="挑战模块">
  206. /**
  207. * 6810 挑战关卡: 更新锁定技能列表
  208. */
  209. public static function TowerUpdateLockskillList() {
  210. list($li_zd, $li_bd, $li_zds, $li_bds) = req()->paras; # 参数解析
  211. $t = ctx()->gates()->TowerGateInfo(); # 记忆技能刷新结果
  212. $t->skill_zhudong = $li_zd;
  213. $t->skill_beidong = $li_bd;
  214. $t->skill_zhudong_lockState = $li_zds;
  215. $t->skill_beidong_lockState = $li_bds;
  216. UserProc::updateUserInfo();
  217. return Resp::ok();
  218. }
  219. /**
  220. * 6809 挑战关卡: 刷新初始技能(扣除免费次数/cost)
  221. */
  222. public static function TowerRefreshSkills() {
  223. list($isFree, $li_zd, $li_bd, $li_zds, $li_bds) = req()->paras; # 参数解析
  224. if ($isFree) {
  225. if (ctx()->gates()->TowerGateInfo()->RefreshSkillTimes >= glc()->tower_daily_refreshChanceNum) {
  226. Err(ErrCode::tower_refreshNo); # 免费次数不足
  227. }
  228. } else {
  229. list($type, $num) = explode(':', glc()->tower_refreshCost); # 二级货币类型(1:金币,2:元宝):数量
  230. if ($type == 1) { # 金币
  231. my_Assert(ctx()->base()->Consume_Gold($num), ErrCode::notenough_gold_msg);
  232. } else if ($type == 2) { # 元宝
  233. my_Assert(ctx()->base()->Consume_Cash($num), ErrCode::notenough_cash_msg);
  234. } else {
  235. Err(ErrCode::err_const_no, "检查刷新扣费配置信息!");
  236. }
  237. }
  238. $t = ctx()->gates()->TowerGateInfo(); # 记忆技能刷新结果
  239. $t->RefreshSkillTimes++;
  240. $t->skill_zhudong = $li_zd;
  241. $t->skill_beidong = $li_bd;
  242. $t->skill_zhudong_lockState = $li_zds;
  243. $t->skill_beidong_lockState = $li_bds;
  244. UserProc::updateUserInfo();
  245. $ret = array(
  246. 'task' => ctx()->task,
  247. );
  248. return Resp::ok($ret);
  249. }
  250. /**
  251. * 6805
  252. * @return type
  253. * @deprecated since version 2024年5月17日 已合并到6801
  254. */
  255. public static function ChallengeGateStartFight() {
  256. // list($layerNum) = req()->paras;
  257. // if ($layerNum != ctx()->gates()->TowerGateInfo()->CurLayer) { # 起始层数校验
  258. // return Resp::err(ErrCode::tower_layerNum);
  259. // }
  260. // if (ctx()->gates()->TowerGateInfo()->TodayChanNum < 1) { # 剩余次数校验
  261. // return Resp::err(ErrCode::tower_timeNo);
  262. // }
  263. // ctx()->gates()->TowerGateInfo()->TodayChanNum--; # 增加次数
  264. // UserProc::updateUserInfo();
  265. // return Resp::ok();
  266. }
  267. /**
  268. * 6804 挑战关卡: 奖励领取
  269. * @return type
  270. */
  271. public static function GateChallengeRewards() {
  272. list($finalLayer) = req()->paras; # 战斗结束时的层数
  273. $lastLayer = ctx()->gates()->TowerGateInfo()->CurLayer;
  274. $arr = GameConfig::waves_getItemArray(self::TowerGateId);
  275. if ($finalLayer > $lastLayer) {
  276. foreach ($arr as $layerId => $layerMo) {
  277. if ($layerId >= $lastLayer && $layerId < $finalLayer) {
  278. my_Assert($layerMo != null, ErrCode::err_const_no);
  279. StoreProc::AddMultiItemInStore($layerMo->rewards); # 发放奖励
  280. }
  281. }
  282. ctx()->gates()->TowerGateInfo()->CurLayer = $finalLayer;
  283. UserProc::updateUserInfo();
  284. $ret = array(
  285. 'store' => ctx()->store,
  286. 'gold' => ctx()->base()->gold,
  287. 'cash' => ctx()->base()->cash,
  288. 'task' => ctx()->task,
  289. );
  290. return Resp::ok($ret);
  291. } else if ($finalLayer == $lastLayer) {
  292. $ret = array(
  293. 'store' => ctx()->store,
  294. 'gold' => ctx()->base()->gold,
  295. 'cash' => ctx()->base()->cash,
  296. 'task' => ctx()->task,
  297. );
  298. return Resp::ok($ret);
  299. }
  300. return Resp::err(ErrCode::tower_rewardNo); # 没有奖励
  301. }
  302. // </editor-fold>
  303. /**
  304. * 6803 关卡选择
  305. * @return type
  306. */
  307. public static function SelectGate() {
  308. list($gateId) = req()->paras;
  309. ctx()->gates->CurrentGateId = $gateId;
  310. UserProc::updateUserInfo();
  311. $ret = array(
  312. 'gates' => ctx()->gates,
  313. );
  314. return Resp::ok($ret);
  315. }
  316. /**
  317. * 6802 章节宝箱的领取
  318. * @return type
  319. */
  320. public static function PassGateTsPrizeReceive() {
  321. list($gateId, $index) = req()->paras;
  322. $gateMo = GameConfig::gate_getItem($gateId);
  323. my_Assert($gateMo != null, ErrCode::err_const_no);
  324. my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
  325. $gateInfo = ctx()->gates->GateList->$gateId;
  326. $tag = false;
  327. $prize = "";
  328. $mask = 0;
  329. switch ($index) {
  330. case 1:
  331. $ts = $gateMo->first_ts1 * 60;
  332. if ($gateInfo->MaxSeconds >= $ts) {
  333. $tag = true;
  334. }
  335. $mask = 1;
  336. $prize = $gateMo->first_reward1;
  337. break;
  338. case 2:
  339. $ts = $gateMo->first_ts2 * 60;
  340. if ($gateInfo->MaxSeconds >= $ts) {
  341. $tag = true;
  342. }
  343. $mask = 2;
  344. $prize = $gateMo->first_reward2;
  345. break;
  346. case 3:
  347. if ($gateInfo->pass > 0) {
  348. $tag = true;
  349. }
  350. $mask = 3;
  351. $prize = $gateMo->first_reward3;
  352. break;
  353. default:
  354. break;
  355. }
  356. if ($tag) {
  357. my_Assert(!in_array($mask, $gateInfo->FirstReward), ErrCode::gate_GatePriceHasReceive);
  358. $gateInfo->FirstReward[] = $mask;
  359. StoreProc::AddMultiItemInStore($prize);
  360. }
  361. ctx()->gates->GateList->$gateId = $gateInfo;
  362. UserProc::updateUserInfo();
  363. $ret = array(
  364. 'gates' => ctx()->gates,
  365. 'store' => ctx()->store,
  366. 'task' => ctx()->task,
  367. 'gold' => ctx()->baseInfo->gold,
  368. 'reward' => StoreProc::$reward,
  369. );
  370. return Resp::ok($ret);
  371. }
  372. /**
  373. * [6801]关卡战斗结算
  374. * @return type
  375. */
  376. public static function Settle() {
  377. list($resultType, $gateId, $gold, $curTs, $pickups,
  378. $finalLayer, $finalHpPercent, $killMonsterNum, $killBossNum) = req()->paras;
  379. # 客户端需要增加参数: killmonserNum,killBosssNum, finalHpPercent(最终血量百分比)
  380. $gateMo = GameConfig::gate_getItem($gateId);
  381. my_Assert($gateMo != null, ErrCode::err_const_no);
  382. my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
  383. $gateInfo = ctx()->gates->GateList->$gateId;
  384. $ts = $gateInfo->MaxSeconds;
  385. if ($curTs >= $ts) {
  386. $gateInfo->MaxSeconds = $curTs;
  387. }
  388. if ($resultType) { # 胜利
  389. if (ctx()->gates->GateList->$gateId->pass == 0) {
  390. ctx()->gates->GateList->$gateId->pass = 1;
  391. TaskProc::Day7TaskReset($gateId); # 刷新七日任务
  392. $maxGateId = ctx()->gates->maxPassGateId();
  393. if ($maxGateId > 0) {
  394. self::Ranking_MainGateIndex($maxGateId);
  395. self::IsAchievedMainGate_PassReward($maxGateId);
  396. }
  397. }
  398. TaskProc::OnPassGate_X($gateId); # 刷新任务进度: 通关第X关
  399. if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {
  400. ctx()->gates()->UnlockNextPlotGate($gateId); # 解锁下一主线关卡
  401. // ctx()->gates()->UnlockMainChallengeGate($gateId); # 挑战关卡解锁逻辑. -gwang 2024年4月15日
  402. } else { # 不是主线关卡, 暂时没有其他逻辑
  403. }
  404. // StoreProc::AddMultiItemInStore($gateMo->reward_win); # 发放胜利奖励(2024.5.30 过期)
  405. }
  406. // else { # 失败
  407. //// StoreProc::AddMultiItemInStore($gateMo->reward_fail); # 发放失败奖励(2024.5.30 过期)
  408. // }
  409. StoreProc::AddMultiItemInStore($pickups); # 战场拾取道具直接入背包
  410. ctx()->base()->Add_Gold($gold); # 战场拾取的金币直接入背包
  411. //ctx()->base()->Add_Exp($exp);
  412. $waveMo = GameConfig::waveItem_getItem($gateId, $finalLayer);
  413. my_Assert(null != $waveMo, ErrCode::err_const_no);
  414. ctx()->base()->Add_Exp($waveMo->rewardExp); # 指挥官经验
  415. ctx()->base()->Add_Gold($waveMo->rewardGold); # 金币奖励
  416. $pickups .= ";1," . $gold + $waveMo->rewardGold;
  417. # 图纸奖励: 数量min-max, 部位随机
  418. if (strlen($waveMo->rewardTuZhi) > 0 && str_contains($waveMo->rewardTuZhi, '-')) {
  419. list($tz_min, $tz_max) = explode('-', $waveMo->rewardTuZhi); # 图纸数量
  420. $tz_n = rand($tz_min, $tz_max);
  421. # 图纸部位数据源 1001, 1002, 1003, 1004, 1005, 1006
  422. for ($i = 0; $i < $tz_n; $i++) {
  423. $id = 1000 + rand(1, 6);
  424. StoreProc::AddMultiItemInStore("$id,1"); # 获得图纸
  425. $pickups .= ";$id,1";
  426. }
  427. }
  428. # 宝石奖励: 数量min-max;品质:权重,品质:权重...
  429. if (strlen($waveMo->rewardGem) > 0) {
  430. list($gs_num, $gs_props) = explode(';', $waveMo->rewardGem);
  431. list($gem_min, $gem_max) = explode('-', $gs_num); # 宝石数量
  432. $gem_n = rand($gem_min, $gem_max);
  433. $arr = explode(",", $gs_props);
  434. $pool = array();
  435. $n = 0;
  436. foreach ($arr as $str) {
  437. list($qual, $props) = explode(':', $str);
  438. $pool[] = array('q' => $qual, 'p' => $props);
  439. $n += $props;
  440. }
  441. for ($i = 0; $i < $gem_n; $i++) { # 随机n块宝石
  442. $r = rand(1, $n); # 投色子
  443. $l = 0;
  444. foreach ($pool as $item) {
  445. if ($r <= ($l + $item['p'])) {
  446. $gemId = $item['q'] * 100000 + rand(1, 6) * 1000;
  447. StoreProc::PutGemInStore($gemId); # 发放宝石并退出本次投色子
  448. $pickups .= ";$gemId,1";
  449. break;
  450. }
  451. $l += $item['p']; # 累计到下一段
  452. }
  453. }
  454. }
  455. if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) { # 主线剧情,
  456. TaskProc::OnFightNumMainGate();
  457. } else if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainChallengeGate) { # 主线剧情对应的难度挑战
  458. TaskProc::OnFightNumChallengeGate();
  459. }
  460. TaskProc::OnKillCommonNumMonster($killMonsterNum);
  461. TaskProc::OnKillleaderNumMonster($killBossNum);
  462. UserProc::updateUserInfo();
  463. $ret = array(
  464. 'gates' => ctx()->gates,
  465. 'store' => ctx()->store,
  466. 'task' => ctx()->task,
  467. 'baseInfo' => ctx()->base(),
  468. 'gold' => $gold + $waveMo->rewardGold,
  469. 'exp' => $waveMo->rewardExp,
  470. 'rewardStr' => $pickups
  471. );
  472. return Resp::ok($ret);
  473. }
  474. // /**
  475. // * [6801]关卡战斗结算
  476. // * @return type
  477. // */
  478. // public static function Settle_bak() {
  479. // list($resultType, $gateId, $gold, $curTs, $pickups) = req()->paras;
  480. // # 客户端需要增加参数: killmonserNum,killBosssNum, finalHpPercent(最终血量百分比)
  481. // $gateMo = GameConfig::gate_getItem($gateId);
  482. // my_Assert($gateMo != null, ErrCode::err_const_no);
  483. // my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
  484. // $gateInfo = ctx()->gates->GateList->$gateId;
  485. // $ts = $gateInfo->MaxSeconds;
  486. // if ($curTs >= $ts) {
  487. // $gateInfo->MaxSeconds = $curTs;
  488. // }
  489. // if ($resultType) { # 胜利
  490. // if (ctx()->gates->GateList->$gateId->pass == 0) {
  491. // ctx()->gates->GateList->$gateId->pass = 1;
  492. // TaskProc::Day7TaskReset($gateId);
  493. // }
  494. // TaskProc::OnPassGate_X($gateId);
  495. // StoreProc::AddMultiItemInStore($gateMo->reward_win);
  496. // if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {
  497. // ctx()->gates->UnlockNextPlotGate();
  498. // $dic = GameConfig::gate();
  499. // $index = 0; # 挑战关卡解锁逻辑. -gwang 2024年4月15日
  500. // foreach ($dic as $id => $item) {
  501. // if (Ins_GateInfo::GateTypeFromId($id) == Enum_GateType::MainChallengeGate && $item->challengeGateId == $gateId) {
  502. // $index += 1;
  503. // $gate = new Ins_GateInfo();
  504. // $gate->GateId = $id;
  505. // ctx()->gates->GateList->$id = $gate;
  506. // }
  507. // if ($index >= 3) {
  508. // break;
  509. // }
  510. // }
  511. // } else {
  512. //
  513. // }
  514. // } else { # 失败
  515. // StoreProc::AddMultiItemInStore($gateMo->reward_fail);
  516. // }
  517. //
  518. // StoreProc::AddMultiItemInStore($pickups); # 战场拾取道具
  519. // ctx()->baseInfo->Add_Gold($gold);
  520. // //ctx()->baseInfo->Add_Exp($exp);
  521. //
  522. // if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {
  523. // TaskProc::OnFightNumMainGate();
  524. // } else if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainChallengeGate) {
  525. // TaskProc::OnFightNumChallengeGate();
  526. // }
  527. // TaskProc::OnKillCommonNumMonster(1000);
  528. // TaskProc::OnKillleaderNumMonster(500);
  529. //
  530. // UserProc::updateUserInfo();
  531. // $ret = array(
  532. // 'gates' => ctx()->gates,
  533. // 'store' => ctx()->store,
  534. // 'task' => ctx()->task,
  535. // );
  536. // return Resp::ok($ret);
  537. // }
  538. // <editor-fold defaultstate="collapsed" desc="排行榜">
  539. /**
  540. * 参与主线关卡排行榜
  541. * @param type $gateIndex
  542. */
  543. public static function Ranking_MainGateIndex($maxGateIndex) {
  544. $memKey = MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid);
  545. $mem = gMem();
  546. $index = 9999999999 - now();
  547. $uid = $index . "-" . req()->uid;
  548. $arr = self::GetRankUid(req()->uid, 1);
  549. $gateId = 0;
  550. if (count($arr) > 0) {
  551. $uid = $arr[0];
  552. $gateId = $arr[1];
  553. }
  554. if ($maxGateIndex > $gateId) {
  555. $arr2 = array();
  556. $arr2["$uid"] = $maxGateIndex;
  557. $mem->zadd($memKey, $arr2);
  558. }
  559. $length = $mem->zlen($memKey);
  560. if ($length > glc()->Rank_MainGateIndex_OnListRank) {
  561. $num = $length - glc()->Rank_MainGateIndex_OnListRank;
  562. $mem->zremrangebyrank($memKey, 0, $num - 1);
  563. }
  564. }
  565. /**
  566. * 战力榜
  567. * @param type $gateIndex
  568. */
  569. public static function Ranking_FightPower() {
  570. $memKey = MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid);
  571. $mem = gMem();
  572. $index = 9999999999 - now();
  573. $uid = $index . "-" . req()->uid;
  574. $lastPower = 0;
  575. $arr = self::GetRankUid(req()->uid, 2);
  576. if (count($arr) > 0) {
  577. $uid = $arr[0];
  578. $lastPower = $arr[1];
  579. }
  580. $power = self::countUserFightPower();
  581. if ($power > $lastPower) {
  582. $arr2["$uid"] = $power;
  583. $mem->zadd($memKey, $arr2);
  584. self::IsAchievedFightPower_PassReward($power);
  585. }
  586. $length = $mem->zlen($memKey);
  587. if ($length > glc()->Rank_FightPower_OnListRank) {
  588. $num = $length - glc()->Rank_FightPower_OnListRank;
  589. $mem->zremrangebyrank($memKey, 0, $num - 1);
  590. }
  591. }
  592. public static function GetRankUid($uid_rank, $type) {
  593. if ($type == 1) {
  594. $dic = gMem()->zrevrange(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
  595. } else {
  596. $dic = gMem()->zrevrange(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
  597. }
  598. $arr = array();
  599. foreach ($dic as $uid => $score) {
  600. $strUid = explode('-', $uid);
  601. if ($strUid[1] == $uid_rank) {
  602. $arr[] = $uid;
  603. $arr[] = $score;
  604. break;
  605. }
  606. }
  607. return $arr;
  608. }
  609. /**
  610. * 6811 获取主线关卡排行榜信息
  611. * @return type
  612. */
  613. public static function GetRankInfo() {
  614. list($type) = req()->paras;
  615. $selfIsHasRank = 0; //本人是否上榜 0未上榜没有排名 1上榜则selfRank就是排名
  616. $selfExtraInfo = 0;
  617. $isExistFinishReward = false;
  618. if ($type == 1) {
  619. $list = gMem()->zrevrange(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
  620. $selfExtraInfo = ctx()->gates->maxPassGateId();
  621. $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
  622. $dic = gMem()->hgetall($memKey);
  623. foreach ($dic as $gateId => $ins_rank) {
  624. if (!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate)) {
  625. $isExistFinishReward = true;
  626. break;
  627. }
  628. }
  629. } else {
  630. $list = gMem()->zrevrange(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
  631. $selfExtraInfo = self::countUserFightPower();
  632. $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
  633. $dic = gMem()->hgetall($memKey);
  634. foreach ($dic as $fightPower => $ins_rank) {
  635. if (!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower)) {
  636. $isExistFinishReward = true;
  637. break;
  638. }
  639. }
  640. }
  641. $selfRank = null;
  642. $retArr = array();
  643. if (count($list) > 0) {
  644. foreach ($list as $uid => $score) {
  645. $rankInfo = self::initOtherUidRankInfo($uid, $score, $type);
  646. if ($rankInfo->uid == req()->uid) {
  647. $selfIsHasRank = 1;
  648. $selfRank = $rankInfo;
  649. }
  650. $retArr[] = $rankInfo;
  651. }
  652. }
  653. if ($selfRank == null) {
  654. $index = 9999999999 - now();
  655. $uid = $index . "-" . req()->uid;
  656. $selfRank = self::initOtherUidRankInfo($uid, $selfExtraInfo, $type);
  657. }
  658. UserProc::updateUserInfo();
  659. $ret = array(
  660. 'rankInfo' => $retArr,
  661. 'selfRank' => $selfRank,
  662. 'selfIsHasRank' => $selfIsHasRank,
  663. 'isExistFinishReward' => $isExistFinishReward,
  664. );
  665. return Resp::ok($ret);
  666. }
  667. /**
  668. * 初始化玩家rank
  669. * @param type $uid
  670. * @param type $score
  671. * @return \loyalsoft\Ins_rank
  672. */
  673. static function initOtherUidRankInfo($uid, $score, $type = null) {
  674. $ins_rank = new Ins_rank();
  675. if ($type == 1) {
  676. $lv = gMem()->zrevrank(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), $uid);
  677. } else {
  678. $lv = gMem()->zrevrank(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), $uid);
  679. }
  680. if ($lv == null) {
  681. $lv = 0;
  682. }
  683. $strUid = explode('-', $uid);
  684. $ins_rank->rank = $lv + 1;
  685. $ins_rank->uid = $strUid[1];
  686. $userInfo = UserProc::getUserGame(req()->zoneid, $strUid[1]);
  687. $ins_rank->name = $userInfo->baseInfo->name;
  688. $ins_rank->headImg = $userInfo->baseInfo->headImg;
  689. $ins_rank->score = $score;
  690. return $ins_rank;
  691. }
  692. /**
  693. * 6812 获取排行榜内玩家的装备信息
  694. * @return type
  695. */
  696. public static function GetUidEquipInfo_Rank() {
  697. list($uid) = req()->paras;
  698. $userInfo = UserProc::getUserGame(req()->zoneid, $uid);
  699. $store = $userInfo->store;
  700. $heros = $userInfo->heros;
  701. UserProc::updateUserInfo();
  702. $ret = array(
  703. 'store' => $store,
  704. 'heros' => $heros,
  705. );
  706. return Resp::ok($ret);
  707. }
  708. /**
  709. * 通关奖励是否达成
  710. * @param type $maxGateIndex
  711. */
  712. public static function IsAchievedMainGate_PassReward($maxGateIndex) {
  713. $rewards = GameConfig::rank_passgatereward();
  714. $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
  715. foreach ($rewards as $passGateId => $mo) {
  716. if ($passGateId == $maxGateIndex && !gMem()->hexists($memKey, $maxGateIndex)) {
  717. $ins_rank = new Ins_rank();
  718. $ins_rank->uid = req()->uid;
  719. $ins_rank->name = ctx()->baseInfo->name;
  720. $ins_rank->headImg = ctx()->baseInfo->headImg;
  721. $ins_rank->score = $passGateId;
  722. gMem()->hset($memKey, $maxGateIndex, $ins_rank);
  723. break;
  724. }
  725. }
  726. }
  727. /*
  728. * 战力奖励是否达成
  729. */
  730. public static function IsAchievedFightPower_PassReward($power) {
  731. $rewards = GameConfig::rank_fightpowerreward();
  732. $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
  733. foreach ($rewards as $fightPower => $mo) {
  734. if ($power >= $fightPower && !gMem()->hexists($memKey, $fightPower)) {
  735. $ins_rank = new Ins_rank();
  736. $ins_rank->uid = req()->uid;
  737. $ins_rank->name = ctx()->baseInfo->name;
  738. $ins_rank->headImg = ctx()->baseInfo->headImg;
  739. $ins_rank->score = $fightPower;
  740. gMem()->hset($memKey, $fightPower, $ins_rank);
  741. }
  742. }
  743. }
  744. /**
  745. * 6813
  746. * @return type
  747. */
  748. public static function GetmainGate_RankRewardInfo() {
  749. //list($type) = req()->paras;
  750. $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
  751. $dic = gMem()->hgetall($memKey);
  752. if ($dic == null) {
  753. $dic = new \stdClass();
  754. }
  755. UserProc::updateUserInfo();
  756. $ret = array(
  757. 'rankReward' => $dic,
  758. );
  759. return Resp::ok($ret);
  760. }
  761. /**
  762. * 6814
  763. * @return type
  764. */
  765. public static function GetFightPower_RankRewardInfo() {
  766. //list($type) = req()->paras;
  767. $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
  768. $dic = gMem()->hgetall($memKey);
  769. if ($dic == null) {
  770. $dic = new \stdClass();
  771. }
  772. UserProc::updateUserInfo();
  773. $ret = array(
  774. 'rankReward' => $dic,
  775. );
  776. return Resp::ok($ret);
  777. }
  778. /**
  779. * 6815 领取通关荣誉榜奖励
  780. * @return type
  781. */
  782. public static function ReceiveRankReward_MainGate() {
  783. list($gateId) = req()->paras;
  784. my_Assert(!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate), ErrCode::rankReward_HasReceive);
  785. $mo = GameConfig::rank_passgatereward_getItem($gateId);
  786. my_Assert($mo != null, ErrCode::err_const_no);
  787. $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
  788. if (gMem()->hexists($memKey, $gateId)) {
  789. StoreProc::AddMultiItemInStore($mo->reward);
  790. ctx()->privateState->rankReward_drawed_MainGate[] = $gateId;
  791. }
  792. UserProc::updateUserInfo();
  793. $ret = array();
  794. return Resp::ok($ret);
  795. }
  796. /**
  797. * 6816 领取战力荣誉榜奖励
  798. * @return type
  799. */
  800. public static function ReceiveRankReward_FightPower() {
  801. list($fightPower) = req()->paras;
  802. my_Assert(!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower), ErrCode::rankReward_HasReceive);
  803. $mo = GameConfig::rank_fightpowerreward_getItem($fightPower);
  804. my_Assert($mo != null, ErrCode::err_const_no);
  805. $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
  806. if (gMem()->hexists($memKey, $fightPower)) {
  807. StoreProc::AddMultiItemInStore($mo->reward);
  808. ctx()->privateState->rankReward_drawed_fightPower[] = $fightPower;
  809. }
  810. UserProc::updateUserInfo();
  811. $ret = array();
  812. return Resp::ok($ret);
  813. }
  814. /**
  815. * 6817
  816. */
  817. public static function IsExistRankReward() {
  818. //list($type) = req()->paras;
  819. $type = 0;
  820. $isExistFinishReward = false;
  821. $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
  822. $dic = gMem()->hgetall($memKey);
  823. foreach ($dic as $gateId => $ins_rank) {
  824. if (!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate)) {
  825. $isExistFinishReward = true;
  826. $type = 1;
  827. break;
  828. }
  829. }
  830. $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
  831. $dic2 = gMem()->hgetall($memKey2);
  832. foreach ($dic2 as $fightPower => $ins_rank) {
  833. if (!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower)) {
  834. $isExistFinishReward = true;
  835. $type = 2;
  836. break;
  837. }
  838. }
  839. UserProc::updateUserInfo();
  840. $ret = array(
  841. 'isExistFinishReward' => $isExistFinishReward,
  842. 'type' => $type,
  843. );
  844. return Resp::ok($ret);
  845. }
  846. /*
  847. * 删除排行榜内注销账号的玩家
  848. */
  849. public static function DeleteRankInvalidUser($uid2) {
  850. $dic1 = gMem()->zrevrangebyscore(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
  851. $key1 = "";
  852. foreach ($dic1 as $uid => $score) {
  853. $strUid = explode('-', $uid);
  854. if ($strUid[1] == $uid2) {
  855. $key1 = $uid;
  856. break;
  857. }
  858. }
  859. $dic2 = gMem()->zrevrangebyscore(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
  860. $key2 = "";
  861. foreach ($dic2 as $uid => $score) {
  862. $strUid = explode('-', $uid);
  863. if ($strUid[1] == $uid2) {
  864. $key2 = $uid;
  865. break;
  866. }
  867. }
  868. if ($key1 != "") {
  869. gMem()->zrem(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), $key1);
  870. }
  871. if ($key1 != "") {
  872. gMem()->zrem(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), $key2);
  873. }
  874. }
  875. /*
  876. * 排行玩家头像变动
  877. */
  878. public static function UpdateRankUserHeadImg($uid, $headImg) {
  879. $memKey1 = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
  880. $dic = gMem()->hgetall($memKey1);
  881. foreach ($dic as $gateId => $ins_rank) {
  882. if ($ins_rank->uid == $uid) {
  883. $ins_rank->headImg = $headImg;
  884. gMem()->hset($memKey1, $gateId, $ins_rank);
  885. }
  886. }
  887. $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
  888. $dic2 = gMem()->hgetall($memKey2);
  889. foreach ($dic2 as $fightPower => $ins_rank) {
  890. if ($ins_rank->uid == $uid) {
  891. $ins_rank->headImg = $headImg;
  892. gMem()->hset($memKey2, $fightPower, $ins_rank);
  893. }
  894. }
  895. }
  896. /*
  897. * 统计战力 战斗力=攻击x(生命-伤害减免值)x(1+暴击率/100x(暴击伤害倍率-1))
  898. */
  899. public static function countUserFightPower() {
  900. $CurrentHeroId = ctx()->heros->CurrentHeroId;
  901. //$hero = ctx()->heros->Dic->$CurrentHeroId;
  902. $mo = GameConfig::hero_getItem($CurrentHeroId);
  903. my_Assert($mo != null, ErrCode::err_const_no);
  904. $heroBashAttack = $mo->attack;
  905. $heroBashHp = $mo->hp;
  906. $equipDic = ctx()->store->equip;
  907. $attck = 0;
  908. $hp = 0;
  909. foreach ($equipDic as $index => $ins_equip) {
  910. $Ins_Equip = new Ins_Equip($ins_equip);
  911. if ($Ins_Equip->mo()->upgradeType == 1) {//攻击力
  912. $attck += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->attckNum;
  913. } elseif ($Ins_Equip->mo()->upgradeType == 2) {
  914. $hp += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->hpNum;
  915. } else {
  916. $attck += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->attckNum;
  917. $hp += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->hpNum;
  918. }
  919. }
  920. $heroAttck = $heroBashAttack + $attck;
  921. $heroHp = $heroBashHp + $hp;
  922. $dec_demage = $mo->dec_demage;
  923. $bigHit_Val = $mo->bigHit_Val / 100;
  924. $bigHit_rate = $mo->bigHit_rate / 100;
  925. $val = $heroAttck * ($heroHp - $dec_demage) * (1 + $bigHit_rate * ($bigHit_Val - 1));
  926. return intval($val);
  927. }
  928. // </editor-fold>
  929. }