userInfo->game; $lottery = new UserLotteryModel($req->userInfo->game->privateState->lottery); if (count($req->paras) < 1) { # 提取参数 return Resp::err(ErrCode::parasnotenough_msg); } $lot_type = $req->paras[0]; # 抽奖类型: 金币,钻石,友情点... (物品id) $cishu = 10; # 想要领取的奖励id(1,2,3)等阶对应需要满足的抽奖次数 if (count($req->paras) > 1) { # 如果没有传第二个参数, 默认给1阶奖励(10次), $cishu = $req->paras[1]; } if ($lottery->baodiLotterys->$lot_type < $cishu) { # 检查累计次数 return Resp::err(ErrCode::lottery_baodi_times_lt); } $baodi = GameConfig::choujiang_baodi_getItem($lot_type, $cishu); # 保底奖池 if (null == $baodi) { # 找不到 return Resp::err(ErrCode::err_const_no); } $settings = GameConfig::choujiang_settings_getItem($lot_type); # 设定 if (null == $settings) { # 找不到 return Resp::err(ErrCode::err_const_no); } # 当达到, 最后一次的时候, 执行减法扣除对应的值?或者其他算法. # 保底的奖励物品, 要切换, 换成不同抽奖道具, 对应不同的奖品池, 因为道具价值不一样. if ($lottery->baodiDrawed->$lot_type >= $cishu) { return Resp::err(ErrCode::active_hasgetted); } $lottery->baodiDrawed->$lot_type = $cishu; if ($cishu == $settings->baodiMax) { $lottery->baodiDrawed->$lot_type = 0; # 防刷, 已经领过的次数要加记录 $lottery->baodiLotterys->$lot_type -= $cishu; # 清零次数 } $err = self::Dice($baodi, 1, $rewardstr); # 投骰子 if ($err) { return Resp::err($err); } if (strlen($rewardstr) <= 0) { # 抽奖结果为空 return Resp::err(ErrCode::err_innerfault); } $err = StoreProc::AddMultiItemInStore($req, $rewardstr, 3); # 发放物品 if ($err) { return Resp::err($cishu); } $req->userInfo->game->privateState->lottery = $lottery; UserProc::updateUserInfo($req); # 回存数据 // var_dump($lottery); return Resp::ok(array('err' => 0, # # 返回值 'store' => $user->store, 'heros' => $user->heros, 'reward' => $rewardstr, 'baodi' => $lottery->baodiLotterys, 'baodidrawed' => $lottery->baodiDrawed )); } /** * [6510] 活动 - 抽奖 - 新手引导定制版 * @param Req $req */ static function demoLottery($req) { $user = $req->userInfo->game; if (count($req->paras) < 1) { # 参数数量不足 return Resp::err(ErrCode::parasnotenough_msg); } # # 提取参数 $type = $req->paras[0]; # 金币,钻石,友情点... $number = 1; # 抽奖次数 if (count($req->paras) > 1) { # 可选参数 $number = $req->paras[1]; } # 记录抽奖次数 $err = self::AddLotteryTimes($user->privateState->lottery, $type, $left_cishu, $number); if ($err) { return Resp::err($err); } $err = self::ConsumeLotteryCost($user, $type, $number); if ($err) { return Resp::err($err); } $req->userInfo->game = $user; // 回写 $err = self::Dice(JsonUtil::decode(glc()->choujiang_guide_items), $number, $rewardstr); if ($err) { // 出错了 return Resp::err($err); } if (strlen($rewardstr) <= 0) { return Resp::err(ErrCode::err_innerfault); } $err = StoreProc::AddMultiItemInStore($req, $rewardstr, 3); # 发放物品 if ($err) { return Resp::err($err); } UserProc::updateUserInfo($req); # 回存数据 return Resp::ok(array('err' => 0, # 返回值 'store' => $user->store, 'heros' => $user->heros, 'reward' => $rewardstr, 'baodi' => $user->privateState->lottery->baodiLotterys, 'left_cishu' => $left_cishu)); } // // /** * [6509] 活动 - 抽奖 * @param Req $req * @ deprecated since version 1.0.1 新版只出英雄, . . . * Ps. 1.0.0版可支持产出道具 */ static function Lottery($req) { $user = $req->userInfo->game; if (count($req->paras) < 1) { # 提取参数 return Resp::err(ErrCode::parasnotenough_msg); } $type = $req->paras[0]; # 金币,钻石,友情点... (物品id) $number = 1; # 抽奖次数 if (count($req->paras) > 1) { # 可选参数 $number = $req->paras[1]; } # 记录抽奖次数 $err = self::AddLotteryTimes($user->privateState->lottery, $type, $left_cishu, $number); if ($err) { return Resp::err($err); } # 扣除抽奖花费 $err = self::ConsumeLotteryCost($user, $type, $number); if ($err) { return Resp::err($err); } # 回写user数据 $req->userInfo->game = $user; # 对奖池依解锁等级进行过滤 $arr = self::FilterPrizepool($req, GameConfig::choujiang_getItem($type)); $err = self::Dice($arr, $number, $rewardstr); # 投骰子 if ($err) { # 出错了 return Resp::err($err); } if (strlen($rewardstr) <= 0) { # 抽奖结果为空 return Resp::err(ErrCode::err_innerfault); } $err = StoreProc::AddMultiItemInStore($req, $rewardstr, 3); # 发放物品 if ($err) { # 出错了 return Resp::err($err); } UserProc::updateUserInfo($req); # 回存数据 return Resp::ok(array('err' => 0, # # 返回值 'store' => $user->store, 'heros' => $user->heros, 'reward' => $rewardstr, 'baodi' => $user->privateState->lottery->baodiLotterys, 'left_cishu' => $left_cishu)); } // // // /** * [6513] 活动 - 抽奖 查询信息(卡槽) * @param Req $req */ static function Lottery_Info($req) { return Resp::ok(array( 'lottery' => new UserLotteryModel($req->userInfo->game->privateState->lottery) )); } /** * [6515] 活动 - 抽奖 缩短搜索时间 * @param Req $req */ static function Lottery_speedup_search($req) { if (count($req->paras) < 1) { # 提取参数 return Resp::err(ErrCode::parasnotenough_msg); } $id = $req->paras[0]; # 卡槽id: 0,1,2, $slotid = 'slot' . $id; $lottery = new UserLotteryModel($req->userInfo->game->privateState->lottery); $slot = new LotterySlotModel($lottery->$slotid); if ($slot->locked) { # 卡槽尚未解锁 return Resp::err(ErrCode::err_lottery_slot_locked); } if (!$slot->herotype) { # 卡槽空 return Resp::err(ErrCode::err_lottery_slot_emputy); } $itemid = glc()->choujiang_dachequan_itemid; # 打车券的itemid if ($slot->opents > now()) { # 已经到时间了,无需扣除, # 先不替客户省钱了, 只要客户端发送请求就执行. $err = StoreProc::removeItemFromStore($req->userInfo->game->store, $itemid, 1); if ($err) { return Resp::err($err); } $slot->opents = now(-15); # 往前偏移15秒 } $lottery->$slotid = $slot; $req->userInfo->game->privateState->lottery = $lottery; UserProc::updateUserInfo($req); # 回写数据 return Resp::ok(array('slot' => $slot)); # 返回 } /** * [6514] 活动 - 抽奖 解锁卡槽 * @param Req $req */ static function Lottery_unlock_Slot($req) { if (count($req->paras) < 1) { # 提取参数 return Resp::err(ErrCode::parasnotenough_msg); } $id = $req->paras[0]; # 卡槽id: 0,1,2, $slotid = 'slot' . $id; $lottery = new UserLotteryModel($req->userInfo->game->privateState->lottery); $slot = new LotterySlotModel($lottery->$slotid); if (!$slot->locked) { # 卡槽已经解锁 return Resp::err(ErrCode::err_lottery_slot_unlocked); } # 判断等级, 等级不足则扣除钻石 $sm_slot = GameConfig::choujiang_slot_getItem($id); # slot 配置 if ($req->userInfo->game->level < $sm_slot->level) { # 等级不足时需要扣除钻石 if (!UserGameModel::Consume_Cash($req->userInfo->game, $sm_slot->cash)) { return Resp::err(ErrCode::notenough_cash_msg); } } $slot->locked = false; # 解锁卡槽 $lottery->$slotid = $slot; $req->userInfo->game->privateState->lottery = $lottery; UserProc::updateUserInfo($req); # 回写数据 return Resp::ok(array('slot' => $slot)); # 返回 } /** * [6512] 活动 - 抽奖 领取到校英雄 * @param Req $req */ static function drawReachHero($req) { if (count($req->paras) < 1) { # 提取参数 return Resp::err(ErrCode::parasnotenough_msg); } $slotid = 'slot' . $req->paras[0]; # 卡槽id: 0,1,2, $lottery = new UserLotteryModel($req->userInfo->game->privateState->lottery); $slot = new LotterySlotModel($lottery->$slotid); if ($slot->locked) { # 卡槽尚未解锁 return Resp::err(ErrCode::err_lottery_slot_locked); } if ($slot->opents > now()) { # 卡槽时间未到 return Resp::err(ErrCode::err_lottery_slot_time); } if (!$slot->herotype || !$slot->herostar) { # 卡槽数据异常 return Resp::err(ErrCode::err_lottery_slot_emputy); } # 提取英雄... $he = HeroProc::AddHeroWithStar($req, $slot->herotype, $slot->herostar); $slot->Clear(); $lottery->$slotid = $slot; $req->userInfo->game->privateState->lottery = $lottery; # 数据回写 UserProc::updateUserInfo($req); return Resp::ok(array( 'heros' => $req->userInfo->game->heros, 'hero' => $he, 'slot' => $slot )); } /** * [6509] 活动 - 抽奖 * @param Req $req */ static function Lottery_Hero($req) { if (count($req->paras) < 1) { # 提取参数 return Resp::err(ErrCode::parasnotenough_msg); } $type = $req->paras[0]; # 金币,钻石,友情点... (物品id) $slotid = 'slot' . $req->paras[1]; # 卡槽id: 0,1,2,3 # // 检查卡槽是否空闲 $user = $req->userInfo->game; $lottery = new UserLotteryModel($user->privateState->lottery); $slot = new LotterySlotModel($lottery->$slotid); if ($slot->locked) { # 卡槽尚未解锁 return Resp::err(ErrCode::err_lottery_slot_locked); } if ($slot->opents > now() || $slot->herotype) { # 卡槽使用中 return Resp::err(ErrCode::err_lottery_slot_not_emputy); } $number = 1; # 抽奖次数, 固定为1 $err = self::AddLotteryTimes($lottery, $type, $left_cishu, $number); # 记录抽奖次数 if ($err) { return Resp::err($err); } $err = self::ConsumeLotteryCost($user, $type, $number); # 扣除抽奖花费(通知书) if ($err) { return Resp::err($err); } $err = self::Dice(GameConfig::choujiang_getItem($type), # 投骰子 $number, $rewardstr); if ($err) { return Resp::err($err); } if (strlen($rewardstr) <= 0) { # 抽奖结果为空 return Resp::err(ErrCode::err_innerfault); } # 依据抽奖次数找到星级数据库 $xingji = self::FindStarSource($lottery->todayLotterys->$type); if (!$xingji) { return Resp::err(ErrCode::err_const_no, "抽奖-星级"); } self::DiceOutStar($xingji, $star); # 计算星级 $val = explode(",", $rewardstr); $itemId = $val[0]; # 发放英雄(异化为英雄放入卡槽... // $he = HeroProc::AddHeroWithStar($req, $itemId, $star); $slot->herostar = $star; $slot->herotype = $itemId; $slot->opents = now() + self::DiceOutCoolingTiem(GameConfig::choujiang_searchtime_getItem($star)); $lottery->$slotid = $slot; $user->privateState->lottery = $lottery; # 回写数据 $req->userInfo->game = $user; # 回写user数据 UserProc::updateUserInfo($req); # 回存数据 return Resp::ok(array('err' => 0, # # 返回值 'store' => $user->store, 'slot' => $slot, # # 卡槽信息 'left_cishu' => $left_cishu)); } // // // /** * 增加抽奖次数 * @param LotterySlotModel $user * @param type $type * @param int $left_cishu out * @param type $number * @return int errno */ static function AddLotteryTimes(&$lottery, $type, &$left_cishu, $number = 1) { $todaylotterys = $lottery->todayLotterys; $totalLottreys = $lottery->totalLotterys; $baodiLotterys = $lottery->baodiLotterys; if (!$todaylotterys) { $todaylotterys = JsonUtil::decode(sprintf('{"%s":0}', $type)); } if (!$totalLottreys) { $totalLottreys = JsonUtil::decode(sprintf('{"%s":0}', $type)); } if (!$baodiLotterys) { $baodiLotterys = JsonUtil::decode(sprintf('{"%s":0}', $type)); } if (!isset($todaylotterys->$type)) { $todaylotterys->$type = 0; } if (!isset($totalLottreys->$type)) { $totalLottreys->$type = 0; } if (!isset($baodiLotterys->$type)) { $baodiLotterys->$type = 0; } $todaylotterys->$type += $number; $totalLottreys->$type += $number; $baodiLotterys->$type += $number; $settings = GameConfig::choujiang_settings_getItem($type); if (null == $settings) { return ErrCode::err_const_no; } $limit = $settings->dailyLimit; if ($limit > 0 && $todaylotterys->$type > $limit) { return ErrCode::err_lottery_daily_limit; # 达到每次次数限制, (@广电总局) } $left_cishu = $limit - $todaylotterys->$type; if ($left_cishu < 0) { $left_cishu = 0; } $lottery->todayLotterys = $todaylotterys; $lottery->totalLotterys = $totalLottreys; $lottery->baodiLotterys = $baodiLotterys; return ErrCode::ok; } /** * 扣除抽奖花费 * @param UserGameModel $user * @param type $type * @param type $number * @return int errno */ static function ConsumeLotteryCost($user, $type, $number = 1) { $settings = GameConfig::choujiang_settings_getItem($type); if (null == $settings) { return ErrCode::err_const_no; } $amt = $settings->price; if ($number > 1) { # n连抽 $amt *= $number; } switch ($type) { // 扣除花费 case META_GOLD_ITEMID: # 金币抽奖 if (!UserGameModel::Consume_Gold($user, $amt)) { return ErrCode::notenough_gold_msg; } break; case META_CASH_ITEMID: # 钻石抽奖 if (!UserGameModel::Consume_Cash($user, $amt)) { return ErrCode::notenough_cash_msg; # 钻石余额不足 } break; case META_FriendShipPoit_ItemId: # 友情点 if (!UserGameModel::Consume_FriendShipPoint($user, $amt)) { return ErrCode::notenough_friendshippoint; } break; default: # 从包裹中消耗道具 $err = StoreProc::removeItemFromStore($user->store, $type, $amt); if ($err) { return $err; } break; } return ErrCode::ok; } /** * 过滤奖池 * @param Req $req * @param array $arr 奖池 */ static function FilterPrizepool($req, $arr) { # 等级限制 $ret = array_filter($arr, function ($value) use($req) { return($req->userInfo->game->level >= $value->unlock_level); }); return $ret; } /** * 投骰子 * @param assoc_array $arr 抽奖物品概率 * @param int $number 连抽次数 * @return string itemid,num;itemid,num;... */ static function Dice($arr, $number, &$rewardstr) { $max = 0; # 计算物品权重总和 array_walk($arr, function ($value) use(&$max) { $max += $value->probability; }); if (!$max) { # 配置数据有问题 return ErrCode::err_const_no; } $reward = ArrayInit(); for ($i = 0; $i < $number; $i++) { $rnd = CommUtil::random(1, $max); # 投骰子 $start = 0; $rew = null; foreach ($arr as $item) { # 循环判断落入那个物品上 if ($start < $rnd && $rnd <= $start + $item->probability) { # 落入区间 $rew = $item; # 记录物品 break; } $start += $item->probability; # 继续判断是否落入下一物品的区间 } # foreach end if (!$rew) { return ErrCode::lottery_noselecteditem; } $reward[] = implode(',', array($rew->rewardItemId, $rew->number)); } # for end $rewardstr = implode(';', $reward); return ErrCode::ok; } /** * 找到计算星级的数据源 * @param type $cishu * @return array of sm_choujiang_xingji */ public static function FindStarSource($cishu) { foreach (GameConfig::choujiang_xingji() as $ci => $arr) { if ($cishu <= $ci) { # 找到对应的阶段了 return $arr; } } return JsonUtil::decode('[{"star":1,"probability":100}]'); # 默认值, 爽吧 } /** * @deprecated since version now * 投骰子获得一个卡牌的星级 * @param type $arr * @param type $ret * @return type */ public static function DiceOutStar($arr, &$ret) { $max = 0; array_walk($arr, function ($value) use(&$max) { $max += $value->probability; # 计算物品权重总和 }); if (!$max) { # 配置数据有问题 return ErrCode::err_const_no; } $rnd = CommUtil::random(1, $max); # 投骰子 $start = 0; # 起点 foreach ($arr as $item) { # 循环判断落入那个物品上 if ($start < $rnd && $rnd <= $start + $item->probability) { # 落入区间 $ret = $item->star; # 设置结果 return ErrCode::ok; } $start += $item->probability; # 继续判断是否落入下一物品的区间 } # foreach end return ErrCode::lottery_noselecteditem; # 没有找到对应的结果 } /** * 依据星级投骰子获得一个到校时间 * @param type $arr * @return type */ public static function DiceOutCoolingTiem($arr) { $max = 0; array_walk($arr, function ($value) use(&$max) { $max += $value->probability; # 计算物品权重总和 }); $rnd = CommUtil::random(1, $max); # 投骰子 $start = 0; # 起点 foreach ($arr as $item) { # 循环判断落入那个物品上 if ($start < $rnd && $rnd <= $start + $item->probability) { # 落入区间 return $item->time; # 设置结果, 返回值 } $start += $item->probability; # 继续判断是否落入下一物品的区间 } # foreach end return 780; # 没有找到对应的结果, 给一个默认值13分钟 } /** * 清理每天的抽奖次数记录 * @param Req $req */ public static function ClearLotteryRecord($req) { $req->userInfo->game->privateState->lottery->todayLotterys = ObjectInit(); } // // }