/*** @overview Life of German - Economy @author kookroach @copyright (c) 2008 - 2019 Life of German */ using System; using System.Collections.Generic; using System.Linq; using GTANetworkAPI; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using ReallifeGamemode.Database.Entities; using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Log; using ReallifeGamemode.Server.Services; using ReallifeGamemode.Server.Wanted; namespace ReallifeGamemode.Server.Finance { public class Economy { private static readonly ILogger logger = LogManager.GetLogger(); public static Dictionary Paychecks { get; set; } = new Dictionary(); public static (int, float, float) GetEconomyClass(Player client, int wage) { int bankAccount = client.GetUser().BankAccount.Balance; float financialHelp = -(float)Math.Pow(1.0001, -(bankAccount + client.GetUser().Handmoney)) * -1000; float financialInterest = 1 - (float)Math.Pow(1.000041, -wage) * 1; if (financialInterest >= 0.7) financialInterest = 0.7f; if (financialHelp > 2500) financialHelp = 2500; return (bankAccount, financialHelp, financialInterest); } public static int GetVehicleTaxation(Player client) { int vehicleTaxation = 0; using (var dbContext = new DatabaseContext()) { User user = client.GetUser(dbContext); foreach (UserVehicle uVeh in dbContext.UserVehicles.Where(u => u.UserId == user.Id)) { if (uVeh.Price == null) vehicleTaxation += 400; else vehicleTaxation += (int)(uVeh.Price * 0.0015f); int taxation = uVeh.BusinessId switch { 3 => 75, /// 4 => 200, /// 5 => 150, /// 6 => 150, /// 7 => 150, /// 8 => 50, /// 9 => 20, /// 10 => 50, /// 11 => 100, /// 12 => 50, /// 13 => 100, /// 14 => 200, /// _ => 0, }; if (taxation is 0) Console.WriteLine($"[FINANCE] USER: {user.Name} ({user.Id}) has no BusinessId on UserVehicle ({uVeh.Id})"); vehicleTaxation += taxation; } } return vehicleTaxation; } public static float GetPropertyTaxation(Player client) { float propertyTaxation = 0; User user = client.GetUser(); if (user.HouseId != null) { propertyTaxation += user.House.Price * 0.005f; } return propertyTaxation; } public static void SetPaycheck(Player client, bool minusJail = true) { User user = client.GetUser(); int wage = user.Wage; (int bankAccount, float financialHelp, float financialInterest) = GetEconomyClass(client, wage); float propertyTax = GetPropertyTaxation(client); int vehicleTaxation = GetVehicleTaxation(client); int rentalFees = GetRentalFees(client); int healthInsurance = (int)((bankAccount + user.Handmoney) * 0.001); if (healthInsurance < 0) { healthInsurance = 0; } int? factionMoney = null; if (user.Faction != null && user.FactionRank != null) { using var dbContext = new DatabaseContext(); int factionRankCount = dbContext.FactionRanks.Where(r => r.FactionId == user.FactionId).Count(); int factionWage = (3000 / factionRankCount) * user.FactionRank.Order; if (wage > 2500) { factionWage /= 2; } factionMoney = factionWage; } int otheramount = user.otheramount; int amount = wage - (int)(wage * financialInterest) - vehicleTaxation - (int)propertyTax + (int)financialHelp - rentalFees - healthInsurance + (factionMoney ?? 0) + otheramount; Paycheck paycheck = new Paycheck(financialHelp, financialInterest, vehicleTaxation, propertyTax, wage, amount, rentalFees, healthInsurance, factionMoney, otheramount); Paychecks[user.Id] = paycheck; ReleasePayDay(client, paycheck, minusJail); } private static int GetRentalFees(Player client) { using (var dbContext = new DatabaseContext()) { User user = client.GetUser(); return dbContext.HouseRentals.Where(h => h.UserId == user.Id).Include(h => h.House).Sum(h => h.House.RentalFee); } } public static void ReleasePayDay(Player client, Paycheck paycheck, bool minusJail) { NAPI.Util.ConsoleOutput("in release payday."); if (client == null || paycheck == null) { return; } int putInJail = 0; using var dbContext = new DatabaseContext(); User u = client.GetUser(dbContext); UserBankAccount bankAccount = u.BankAccount; if (bankAccount.Balance < 0) { if (bankAccount.Balance >= -2500) { putInJail = 5; } else { putInJail = 10; } } logger.LogInformation("Player {0} has a payday of {1} dollars. old balance: {2}, new balance: {3}, wage: {4}, interest: {5}, other: {6}", client.Name, paycheck.Amount, u.BankAccount.Balance, u.BankAccount.Balance + paycheck.Amount, paycheck.Wage, paycheck.FinancialInterest, paycheck.otheramount); u.BankAccount.Balance += paycheck.Amount; u.Wage = 0; u.otheramount = 0; u.PaydayTimer = 60; var rentals = dbContext.HouseRentals .Include(hR => hR.House) .ThenInclude(h => h.BankAccount) .Where(hR => hR.UserId == u.Id); dbContext.Factions.Include(f => f.BankAccount).Where(f => f.Id == 2).First().BankAccount.Balance += (int)(paycheck.HealthInsurance * 0.1); logger.LogInformation("Medic faction got a health insurance payment of {0} dollars from player {1}", paycheck.HealthInsurance * 0.1, client.Name); if (rentals.Any()) { foreach (var rental in rentals) { if (rental?.House?.BankAccount != null) { rental.House.BankAccount.Balance += (int)(rental.House.RentalFee * 0.7); logger.LogInformation("House {0} got a rentalfee of {1} from paycheck from user {2}", rental.House.Id, rental.House.RentalFee * 0.7, u.Name); } } } if (paycheck.Amount > 0) ChatService.SendMessage(client, $"~g~[PAYDAY]~s~ Dein Stundenumsatz beträgt ~g~{ paycheck.Amount.ToMoneyString() }~s~."); else ChatService.SendMessage(client, $"~g~[PAYDAY]~s~ Dein Stundenumsatz beträgt ~r~-{ Math.Abs(paycheck.Amount).ToMoneyString() }~s~."); if (putInJail != 0 && minusJail) { u.JailTime = putInJail * 60; ChatService.SendMessage(client, "Du hattest beim PayDay einen negativen Betrag auf deinem Bankkonto, dafür wirst du eingesperrt."); ChatService.SendMessage(client, "Achte darauf, keinen negativen Geldbetrag zu besitzen."); } dbContext.SaveChanges(); if (putInJail != 0 && minusJail) { Jail.Check_PutBehindBars(u, JailInLocations.InCell); } } public static void Timer_Elapsed() { using var dbContext = new DatabaseContext(); foreach (var player in NAPI.Pools.GetAllPlayers().Where(p => p.IsLoggedIn())) { if (player.IsAfk()) { continue; } User user = player.GetUser(dbContext); if (user == null) { continue; } user.PlayedMinutes += 1; if (user.PaydayTimer <= 0) { Economy.SetPaycheck(player); user.PaydayTimer = 60; } else if (user.PaydayTimer > 0) { user.PaydayTimer -= 1; } } dbContext.SaveChanges(); } } }