ace/Source/ACE.Server/Entity/Proficiency.cs
ziang4891 a9400f04f1
Olthoi play plus (#3668)
* adding the very basics for olthoi play

* Add more Olthoi Play restrictions

* Fix merge master conflicts

* Disable Allegiance and Fellowship for Olthoi players

* Add more of the restrictions

* More restrictions

* disable skill XP updates for Olthoi play

* Update comments and WeenieError used

* Disable normal treasure gen for Olthoi players

* Couple more adjustments

* opps

Co-authored-by: gmriggs <gmriggs@gmail.com>
2021-10-14 23:59:37 -04:00

123 lines
4.7 KiB
C#

using System;
using log4net;
using ACE.Common;
using ACE.Entity.Enum;
using ACE.Server.WorldObjects;
using ACE.Server.WorldObjects.Entity;
namespace ACE.Server.Entity
{
public class Proficiency
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static TimeSpan FullTime = TimeSpan.FromMinutes(15);
public static void OnSuccessUse(Player player, CreatureSkill skill, uint difficulty)
{
//Console.WriteLine($"Proficiency.OnSuccessUse({player.Name}, {skill.Skill}, targetDiff: {difficulty})");
// TODO: this formula still probably needs some work to match up with retail truly...
// possible todo: does this only apply to players?
// ie., can monsters still level up from skill usage, or killing players?
// it was possible on release, but i think they might have removed that feature?
if (player.IsOlthoiPlayer)
return;
// ensure skill is at least trained
if (skill.AdvancementClass < SkillAdvancementClass.Trained)
return;
var last_difficulty = skill.PropertiesSkill.ResistanceAtLastCheck;
var last_used_time = skill.PropertiesSkill.LastUsedTime;
var currentTime = Time.GetUnixTime();
var timeDiff = currentTime - last_used_time;
if (timeDiff < 0)
{
// can happen if server clock is rewound back in time
log.Warn($"Proficiency.OnSuccessUse({player.Name}, {skill.Skill}, {difficulty}) - timeDiff: {timeDiff}");
skill.PropertiesSkill.LastUsedTime = currentTime; // update to prevent log spam
return;
}
var difficulty_check = difficulty > last_difficulty;
var time_check = timeDiff >= FullTime.TotalSeconds;
if (difficulty_check || time_check)
{
// todo: not independent variables?
// always scale if timeDiff < FullTime?
var timeScale = 1.0f;
if (!time_check)
{
// 10 mins elapsed from 15 min FullTime:
// 0.66f timeScale
timeScale = (float)(timeDiff / FullTime.TotalSeconds);
// any rng involved?
}
skill.PropertiesSkill.ResistanceAtLastCheck = difficulty;
skill.PropertiesSkill.LastUsedTime = currentTime;
player.ChangesDetected = true;
if (player.IsMaxLevel) return;
var pp = (uint)Math.Round(difficulty * timeScale);
var totalXPGranted = (long)Math.Round(pp * 1.1f); // give additional 10% of proficiency XP to unassigned XP
if (totalXPGranted > 10000)
{
log.Warn($"Proficiency.OnSuccessUse({player.Name}, {skill.Skill}, {difficulty}) - totalXPGranted: {totalXPGranted:N0}");
}
var maxLevel = Player.GetMaxLevel();
var remainingXP = player.GetRemainingXP(maxLevel).Value;
if (totalXPGranted > remainingXP)
{
// checks and balances:
// total xp = pp * 1.1
// pp = total xp / 1.1
totalXPGranted = remainingXP;
pp = (uint)Math.Round(totalXPGranted / 1.1f);
}
// if skill is maxed out, but player is below MaxLevel,
// not sure if retail granted 0%, 10%, or 110% of the pp to TotalExperience here
// since pp is such a miniscule system at the higher levels,
// going to just naturally add it to TotalXP for now..
pp = Math.Min(pp, skill.ExperienceLeft);
//Console.WriteLine($"Earned {pp} PP ({skill.Skill})");
// send CP to player as unassigned XP
player.GrantXP(totalXPGranted, XpType.Proficiency, ShareType.None);
// send PP to player as skill XP, which gets spent from the CP sent
if (pp > 0)
{
player.HandleActionRaiseSkill(skill.Skill, pp);
}
}
}
public static void OnSuccessUse(Player player, CreatureSkill skill, int difficulty)
{
if (difficulty < 0)
{
log.Error($"Proficiency.OnSuccessUse({player.Name}, {skill.Skill}, {difficulty}) - difficulty cannot be negative");
return;
}
OnSuccessUse(player, skill, (uint)difficulty);
}
}
}