mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
commit
c84dc13d53
@ -110,6 +110,7 @@ SET(zone_sources
|
||||
trading.cpp
|
||||
trap.cpp
|
||||
tribute.cpp
|
||||
tune.cpp
|
||||
water_map.cpp
|
||||
water_map_v1.cpp
|
||||
water_map_v2.cpp
|
||||
|
||||
@ -1247,6 +1247,10 @@ public:
|
||||
|
||||
bool InterrogateInventory(Client* requester, bool log, bool silent, bool allowtrip, bool& error, bool autolog = true);
|
||||
|
||||
//Command #Tune functions
|
||||
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false);
|
||||
|
||||
protected:
|
||||
friend class Mob;
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
|
||||
212
zone/command.cpp
212
zone/command.cpp
@ -427,7 +427,8 @@ int command_init(void) {
|
||||
command_add("open_shop", nullptr, 100, command_merchantopenshop) ||
|
||||
command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) ||
|
||||
command_add("close_shop", nullptr, 100, command_merchantcloseshop) ||
|
||||
command_add("shownumhits", "Shows buffs numhits for yourself.", 0, command_shownumhits)
|
||||
command_add("shownumhits", "Shows buffs numhits for yourself.", 0, command_shownumhits) ||
|
||||
command_add("tune", "Calculate ideal statical values related to combat.", 100, command_tune)
|
||||
)
|
||||
{
|
||||
command_deinit();
|
||||
@ -10666,3 +10667,212 @@ void command_shownumhits(Client *c, const Seperator *sep)
|
||||
c->ShowNumHits();
|
||||
return;
|
||||
}
|
||||
|
||||
void command_tune(Client *c, const Seperator *sep)
|
||||
{
|
||||
//Work in progress - Kayen
|
||||
|
||||
if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) {
|
||||
c->Message(0, "Syntax: #tune [subcommand].");
|
||||
c->Message(0, "-- Tune System Commands --");
|
||||
c->Message(0, "-- Usage: Returning recommended combat statistical values based on a desired outcome.");
|
||||
c->Message(0, "-- Note: If targeted mob does not have a target (ie not engaged in combat), YOU will be considered the target.");
|
||||
c->Message(0, "-- Warning: The calculations done in this process are intense and can potentially cause zone crashes depending on parameters set, use with caution!");
|
||||
c->Message(0, "-- Below are OPTIONAL parameters.");
|
||||
c->Message(0, "-- Note: [interval] Determines how fast the stat being checked increases/decreases till it finds the best result. Default [ATK/AC 50][Acc/Avoid 10] ");
|
||||
c->Message(0, "-- Note: [loop_max] Determines how many iterations are done to increases/decreases the stat till it finds the best result. Default [ATK/AC 100][Acc/Avoid 1000]");
|
||||
c->Message(0, "-- Note: [Stat Override] Will override that stat on mob being checkd with the specified value. Default=0");
|
||||
c->Message(0, "-- Note: [Info Level] How much statistical detail is displayed[0 - 3]. Default=0 ");
|
||||
c->Message(0, "-- Note: Results are only approximations usually accurate to +/- 2 intervals.");
|
||||
|
||||
c->Message(0, "... ");
|
||||
c->Message(0, "...### Category A ### Target = ATTACKER ### YOU or Target's Target = DEFENDER ###");
|
||||
c->Message(0, "...### Category B ### Target = DEFENDER ### YOU or Target's Target = ATTACKER ###");
|
||||
c->Message(0, "... ");
|
||||
c->Message(0, "...#Returns recommended ATK adjustment +/- on ATTACKER that will result in an average mitigation pct on DEFENDER. ");
|
||||
c->Message(0, "...tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level]");
|
||||
c->Message(0, "... ");
|
||||
c->Message(0, "...#Returns recommended AC adjustment +/- on DEFENDER for an average mitigation pct from ATTACKER. ");
|
||||
c->Message(0, "...tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] ");
|
||||
c->Message(0, "... ");
|
||||
c->Message(0, "...#Returns recommended Accuracy adjustment +/- on ATTACKER that will result in a hit chance pct on DEFENDER. ");
|
||||
c->Message(0, "...tune FindAccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]");
|
||||
c->Message(0, "... ");
|
||||
c->Message(0, "...#Returns recommended Avoidance adjustment +/- on DEFENDER for in a hit chance pct from ATTACKER. ");
|
||||
c->Message(0, "...tune FindAvoidance [A/B] [pct mitigation] [interval][loop_max][Accuracy Overwride][Info Level] ");
|
||||
|
||||
return;
|
||||
}
|
||||
//Default is category A for attacker/defender settings, which then are swapped under category B.
|
||||
Mob* defender = c;
|
||||
Mob* attacker = c->GetTarget();
|
||||
|
||||
if (!attacker)
|
||||
{
|
||||
c->Message(0, "#Tune - Error no target selected. [#Tune help]");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* ttarget = attacker->GetTarget();
|
||||
|
||||
if (ttarget)
|
||||
defender = ttarget;
|
||||
|
||||
if(!strcasecmp(sep->arg[1], "FindATK"))
|
||||
{
|
||||
float pct_mitigation = atof(sep->arg[3]);
|
||||
int interval = atoi(sep->arg[4]);
|
||||
int max_loop = atoi(sep->arg[5]);
|
||||
int ac_override = atoi(sep->arg[6]);
|
||||
int info_level = atoi(sep->arg[7]);
|
||||
|
||||
if (!pct_mitigation)
|
||||
{
|
||||
c->Message(13, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!interval)
|
||||
interval = 50;
|
||||
if (!max_loop)
|
||||
max_loop = 100;
|
||||
if(!ac_override)
|
||||
ac_override = 0;
|
||||
if (!info_level)
|
||||
info_level = 1;
|
||||
|
||||
if(!strcasecmp(sep->arg[2], "A"))
|
||||
c->Tune_FindATKByPctMitigation(c, attacker, pct_mitigation, interval, max_loop,ac_override,info_level);
|
||||
else if(!strcasecmp(sep->arg[2], "B"))
|
||||
c->Tune_FindATKByPctMitigation(attacker,c, pct_mitigation, interval, max_loop,ac_override,info_level);
|
||||
else {
|
||||
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
|
||||
c->Message(0, "Usage #tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level] ");
|
||||
c->Message(0, "Example #tune FindATK A 60");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcasecmp(sep->arg[1], "FindAC"))
|
||||
{
|
||||
float pct_mitigation = atof(sep->arg[3]);
|
||||
int interval = atoi(sep->arg[4]);
|
||||
int max_loop = atoi(sep->arg[5]);
|
||||
int atk_override = atoi(sep->arg[6]);
|
||||
int info_level = atoi(sep->arg[7]);
|
||||
|
||||
if (!pct_mitigation)
|
||||
{
|
||||
c->Message(13, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!interval)
|
||||
interval = 50;
|
||||
if (!max_loop)
|
||||
max_loop = 100;
|
||||
if(!atk_override)
|
||||
atk_override = 0;
|
||||
if (!info_level)
|
||||
info_level = 1;
|
||||
|
||||
if(!strcasecmp(sep->arg[2], "A"))
|
||||
c->Tune_FindACByPctMitigation(c, attacker, pct_mitigation, interval, max_loop,atk_override,info_level);
|
||||
else if(!strcasecmp(sep->arg[2], "B"))
|
||||
c->Tune_FindACByPctMitigation(attacker, c, pct_mitigation, interval, max_loop,atk_override,info_level);
|
||||
else {
|
||||
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
|
||||
c->Message(0, "Usage #tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] ");
|
||||
c->Message(0, "Example #tune FindAC A 60");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcasecmp(sep->arg[1], "FindAccuracy"))
|
||||
{
|
||||
float hit_chance = atof(sep->arg[3]);
|
||||
int interval = atoi(sep->arg[4]);
|
||||
int max_loop = atoi(sep->arg[5]);
|
||||
int avoid_override = atoi(sep->arg[6]);
|
||||
int info_level = atoi(sep->arg[7]);
|
||||
|
||||
if (!hit_chance)
|
||||
{
|
||||
c->Message(10, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!interval)
|
||||
interval = 10;
|
||||
if (!max_loop)
|
||||
max_loop = 1000;
|
||||
if(!avoid_override)
|
||||
avoid_override = 0;
|
||||
if (!info_level)
|
||||
info_level = 1;
|
||||
|
||||
if (hit_chance > RuleR(Combat,MaxChancetoHit) || hit_chance < RuleR(Combat,MinChancetoHit))
|
||||
{
|
||||
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcasecmp(sep->arg[2], "A"))
|
||||
c->Tune_FindAccuaryByHitChance(c, attacker, hit_chance, interval, max_loop,avoid_override,info_level);
|
||||
else if(!strcasecmp(sep->arg[2], "B"))
|
||||
c->Tune_FindAccuaryByHitChance(attacker, c, hit_chance, interval, max_loop,avoid_override,info_level);
|
||||
else {
|
||||
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
|
||||
c->Message(0, "Usage #tune FindAcccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]");
|
||||
c->Message(0, "Exampled #tune FindAccuracy B 30");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcasecmp(sep->arg[1], "FindAvoidance"))
|
||||
{
|
||||
float hit_chance = atof(sep->arg[3]);
|
||||
int interval = atoi(sep->arg[4]);
|
||||
int max_loop = atoi(sep->arg[5]);
|
||||
int acc_override = atoi(sep->arg[6]);
|
||||
int info_level = atoi(sep->arg[7]);
|
||||
|
||||
if (!hit_chance)
|
||||
{
|
||||
c->Message(0, "#Tune - Error must enter the desired hit chance on defender. Ie. Defender to have hit chance of 40 pct.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!interval)
|
||||
interval = 10;
|
||||
if (!max_loop)
|
||||
max_loop = 1000;
|
||||
if(!acc_override)
|
||||
acc_override = 0;
|
||||
if (!info_level)
|
||||
info_level = 1;
|
||||
|
||||
if (hit_chance > RuleR(Combat,MaxChancetoHit) || hit_chance < RuleR(Combat,MinChancetoHit))
|
||||
{
|
||||
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcasecmp(sep->arg[2], "A"))
|
||||
c->Tune_FindAvoidanceByHitChance(c, attacker, hit_chance, interval, max_loop,acc_override, info_level);
|
||||
else if(!strcasecmp(sep->arg[2], "B"))
|
||||
c->Tune_FindAvoidanceByHitChance(attacker, c, hit_chance, interval, max_loop,acc_override, info_level);
|
||||
else {
|
||||
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
|
||||
c->Message(0, "Usage #tune FindAvoidance [A/B] [hit chance] [interval][loop_max][Accuracy Overwride][Info Level]");
|
||||
c->Message(0, "Exampled #tune FindAvoidance B 30");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -326,6 +326,7 @@ void command_npctype_cache(Client *c, const Seperator *sep);
|
||||
void command_merchantopenshop(Client *c, const Seperator *sep);
|
||||
void command_merchantcloseshop(Client *c, const Seperator *sep);
|
||||
void command_shownumhits(Client *c, const Seperator *sep);
|
||||
void command_tune(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef EQPROFILE
|
||||
void command_profiledump(Client *c, const Seperator *sep);
|
||||
|
||||
10
zone/mob.h
10
zone/mob.h
@ -930,6 +930,16 @@ public:
|
||||
void mod_spell_cast(uint16 spell_id, Mob* spelltar, bool reflect, bool use_resist_adjust, int16 resist_adjust, bool isproc);
|
||||
bool mod_will_aggro(Mob *attacker, Mob *on);
|
||||
|
||||
//Command #Tune functions
|
||||
int32 Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minhit, ExtraAttackOptions *opts = nullptr, int Msg =0, int ac_override=0, int atk_override=0, int add_ac=0, int add_atk = 0);
|
||||
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
uint32 Tune_GetMeanDamage(Mob* GM, Mob *attacker, int32 damage, int32 minhit, ExtraAttackOptions *opts = nullptr, int Msg = 0,int ac_override=0, int atk_override=0, int add_ac=0, int add_atk = 0);
|
||||
void Tune_FindATKByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int ac_override=0,int Msg =0);
|
||||
void Tune_FindACByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int atk_override=0,int Msg =0);
|
||||
float Tune_CheckHitChance(Mob* defender, Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod, int Msg = 1,int acc_override=0, int avoid_override=0, int add_acc=0, int add_avoid = 0);
|
||||
void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0);
|
||||
void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0);
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||
|
||||
1089
zone/tune.cpp
Normal file
1089
zone/tune.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user