hy-farm/muchang/common/modules/achievement/AchievementUtil.php
2026-05-29 19:54:56 +08:00

275 lines
9.9 KiB
PHP

<?php
/**
* Created by PhpStorm.
* User: zn
* Date: 2017/8/9
* Time: 11:51
*/
namespace common\modules\achievement;
use common\models\Farm;
use common\modules\achievement\vo\Achievement;
use common\modules\safe\SafeUtil;
use common\modules\systemlog\SystemLogUtil;
use common\services\GameConfigServices;
use common\services\ResultStatusServices;
use common\services\StatusException;
use common\utils\MoneyUtil;
use common\utils\RedisKeyUtil;
/**
* 成就
* Class
*/
class AchievementUtil
{
const GIFT_NOT_GET = 0;//未领取奖励
const GIFT_GET = 1;//已领取奖励
const GIFT_GET_LIST = [
self::GIFT_NOT_GET,
self::GIFT_GET,
];
const ID_SOW_SEEDS = 1;//玩家完成日常种植任务次数
const ID_GET_ONLINE_GIFT = 2;//玩家领取在线礼包次数
const ID_LOTTERY_DRAW = 3;//玩家积累开启大转盘次数
const ID_PLEASURE_GROUND = 5;//玩家积累进入游乐场
const ID_ENTER_GYMKHANA = 6;//玩家积累挑战玩家
const ID_STEAL = 7;//玩家积累掠夺玩家资源次数
const ID_ACCUMULATION_CRYSTAL = 8;//玩家积累水晶
const ID_ACCUMULATION_STONE = 9;//成功积累石材数量
const ID_HATCH_PET = 10;//成功孵化宠物
const ID_PET_LEVEL = 11;//农场主宠物等级达到
const ID_PET_LEVEL_2 = 12;//农场主宠物等级达到
const ID_CONSUME = 13;//玩家建设农场消耗次数
const ID_GYMKHANA_SUCCESS = 14;//击败并战胜对手个数
const ID_GET_FRUIT = 15;//种植收获多少水果个数
const ID_CONSUME_FRUIT = 16;//积累消耗水果个数
const ID_MAKE = 17;//成功加工多少次
const ID_COMPOSE = 18;//成功合成多少次
const ID_FARM_UPGRADE = 19;//成功升级场景主建筑
const ID_ACHIEVEMENT_COUNT = 20;//收集成就徽章个数
const ID_SIGN = 21;//成功签到天数
const ID_FRAGMENT_COUNT = 22;//成功收集碎片个数
const ID_CATCHING_THIEF = 24;//成功抓捕小偷次数
const ID_STEAL_SUCCESS = 25;//成功偷取玩家果实次数
const ID_NUMBER_ONE = 26;//成为全世界第一名
const ID_CONSUME_GEM = 27;//在商城钻石消费积累
const ID_PAY_COUNT = 28;//充值次数
const ID_LIST = [
self::ID_SOW_SEEDS,
self::ID_GET_ONLINE_GIFT,
self::ID_LOTTERY_DRAW,
self::ID_PLEASURE_GROUND,
self::ID_ENTER_GYMKHANA,
self::ID_STEAL,
self::ID_ACCUMULATION_CRYSTAL,
self::ID_ACCUMULATION_STONE,
self::ID_HATCH_PET,
self::ID_PET_LEVEL,
self::ID_PET_LEVEL_2,
self::ID_CONSUME,
self::ID_GYMKHANA_SUCCESS,
self::ID_GET_FRUIT,
self::ID_CONSUME_FRUIT,
self::ID_MAKE,
self::ID_COMPOSE,
self::ID_FARM_UPGRADE,
self::ID_ACHIEVEMENT_COUNT,
self::ID_SIGN,
self::ID_FRAGMENT_COUNT,
self::ID_CATCHING_THIEF,
self::ID_STEAL_SUCCESS,
self::ID_NUMBER_ONE,
self::ID_CONSUME_GEM,
self::ID_PAY_COUNT,
];
private static function hasNextLevel($configID, $level)
{
$level = (int)$level;
$config = GameConfigServices::getParamByPath('achievement_list.' . $configID);
if (empty($config)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$configList = explode(':', $config['complete']);
if (isset($configList[$level])) return true;
return false;
}
private static function parseConfig($configID, $level)
{
$level = (int)$level;
$config = GameConfigServices::getParamByPath('achievement_list.' . $configID);
if (empty($config)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$configList = explode(':', $config['complete']);
if (!isset($configList[$level])) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$count = (int)$configList[$level];
if ($count <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$awardItemID = $config['item_id'];
$itemConfig = GameConfigServices::getParamByPath('item_list.' . $awardItemID);
if (empty($itemConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$configList = explode(':', $config['gold_id']);
if (!isset($configList[$level])) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$awardItemNum = (int)$configList[$level];
if ($awardItemNum <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$configList = explode(':', $config['experience']);
if (!isset($configList[$level])) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$exp = (int)$configList[$level];
if ($exp <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
return [$count, $awardItemID, $awardItemNum, $exp];
}
private static function createAch($userID, $configID)
{
$config = GameConfigServices::getParamByPath('achievement_list.' . $configID);
if (empty($config)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$ach = new Achievement();
$ach->user_id = $userID;
$ach->config_id = $configID;
$ach->name = $config['name'];
$ach->content = $config['content'];
return $ach;
}
/**
* 更新徽章成就
*/
private static function updateAchCount($userID)
{
$allList = Achievement::findAllByUserID($userID);
$count = 0;
$ach = null;
foreach ($allList as $item) {
if ($item->config_id == self::ID_ACHIEVEMENT_COUNT) {
$ach = $item;
continue;
}
list($maxCount, $temp1, $temp2, $temp3) = self::parseConfig($item->config_id, $item->level);
if ($item->count == $maxCount) $count++;
}
if (empty($ach)) $ach = self::createAch($userID, self::ID_ACHIEVEMENT_COUNT);
$ach->count = $count;
list($maxCount, $temp1, $temp2, $temp3) = self::parseConfig($ach->config_id, $ach->level);
if ($ach->count > $maxCount) $ach->count = $maxCount;
if (!$ach->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
}
public static function getList($userID)
{
$dbList = Achievement::findAllByUserID($userID);
$list = [];
foreach ($dbList as $item) {
array_push($list, $item->toArray());
}
return $list;
}
/**
* 计数
* @param $userID
* @param $configID
* @param $addCount
*/
public static function addCount($userID, $configID, $addCount, $isSet = false)
{
SafeUtil::redisLockOperate(function ($userID, $configID, $addCount, $isSet) {
$addCount = (int)$addCount;
if ($addCount <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$config = GameConfigServices::getParamByPath('achievement_list.' . $configID);
if (empty($config)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$ach = Achievement::findByUserIDAndConfigID($userID, $configID);
if (empty($ach)) $ach = self::createAch($userID, $configID);
list($maxCount, $temp1, $temp2, $temp3) = self::parseConfig($ach->config_id, $ach->level);
if ($ach->count == $maxCount) return;
$needUpdateAch = false;
if ($isSet)
$ach->count = $addCount;
else
$ach->count += $addCount;
if ($ach->count > $maxCount) {
$ach->count = $maxCount;
$needUpdateAch = true;
}
if (!$ach->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
if ($needUpdateAch) self::updateAchCount($userID);
}, [$userID, $configID, $addCount, $isSet], RedisKeyUtil::lockAchievement($userID, $configID));
}
/**
* 获取奖励
* @param $userID
* @param $achID
*/
public static function getGift($userID, $achID)
{
SafeUtil::dbOperate(function ($userID, $achID) {
$ach = Achievement::findByID($achID);
if (empty($ach) || $ach->user_id != $userID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
SafeUtil::redisLockOperate(function ($userID, $achID) {
$ach = Achievement::findByID($achID);
if (empty($ach) || $ach->user_id != $userID || $ach->receive == 1) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$config = GameConfigServices::getParamByPath('achievement_list.' . $ach->config_id);
if (empty($config)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
list($maxCount, $awardItemID, $awardItemNum, $exp) = self::parseConfig($ach->config_id, $ach->level);
$str = sprintf('%s:%d', $awardItemID, $awardItemNum);
MoneyUtil::parseItem($str, 1, true, $userID, SystemLogUtil::FROM_TYPE_GET_ACH_GIFT, ['config' => $config]);
MoneyUtil::addUserExp($userID, $exp);
$needUpdateAch = false;
if (self::hasNextLevel($ach->config_id, $ach->level + 1)) {
//计算下一级
$ach->level++;
if ($ach->config_id == AchievementUtil::ID_FARM_UPGRADE) {
$farmDbData = Farm::findOne(['user_id' => $userID]);
$ach->count = $farmDbData->level;
} else {
$ach->count = 0;
}
$needUpdateAch = true;
} else {
$ach->receive = 1;
}
if (!$ach->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
if ($needUpdateAch) self::updateAchCount($userID);
}, [$userID, $achID], RedisKeyUtil::lockAchievement($userID, $ach->config_id));
}, [$userID, $achID]);
}
}