-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
328 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
251 changes: 251 additions & 0 deletions
251
app/Game/BattleRewardProcessing/Handlers/GoldMinesRewardHandler.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
<?php | ||
|
||
namespace App\Game\BattleRewardProcessing\Handlers; | ||
|
||
use App\Flare\Builders\RandomAffixGenerator; | ||
use Facades\App\Flare\Calculators\DropCheckCalculator; | ||
use App\Flare\Models\Character; | ||
use App\Flare\Models\Event; | ||
use App\Flare\Models\Item; | ||
use App\Flare\Models\Location; | ||
use App\Flare\Models\Monster; | ||
use Facades\App\Flare\RandomNumber\RandomNumberGenerator; | ||
use App\Flare\Values\ItemEffectsValue; | ||
use App\Flare\Values\ItemSpecialtyType; | ||
use App\Flare\Values\MaxCurrenciesValue; | ||
use App\Flare\Values\RandomAffixDetails; | ||
use Facades\App\Game\Core\Handlers\AnnouncementHandler; | ||
use App\Game\Events\Values\EventType; | ||
use App\Game\Mercenaries\Values\MercenaryValue; | ||
use App\Game\Messages\Events\GlobalMessageEvent; | ||
use App\Game\Messages\Events\ServerMessageEvent; | ||
use Exception; | ||
use Illuminate\Support\Facades\Cache; | ||
|
||
class GoldMinesRewardHandler { | ||
|
||
|
||
/** | ||
* @var RandomAffixGenerator $randomAffixGenerator | ||
*/ | ||
private RandomAffixGenerator $randomAffixGenerator; | ||
|
||
/** | ||
* @param RandomAffixGenerator $randomAffixGenerator | ||
*/ | ||
public function __construct(RandomAffixGenerator $randomAffixGenerator) { | ||
$this->randomAffixGenerator = $randomAffixGenerator; | ||
} | ||
|
||
public function handleFightingAtGoldMines(Character $character, Monster $monster): Character { | ||
|
||
$location = Location::where('x', $character->x_position) | ||
->where('y', $character->y_position) | ||
->where('game_map_id', $character->map->game_map_id) | ||
->first(); | ||
|
||
if (is_null($location) || is_null($location->locationType())) { | ||
return $character; | ||
} | ||
|
||
if (!$location->locationType()->isGoldMines()) { | ||
return $character; | ||
} | ||
|
||
$event = Event::where('type', EventType::GOLD_MINES)->first(); | ||
|
||
$character = $this->currencyReward($character, $event); | ||
|
||
if ($this->isMonsterAtLeastHalfWayOrMore($location, $monster)) { | ||
$character = $this->handleItemReward($character, $event); | ||
} | ||
|
||
return $character; | ||
} | ||
|
||
/** | ||
* is the monster at least halfway down the list? | ||
* | ||
* @param Location $location | ||
* @param Monster $monster | ||
* @return bool | ||
*/ | ||
protected function isMonsterAtLeastHalfWayOrMore(Location $location, Monster $monster): bool { | ||
|
||
$monsters = Cache::get('monsters')[$location->name]; | ||
|
||
$monsterCount = count($monsters); | ||
$halfWay = (int) ($monsterCount / 2); | ||
|
||
$position = array_search($monster->id, array_column($monsters, 'id')); | ||
|
||
return $position !== false && $position >= $halfWay; | ||
} | ||
|
||
/** | ||
* Reward the character with currencies. | ||
* | ||
* - Only gives copper coins if the character has | ||
* | ||
* @param Character $character | ||
* @param Event|null $event | ||
* @return Character | ||
*/ | ||
public function currencyReward(Character $character, Event $event = null): Character { | ||
$maximumAmount = 500; | ||
$maximumGold = 10000; | ||
|
||
if (!is_null($event)) { | ||
$maximumAmount = 1000; | ||
$maximumGold = 50000; | ||
} | ||
|
||
$goldDust = RandomNumberGenerator::generateRandomNumber(1, $maximumAmount); | ||
$shards = RandomNumberGenerator::generateRandomNumber(1, $maximumAmount); | ||
$gold = RandomNumberGenerator::generateRandomNumber(1, $maximumGold); | ||
|
||
$goldDust = $goldDust + $goldDust * $this->getCurrencyMercenaryBonus($character, MercenaryValue::CHILD_OF_GOLD_DUST); | ||
$shards = $shards + $shards * $this->getCurrencyMercenaryBonus($character, MercenaryValue::CHILD_OF_SHARDS); | ||
|
||
$goldDust += $character->gold_dust; | ||
$shards += $character->shards; | ||
|
||
if ($goldDust > MaxCurrenciesValue::MAX_GOLD_DUST) { | ||
$goldDust = MaxCurrenciesValue::MAX_GOLD_DUST; | ||
} | ||
|
||
if ($shards > MaxCurrenciesValue::MAX_SHARDS) { | ||
$shards = MaxCurrenciesValue::MAX_SHARDS; | ||
} | ||
|
||
if ($gold > MaxCurrenciesValue::MAX_GOLD) { | ||
$gold = MaxCurrenciesValue::MAX_GOLD; | ||
} | ||
|
||
$character->update([ | ||
'gold_dust' => $goldDust, | ||
'shards' => $shards, | ||
'gold' => $gold, | ||
]); | ||
|
||
return $character->refresh(); | ||
} | ||
|
||
/** | ||
* Handle item Reward for player. | ||
* | ||
* @param Character $character | ||
* @param bool $isMythic | ||
* @param Event|null $event | ||
* @return Character | ||
* @throws Exception | ||
*/ | ||
protected function handleItemReward(Character $character, Event $event = null): Character { | ||
$lootingChance = $character->skills->where('baseSkill.name', 'Looting')->first()->skill_bonus; | ||
$maxRoll = 1000000; | ||
|
||
if ($lootingChance > 0.15) { | ||
$lootingChance = 0.15; | ||
} | ||
|
||
if (!is_null($event)) { | ||
$lootingChance = .30; | ||
$maxRoll = $maxRoll / 2; | ||
} | ||
|
||
if (DropCheckCalculator::fetchDifficultItemChance($lootingChance, $maxRoll)) { | ||
if (!$character->isInventoryFull()) { | ||
$this->rewardForCharacter($character); | ||
} | ||
} | ||
|
||
$this->createPossibleEvent(); | ||
|
||
return $character->refresh(); | ||
} | ||
|
||
/** | ||
* Reward player with item. | ||
* | ||
* @param Character $character | ||
* @param bool $isMythic | ||
* @return void | ||
* @throws Exception | ||
*/ | ||
protected function rewardForCharacter(Character $character, bool $isMythic = false) { | ||
$item = Item::whereIsNull('specialty_type') | ||
->whereIsNull('item_prefix_id') | ||
->whereIsNull('item_suffix_id') | ||
->whereDoesntHave('appliedHolyStacks') | ||
->whereNotIn('type', ['alchemy', 'artifact', 'trinket']) | ||
->inRandomOrder() | ||
->first(); | ||
|
||
if (is_null($item)) { | ||
return; | ||
} | ||
|
||
if (!$isMythic) { | ||
$randomAffixGenerator = $this->randomAffixGenerator->setPaidAmount(RandomAffixDetails::MEDIUM); | ||
|
||
$newItem = $item->duplicate(); | ||
|
||
$newItem->update([ | ||
'item_prefix_id' => $randomAffixGenerator->generateAffix('prefix')->id, | ||
'item_suffix_id' => $randomAffixGenerator->generateAffix('suffix')->id, | ||
]); | ||
|
||
$slot = $character->inventory->slots()->create([ | ||
'inventory_id' => $character->inventory->id, | ||
'item_id' => $newItem->id, | ||
]); | ||
|
||
event(new ServerMessageEvent($character->user, 'You found something MEDIUM but still unique, in the mines child: ' . $item->affix_name, $slot->id)); | ||
} | ||
} | ||
|
||
/** | ||
* Get mercenary bonus. | ||
* | ||
* @param Character $character | ||
* @param string $mercenaryType | ||
* @return float | ||
*/ | ||
protected function getCurrencyMercenaryBonus(Character $character, string $mercenaryType): float { | ||
|
||
$mercenary = $character->mercenaries()->where('mercenary_type', $mercenaryType)->first(); | ||
|
||
if (!is_null($mercenary)) { | ||
return $mercenary->type()->getBonus($mercenary->current_level, $mercenary->reincarnated_bonus); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* 1 out of 1 million chance to create an event. | ||
* | ||
* @return void | ||
*/ | ||
protected function createPossibleEvent() { | ||
|
||
if (Event::where('type', EventType::GOLD_MINES)->exists()) { | ||
return; | ||
} | ||
|
||
if (RandomNumberGenerator::generateTureRandomNumber(0, 1) <= (1 / 1000000)) { | ||
Event::create([ | ||
'type' => EventType::GOLD_MINES, | ||
'started_at' => now(), | ||
'ends_at' => now()->addHour(), | ||
]); | ||
|
||
AnnouncementHandler::createAnnouncement('purgatory_house'); | ||
|
||
event(new GlobalMessageEvent( | ||
'There comes a howling scream from the depths of the mines in the land of tormenting shadows. | ||
Someone released the vien of hate and flooded the mines with treasure!' | ||
)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.