mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
commit
12f8357373
@ -1,5 +1,12 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 03/27/2014 ==
|
||||
Kayen: SE_Gate will now use have a fail chance as defined by its base value in the spell data.
|
||||
Kayen: SE_Succor will now have a baseline fail chance of (2%). Rule added to adjust this as needed.
|
||||
Kayen: SE_FeignDeath will now have a fail chance as defined by its base value in the spell data.
|
||||
|
||||
Optional SQL: utils/sql/git/optional/2014_03_27_SuccorFailRule.sql
|
||||
|
||||
== 03/22/2014 ==
|
||||
Uleat: Moved the existing 'load_bots' and 'drop_bots' sqls into the emu git repository for the time being. Look to the
|
||||
/utils/sql/git/bots/ folder to find them. The 'load_bots' sql has been updated to include the below fix, as well as
|
||||
|
||||
@ -302,6 +302,7 @@ RULE_BOOL ( Spells, UseCHAScribeHack, false) //ScribeSpells and TrainDiscs quest
|
||||
RULE_BOOL ( Spells, BuffLevelRestrictions, true) //Buffs will not land on low level toons like live
|
||||
RULE_INT ( Spells, RootBreakCheckChance, 70) //Determines chance for a root break check to occur each buff tick.
|
||||
RULE_INT ( Spells, FearBreakCheckChance, 70) //Determines chance for a fear break check to occur each buff tick.
|
||||
RULE_INT ( Spells, SuccorFailChance, 2) //Determines chance for a succor spell not to teleport an invidual player
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY( Combat )
|
||||
|
||||
@ -159,8 +159,8 @@ typedef enum {
|
||||
#define SE_WIS 9 // implemented
|
||||
#define SE_CHA 10 // implemented - used as a spacer
|
||||
#define SE_AttackSpeed 11 // implemented
|
||||
#define SE_Invisibility 12 // implemented
|
||||
#define SE_SeeInvis 13 // implemented
|
||||
#define SE_Invisibility 12 // implemented - TO DO: Implemented Invisiblity Levels
|
||||
#define SE_SeeInvis 13 // implemented - TO DO: Implemented See Invisiblity Levels
|
||||
#define SE_WaterBreathing 14 // implemented
|
||||
#define SE_CurrentMana 15 // implemented
|
||||
//#define SE_NPCFrenzy 16 // not used
|
||||
@ -172,7 +172,7 @@ typedef enum {
|
||||
#define SE_Charm 22 // implemented
|
||||
#define SE_Fear 23 // implemented
|
||||
#define SE_Stamina 24 // implemented - Invigor and such
|
||||
#define SE_BindAffinity 25 // implemented
|
||||
#define SE_BindAffinity 25 // implemented - TO DO: Implement 2nd and 3rd Recall (value 2,3 ect). Sets additional bind points.
|
||||
#define SE_Gate 26 // implemented - Gate to bind point
|
||||
#define SE_CancelMagic 27 // implemented
|
||||
#define SE_InvisVsUndead 28 // implemented
|
||||
@ -211,7 +211,7 @@ typedef enum {
|
||||
#define SE_Identify 61 // implemented
|
||||
//#define SE_ItemID 62 // not used
|
||||
#define SE_WipeHateList 63 // implemented
|
||||
#define SE_SpinTarget 64 // implemented
|
||||
#define SE_SpinTarget 64 // implemented - TO DO: Not sure stun portion is working correctly
|
||||
#define SE_InfraVision 65 // implemented
|
||||
#define SE_UltraVision 66 // implemented
|
||||
#define SE_EyeOfZomm 67 // implemented
|
||||
@ -241,7 +241,7 @@ typedef enum {
|
||||
#define SE_SummonCorpse 91 // implemented
|
||||
#define SE_InstantHate 92 // implemented - add hate
|
||||
#define SE_StopRain 93 // implemented - Wake of Karana
|
||||
#define SE_NegateIfCombat 94 // *not implemented? - Works client side but there is comment todo in spell effects...Component of Spirit of Scale
|
||||
#define SE_NegateIfCombat 94 // implemented
|
||||
#define SE_Sacrifice 95 // implemented
|
||||
#define SE_Silence 96 // implemented
|
||||
#define SE_ManaPool 97 // implemented
|
||||
@ -456,7 +456,7 @@ typedef enum {
|
||||
//#define SE_ArmyOfTheDead 306 // *not implemented NecroAA - This ability calls up to five shades of nearby corpses back to life to serve the necromancer. The soulless abominations will mindlessly fight the target until called back to the afterlife some time later. The first rank summons up to three shades that serve for 60 seconds, and each additional rank adds one more possible shade and increases their duration by 15 seconds
|
||||
//#define SE_Appraisal 307 // *not implemented Rogue AA - This ability allows you to estimate the selling price of an item you are holding on your cursor.
|
||||
#define SE_SuspendMinion 308 // not implemented as bonus
|
||||
#define SE_YetAnotherGate 309 // implemented
|
||||
#define SE_GateCastersBindpoint 309 // implemented - Gate to casters bind point
|
||||
#define SE_ReduceReuseTimer 310 // implemented
|
||||
#define SE_LimitCombatSkills 311 // implemented - Excludes focus from procs (except if proc is a memorizable spell)
|
||||
//#define SE_Sanctuary 312 // *not implemented
|
||||
|
||||
1
utils/sql/git/optional/2014_03_27_SuccorFailRule.sql
Normal file
1
utils/sql/git/optional/2014_03_27_SuccorFailRule.sql
Normal file
@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:SuccorFailChance', '2', 'Determines chance for a succor spell not to teleport an invidual player.');
|
||||
@ -80,6 +80,7 @@
|
||||
#define CANNOT_AFFECT_NPC 251 //That spell can not affect this target NPC.
|
||||
#define SUSPEND_MINION_HAS_AGGRO 256 //Your pet is the focus of something's attention.
|
||||
#define NO_PET 255 //You do not have a pet.
|
||||
#define GATE_FAIL 260 //Your gate is too unstable, and collapses.
|
||||
#define CORPSE_CANT_SENSE 262 //You cannot sense any corpses for this PC in this zone.
|
||||
#define SPELL_NO_HOLD 263 //Your spell did not take hold.
|
||||
#define CANNOT_CHARM 267 //This NPC cannot be charmed.
|
||||
@ -208,6 +209,7 @@
|
||||
#define AA_POINTS 1215 //points
|
||||
#define SPELL_FIZZLE_OTHER 1218 //%1's spell fizzles!
|
||||
#define MISSED_NOTE_OTHER 1219 //A missed note brings %1's song to a close!
|
||||
#define SPELL_LEVEL_REQ 1226 //This spell only works on people who are level %1 and under.
|
||||
#define CORPSE_DECAY_NOW 1227 //This corpse is waiting to expire.
|
||||
#define SURNAME_REJECTED 1374 //Your new surname was rejected. Please try a different name.
|
||||
#define DUEL_DECLINE 1383 //%1 has declined your challenge to duel to the death.
|
||||
@ -253,6 +255,7 @@
|
||||
#define GAIN_RAIDEXP 5085 //You gained raid experience!
|
||||
#define DUNGEON_SEALED 5141 //The gateway to the dungeon is sealed off to you. Perhaps you would be able to enter if you needed to adventure there.
|
||||
#define ADVENTURE_COMPLETE 5147 //You received %1 points for successfully completing the adventure.
|
||||
#define SUCCOR_FAIL 5169 //The portal collapes before you can escape!
|
||||
#define PET_ATTACKING 5501 //%1 tells you, 'Attacking %2 Master.'
|
||||
#define FATAL_BOW_SHOT 5745 //%1 performs a FATAL BOW SHOT!!
|
||||
#define MELEE_SILENCE 5806 //You *CANNOT* use this melee ability, you are suffering from amnesia!
|
||||
|
||||
@ -1371,6 +1371,9 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
invisible_animals = false;
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(hidden || improved_hidden){
|
||||
hidden = false;
|
||||
improved_hidden = false;
|
||||
@ -1983,6 +1986,9 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
invisible_animals = false;
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(hidden || improved_hidden)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||
|
||||
@ -1358,16 +1358,27 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
case SE_AttackSpeed2:
|
||||
{
|
||||
if ((effect_value - 100) > 0) { // Haste V2 - Stacks with V1 but does not Overcap
|
||||
if (newbon->hastetype2 < 0) break; //Slowed - Don't apply haste2
|
||||
if ((effect_value - 100) > newbon->hastetype2) {
|
||||
newbon->hastetype2 = effect_value - 100;
|
||||
}
|
||||
}
|
||||
else if ((effect_value - 100) < 0) { // Slow
|
||||
int real_slow_value = (100 - effect_value) * -1;
|
||||
if (real_slow_value < newbon->hastetype2)
|
||||
newbon->hastetype2 = real_slow_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_AttackSpeed3:
|
||||
{
|
||||
if (effect_value > 0) { // Haste V3 - Stacks and Overcaps
|
||||
if (effect_value < 0){ //Slow
|
||||
if (effect_value < newbon->hastetype3)
|
||||
newbon->hastetype3 = effect_value;
|
||||
}
|
||||
|
||||
else if (effect_value > 0) { // Haste V3 - Stacks and Overcaps
|
||||
if (effect_value > newbon->hastetype3) {
|
||||
newbon->hastetype3 = effect_value;
|
||||
}
|
||||
@ -1377,18 +1388,24 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
|
||||
case SE_AttackSpeed4:
|
||||
{
|
||||
if (effect_value > 0) {
|
||||
if (effect_value < 0) //A few spells use negative values(Descriptions all indicate it should be a slow)
|
||||
effect_value = effect_value * -1;
|
||||
|
||||
if (effect_value > 0 && effect_value > newbon->inhibitmelee) {
|
||||
|
||||
if (slow_mitigation){
|
||||
int new_effect_value = SlowMitigation(false,caster,effect_value);
|
||||
if (new_effect_value > newbon->inhibitmelee) {
|
||||
newbon->inhibitmelee = new_effect_value;
|
||||
SlowMitigation(true,caster);
|
||||
newbon->inhibitmelee = new_effect_value;
|
||||
SlowMitigation(true,caster);
|
||||
}
|
||||
}
|
||||
|
||||
else if (effect_value > newbon->inhibitmelee) {
|
||||
newbon->inhibitmelee = effect_value;
|
||||
newbon->inhibitmelee = effect_value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2568,6 +2585,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
newbon->AbsorbMagicAtt[1] = buffslot;
|
||||
}
|
||||
break;
|
||||
|
||||
case SE_NegateIfCombat:
|
||||
newbon->NegateIfCombat = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3237,6 +3237,9 @@ void Bot::BotRangedAttack(Mob* other) {
|
||||
invisible_animals = false;
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(hidden || improved_hidden){
|
||||
hidden = false;
|
||||
improved_hidden = false;
|
||||
@ -6640,6 +6643,9 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(GetTarget())
|
||||
TriggerDefensiveProcs(weapon, other, Hand, damage);
|
||||
|
||||
|
||||
@ -344,6 +344,7 @@ struct StatBonuses {
|
||||
int16 FrenziedDevastation; // base1= AArank(used) base2= chance increase spell criticals + all DD spells 2x mana.
|
||||
uint16 AbsorbMagicAtt[2]; // 0 = magic rune value 1 = buff slot
|
||||
uint16 MeleeRune[2]; // 0 = rune value 1 = buff slot
|
||||
bool NegateIfCombat; // Bool Drop buff if cast or melee
|
||||
|
||||
// AAs
|
||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||
|
||||
@ -839,6 +839,9 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
||||
invisible_animals = false;
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(hidden || improved_hidden){
|
||||
hidden = false;
|
||||
improved_hidden = false;
|
||||
@ -1085,6 +1088,9 @@ void NPC::RangedAttack(Mob* other)
|
||||
invisible_animals = false;
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(hidden || improved_hidden){
|
||||
hidden = false;
|
||||
improved_hidden = false;
|
||||
@ -1227,6 +1233,9 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
invisible_animals = false;
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(hidden || improved_hidden){
|
||||
hidden = false;
|
||||
improved_hidden = false;
|
||||
|
||||
@ -396,10 +396,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
}
|
||||
|
||||
case SE_Succor:
|
||||
{
|
||||
{
|
||||
|
||||
float x, y, z, heading;
|
||||
const char *target_zone;
|
||||
|
||||
|
||||
x = spell.base[1];
|
||||
y = spell.base[0];
|
||||
z = spell.base[2];
|
||||
@ -426,6 +427,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
|
||||
if(IsClient())
|
||||
{
|
||||
if(MakeRandomInt(0, 99) < RuleI(Spells, SuccorFailChance)) { //2% Fail chance by default
|
||||
|
||||
if(IsClient()) {
|
||||
CastToClient()->Message_StringID(MT_SpellFailure,SUCCOR_FAIL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Below are the spellid's for known evac/succor spells that send player
|
||||
// to the current zone's safe points.
|
||||
|
||||
@ -441,10 +450,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell In Same Zone.");
|
||||
#endif
|
||||
if(IsClient())
|
||||
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
|
||||
else
|
||||
GMMove(x, y, z, heading);
|
||||
if(IsClient())
|
||||
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
|
||||
else
|
||||
GMMove(x, y, z, heading);
|
||||
}
|
||||
else {
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
@ -457,7 +466,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
|
||||
break;
|
||||
}
|
||||
case SE_YetAnotherGate: //Shin: Used on Teleport Bind.
|
||||
case SE_GateCastersBindpoint: //Shin: Used on Teleport Bind.
|
||||
case SE_Teleport: // gates, rings, circles, etc
|
||||
case SE_Teleport2:
|
||||
{
|
||||
@ -489,7 +498,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
}
|
||||
}
|
||||
|
||||
if (effect == SE_YetAnotherGate && caster->IsClient())
|
||||
if (effect == SE_GateCastersBindpoint && caster->IsClient())
|
||||
{ //Shin: Teleport Bind uses caster's bind point
|
||||
x = caster->CastToClient()->GetBindX();
|
||||
y = caster->CastToClient()->GetBindY();
|
||||
@ -857,7 +866,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_BindAffinity:
|
||||
case SE_BindAffinity: //TO DO: Add support for secondary and tertiary gate abilities
|
||||
{
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Bind Affinity");
|
||||
@ -989,13 +998,18 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Gate:
|
||||
case SE_Gate: //TO DO: Add support for secondary and tertiary gate abilities (base2)
|
||||
{
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Gate");
|
||||
#endif
|
||||
if(!spellbonuses.AntiGate)
|
||||
Gate();
|
||||
if(!spellbonuses.AntiGate){
|
||||
|
||||
if(MakeRandomInt(0, 99) < effect_value)
|
||||
Gate();
|
||||
else
|
||||
caster->Message_StringID(MT_SpellFailure,GATE_FAIL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1378,7 +1392,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
(
|
||||
spell.base[i],
|
||||
Mob::GetDefaultGender(spell.base[i], GetGender()),
|
||||
spell.base2[i]
|
||||
spell.base2[i],
|
||||
spell.max[i]
|
||||
);
|
||||
if(spell.base[i] == OGRE){
|
||||
SendAppearancePacket(AT_Size, 9);
|
||||
@ -1554,8 +1569,15 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
if(spell_id == 2488) //Dook- Lifeburn fix
|
||||
break;
|
||||
|
||||
if(IsClient())
|
||||
CastToClient()->SetFeigned(true);
|
||||
if(IsClient()) {
|
||||
|
||||
if (MakeRandomInt(0, 99) > spells[spell_id].base[i]) {
|
||||
CastToClient()->SetFeigned(false);
|
||||
entity_list.MessageClose_StringID(this, false, 200, 10, STRING_FEIGNFAILED, GetName());
|
||||
}
|
||||
else
|
||||
CastToClient()->SetFeigned(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1691,19 +1713,25 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
|
||||
// Now we should either be casting this on self or its being cast on a valid group member
|
||||
if(TargetClient) {
|
||||
Corpse *corpse = entity_list.GetCorpseByOwner(TargetClient);
|
||||
if(corpse) {
|
||||
if(TargetClient == this->CastToClient())
|
||||
Message_StringID(4, SUMMONING_CORPSE, TargetClient->CastToMob()->GetCleanName());
|
||||
else
|
||||
Message_StringID(4, SUMMONING_CORPSE_OTHER, TargetClient->CastToMob()->GetCleanName());
|
||||
|
||||
corpse->Summon(CastToClient(), true, true);
|
||||
}
|
||||
else {
|
||||
// No corpse found in the zone
|
||||
Message_StringID(4, CORPSE_CANT_SENSE);
|
||||
if (TargetClient->GetLevel() <= effect_value){
|
||||
|
||||
Corpse *corpse = entity_list.GetCorpseByOwner(TargetClient);
|
||||
if(corpse) {
|
||||
if(TargetClient == this->CastToClient())
|
||||
Message_StringID(4, SUMMONING_CORPSE, TargetClient->CastToMob()->GetCleanName());
|
||||
else
|
||||
Message_StringID(4, SUMMONING_CORPSE_OTHER, TargetClient->CastToMob()->GetCleanName());
|
||||
|
||||
corpse->Summon(CastToClient(), true, true);
|
||||
}
|
||||
else {
|
||||
// No corpse found in the zone
|
||||
Message_StringID(4, CORPSE_CANT_SENSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
caster->Message_StringID(MT_SpellFailure, SPELL_LEVEL_REQ);
|
||||
}
|
||||
else {
|
||||
Message_StringID(4, TARGET_NOT_FOUND);
|
||||
|
||||
@ -211,6 +211,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (spellbonuses.NegateIfCombat)
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
|
||||
if(IsClient() && GetTarget() && IsHarmonySpell(spell_id))
|
||||
{
|
||||
for(int i = 0; i < EFFECT_COUNT; i++) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user