#131
|
|||
|
TRIPLE MADZ POST#!#
ZMFG. | ||
|
#132
|
||||
|
Quote:
Got it. | |||
|
#133
|
||||
|
Quote:
Fix your defense though. Fight a light blue or higher pet in an arena. | |||
|
#134
|
||||
|
Quote:
| |||
|
#135
|
|||
|
They posted today that NPC bash rate is 100%, will be fixed.
| ||
|
#136
|
|||
|
Can we please get this server rolling soon lol. Been longing for this for years
__________________
Laven Crackbringer | Level 56 High Elf Enchanter of Tunare |Blue|
Tyrenell Stormrage | Level 58 Human Druid of Tunare |Blue| Nazaruul | Level 55 Dark Elf Necromancer of Innoruuk |Green| | ||
|
#137
|
||||
|
Quote:
Here's the formula. It matches logs Torven has (and actually, Torven was the one who wrote this formula) Code:
// this is precise for the vast majority of NPCs // at some point around level 61, base stun chance goes from 45 to 40. not sure why int stun_chance = 45; int defenderLevel = defender->GetLevel(); int levelDiff = GetLevel() - defenderLevel; if (GetLevel() > 60) stun_chance = 40; if (levelDiff < 0) { stun_chance -= levelDiff * levelDiff / 2; } else { stun_chance += levelDiff * levelDiff / 2; } if (stun_chance < 2) stun_chance = 2; if (defender->IsNPC() && defenderLevel > RuleI(Spells, BaseImmunityLevel)) stun_chance = 0; if (stun_chance && zone->random.Roll(stun_chance)) { Log(Logs::Detail, Logs::Combat, "Stun passed, checking resists. Was %d chance.", stun_chance); int stun_resist = 0; if (defender->IsClient()) { stun_resist = defender->aabonuses.StunResist; // Stalwart Endurance AA } if (defender->GetBaseRace() == OGRE && !BehindMob(defender, GetX(), GetY())) // should this work if the ogre is illusioned? { Log(Logs::Detail, Logs::Combat, "Frontal stun resisted because, Ogre."); } else { if (stun_resist && zone->random.Roll(stun_resist)) { defender->Message_StringID(MT_DefaultText, AVOID_STUN); Log(Logs::Detail, Logs::Combat, "Stun Resisted. %d chance.", stun_resist); } else { Log(Logs::Detail, Logs::Combat, "Stunned. %d resist chance.", stun_resist); defender->Stun(2000, this); // bash/kick stun is always 2 seconds } } } else { Log(Logs::Detail, Logs::Combat, "Stun failed. %d chance.", stun_chance); // This is a crude approximation of interrupt chance based on old EQ log parses int interruptChance = 100; if (IsNPC() && !IsPet()) { if (GetLevel() < defenderLevel) interruptChance = 80; // Daybreak recently confirmed this 80% chance } else if (defender->IsNPC()) { int levelDiff = GetLevel() - defenderLevel; interruptChance += levelDiff * 10; if (defenderLevel > 65 && interruptChance > 0) interruptChance = 2; else if (defenderLevel > 55) interruptChance /= 2; else if (defenderLevel > 50) interruptChance = 3 * interruptChance / 4; } Log(Logs::Detail, Logs::Combat, "Non-stunning bash/kick interrupt roll: chance = %i", interruptChance); if (zone->random.Roll(interruptChance)) { if (IsValidSpell(defender->casting_spell_id) && !spells[defender->casting_spell_id].uninterruptable) { Log(Logs::Detail, Logs::Combat, "Non-stunning bash/kick successfully interrupted spell"); defender->InterruptSpell(SPELL_UNKNOWN, true); } } } Code:
// 3 second flee stun check. NPCs can stun players who are running away from them. 10% chance on hit if (spell_id == SPELL_UNKNOWN && damage > 0 && other && other->IsNPC() && !other->IsPet() && other->GetLevel() > 4 && EQ::skills::IsMeleeWeaponSkill(attack_skill)) { if (animation > 0 && zone->random.Roll(10) && other->BehindMob(this, other->GetX(), other->GetY())) { int stun_resist = aabonuses.StunResist; if (!stun_resist || zone->random.Roll(100 - stun_resist)) { if (CombatRange(other, 0.0f, false, true)) { Log(Logs::Detail, Logs::Combat, "3 second flee stun sucessful"); Stun(3000, other); } } else { Log(Logs::Detail, Logs::Combat, "Stun Resisted. %d chance.", stun_resist); Message_StringID(MT_DefaultText, AVOID_STUN); } } }
__________________
Engineer of Things and Stuff, Wearer of Many Hats
“Knowing yourself is the beginning of all wisdom.” — Aristotle | |||
|
#138
|
||||
|
Quote:
Code:
else if (!spells[spell_id].uninterruptable) // not bard, check movement { // special case - this item can be cast while moving, by any player, not just bards if ((IsClient() && ((slot == CastingSlot::Item)) && inventory_slot != 0xFFFFFFFF) && CastToClient()->GetItemIDAt(inventory_slot) == 28906 /* Bracelet of the Shadow Hive */) { Log(Logs::Detail, Logs::Spells, "Casting from clicky item %s. Allowing cast while moving.", CastToClient()->GetInv()[inventory_slot]->GetItem()->Name); } // if has been attacked, or moved while casting, try to channel else if (attacked_count > 0 || GetX() != GetSpellX() || GetY() != GetSpellY()) { uint16 channel_chance = 0; if (IsClient()) { // this is fairly accurate (but not perfect) and based on decompiles // client is holding down forward movement key or no skill if (animation > 0 || GetSkill(EQ::skills::SkillChanneling) == 0) { InterruptSpell(); return; } float distance_moved, d_x, d_y; if (GetX() != GetSpellX() || GetY() != GetSpellY()) { d_x = std::abs(std::abs(GetX()) - std::abs(GetSpellX())); d_y = std::abs(std::abs(GetY()) - std::abs(GetSpellY())); if (d_x > 1.00001f || d_y > 1.00001f) { InterruptSpell(); return; } } if (attacked_count == 0) attacked_count = 1; uint16 bonus_chance = 0; uint16 spell_level = spells[spell_id].classes[GetClass() - 1]; uint16 roll = 0; uint16 loops = 0; do { roll = zone->random.Int(1, 390); if (!IsFromItem && aabonuses.ChannelChanceSpells) { roll = (100 - aabonuses.ChannelChanceSpells) * roll / 100; } if (GetLevel() > (spell_level + 5)) bonus_chance = 3 * (GetLevel() - spell_level) + 35; channel_chance = GetSkill(EQ::skills::SkillChanneling) + GetLevel() + bonus_chance; if (channel_chance > 370) channel_chance = 370; Log(Logs::Detail, Logs::Spells, "Checking Interruption: spell x: %f spell y: %f cur x: %f cur y: %f channelchance %f channeling skill %d\n", GetSpellX(), GetSpellY(), GetX(), GetY(), channel_chance, GetSkill(EQ::skills::SkillChanneling)); if (roll > channel_chance && roll >= 39) { Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: interrupted.", spell_id); InterruptSpell(SPELL_UNKNOWN, true); return; } loops++; } while (loops < attacked_count); regain_conc = true; } else { // NPCs don't use channeling skill (says Rashere circa 2006) or fail spells from push // this is an extremely crude approximation but based on AK log greps of a handful of NPCs // hit NPCs typically don't even regain concentration and just finish casts int roll = 30; if (GetLevel() > 70) roll = 10; else if (GetLevel() > 30) roll = 20; // this spell id range is hardcoded to not be interruptable. // this was determined from a client decompile. credit: Mackal if (IsNPC() && spell_id >= 859 && spell_id <= 1023) roll = 0; if (zone->random.Roll(roll)) { // caster NPCs have an extremely high regains rate; almost 100% at high levels roll = zone->random.Int(1, 390); // AK logs show some warrior NPCs (e.g. Tallon Zek) not regaining concentration; maybe NPCs used channeling skill in 2002 but not 2006? shrug if (GetClass() == WARRIOR || GetClass() == ROGUE || GetClass() == MONK) roll = 0; if (roll > ((GetLevel() < 51 ? 325 : 225) - GetLevel() * 3)) // not how Sony did it; replace this if you find data/evidence/leaks regain_conc = true; else { Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: interrupted.", spell_id); InterruptSpell(SPELL_UNKNOWN, true); return; } } } if (regain_conc) { Message_StringID(CC_User_Spells, REGAIN_AND_CONTINUE); uint16 textcolor = IsNPC() ? CC_User_Default : CC_User_Spells; entity_list.MessageClose_StringID(this, true, 200, textcolor, OTHER_REGAIN_CAST, this->GetCleanName()); } } // mob was hit or moved from start of cast loc } // class != bard You should see the amount of stuff Torven had to go through to make sure this information was all correct. This is mostly a case of EQ actually being this hard in classic, but people wanting it to feel a specific way. P99 is full of inaccuracies that basically give you the feel of classic, though arguably their content / zone populations are much better at least for classic. (for now.)
__________________
Engineer of Things and Stuff, Wearer of Many Hats
“Knowing yourself is the beginning of all wisdom.” — Aristotle | |||
|
#140
|
|||
|
He has the defense skill of a level 2 at level 16. Of course he's not going to tank well.
Defense being hard to raise if you neglect it is a very, very well known phenomenon and is entirely accurate. Our skill-up difficulty values are pulled from the client. If you don't keep up with raising the skill then it becomes very hard to raise because it can only raise on a successful miss. If the skill is near zero then mobs will almost never miss you if your skill is super low and you keep leveling. The math on avoidance is precise. In fact I always tell new players that they absolutely need to tank level 1 mobs to max defensive skill once they hit level 4 otherwise they'll outpace their skill and won't be able to raise it without arena visits. On severs with experience bonuses you'll notice this more because you out-level your skillup rate. Quarm has the 20% bonus on at least. Incidentally the cast time on the level 16 nuke is 2.5 seconds and NPC attack delays at low levels is 3 seconds. | ||
|
|
|