275 lines
9.9 KiB
PHP
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]);
|
|
}
|
|
}
|