Skip to content

Commit

Permalink
Changes to Gold Mines and rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamKyle committed Dec 13, 2023
1 parent e4a6d4a commit 2a5c2fb
Show file tree
Hide file tree
Showing 17 changed files with 328 additions and 84 deletions.
51 changes: 0 additions & 51 deletions app/Flare/Services/CharacterRewardService.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,6 @@ public function giveCurrencies(Monster $monster): CharacterRewardService {

$this->distributeCopperCoins($monster);

$this->giveShards();

$this->currencyEventReward($monster);

if (!$this->character->is_auto_battling && $this->character->isLoggedIn()) {
Expand All @@ -161,41 +159,6 @@ public function giveCurrencies(Monster $monster): CharacterRewardService {
return $this;
}

/**
* Give character shards.
*
* - Only if they are at a special location and in gold mines.
*
* @param Character $character
* @return CharacterRewardService
* @throws Exception
*/
public function giveShards(): CharacterRewardService {
$specialLocation = $this->findLocationWithEffect($this->character->map);

if (!is_null($specialLocation)) {
if (!is_null($specialLocation->type)) {
$locationType = new LocationType($specialLocation->type);

if ($locationType->isGoldMines()) {
$shards = rand(1, 1000);

$shards = $shards + $shards * $this->getShardBonus($this->character);

$newShards = $this->character->shards + $shards;

if ($newShards > MaxCurrenciesValue::MAX_SHARDS) {
$newShards = MaxCurrenciesValue::MAX_SHARDS;
}

$this->character->update(['shards' => $newShards]);
}
}
}

return $this;
}

/**
* Handles Currency Event Rewards when the event is running.
*
Expand Down Expand Up @@ -257,20 +220,6 @@ public function currencyEventReward(Monster $monster): CharacterRewardService {
return $this;
}

/**
* Are we at a location with an effect (special location)?
*
* @param Map $map
* @return Location|null
*/
protected function findLocationWithEffect(Map $map): ?Location {
return Location::whereNotNull('enemy_strength_type')
->where('x', $map->character_position_x)
->where('y', $map->character_position_y)
->where('game_map_id', $map->game_map_id)
->first();
}


/**
* Handle instances where we could have multiple level ups.
Expand Down
251 changes: 251 additions & 0 deletions app/Game/BattleRewardProcessing/Handlers/GoldMinesRewardHandler.php
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!'
));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ protected function rewardForCharacter(Character $character, bool $isMythic = fal
->whereIsNull('item_prefix_id')
->whereIsNull('item_suffix_id')
->whereDoesntHave('appliedHolyStacks')
->whereNotIn('type', ['alchemy', 'artifact', 'trinket'])
->inRandomOrder()
->first();

Expand Down
10 changes: 9 additions & 1 deletion app/Game/BattleRewardProcessing/Providers/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Game\Battle\Handlers\BattleEventHandler;
use App\Game\BattleRewardProcessing\Handlers\FactionHandler;
use App\Game\BattleRewardProcessing\Handlers\GlobalEventParticipationHandler;
use App\Game\BattleRewardProcessing\Handlers\GoldMinesRewardHandler;
use App\Game\BattleRewardProcessing\Handlers\PurgatorySmithHouseRewardHandler;
use App\Game\BattleRewardProcessing\Services\BattleRewardService;
use App\Game\BattleRewardProcessing\Services\SecondaryRewardService;
Expand Down Expand Up @@ -44,13 +45,20 @@ public function register() {
);
});

$this->app->bind(GoldMinesRewardHandler::class, function($app) {
return new GoldMinesRewardHandler(
$app->make(RandomAffixGenerator::class),
);
});

$this->app->bind(BattleRewardService::class, function ($app) {
return new BattleRewardService(
$app->make(FactionHandler::class),
$app->make(CharacterRewardService::class),
$app->make(GoldRush::class),
$app->make(GlobalEventParticipationHandler::class),
$app->make(PurgatorySmithHouseRewardHandler::class)
$app->make(PurgatorySmithHouseRewardHandler::class),
$app->make(GoldMinesRewardHandler::class),
);
});

Expand Down
Loading

0 comments on commit 2a5c2fb

Please sign in to comment.