private static void ApplyCEOLoyalty(GameEntity company, TeamInfo team, GameContext gameContext, ref Bonus <int> bonus, GameEntity worker, WorkerRole role) { bool hasCeo = HasMainManagerInTeam(company.team.Teams[0]); bonus.AppendAndHideIfZero("No CEO", hasCeo ? 0 : -4); var manager = GetMainManagerRole(team); var lead = GetWorkerByRole(manager, team, gameContext); if (lead == null) { bonus.Append($"No {Humans.GetFormattedRole(manager)} in team", -4); } else { var CEORating = Humans.GetRating(lead); var workerRating = Humans.GetRating(worker); if (CEORating < workerRating) { bonus.Append($"Incompetent leader (leader rating less than {workerRating})", -1); } } }
public static Bonus <long> GetMarketingEfficiency(GameEntity company) { var b = new Bonus <long>("Gain"); b.SetDimension("%"); b.Append("From teams", Teams.GetMarketingEfficiency(company)); foreach (var f in Products.GetAllFeaturesForProduct()) { if (f.IsMonetizationFeature) { continue; } if (Products.IsLeadingInFeature(company, f, null)) { b.Append("Leading in " + f.Name, 40); continue; } if (Products.IsUpgradedFeature(company, f.Name)) { b.Append(f.Name, 10); } } return(b); }
public static Bonus <float> GetDirectManagementCostOfTeam(TeamInfo team, GameEntity company, GameContext gameContext) { var bonus = new Bonus <float>("Cost of " + team.Name); var managers = GetPeople(team, gameContext); var mainRole = GetMainManagerRole(team); // 50...90 foreach (var m in managers) { var rating = Humans.GetRating(m); // Lead gain if (Humans.GetRole(m) == mainRole) { bonus.Append($"{mainRole} <b>{rating}lvl</b>", rating / 10f); continue; } bonus.Append($"{m.HumanComponent.Name} {m.HumanComponent.Surname} <b>{rating}lvl</b>", (rating - 150) / 100f); } var processes = GetPolicyValueModified(company, CorporatePolicy.PeopleOrProcesses, 1f, 0.5f, 0.25f); bonus.MultiplyAndHideIfOne("From corporate policies", processes); team.isManagedBadly = bonus.Sum() < 0; return(bonus); }
public static void ApplyProductEconomyToProfitBonus(GameEntity c, GameContext context, Bonus <long> bonus) { if (!c.hasProduct) { return; } // ** income ** // * base income // * investments // ** expenses ** // * teams // * managers // * marketing // * servers // income bonus.Append("Product income", GetProductIncome(c)); // expenses var maintenance = GetProductCompanyMaintenance(c, true); foreach (var m in maintenance.bonusDescriptions) { if (m.HideIfZero) { bonus.AppendAndHideIfZero(m.Name, -m.Value); } else { bonus.Append(m.Name, -m.Value); } } }
public static Bonus <long> GetFounderOpinionAboutOffer(AcquisitionOfferComponent acquisitionOffer, GameEntity investor, GameEntity company, GameContext gameContext) { var bonus = new Bonus <long>("Founder Opinion"); var conditions = acquisitionOffer.BuyerOffer; var priceOk = conditions.Price < acquisitionOffer.SellerOffer.Price; bonus.Append("Offered price", priceOk ? -100 : 1); //var wantsOurShares = GetHashedRandom(company.company.Id, acquisitionOffer.BuyerId) > 0.22f; //if (conditions.ByShares > 0) // bonus.AppendAndHideIfZero("Does not want our shares", wantsOurShares ? 0 : -120); var ambition = GetFounderAmbition(company, gameContext); //var wantsToStayInCompany = ambition == Ambition.RuleProductCompany; var wantsToRuleIndependently = ambition == Ambition.RuleCorporation; //if (wantsToStayInCompany) // bonus.Append("Wants to stay in company", conditions.KeepLeaderAsCEO ? 0 : -100); if (wantsToRuleIndependently) { bonus.Append("Ambitious founder", -1000); } return(bonus); }
public static Bonus <float> GetTeamCostForParentTeam(TeamInfo team, GameEntity company, GameContext gameContext, bool fullDescription = false) { var gain = GetLeaderGain(team, company, gameContext); // always positive var cost = GetDirectManagementCostOfTeam(team, company, gameContext); var directCost = cost.Sum(); // always positive or 0 var dependantTeams = GetDependantTeams(team, company); var dependantTeamCost = Math.Abs(dependantTeams.Sum(s => GetTeamCostForParentTeam(s, company, gameContext).Sum())); var totalCost = directCost + dependantTeamCost; var bonus = new Bonus <float>("Team Cost"); if (team.isCoreTeam) { bonus.AddBonus(cost); /*bonus.Append("CEO", gain); * bonus.Append($"Direct cost of Core team", -directCost);*/ ApplyDependantTeamsBonus(bonus, team, company, gameContext); return(bonus); } if (gain > totalCost) { // team is managed well and can be managed indirectly // except it is a core team (or independent team?) bonus.Append($"Management of {team.Name}", -GetIndirectManagementCostOfTeam(team, company)); return(bonus); } // team managed badly and will cause additional troubles in parent team var indirectCost = GetIndirectManagementCostOfTeam(team, company); if (fullDescription) { bonus .Append("Manager", gain) .Append("Team self cost", -directCost) .Append("Indirect cost", -indirectCost); ApplyDependantTeamsBonus(bonus, team, company, gameContext); return(bonus); } return(bonus.Append($"Management cost", gain - totalCost - indirectCost)); }
private static void ApplyLowSalaryLoyalty(GameEntity company, ref Bonus <int> bonus, HumanFF worker) { bool isFounder = worker.hasShareholder; // && // company.shareholders.Shareholders.ContainsKey(worker.shareholder.Id); if (isFounder) { return; } var salary = Humans.GetSalary(worker); var expectedSalary = (double)GetSalaryPerRating(worker); bool isGreedy = Humans.HasTrait(worker, Trait.Greedy); bool isShy = Humans.HasTrait(worker, Trait.Shy); float multiplier = 0.8f; if (isGreedy) { multiplier = 0.9f; } else if (isShy) { multiplier = 0.5f; } // multiply on 4 cause period = week if (salary * 4 < expectedSalary * multiplier) { bonus.Append("Low salary", -5); } }
public static Bonus <int> GetManagerGrowthBonus(GameEntity worker, TeamInfo teamInfo, bool hasTeacherInTeam, GameContext gameContext) { var rating = Humans.GetRating(worker); bool isCurious = worker.humanSkills.Traits.Contains(Trait.Curious); var bonus = new Bonus <int>("Growth"); bonus //.Append("Base", 25) .Append("Rating", (int)Mathf.Pow(100 - rating, 0.95f)) .AppendAndHideIfZero("Curious", isCurious ? 15 : 0) .AppendAndHideIfZero("Works with Teacher", hasTeacherInTeam ? 7 : 0) ; // market complexity // worker current rating (noob - fast growth, senior - slow) // trait: curious // consultant // loyalty change bonus.Cap(0, (rating < 100) ? 100 : 0); return(bonus); }
public static Bonus <int> GetHRBasedNewManagerRatingBonus(GameEntity company, GameContext gameContext) { var bonus = new Bonus <int>("New manager rating"); var managingCompany = Companies.GetManagingCompanyOf(company, gameContext); var productsOfManagingCompany = Companies.GetDaughterProducts(gameContext, managingCompany); bool hasGlobalMarkets = productsOfManagingCompany .Select(p => Markets.Get(gameContext, p)) .Count(m => m.nicheBaseProfile.Profile.AudienceSize == AudienceSize.Global) > 0; int positionOnMarket = 0; if (company.hasProduct) { var clampedPosition = Mathf.Clamp(Markets.GetPositionOnMarket(gameContext, company), 0, 5); positionOnMarket = (5 - clampedPosition) * 2; } bonus .Append("Base value", C.NEW_MANAGER_RATING_MIN) .Append("Mission", 0) .AppendAndHideIfZero("Position on market", positionOnMarket) .Append("Has Global Markets", hasGlobalMarkets ? 10 : 0) //.Append("Is TOP10 Company", 0) //.Append("Is TOP10 in teams", 0) ; return(bonus); }
public static void ApplyDependantTeamsBonus(Bonus <float> bonus, TeamInfo team, GameEntity company, GameContext gameContext) { foreach (var t in GetDependantTeams(team, company)) { var cost = GetTeamCostForParentTeam(t, company, gameContext).Sum(); bonus.Append(t.Name, -Math.Abs(cost)); } }
public static Bonus <int> GetLoyaltyChangeBonus(HumanFF worker, TeamInfo team, Dictionary <CorporatePolicy, int> culture, GameEntity company) { var bonus = new Bonus <int>("Loyalty"); bonus.Append("Base value", 1); var loyaltyBuff = team.ManagerTasks.Count(t => t == ManagerTask.ImproveAtmosphere); bonus.AppendAndHideIfZero("Manager focus on atmosphere", loyaltyBuff); var role = worker.WorkerComponent.WorkerRole; // TODO: if is CEO in own project, morale loss is zero or very low bonus.AppendAndHideIfZero("IS FOUNDER", worker.WorkerComponent.WorkerRole == WorkerRole.CEO ? 5 : 0); // same role workers //ApplyDuplicateWorkersLoyalty(company, team, gameContext, ref bonus, worker, role); // salary ApplyLowSalaryLoyalty(company, ref bonus, worker); // incompetent leader //ApplyCEOLoyalty(company, team, gameContext, ref bonus, worker, role); // no possibilities to grow var rating = Humans.GetRating(worker); var max = 70; if (role != WorkerRole.CEO) { bonus.AppendAndHideIfZero($"Outgrown company (skill >= {max})", rating >= max ? -3 : 0); } bonus.AppendAndHideIfZero("Too many leaders", Humans.HasTrait(worker, Trait.Leader) && team.TooManyLeaders ? -2 : 0); if (team.isManagedBadly) { bonus.Append("Terrible management", -3); } // bonus.AppendAndHideIfZero(hu) return(bonus); }
public static Bonus <long> GetAudienceChange(GameEntity product, GameContext gameContext, bool isBonus) { var bonus = new Bonus <long>("Audience change"); long churnUsers = 0; var segments = GetAudienceInfos(); for (var i = 0; i < segments.Count; i++) { churnUsers += GetChurnClients(product, gameContext); } bonus.Append("Marketing", GetAudienceGrowth(product, gameContext)); bonus.Append("Loss", -churnUsers); bonus.MinifyValues(); return(bonus); }
// TODO <float> public static Bonus <long> GetInvestorOpinionBonus(GameContext gameContext, GameEntity company, GameEntity investor) { var description = new Bonus <long>("Investor opinion"); if (IsInvestsInCompany(investor, company)) { description.AppendAndHideIfZero("Invests already", 35); } description.Append("Same goals", 25); return(description); }
public static void ApplyGroupInvestmentsToProfitBonus(GameEntity c, GameContext context, Bonus <long> bonus) { if (!Companies.IsGroup(c)) { return; } var holdings = Investments.GetHoldings(c, context, true); bool isOnlyHolding = holdings.Count == 1; foreach (var h in holdings) { var b = GetProfit(context, h.company, true); if (isOnlyHolding) { // render full description foreach (var d in b.bonusDescriptions) { if (d.HideIfZero) { bonus.AppendAndHideIfZero(d.Name, d.Value); } else { bonus.Append(d.Name, d.Value); } } } else { // general info is enough bonus.Append(h.company.company.Name, b.Sum()); } } }
// team cost public static Bonus <long> GetSalaries(GameEntity e, GameContext gameContext) { Bonus <long> salaries = new Bonus <long>("Manager salaries"); foreach (var t in e.team.Teams) { foreach (var human in t.Managers) { var salary = Humans.GetSalary(human); salaries.Append(Humans.GetFullName(human), salary); } } return(salaries); }
public static Bonus <long> GetVentureOpinionAboutOffer(AcquisitionOfferComponent acquisitionOffer, GameEntity investor, GameEntity company, GameContext gameContext) { var bonus = new Bonus <long>("Venture investor Opinion"); var conditions = acquisitionOffer.BuyerOffer; var priceOk = conditions.Price < acquisitionOffer.SellerOffer.Price; bonus.Append("Offered price", priceOk ? -100 : 1); //var wantsOurShares = GetHashedRandom(company.company.Id, acquisitionOffer.BuyerId) > 0.22f; //bonus.AppendAndHideIfZero("Does not want our shares", wantsOurShares ? 0 : -120); return(bonus); }
public static long GetBaseDesireToSellShares(GameContext gameContext, GameEntity company, int shareholderId, InvestorType investorType) { bool isProduct = company.hasProduct; var bonusContainer = new Bonus <long>("Desire to sell"); bonusContainer.Append("Base", 5); //bonusContainer.Append("Base", -1); //bonusContainer.AppendAndHideIfZero("Is young company", IsYoungCompany(company) ? -10 : 0); //if (isProduct) // bonusContainer.AppendAndHideIfZero("By investor type", GetDesireToSellStartupByInvestorType(company, investorType, shareholderId, gameContext)); //else // bonusContainer.AppendAndHideIfZero("By investor type", GetDesireToSellGroupByInvestorType(company, investorType, shareholderId, gameContext)); return((long)bonusContainer.Sum()); }
// opinion about offer // TODO <float> public static Bonus <long> GetInvestorOpinionAboutAcquisitionOffer(AcquisitionOfferComponent ackOffer, GameEntity investor, GameEntity targetCompany, GameContext gameContext) { var container = new Bonus <long>("Opinion about acquisition offer"); switch (investor.shareholder.InvestorType) { case InvestorType.Founder: container = GetFounderOpinionAboutOffer(ackOffer, investor, targetCompany, gameContext); break; case InvestorType.VentureInvestor: container = GetVentureOpinionAboutOffer(ackOffer, investor, targetCompany, gameContext); break; case InvestorType.Strategic: container.Append("Views this company as strategic interest", -1000); break; } return(container); }
public static Bonus <float> GetFeatureRatingCap(GameEntity product, TeamInfo team, GameContext gameContext) { var productManager = Teams.GetWorkerInRole(team, WorkerRole.ProductManager, gameContext); var bonus = new Bonus <float>("Max feature lvl"); bonus.Append("Base", 3f); bonus.AppendAndHideIfZero("Development Team", team.TeamType == TeamType.DevelopmentTeam ? 1f : 0); if (productManager != null) { // ... 5f var addedCap = 6 * Humans.GetRating(productManager) / 100f; bonus.AppendAndHideIfZero("Product Manager", addedCap); } // var culture = Companies.GetOwnCulture(Companies.GetManagingCompanyOf(product, gameContext)); // // var cultureBonus = (10 - culture[CorporatePolicy.DoOrDelegate]) * 0.2f; // var cultureBonus2 = (culture[CorporatePolicy.DecisionsManagerOrTeam]) * 0.4f; // // bonus.Append("Corporate culture Do or Delegate", cultureBonus); // bonus.Append("Corporate culture Structure", cultureBonus2); //bool hasMainManager = Teams.HasMainManagerInTeam(team, gameContext, product); //if (hasMainManager) //{ // var focus = team.ManagerTasks.Count(t => t == ManagerTask.Polishing); // cap += focus * 0.4f; //} bonus.Cap(0, 10); return(bonus); //return Mathf.Clamp(cap, 0, 10); }
public static Bonus <float> GetManagerPointChange(GameEntity company, GameContext gameContext) { var teams = company.team.Teams; var bonus = new Bonus <float>("Point gain"); bool teamsOnly = teams.Count > 3; foreach (var team in teams.Where(t => t.isIndependentTeam)) { var b = GetTeamCostForParentTeam(team, company, gameContext, false); if (teamsOnly) { bonus.Append(team.Name, b.Sum()); } else { bonus.AddBonus(b); } } return(bonus); }
public static Bonus <float> GetOpinionAboutOffer(HumanFF worker, ExpiringJobOffer newOffer) { bool willNeedToLeaveCompany = worker.WorkerComponent.companyId != newOffer.CompanyId; var bonus = new Bonus <float>("Opinion about offer"); // scenarios // 1 - unemployed // 2 - employed, same company // 3 - employed, recruiting // 4 - !founder if (!Humans.IsEmployed(worker)) { return(bonus.Append("Salary", newOffer.JobOffer.Salary > GetSalaryPerRating(worker) ? 1 : -1)); } int loyaltyBonus = (worker.HumanCompanyRelationshipComponent.Morale - 50) / 10; int desireToLeaveCompany = 0; if (willNeedToLeaveCompany) { // it's not easy to recruit worker from other company desireToLeaveCompany -= 5; // and if your worker loves stability... if (Humans.HasTrait(worker, Trait.Loyal)) { desireToLeaveCompany -= 5; } // but if your worker loves new challenges... if (Humans.HasTrait(worker, Trait.NewChallenges)) { desireToLeaveCompany += 10; } if (desireToLeaveCompany > 0) { bonus.AppendAndHideIfZero("Wants to leave company", desireToLeaveCompany); } else { bonus.AppendAndHideIfZero("Wants to stay in company", desireToLeaveCompany); } bonus.Append("Loyalty to company", -loyaltyBonus); } else { // prolongation of contract bonus.Append("Loyalty to company", loyaltyBonus); } long newSalary = newOffer.JobOffer.Salary; long salary; salary = (long)Mathf.Max(Humans.GetCurrentOffer(worker).JobOffer.Salary, 1); float salaryRatio; salaryRatio = (newSalary - salary) * 1f / salary; salaryRatio = Mathf.Clamp(salaryRatio, -5, 5); bonus.Append("Salary", salaryRatio); return(bonus); }