Add action gathering functionality: implement ActionGathered model and repository, update Pet model and services, and enhance GameItemsRepository with item retrieval methods.

This commit is contained in:
2025-02-09 21:22:52 -03:00
parent 653cc451d2
commit 215d4ecb72
18 changed files with 481 additions and 41 deletions

View File

@@ -35,6 +35,14 @@ namespace PetCompanion.Services
}
}
public GameItem GetRandomItem()
{
var items = gameItemsRepository.GetAll();
var random = new Random();
var index = random.Next(items.Count());
return items.ElementAt(index);
}
public void ApplyItemEffect(Pet pet, GameItem item)
{
var effects = item.Effect.Split(';');

View File

@@ -0,0 +1,26 @@
namespace PetCompanion.Services
{
public class PetActionBackgroundService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
public PetActionBackgroundService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using (var scope = _serviceProvider.CreateScope())
{
var petActionService = scope.ServiceProvider.GetRequiredService<PetActionService>();
petActionService.LoopPetActions();
}
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
}
}

View File

@@ -0,0 +1,153 @@
using PetCompanion.Models;
using PetCompanion.Repositories;
namespace PetCompanion.Services
{
public class PetActionService
{
private readonly ActionGatheredRepository actionGatheredRepository;
private readonly PetRepository petRepository;
private readonly GameItemService gameItemService;
public PetActionService(ActionGatheredRepository actionGatheredRepository, GameItemService gameItemService, PetRepository petRepository)
{
this.actionGatheredRepository = actionGatheredRepository;
this.gameItemService = gameItemService;
this.petRepository = petRepository;
}
public IEnumerable<ActionGathered> GetGatheredByPet(string petId)
{
return actionGatheredRepository.GetAllActionGatheredByPetId(petId);
}
public void DeleteAllActionGatheredByPetId(string petId)
{
actionGatheredRepository.DeleteAllActionGatheredByPetId(petId);
}
public void LoopPetActions()
{
var pets = petRepository.GetPetWithActions();
foreach (var pet in pets)
{
var gatheredResources = CalculateGatheredResources(pet);
if (gatheredResources != null)
{
var gatheredResourcesDb = actionGatheredRepository.GetAllActionGatheredByPetId(pet.Id);
foreach (var resource in gatheredResources)
{
if (gatheredResourcesDb.Any(ag => ag.Resource == resource.Resource))
{
var existingResource = gatheredResourcesDb.First(ag => ag.Resource == resource.Resource);
existingResource.Amount += resource.Amount;
actionGatheredRepository.UpdateActionGathered(existingResource);
}
else
{
actionGatheredRepository.CreateActionGathered(resource);
}
}
}
}
}
public ICollection<ActionGathered>? CalculateGatheredResources(Pet pet)
{
if (pet.PetGatherAction == PetActionGather.IDLE)
return null;
var timeElapsed = (DateTime.UtcNow - pet.GatherActionSince).TotalMinutes;
var gathered = new List<ActionGathered>();
var baseRate = timeElapsed + pet.Level * 10; // Base rate per hour
gathered.Add(new ActionGathered
{
Resource = "Junk",
Amount = (int)(baseRate * 2)
});
var random = new Random();
switch (pet.PetGatherAction)
{
case PetActionGather.GATHERING_WISDOM:
gathered.Add(new ActionGathered
{
Resource = "Wisdom",
Amount = (int)(baseRate * (pet.Stats.Intelligence * 2))
});
break;
case PetActionGather.GATHERING_GOLD:
gathered.Add(new ActionGathered
{
Resource = "Gold",
Amount = (int)(baseRate * (pet.Stats.Charisma * 2))
});
break;
case PetActionGather.GATHERING_FOOD:
gathered.Add(new ActionGathered
{
Resource = "Food",
Amount = (int)(baseRate * (pet.Stats.Strength * 1.5))
});
break;
case PetActionGather.EXPLORE:
gathered.Add(new ActionGathered
{
Resource = "Wisdom",
Amount = (int)(baseRate * (pet.Stats.Strength * 3))
});
if (random.Next(0, 100) < 5)
{
pet.Health -= 5;
}
if (random.Next(0, 100) < 5)
{
gathered.Add(new ActionGathered
{
ItemId = gameItemService.GetRandomItem().Id,
Amount = 1
});
}
break;
case PetActionGather.BATTLE:
gathered.Add(new ActionGathered
{
Resource = "Gold",
Amount = (int)(baseRate * (pet.Stats.Strength * 3))
});
if (random.Next(0, 100) < 10)
{
pet.Health -= random.Next(5, 10);
}
if (random.Next(0, 100) < 500)
{
gathered.Add(new ActionGathered
{
ItemId = gameItemService.GetRandomItem().Id,
Amount = 1
});
}
break;
}
for (int i = 0; i < gathered.Count; i++)
{
gathered[i].PetId = pet.Id;
}
return gathered;
}
}
}

View File

@@ -16,32 +16,5 @@ namespace PetCompanion.Services
{
return _petClassRepository.GetAllPetClassesInfo();
}
public Resources CalculateGatheredResources(PetStats stats, int petLevel, PetActionGather action, DateTime actionSince)
{
var timeElapsed = (DateTime.UtcNow - actionSince).TotalHours;
var resources = new Resources();
if (action == PetActionGather.IDLE)
return resources;
var baseRate = timeElapsed * 0.5 + petLevel; // Base rate per hour
resources.Junk = (int)(baseRate * 2);
switch (action)
{
case PetActionGather.GATHERING_WISDOM:
resources.Wisdom = (int)(baseRate * (stats.Intelligence * 2));
break;
case PetActionGather.GATHERING_GOLD:
resources.Gold = (int)(baseRate * (stats.Charisma * 2));
break;
case PetActionGather.GATHERING_FOOD:
resources.Food = (int)(baseRate * (stats.Strength * 1.5));
break;
}
return resources;
}
}
}

View File

@@ -146,6 +146,12 @@ namespace PetCompanion.Services
if (gameItem == null)
throw new Exception("Item not found");
if (pet == null)
throw new Exception("Pet not found");
if (pet.Inventory.Items.Count + quantity > pet.Inventory.Capacity)
throw new Exception("Not enough space in inventory");
for (int i = 0; i < quantity; i++)
{
pet.Inventory.Items.Add(itemId);

View File

@@ -1,4 +1,5 @@
using PetCompanion.Models;
using Microsoft.EntityFrameworkCore.Query;
using PetCompanion.Models;
using PetCompanion.Repositories;
namespace PetCompanion.Services
@@ -10,19 +11,22 @@ namespace PetCompanion.Services
private readonly GameItemService gameItemService;
private readonly GameItemsRepository gameItemsRepository;
private readonly PetInventoryService petInventoryService;
private readonly PetActionService petActionService;
public PetService(
PetRepository petRepository,
PetClassService petClassService,
GameItemService gameItemService,
GameItemsRepository gameItemsRepository,
PetInventoryService petInventoryService)
PetInventoryService petInventoryService,
PetActionService petActionService)
{
this.petRepository = petRepository;
this.petClassService = petClassService;
this.gameItemService = gameItemService;
this.gameItemsRepository = gameItemsRepository;
this.petInventoryService = petInventoryService;
this.petActionService = petActionService;
}
public IEnumerable<Pet> GetAllPets(Guid userId)
@@ -123,7 +127,7 @@ namespace PetCompanion.Services
}
}
public Resources GetGatheredResources(string petId, string userId)
public IEnumerable<ActionGathered> GetGatheredResources(string petId, string userId)
{
var pet = petRepository.GetPetById(petId, userId);
@@ -132,10 +136,10 @@ namespace PetCompanion.Services
throw new Exception("Pet not found");
}
return petClassService.CalculateGatheredResources(pet.Stats, pet.Level, pet.PetGatherAction, pet.GatherActionSince);
return petActionService.GetGatheredByPet(petId);
}
public Pet UpdatePetResources(string petId, string userId)
public Pet CollectPetGathered(string petId, string userId)
{
var pet = petRepository.GetPetById(petId, userId);
if (pet == null)
@@ -143,15 +147,43 @@ namespace PetCompanion.Services
throw new Exception("Pet not found");
}
var gatheredResources = petClassService.CalculateGatheredResources(pet.Stats, pet.Level, pet.PetGatherAction, pet.GatherActionSince);
var petGathered = petActionService.GetGatheredByPet(petId);
pet.Resources.Wisdom += gatheredResources.Wisdom;
pet.Resources.Gold += gatheredResources.Gold;
pet.Resources.Food += gatheredResources.Food;
pet.Resources.Junk += gatheredResources.Junk;
pet.GatherActionSince = DateTime.UtcNow;
if (petGathered == null)
{
throw new Exception("No resources to collect");
}
return petRepository.UpdatePetResources(pet);
foreach (var resource in petGathered)
{
if (resource.Resource != null && resource.Resource != string.Empty)
{
switch (resource.Resource)
{
case "Junk":
pet.Resources.Junk += resource.Amount;
break;
case "Food":
pet.Resources.Food += resource.Amount;
break;
case "Gold":
pet.Resources.Gold += resource.Amount;
break;
case "Wisdom":
pet.Resources.Wisdom += resource.Amount;
break;
}
}
else if (resource.ItemId != null && resource.ItemId > 0)
{
petInventoryService.AddItemToPet(petId, userId, resource.ItemId ?? 1, resource.Amount);
}
}
var updatedPet = petRepository.UpdatePet(pet);
petActionService.DeleteAllActionGatheredByPetId(petId);
return updatedPet;
}
public Pet GetPet(string petId, string userId)