From b65d3c85b668f85370a3db625b8a6a852ecc5f6e Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Sat, 2 Aug 2014 10:42:11 -0400 Subject: [PATCH] Implemented support for spells_new fields InCombat, OutofCombat Required SQL to rename and add new fields to spells_new table. --- changelog.txt | 9 +++++++++ common/shareddb.cpp | 12 ++++++++++-- common/spdat.h | 27 ++++++++++++++++---------- zone/StringIDs.h | 4 ++++ zone/spells.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 12 deletions(-) diff --git a/changelog.txt b/changelog.txt index 464669fd5..2847b92e6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,14 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 08/02/2014 == +Kayen: Implemented spell_news fields +- npc_no_los (check if LOS is required for spells) +- InCombat, OutofCombat - Used together to restrict spells to only be cast while +in/out of combat (beneficial) or if target is in/out of combat (detrimental). +Many new fields added and defined for future development. + +Required SQL: utils/sql/git/required/2014_08_02_spells_new.sql + == 07/31/2014 == Uleat: More inventory slot constant conversions. This should be the bulk of everything..but, due to the size of the server code, there may be some hidden ones. (client_packet.cpp and the client translators still need a thorough review.) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index b93b57710..585576f17 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1726,6 +1726,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].EndurCost=atoi(row[166]); sp[tempid].EndurTimerIndex=atoi(row[167]); + sp[tempid].IsDisciplineBuff = atoi(row[168]) != 0; sp[tempid].HateAdded=atoi(row[173]); sp[tempid].EndurUpkeep=atoi(row[174]); sp[tempid].numhitstype = atoi(row[175]); @@ -1745,15 +1746,22 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].directional_end = (float)atoi(row[195]); sp[tempid].not_extendable = atoi(row[197]) != 0; sp[tempid].suspendable = atoi(row[200]) != 0; + sp[tempid].viral_range = atoi(row[201]); sp[tempid].spellgroup=atoi(row[207]); + sp[tempid].rank = atoi(row[208]); sp[tempid].powerful_flag=atoi(row[209]); sp[tempid].CastRestriction = atoi(row[211]); sp[tempid].AllowRest = atoi(row[212]) != 0; - sp[tempid].NotOutofCombat = atoi(row[213]) != 0; - sp[tempid].NotInCombat = atoi(row[214]) != 0; + sp[tempid].InCombat = atoi(row[213]) != 0; + sp[tempid].OutofCombat = atoi(row[214]) != 0; sp[tempid].aemaxtargets = atoi(row[218]); sp[tempid].maxtargets = atoi(row[219]); sp[tempid].persistdeath = atoi(row[224]) != 0; + sp[tempid].min_dist = atof(row[227]); + sp[tempid].min_dist_mod = atof(row[228]); + sp[tempid].max_dist = atof(row[229]); + sp[tempid].max_dist_mod = atof(row[230]); + sp[tempid].min_range = atoi(row[231]); sp[tempid].DamageShieldType = 0; } mysql_free_result(result); diff --git a/common/spdat.h b/common/spdat.h index 927550fc6..510817121 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -697,8 +697,8 @@ struct SPDat_Spell_Struct /* 164 */ // for most spells this appears to mimic ResistDiff /* 166 */ int EndurCost; /* 167 */ int8 EndurTimerIndex; -/* 168 */ //int IsDisciplineBuff; //Will goto the combat window when cast -/* 169 */ +/* 168 */ bool IsDisciplineBuff; //Will goto the combat window when cast +/* 169 - 172*/ //These are zero for ALL spells /* 173 */ int HateAdded; /* 174 */ int EndurUpkeep; /* 175 */ int numhitstype; // defines which type of behavior will tick down the numhit counter. @@ -721,23 +721,30 @@ struct SPDat_Spell_Struct /* 197 */ bool not_extendable; /* 198- 199 */ /* 200 */ bool suspendable; // buff is suspended in suspended buff zones -/* 201 - 202 */ +/* 201 */ int viral_range; +/* 202 */ /* 203 */ //int songcap; // individual song cap (how live currently does it, not implemented) /* 204 - 206 */ /* 207 */ int spellgroup; -/* 208 */ // int rank - increments AA effects with same name +/* 208 */ int rank; //increments AA effects with same name /* 209 */ int powerful_flag; // Need more investigation to figure out what to call this, for now we know -1 makes charm spells not break before their duration is complete, it does alot more though /* 210 */ // bool DurationFrozen; ??? /* 211 */ int CastRestriction; //Various restriction categories for spells most seem targetable race related but have also seen others for instance only castable if target hp 20% or lower or only if target out of combat /* 212 */ bool AllowRest; -/* 213 */ bool NotOutofCombat; //Fail if cast out of combat -/* 214 */ bool NotInCombat; //Fail if cast in combat +/* 213 */ bool InCombat; //Allow spell if target is in combat +/* 214 */ bool OutofCombat; //Allow spell if target is out of combat /* 215 - 217 */ -/* 219 */ int aemaxtargets; // -/* 219 */ int maxtargets; // is used for beam and ring spells for target # limits (not implemented) -/* 220 - 223 */ +/* 218 */ int aemaxtargets; //Is used for various AE effects +/* 219 */ int maxtargets; //Is used for beam and ring spells for target # limits (not implemented) +/* 220 - 223 */ /* 224 */ bool persistdeath; // buff doesn't get stripped on death -/* 225 - 236 */ // Not in DB +/* 225 - 226 */ +/* 227 */ float min_dist; //spell power modified by distance from caster (Min Distance) +/* 228 */ float min_dist_mod; //spell power modified by distance from caster (Modifier at Min Distance) +/* 229 */ float max_dist; //spell power modified by distance from caster (Max Distance) +/* 230 */ float max_dist_mod; //spell power modified by distance from caster (Modifier at Max Distance) +/* 231 */ int min_range; //Min casting range +/* 232 - 236 */ uint8 DamageShieldType; // This field does not exist in spells_us.txt }; diff --git a/zone/StringIDs.h b/zone/StringIDs.h index 9a222d276..5e5d16bb2 100644 --- a/zone/StringIDs.h +++ b/zone/StringIDs.h @@ -316,6 +316,10 @@ #define PET_NOT_FOCUSING 9263 //No longer focusing on one target, Master. #define PET_NOT_CASTING 9264 //Not casting spells, Master. #define PET_CASTING 9291 //Casting spells normally, Master. +#define NO_CAST_IN_COMBAT 9190 //You can not cast this spell while in combat. +#define NO_CAST_OUT_OF_COMBAT 9191 //You can not cast this spell while out of combat. +#define NO_ABILITY_IN_COMBAT 9192 //You can not use this ability while in combat. +#define NO_ABILITY_OUT_OF_COMBAT 9194 //You can not use this ability while out of combat. #define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE! #define FACE_ACCEPTED 12028 //Facial features accepted. #define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2. diff --git a/zone/spells.cpp b/zone/spells.cpp index 305156b63..6757a7ba6 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1384,6 +1384,52 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce return false; } + //Must be out of combat. (If Beneficial checks casters combat state, Deterimental checks targets) + if (!spells[spell_id].InCombat && spells[spell_id].OutofCombat){ + if (IsDetrimentalSpell(spell_id)) { + if ( (spell_target->IsNPC() && spell_target->IsEngaged()) || + (spell_target->IsClient() && spell_target->CastToClient()->GetAggroCount())){ + Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string + return false; + } + } + + else if (IsBeneficialSpell(spell_id)) { + if ( (IsNPC() && IsEngaged()) || + (IsClient() && CastToClient()->GetAggroCount())){ + if (IsDiscipline(spell_id)) + Message_StringID(13,NO_ABILITY_IN_COMBAT); + else + Message_StringID(13,NO_CAST_IN_COMBAT); + + return false; + } + } + } + + //Must be in combat. (If Beneficial checks casters combat state, Deterimental checks targets) + else if (spells[spell_id].InCombat && !spells[spell_id].OutofCombat){ + if (IsDetrimentalSpell(spell_id)) { + if ( (spell_target->IsNPC() && !spell_target->IsEngaged()) || + (spell_target->IsClient() && !spell_target->CastToClient()->GetAggroCount())){ + Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string + return false; + } + } + + else if (IsBeneficialSpell(spell_id)) { + if ( (IsNPC() && !IsEngaged()) || + (IsClient() && !CastToClient()->GetAggroCount())){ + if (IsDiscipline(spell_id)) + Message_StringID(13,NO_ABILITY_OUT_OF_COMBAT); + else + Message_StringID(13,NO_CAST_OUT_OF_COMBAT); + + return false; + } + } + } + switch (targetType) { // single target spells