633 lines
28 KiB
PHP
633 lines
28 KiB
PHP
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: zn
|
|
* Date: 2017/8/9
|
|
* Time: 11:51
|
|
*/
|
|
|
|
namespace common\modules\pet;
|
|
|
|
|
|
use common\models\User;
|
|
use common\modules\achievement\AchievementUtil;
|
|
use common\modules\arena\ArenaUtil;
|
|
use common\modules\dailytask\DailyTaskUtil;
|
|
use common\modules\pet\vo\Pet;
|
|
use common\modules\safe\SafeUtil;
|
|
use common\modules\systemlog\SystemLogUtil;
|
|
use common\services\FriendServices;
|
|
use common\services\GameConfigServices;
|
|
use common\services\ItemServices;
|
|
use common\services\ResultStatusServices;
|
|
use common\services\StatusException;
|
|
use common\utils\MoneyUtil;
|
|
use common\utils\RedisKeyUtil;
|
|
|
|
/**
|
|
* 宠物
|
|
* Class
|
|
* @package common\modules\levelgift
|
|
*/
|
|
class PetUtil
|
|
{
|
|
|
|
const NOT_ENTER_WAR = 0;//没有参战
|
|
const ENTER_WAR = 1;//参战
|
|
const ENTER_WAR_LIST = [
|
|
self::NOT_ENTER_WAR,
|
|
self::ENTER_WAR,
|
|
];
|
|
|
|
const PROPERTY_BLOOD = 1;
|
|
const PROPERTY_ATTACK = 2;
|
|
const PROPERTY_ANTI = 3;
|
|
const PROPERTY_CRIT = 4;
|
|
const PROPERTY_DODGE = 5;
|
|
const PROPERTY_LIST = [
|
|
self::PROPERTY_BLOOD,
|
|
self::PROPERTY_ATTACK,
|
|
self::PROPERTY_ANTI,
|
|
self::PROPERTY_CRIT,
|
|
self::PROPERTY_DODGE,
|
|
];
|
|
|
|
const BATTLE_SUCCESS = 0;//战斗胜利
|
|
const BATTLE_FAIL = 1;//战斗失败
|
|
const BATTLE_RESULT_LIST = [
|
|
self::BATTLE_SUCCESS,
|
|
self::BATTLE_FAIL,
|
|
];
|
|
|
|
private static function updateFight(Pet $pet)
|
|
{
|
|
//血量X0.2+攻击x1+防御x2+暴击x3+闪避x3
|
|
$pet->fighting_capacity =
|
|
($pet->blood + $pet->blood_add) * 0.2 +
|
|
($pet->attack + $pet->attack_add) * 1 +
|
|
($pet->anti + $pet->anti_add) * 2 +
|
|
($pet->crit + $pet->crit_add) * 3 +
|
|
($pet->dodge + $pet->dodge_add) * 3;
|
|
|
|
}
|
|
|
|
/**
|
|
* 孵化
|
|
* @param $userID
|
|
* @param $petItemID
|
|
* @return Pet
|
|
*/
|
|
public static function broodingEgg($userID, $petItemID)
|
|
{
|
|
return SafeUtil::dbOperate(function ($userID, $petItemID) {
|
|
$itemConfig = GameConfigServices::getParamByPath('item_list.' . $petItemID);
|
|
if (empty($itemConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ((int)$itemConfig['type2'] != ItemServices::ITEM_TYPE2_EGG) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$evolutionConfig = GameConfigServices::getParamByPath('evolution_list.' . $petItemID);
|
|
if (empty($evolutionConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$needTime = intval($evolutionConfig['evolution_time']);
|
|
$gem = intval($evolutionConfig['Diamonds']);
|
|
if ($needTime <= 0 || $gem <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$user = User::findById($userID);
|
|
$petConfig = GameConfigServices::getParamByPath('pet.' . $petItemID);
|
|
if (intval($petConfig['player_level']) > $user->level) throw new StatusException(ResultStatusServices::RS_LEVEL_LIMIT);
|
|
|
|
$petConfig = GameConfigServices::getParamByPath('pet.' . $evolutionConfig['next_id']);
|
|
if (empty($petConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$log = SystemLogUtil::get($userID, SystemLogUtil::TYPE_ITEM, $petItemID, -1, SystemLogUtil::FROM_TYPE_BROODING_EGG, []);
|
|
MoneyUtil::checkAndModifyNum($userID, $petItemID, false, -1, $log);
|
|
|
|
$pet = new Pet();
|
|
$pet->user_id = $userID;
|
|
$pet->pet_config_id = $petConfig['id'];
|
|
$pet->name = $petConfig['name'];
|
|
$pet->blood = (int)$petConfig['blood'];
|
|
$pet->attack = (int)$petConfig['attack'];
|
|
$pet->anti = (int)$petConfig['anti'];
|
|
$pet->crit = (int)$petConfig['crit'];
|
|
$pet->dodge = (int)$petConfig['dodge'];
|
|
|
|
$pet->end_brooding_time = time() + $needTime;
|
|
$pet->accelerate_brooding_gem = $gem;
|
|
|
|
self::updateFight($pet);
|
|
self::updateFeedTime($pet);
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
//成就
|
|
AchievementUtil::addCount($userID, AchievementUtil::ID_HATCH_PET, 1);
|
|
|
|
return $pet;
|
|
|
|
}, [$userID, $petItemID]);
|
|
}
|
|
|
|
/**
|
|
* 加速孵化
|
|
*/
|
|
public static function accelerateBroodingEgg($userID, $petID)
|
|
{
|
|
SafeUtil::dbOperate(function ($userID, $petID) {
|
|
return SafeUtil::redisLockOperate(function ($userID, $petID) {
|
|
|
|
$pet = Pet::findByPetID($petID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->end_brooding_time <= time() || $pet->accelerate_brooding_gem <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->user_id != $userID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$log = SystemLogUtil::get($pet->user_id, SystemLogUtil::TYPE_GEM, -$pet->accelerate_brooding_gem, 0, SystemLogUtil::FROM_TYPE_ACCELERATE_BROODING_EGG, []);
|
|
MoneyUtil::checkAndModifyRes($pet->user_id, false, -$pet->accelerate_brooding_gem, ItemServices::ITEM_TYPE2_GEM, $log);
|
|
|
|
$pet->end_brooding_time = time();
|
|
$pet->accelerate_brooding_gem = 0;
|
|
self::updateFeedTime($pet);
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
}, [$userID, $petID], RedisKeyUtil::lockPet($petID));
|
|
}, [$userID, $petID]);
|
|
}
|
|
|
|
/**
|
|
* 进化
|
|
* @param $petID
|
|
*/
|
|
public static function evolution($userID, $petID)
|
|
{
|
|
SafeUtil::dbOperate(function ($userID, $petID) {
|
|
SafeUtil::redisLockOperate(function ($userID, $petID) {
|
|
|
|
$pet = Pet::findByPetID($petID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->end_brooding_time > time()) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->user_id != $userID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$petConfig = GameConfigServices::getParamByPath('pet.' . $pet->pet_config_id);
|
|
if ($pet->level != intval($petConfig['max_level']))
|
|
throw new StatusException(ResultStatusServices::RS_PET_NEED_UPGRADE_MAX_LEVEL);
|
|
|
|
if ($pet->blood_train_count != $pet->level ||
|
|
$pet->attack_train_count != $pet->level ||
|
|
$pet->anti_train_count != $pet->level ||
|
|
$pet->crit_train_count != $pet->level ||
|
|
$pet->dodge_train_count != $pet->level
|
|
)
|
|
throw new StatusException(ResultStatusServices::RS_PET_TRAIN_NEED_MAX);
|
|
|
|
$evolutionConfig = GameConfigServices::getParamByPath('evolution_list.' . $pet->pet_config_id);
|
|
if (empty($evolutionConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$user = User::findById($userID);
|
|
$nextPetConfig = GameConfigServices::getParamByPath('pet.' . $evolutionConfig['next_id']);
|
|
if (intval($nextPetConfig['player_level']) > $user->level) throw new StatusException(ResultStatusServices::RS_LEVEL_LIMIT);
|
|
|
|
MoneyUtil::parseItem(sprintf('%s:1', $evolutionConfig['drawing_id']), 1, false, $pet->user_id,
|
|
SystemLogUtil::FROM_TYPE_PET_EVOLUTION, ['config' => $evolutionConfig]);
|
|
|
|
$expendList = MoneyUtil::parseAllItem($evolutionConfig['crystal_id'], 1, false, $pet->user_id, SystemLogUtil::FROM_TYPE_PET_EVOLUTION, ['config' => $evolutionConfig]);
|
|
if (count($expendList) == 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$pet->pet_config_id = $evolutionConfig['next_id'];
|
|
// $pet->level = 1;
|
|
// $pet->exp = 0;
|
|
|
|
$petConfig = GameConfigServices::getParamByPath('pet.' . $pet->pet_config_id);
|
|
$pet->name = (int)$petConfig['name'];
|
|
$pet->blood = (int)$petConfig['blood'];
|
|
$pet->attack = (int)$petConfig['attack'];
|
|
$pet->anti = (int)$petConfig['anti'];
|
|
$pet->crit = (int)$petConfig['crit'];
|
|
$pet->dodge = (int)$petConfig['dodge'];
|
|
|
|
// $pet->blood_train_count = 0;
|
|
// $pet->attack_train_count = 0;
|
|
// $pet->anti_train_count = 0;
|
|
// $pet->crit_train_count = 0;
|
|
// $pet->dodge_train_count = 0;
|
|
|
|
self::updateFight($pet);
|
|
self::updateFeedTime($pet);
|
|
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
if ($pet->is_enter_war == self::ENTER_WAR)
|
|
ArenaUtil::updatePet($userID, $pet);
|
|
|
|
}, [$userID, $petID], RedisKeyUtil::lockPet($petID));
|
|
}, [$userID, $petID]);
|
|
}
|
|
|
|
/**
|
|
* 培养
|
|
* @param $petID
|
|
*/
|
|
public static function train($userID, $petID, $type)
|
|
{
|
|
SafeUtil::dbOperate(function ($userID, $petID, $type) {
|
|
SafeUtil::redisLockOperate(function ($userID, $petID, $type) {
|
|
|
|
$type = (int)$type;
|
|
|
|
if (!in_array($type, self::PROPERTY_LIST)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$pet = Pet::findByPetID($petID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->end_brooding_time > time()) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->user_id != $userID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$trainConfig = GameConfigServices::getParamByPath('culture.' . $pet->pet_config_id);
|
|
if (empty($trainConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$expendList = MoneyUtil::parseAllItemIndex($trainConfig['consume_id'], $type - 1, 1, false, $pet->user_id, SystemLogUtil::FROM_TYPE_PET_TRAIN, ['config' => $trainConfig]);
|
|
if (count($expendList) == 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
switch ($type) {
|
|
case self::PROPERTY_BLOOD: {
|
|
if ($pet->blood_train_count == $pet->level) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
$pet->blood_add += (int)$trainConfig['blood'];
|
|
$pet->blood_train_count += 1;
|
|
//任务记录
|
|
DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_TRAIN_PET_BLOOD, null, 1);
|
|
break;
|
|
}
|
|
case self::PROPERTY_ATTACK: {
|
|
if ($pet->attack_train_count == $pet->level) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
$pet->attack_add += (int)$trainConfig['attack'];
|
|
$pet->attack_train_count += 1;
|
|
//任务记录
|
|
DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_TRAIN_PET_ATTACK, null, 1);
|
|
break;
|
|
}
|
|
case self::PROPERTY_ANTI: {
|
|
if ($pet->anti_train_count == $pet->level) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
$pet->anti_add += (int)$trainConfig['anti'];
|
|
$pet->anti_train_count += 1;
|
|
//任务记录
|
|
DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_TRAIN_PET_ANTI, null, 1);
|
|
break;
|
|
}
|
|
case self::PROPERTY_CRIT: {
|
|
if ($pet->crit_train_count == $pet->level) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
$pet->crit_add += (int)$trainConfig['crit'];
|
|
$pet->crit_train_count += 1;
|
|
//任务记录
|
|
DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_TRAIN_PET_CRIT, null, 1);
|
|
break;
|
|
}
|
|
case self::PROPERTY_DODGE: {
|
|
if ($pet->dodge_train_count == $pet->level) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
$pet->dodge_add += (int)$trainConfig['dodge'];
|
|
$pet->dodge_train_count += 1;
|
|
//任务记录
|
|
DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_TRAIN_PET_DODGE, null, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
self::updateFight($pet);
|
|
self::updateFeedTime($pet);
|
|
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
if ($pet->is_enter_war == self::ENTER_WAR)
|
|
ArenaUtil::updatePet($userID, $pet);
|
|
|
|
}, [$userID, $petID, $type], RedisKeyUtil::lockPet($petID));
|
|
}, [$userID, $petID, $type]);
|
|
}
|
|
|
|
/**
|
|
* 升级
|
|
* @param $petID
|
|
*/
|
|
public static function upgrade($userID, $petID, $gold)
|
|
{
|
|
SafeUtil::dbOperate(function ($userID, $petID, $gold) {
|
|
SafeUtil::redisLockOperate(function ($userID, $petID, $gold) {
|
|
|
|
$gold = (int)$gold;
|
|
|
|
if ($gold <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$pet = Pet::findByPetID($petID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->end_brooding_time > time()) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->user_id != $userID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$user = User::findById($userID);
|
|
|
|
$petConfig = GameConfigServices::getParamByPath('pet.' . $pet->pet_config_id);
|
|
if ($pet->level >= intval($petConfig['max_level']))
|
|
throw new StatusException(ResultStatusServices::RS_PET_MAX_LEVEL_LIMIT);
|
|
|
|
$levelConfig = GameConfigServices::getParamByPath('pet_level.' . ($pet->level + 1));
|
|
if (empty($levelConfig)) throw new StatusException(ResultStatusServices::RS_PET_MAX_LEVEL_LIMIT);
|
|
|
|
$rate = (int)GameConfigServices::getCommonNumByID(GameConfigServices::COMMON_GOLD_EXCHANGE_PET_EXP_RATE);
|
|
if ($rate <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$addExp = intval($gold / $rate);
|
|
$gold = intval($addExp * $rate);
|
|
|
|
if ($addExp <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$log = SystemLogUtil::get($pet->user_id, SystemLogUtil::TYPE_GOLD, -$gold, 0, SystemLogUtil::FROM_TYPE_PET_UPGRADE, []);
|
|
MoneyUtil::checkAndModifyRes($userID, false, -$gold, ItemServices::ITEM_TYPE2_GOLD, $log);
|
|
|
|
$pet->exp += $addExp;
|
|
if ($pet->exp >= $levelConfig['exp']) {
|
|
|
|
if ($pet->level >= $user->level) throw new StatusException(ResultStatusServices::RS_PET_FARM_LEVEL_LIMIT);
|
|
|
|
$pet->level++;
|
|
$pet->exp = 0;
|
|
|
|
$pet->blood_add += (int)$levelConfig['blood'];
|
|
$pet->attack_add += (int)$levelConfig['attack'];
|
|
$pet->anti_add += (int)$levelConfig['anti'];
|
|
$pet->crit_add += (int)$levelConfig['crit'];
|
|
$pet->dodge_add += (int)$levelConfig['dodge'];
|
|
|
|
//成就
|
|
AchievementUtil::addCount($userID, AchievementUtil::ID_PET_LEVEL, $pet->level, true);
|
|
AchievementUtil::addCount($userID, AchievementUtil::ID_PET_LEVEL_2, $pet->level, true);
|
|
}
|
|
|
|
self::updateFight($pet);
|
|
self::updateFeedTime($pet);
|
|
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
if ($pet->is_enter_war == self::ENTER_WAR)
|
|
ArenaUtil::updatePet($userID, $pet);
|
|
|
|
}, [$userID, $petID, $gold], RedisKeyUtil::lockPet($petID));
|
|
}, [$userID, $petID, $gold]);
|
|
}
|
|
|
|
/**
|
|
* 喂养
|
|
* @param $petID
|
|
*/
|
|
public static function feed($userID, $petID, $itemID)
|
|
{
|
|
SafeUtil::dbOperate(function ($userID, $petID, $itemID) {
|
|
SafeUtil::redisLockOperate(function ($userID, $petID, $itemID) {
|
|
|
|
$pet = Pet::findByPetID($petID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->end_brooding_time > time()) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->user_id != $userID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$itemConfig = GameConfigServices::getParamByPath('item_list.' . $itemID);
|
|
if (empty($itemConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ((int)$itemConfig['type2'] != ItemServices::ITEM_TYPE2_DOG_FOOD) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$addFeed = (int)$itemConfig['effect_id'];
|
|
if ($addFeed <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$log = SystemLogUtil::get($userID, SystemLogUtil::TYPE_ITEM, $itemID, -1, SystemLogUtil::FROM_TYPE_FEED_DOG, []);
|
|
MoneyUtil::checkAndModifyNum($userID, $itemID, false, -1, $log);
|
|
|
|
self::updateFeedTime($pet);
|
|
|
|
$pet->feed += $addFeed;
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
//任务记录
|
|
DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_FEED_PET, null, 1);
|
|
|
|
}, [$userID, $petID, $itemID], RedisKeyUtil::lockPet($petID));
|
|
}, [$userID, $petID, $itemID]);
|
|
}
|
|
|
|
/**
|
|
* 参战
|
|
* @param $petID
|
|
*/
|
|
public static function setEnterWar($userID, $petID)
|
|
{
|
|
SafeUtil::dbOperate(function ($userID, $petID) {
|
|
SafeUtil::redisLockOperate(function ($userID, $petID) {
|
|
|
|
$pet = Pet::findEnterWarPetByUserID($userID);
|
|
if (!empty($pet)) {
|
|
if ($pet->id == $petID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
self::updateFeedTime($pet);
|
|
$pet->is_enter_war = self::NOT_ENTER_WAR;
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
}
|
|
|
|
$pet = Pet::findByPetID($petID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->end_brooding_time > time()) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->user_id != $userID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->is_enter_war == self::ENTER_WAR) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
self::updateFeedTime($pet);
|
|
$pet->is_enter_war = self::ENTER_WAR;
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
if ($pet->is_enter_war == self::ENTER_WAR)
|
|
ArenaUtil::updatePet($userID, $pet);
|
|
|
|
}, [$userID, $petID], RedisKeyUtil::lockPet($petID));
|
|
}, [$userID, $petID]);
|
|
}
|
|
|
|
/**
|
|
* 获取战斗信息
|
|
* @param $fromUserID
|
|
* @param $beUserID
|
|
* @return mixed
|
|
* @throws StatusException
|
|
*/
|
|
public static function getBattleInfo($fromUserID, $beUserID, $checkFriend = true)
|
|
{
|
|
$pet = Pet::findEnterWarPetByUserID($fromUserID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_BATTLE_PET_NOT_ENTER_BATTLE);
|
|
|
|
if ($checkFriend && !FriendServices::isFriend($fromUserID, $beUserID)) throw new StatusException(ResultStatusServices::RS_NOT_FRIEND);
|
|
|
|
$data['from_pet'] = $pet->toArray();
|
|
$data['from_user'] = User::findById($fromUserID)->genClientData(false);
|
|
|
|
$pet = Pet::findEnterWarPetByUserID($beUserID);
|
|
if (empty($pet)) {
|
|
$list = Pet::findAllByUserID($beUserID);
|
|
if (count($list) > 0) $pet = $list[0];
|
|
}
|
|
|
|
$data['be_pet'] = empty($pet) ? null : $pet->toArray();
|
|
$data['be_user'] = User::findById($beUserID)->genClientData(false);
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 战斗
|
|
* @param $fromUserID
|
|
* @param $fromPetID
|
|
* @param $beUserID
|
|
* @param $battleResultType
|
|
* @return mixed
|
|
*/
|
|
public static function battle($fromUserID, $fromPetID, $beUserID, $battleResultType)
|
|
{
|
|
SafeUtil::dbOperate(function ($fromUserID, $fromPetID, $beUserID, $battleResultType) {
|
|
SafeUtil::redisLockOperate(function ($fromUserID, $fromPetID, $beUserID, $battleResultType) {
|
|
|
|
if (!in_array($battleResultType, self::BATTLE_RESULT_LIST)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$pet = Pet::findByPetID($fromPetID);
|
|
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->end_brooding_time > time()) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
if ($pet->user_id != $fromUserID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
$petConfig = GameConfigServices::getParamByPath('pet.' . $pet->pet_config_id);
|
|
if (empty($petConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
$hunger = intval($petConfig['hunger']);
|
|
if ($hunger < 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
|
|
|
|
self::updateFeedTime($pet);
|
|
|
|
$pet->feed -= $hunger;
|
|
// if ($pet->feed < 0) throw new StatusException(ResultStatusServices::RS_PET_HUNGER);
|
|
if ($pet->feed < 0) $pet->feed = 0;
|
|
|
|
$battleConfig = GameConfigServices::getBattleConfig($battleResultType);
|
|
|
|
$levelConfig = GameConfigServices::getParamByPath('pet_level.' . ($pet->level + 1));
|
|
// if (empty($levelConfig)) throw new StatusException(ResultStatusServices::RS_MAX_LEVEL);
|
|
|
|
$exp = intval($battleConfig['experience_outcome']);
|
|
// if ($exp > 0) MoneyUtil::addUserExp($fromUserID, intval($battleConfig['experience_outcome']));
|
|
|
|
if (!empty($levelConfig)) {
|
|
$pet->exp += $exp;
|
|
if ($pet->level >= intval($petConfig['max_level'])) {
|
|
if ($pet->exp >= $levelConfig['exp']) $pet->exp = $levelConfig['exp'];
|
|
} elseif ($pet->exp >= $levelConfig['exp']) {
|
|
|
|
$fromUser = User::findById($fromUserID);
|
|
if ($pet->level < $fromUser->level) {
|
|
$pet->level++;
|
|
$pet->exp = 0;
|
|
|
|
$pet->blood += (int)$levelConfig['blood'];
|
|
$pet->attack += (int)$levelConfig['attack'];
|
|
$pet->anti += (int)$levelConfig['anti'];
|
|
$pet->crit += (int)$levelConfig['crit'];
|
|
$pet->dodge += (int)$levelConfig['dodge'];
|
|
|
|
self::updateFight($pet);
|
|
|
|
//成就
|
|
AchievementUtil::addCount($fromUserID, AchievementUtil::ID_PET_LEVEL, $pet->level, true);
|
|
AchievementUtil::addCount($fromUserID, AchievementUtil::ID_PET_LEVEL_2, $pet->level, true);
|
|
} else {
|
|
$pet->exp = intval($levelConfig['exp']);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$pet->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
|
|
|
|
if ($battleResultType == self::BATTLE_SUCCESS) {
|
|
//胜利
|
|
MoneyUtil::parseItem($battleConfig['outcome_id'], 1, true, $fromUserID, SystemLogUtil::FROM_TYPE_BATTLE_SUCCESS, ['config' => $battleConfig]);
|
|
|
|
// //偷果实
|
|
// $stealNum = rand(intval($battleConfig['fruit_min']), intval($battleConfig['fruit_max']));
|
|
// if ($stealNum > 0) {
|
|
// $farmDbData = Farm::findRedis($beUserID);
|
|
// LandService::updateAllCropStatus($beUserID, $farmDbData->id, $farmDbData->level);
|
|
//
|
|
// $landDbList = Land::findAll(['farm_id' => $farmDbData->id]);
|
|
//
|
|
// $num = $stealNum;
|
|
// foreach ($landDbList as $land) {
|
|
//
|
|
// $rs = LandService::steal($farmDbData->id, $land->position, $num);
|
|
// if ($rs != ResultStatusServices::RS_OPERATION_SUCCESS) continue;
|
|
//
|
|
// if ($num > 0) $stealNum -= $num;
|
|
//
|
|
// //修改仓库数量
|
|
// $cropConfig = GameConfigServices::getParamByPath('crop_list.' . $land->crop_id);
|
|
// $itemID = $cropConfig['item_id'];
|
|
// $log = SystemLogUtil::get($fromUserID, SystemLogUtil::TYPE_ITEM, $itemID, $num, SystemLogUtil::FROM_TYPE_STEAL_GET, []);
|
|
// MoneyUtil::checkAndModifyNum($fromUserID, $itemID, true, $num, $log);
|
|
// array_push($stealItemList, ['item_id' => $itemID, 'num' => $num]);
|
|
//
|
|
// if ($stealNum == 0) break;
|
|
// }
|
|
//
|
|
// //任务记录
|
|
// DailyTaskUtil::addTaskCount($fromUserID, DailyTaskUtil::TYPE_STEAL_SUCCESS, null, 1);
|
|
//
|
|
// //成就
|
|
// AchievementUtil::addCount($fromUserID, AchievementUtil::ID_STEAL, 1);
|
|
//
|
|
// AchievementUtil::addCount($fromUserID, AchievementUtil::ID_STEAL_SUCCESS, 1);
|
|
// }
|
|
} else {
|
|
//失败
|
|
MoneyUtil::parseItem($battleConfig['outcome_id'], 1, false, $fromUserID, SystemLogUtil::FROM_TYPE_BATTLE_FAIL, ['config' => $battleConfig]);
|
|
|
|
AchievementUtil::addCount($beUserID, AchievementUtil::ID_CATCHING_THIEF, 1);
|
|
}
|
|
|
|
//任务记录
|
|
DailyTaskUtil::addTaskCount($fromUserID, DailyTaskUtil::TYPE_STEAL, null, 1);
|
|
|
|
}, [$fromUserID, $fromPetID, $beUserID, $battleResultType], RedisKeyUtil::lockPet($fromPetID));
|
|
}, [$fromUserID, $fromPetID, $beUserID, $battleResultType]);
|
|
}
|
|
|
|
/**
|
|
* 更新喂养扣点
|
|
* @param Pet $pet
|
|
*/
|
|
public static function updateFeedTime(Pet $pet)
|
|
{
|
|
if ($pet->is_enter_war == self::ENTER_WAR) {
|
|
$dis = time() - $pet->last_feed_update_time;
|
|
$period = intval(GameConfigServices::getCommonNumByID(GameConfigServices::COMMON_FEED_EXPEND_PERIOD));
|
|
$expendPoint = intval(GameConfigServices::getCommonNumByID(GameConfigServices::COMMON_FEED_EXPEND_POINT));
|
|
if ($expendPoint <= 0) return;
|
|
|
|
$point = intval($expendPoint * floatval($dis) / $period);
|
|
|
|
if ($point > 0) {
|
|
$pet->feed -= $point;
|
|
if ($pet->feed < 0) $pet->feed = 0;
|
|
|
|
$pet->last_feed_update_time = time();
|
|
}
|
|
} else {
|
|
$pet->last_feed_update_time = time();
|
|
}
|
|
}
|
|
} |