Skill caps load with new smem scheme

This commit is contained in:
KimLS
2013-02-20 13:54:26 -08:00
parent 12bde7434a
commit 8eb7d0aaa8
54 changed files with 311 additions and 253 deletions
+1
View File
@@ -130,6 +130,7 @@ SET(common_headers
eqtime.h
errmsg.h
extprofile.h
features.h
fixed_memory_hash_set.h
guild_base.h
guilds.h
+1 -1
View File
@@ -19,7 +19,7 @@
#define COMMON_PROFILE_H
#ifdef ZONE
#include "../zone/features.h"
#include "../common/features.h"
#ifndef EQPROFILE
#ifdef COMMON_PROFILE
+308
View File
@@ -0,0 +1,308 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2004 EQEMu Development Team (http://eqemu.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FEATURES_H
#define FEATURES_H
/*
This file defines many optional features for the emu
as well as various parameters used by the emu.
If ambitious, most of these could prolly be turned into
database variables, but the really frequently run pieces
of code, should not be done that way for speed reasons IMO
*/
/*
Core Zone features
*/
//Uncomment this to cause a zone to basically idle
//when there are no players in it, mobs stop wandering, etc..
#define IDLE_WHEN_EMPTY
#ifdef EMBPERL
//Enable the new XS based perl parser
#define EMBPERL_XS
//enable classes in the new XS based parser
#define EMBPERL_XS_CLASSES
//enable IO capture and transmission to in game clients
//this seems to make perl very unhappy on reload, and crashes
#define EMBPERL_IO_CAPTURE
//enable perl-based in-game command, pretty useless without EMBPERL_XS_CLASSES
#define EMBPERL_COMMANDS
//enable #plugin and #peval, which requires IO::Stringy
//#define EMBPERL_EVAL_COMMANDS
#endif
/*
Map Configuration
In general, these computations are expensive, so if you have performance
problems, consider turning them off.
*/
//uncomment this to make the LOS code say all mobs can see all others
//when no map file is loaded, opposed to the default nobody-sees-anybody
#define LOS_DEFAULT_CAN_SEE
/*
Zone extensions and features
*/
//Uncomment this to scale XP gained from MOBs based on their CON
//#define CON_XP_SCALING
//Uncomment to make group buffs affect group pets
#define GROUP_BUFF_PETS
//Uncomment this line to enable named quest files:
#define QUEST_SCRIPTS_BYNAME
#ifdef QUEST_SCRIPTS_BYNAME
//extends byname system to look in a templates directory
//independant of zone name
#define QUEST_TEMPLATES_BYNAME
#define QUEST_TEMPLATES_DIRECTORY "templates"
#endif
//the min ratio at which a mob's speed is reduced
#define FLEE_HP_MINSPEED 22
//number of tics to try to run straight away before looking again
#define FLEE_RUN_DURATION 1000
//number of miliseconds between when a mob will check its flee state
//this is only checked when the mob is damaged.
#define FLEE_CHECK_TIMER 2000
//enable functionality to send log message to the client
//it still needs to be enabled with the #logs command
#define CLIENT_LOGS
//uncomment to print warnings about commands with 0 status...
//#define COMMANDS_WARNINGS
//uncomment to allow perl commands to override compiled commands
#define COMMANDS_PERL_OVERRIDE
//enable logging of commands used
#define COMMANDS_LOGGING
//only log commands which require this minimum status or more
#define COMMANDS_LOGGING_MIN_STATUS 1
//path to where sql logs should be placed
#define SQL_LOG_PATH "sql_logs/"
//New aggro system to reduce overhead.
#define REVERSE_AGGRO
//Enable spacial queue to manage NPC update packets
//#define PACKET_UPDATE_MANAGER
//#define MANAGE_HP_UPDATES
//The highest you can #setskill / #setallskill
#define HIGHEST_CAN_SET_SKILL 400
#define SKILL_MAX_LEVEL 75
//#define MIN_RANGED_ATK_RANGE 25
//replaced the above define with RuleI(Combat, MinRangedAttackDist)
/*
Zone Numerical configuration
*/
//Reuse times for various skills, here for convenience, in sec
//set to 0 to disable server side checking of timers.
enum { //reuse times
FeignDeathReuseTime = 9,
SneakReuseTime = 7,
HideReuseTime = 8,
TauntReuseTime = 5,
InstillDoubtReuseTime = 9,
FishingReuseTime = 11,
ForagingReuseTime = 50,
MendReuseTime = 290,
BashReuseTime = 5,
BackstabReuseTime = 9,
KickReuseTime = 5,
TailRakeReuseTime = 6,
EagleStrikeReuseTime = 5,
RoundKickReuseTime = 9,
TigerClawReuseTime = 6,
FlyingKickReuseTime = 7,
SenseTrapsReuseTime = 9,
DisarmTrapsReuseTime = 9,
HarmTouchReuseTime = 4300,
LayOnHandsReuseTime = 4300,
FrenzyReuseTime = 10
};
enum { //timer settings, all in milliseconds
AImovement_duration = 100,
AIthink_duration = 150,
AIscanarea_delay = 500,
AIfeignremember_delay = 500,
AItarget_check_duration = 500,
AIClientScanarea_delay = 750, //used in REVERSE_AGGRO
AIassistcheck_delay = 3000, //now often a fighting NPC will yell for help
ClientProximity_interval = 1000,
CombatEventTimer_expire = 12000,
Tribute_duration = 600000,
ZoneTimerResolution = 3, //sleep time between zone main loop runs (milliseconds)
FeignMemoryDuration = 120000, // EverHood - Duration player must feign death to clear zonewide agro.
EnragedTimer = 360000,
EnragedDurationTimer = 10000
};
enum { //some random constants
//each of these attack modifiers are added to the NPC's level to determine their
//probability of executing such an attack (which may or may not hit)
NPCDualAttackModifier = 20,
NPCTripleAttackModifier = 0,
NPCQuadAttackModifier = -20
};
//Max number of groups you can link with. Not tied to the client.
//if group linking is enabled above
#define MAX_GROUP_LINKS 8
//this is the number of levels above the thief's level that
//an npc can be and still let the theif PP them
#define THIEF_PICKPOCKET_OVER 5
//this is the % chance that an NPC will dual wield a 2nd weapon
//in its loot table, if it is able to.
//Aug 2007: was 5% chance.. changed to 100% by default since that seems more normal
//Kept it intact codewise incase someone wants to or is already using it.
#define NPC_DW_CHANCE 100
//This is the entry in npc_types to spawn for trap damagaes
#define TRAP_NPC_TYPE 1586
//This is the multiplier of eqemu speed to get client speed
//tweak this if pathing mobs seem to jump forward or backwards
//this should prolly be dynamic based on ping time or something.. who knows
//Values found in the emu somewhere at one point in time: 36, 43
#define NPC_RUNANIM_RATIO 37
//this is used to multiply an NPCs movement rate, yeilding map units..
#define NPC_SPEED_MULTIPLIER 46 //used to be 2.8... no idea why it changed
//minimum level to do alchemy
#define MIN_LEVEL_ALCHEMY 25
//chance ratio that a
#define THREATENLY_ARRGO_CHANCE 32 // 32/128 (25%) chance that a mob will arrgo on con Threatenly
// max factions per npc faction list
#define MAX_NPC_FACTIONS 20
//value caps
#define MAX_FACTION 1500
#define MIN_FACTION -1500
//The Level Cap:
//#define LEVEL_CAP RuleI(Character, MaxLevel) //hard cap is 127
#define HARD_LEVEL_CAP 127
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
#define USE_NPC_RANGE2 200*200 //arbitrary right now
//the formula for experience for killing a mob.
//level is the only valid variable to use
#define EXP_FORMULA level*level*75*35/10
#define HIGHEST_AA_VALUE 35
//Leadership AA experience points
#define GROUP_EXP_PER_POINT 1000
#define RAID_EXP_PER_POINT 2000
//Some hard coded statuses from commands and other places:
enum {
minStatusToBeGM = 40,
minStatusToUseGMCommands = 80,
minStatusToKick = 150,
minStatusToAvoidFalling = 100,
minStatusToHaveInvalidSpells = 80,
minStatusToHaveInvalidSkills = 80,
minStatusToIgnoreZoneFlags = 80,
minStatusToSeeOthersZoneFlags = 80,
minStatusToEditOtherGuilds = 80,
commandMovecharSelfOnly = 80, //below this == only self move allowed
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
commandZoneToSpecials = 80, //zone to cshome, out of load zones
commandToggleAI = 250, //can turn NPC AI on and off
commandCastSpecials = 100, //can cast special spells
commandInstacast = 100, //insta-cast all #casted spells
commandLevelAboveCap = 100, //can #level players above level cap
commandLevelNPCAboveCap = 100, //can #level NPCs above level cap
commandSetSkillsOther = 100, //ability to setskills on others
commandRaceOthers = 100, //ability to #race on others
commandGenderOthers = 100, //ability to #gender on others
commandTextureOthers = 100, //ability to #texture on others
commandDoAnimOthers = 100, //can #doanim on others
commandLockZones = 101, //can lock or unlock zones
commandEditPlayerCorpses = 150, //can Edit Player Corpses
commandChangeFlags = 200, //ability to set/refresh flags
commandBanPlayers = 100, //can set bans on players
commandChangeDatarate = 201, //edit client's data rate
commandZoneToCoords = 0 //can #zone with coords
};
//default states for logging flag on NPCs and clients (having NPCs on by default is prolly a bad idea)
#define CLIENT_DEFAULT_LOGGING_ENABLED true
#define NPC_DEFAULT_LOGGING_ENABLED false
/*
Developer configuration
*/
//#define EQPROFILE
#ifdef EQPROFILE
//Enable the zone profiler
#define ZONE_PROFILE
#define COMMON_PROFILE
#define PROFILE_DUMP_TIME 3*60
#endif //EQPROFILE
#endif
+2 -2
View File
@@ -50,7 +50,7 @@ namespace EQEmu {
byte *ptr = data;
*reinterpret_cast<key_type*>(ptr) = max_element_id;
offset_count_ = max_element_id;
offset_count_ = max_element_id + 1;
ptr += sizeof(key_type);
*reinterpret_cast<key_type*>(ptr) = element_count;
@@ -227,7 +227,7 @@ namespace EQEmu {
//! Calculates how much memory we should allocate based on element size and count
static size_type estimated_size(key_type element_count, key_type max_elements) {
size_type total_size = 3 * sizeof(key_type);
total_size += sizeof(key_type) * max_elements;
total_size += sizeof(key_type) * (max_elements + 1);
total_size += sizeof(T) * element_count;
return total_size;
}
+133 -84
View File
@@ -1,17 +1,20 @@
#include "shareddb.h"
#include "../common/Item.h"
#include "../common/EMuShareMem.h"
#include "../common/classes.h"
#include "../common/rulesys.h"
#include "../common/seperator.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
#include "Item.h"
#include "EMuShareMem.h"
#include "classes.h"
#include "rulesys.h"
#include "seperator.h"
#include "MiscFunctions.h"
#include "eq_packet_structs.h"
#include "guilds.h"
#include "extprofile.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
#include "memory_mapped_file.h"
#include "ipc_mutex.h"
#include "eqemu_exception.h"
using namespace std;
@@ -22,14 +25,14 @@ extern LoadEMuShareMemDLL EMuShareMemDLL;
SharedDatabase *SharedDatabase::s_usedb = NULL;
SharedDatabase::SharedDatabase()
: Database()
: Database(), skill_caps_mmf(NULL)
{
SDBInitVars();
s_usedb = this;
}
SharedDatabase::SharedDatabase(const char* host, const char* user, const char* passwd, const char* database, uint32 port)
: Database(host, user, passwd, database, port)
: Database(host, user, passwd, database, port), skill_caps_mmf(NULL)
{
SDBInitVars();
s_usedb = this;
@@ -46,6 +49,7 @@ void SharedDatabase::SDBInitVars() {
}
SharedDatabase::~SharedDatabase() {
safe_delete(skill_caps_mmf);
}
bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme)
@@ -1519,15 +1523,62 @@ bool SharedDatabase::extDBLoadSkillCaps() {
}
bool SharedDatabase::LoadSkillCaps() {
if (!EMuShareMemDLL.Load())
return false;
uint8 class_count = PLAYER_CLASS_COUNT;
uint8 skill_count = HIGHEST_SKILL+1;
uint8 level_count = HARD_LEVEL_CAP+1;
if(skill_caps_mmf)
return true;
return EMuShareMemDLL.SkillCaps.LoadSkillCaps(&extDBLoadSkillCaps,
sizeof(uint16), class_count, skill_count, level_count);
uint32 class_count = PLAYER_CLASS_COUNT;
uint32 skill_count = HIGHEST_SKILL + 1;
uint32 level_count = HARD_LEVEL_CAP + 1;
uint32 size = (class_count * skill_count * level_count * sizeof(uint16));
try {
EQEmu::IPCMutex mutex("skill_caps");
mutex.Lock();
skill_caps_mmf = new EQEmu::MemoryMappedFile("shared/skill_caps");
if(skill_caps_mmf->Size() != size) {
EQ_EXCEPT("SharedDatabase", "Unable to load skill caps: skill_caps_mmf->Size() != size");
}
mutex.Unlock();
} catch(std::exception &ex) {
LogFile->write(EQEMuLog::Error, "Error loading skill caps: %s", ex.what());
return false;
}
return true;
}
void SharedDatabase::LoadSkillCaps(void *data) {
uint32 class_count = PLAYER_CLASS_COUNT;
uint32 skill_count = HIGHEST_SKILL + 1;
uint32 level_count = HARD_LEVEL_CAP + 1;
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(RunQuery(query, MakeAnyLenString(&query,
"SELECT skillID, class, level, cap FROM skill_caps ORDER BY skillID, class, level"),
errbuf, &result)) {
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
uint8 skillID = atoi(row[0]);
uint8 class_ = atoi(row[1]) - 1;
uint8 level = atoi(row[2]);
uint16 cap = atoi(row[3]);
if(skillID >= skill_count || class_ >= class_count || level >= level_count)
continue;
uint32 index = (((class_ * class_count) + skillID) * level_count) + level;
uint16 *skill_caps_table = reinterpret_cast<uint16*>(data);
skill_caps_table[index] = cap;
}
mysql_free_result(result);
} else {
LogFile->write(EQEMuLog::Error, "Error loading skill caps from database: %s", errbuf);
safe_delete_array(query);
}
}
bool SharedDatabase::DBLoadSkillCaps() {
@@ -1567,48 +1618,82 @@ bool SharedDatabase::DBLoadSkillCaps() {
}
uint16 SharedDatabase::GetSkillCap(uint8 Class_, SkillType Skill, uint8 Level) {
if(Class_ == 0)
return(0);
int SkillMaxLevel = RuleI(Character, SkillCapMaxLevel);
if (SkillMaxLevel < 1) {
SkillMaxLevel = RuleI(Character, MaxLevel);
}
if(Level > SkillMaxLevel){
return EMuShareMemDLL.SkillCaps.GetSkillCap(Class_-1, Skill, SkillMaxLevel);
}
else{
return EMuShareMemDLL.SkillCaps.GetSkillCap(Class_-1, Skill, Level);
}
if(!skill_caps_mmf) {
return 0;
}
if(Class_ == 0)
return 0;
int SkillMaxLevel = RuleI(Character, SkillCapMaxLevel);
if(SkillMaxLevel < 1) {
SkillMaxLevel = RuleI(Character, MaxLevel);
}
uint32 class_count = PLAYER_CLASS_COUNT;
uint32 skill_count = HIGHEST_SKILL + 1;
uint32 level_count = HARD_LEVEL_CAP + 1;
if(Level > static_cast<uint8>(SkillMaxLevel)){
Level = static_cast<uint8>(SkillMaxLevel);
}
uint32 index = ((((Class_ - 1) * class_count) + Skill) * level_count) + Level;
uint16 *skill_caps_table = reinterpret_cast<uint16*>(skill_caps_mmf->Get());
return skill_caps_table[index];
}
uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillType Skill, uint8 Level) {
if(Class_ == 0)
return(0);
if(!skill_caps_mmf) {
return 0;
}
uint8 ret = 0;
int SkillMaxLevel = RuleI(Character, SkillCapMaxLevel);
if (SkillMaxLevel < 1) {
SkillMaxLevel = RuleI(Character, MaxLevel);
}
if(Level > SkillMaxLevel) {
ret = EMuShareMemDLL.SkillCaps.GetTrainLevel(Class_-1, Skill, SkillMaxLevel);
if(Class_ == 0)
return 0;
int SkillMaxLevel = RuleI(Character, SkillCapMaxLevel);
if (SkillMaxLevel < 1) {
SkillMaxLevel = RuleI(Character, MaxLevel);
}
uint32 class_count = PLAYER_CLASS_COUNT;
uint32 skill_count = HIGHEST_SKILL + 1;
uint32 level_count = HARD_LEVEL_CAP + 1;
uint8 ret = 0;
if(Level > static_cast<uint8>(SkillMaxLevel)) {
uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count);
uint16 *skill_caps_table = reinterpret_cast<uint16*>(skill_caps_mmf->Get());
for(uint8 x = 0; x < Level; x++){
if(skill_caps_table[index + x]){
ret = x;
break;
}
}
}
else
{
ret = EMuShareMemDLL.SkillCaps.GetTrainLevel(Class_-1, Skill, Level);
uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count);
uint16 *skill_caps_table = reinterpret_cast<uint16*>(skill_caps_mmf->Get());
for(int x = 0; x < SkillMaxLevel; x++){
if(skill_caps_table[index + x]){
ret = x;
break;
}
}
}
if(ret > GetSkillCap(Class_, Skill, Level))
ret = GetSkillCap(Class_, Skill, Level);
if(ret > GetSkillCap(Class_, Skill, Level))
ret = GetSkillCap(Class_, Skill, Level);
return ret;
return ret;
}
void SharedDatabase::DBLoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID) {
void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID) {
const char *DSQuery = "SELECT `spellid`, `type` from `damageshieldtypes` WHERE `spellid` > 0 "
"AND `spellid` <= %i";
const char *ERR_MYSQLERROR = "Error in DBLoadDamageShieldTypes: %s %s";
const char *ERR_MYSQLERROR = "Error in LoadDamageShieldTypes: %s %s";
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
@@ -1777,10 +1862,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
sp[tempid].base2[y]=atoi(row[32+y]); // effect_limit_value
for(y=0; y< EFFECT_COUNT;y++)
sp[tempid].max[y]=atoi(row[44+y]);
sp[tempid].icon=atoi(row[56]);
sp[tempid].memicon=atoi(row[57]);
for(y=0; y< 4;y++)
sp[tempid].components[y]=atoi(row[58+y]);
@@ -1793,7 +1875,6 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
for(y=0; y< EFFECT_COUNT;y++)
sp[tempid].formula[y]=atoi(row[70+y]);
sp[tempid].LightType=atoi(row[82]);
sp[tempid].goodEffect=atoi(row[83]);
sp[tempid].Activated=atoi(row[84]);
sp[tempid].resisttype=atoi(row[85]);
@@ -1816,63 +1897,31 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
sp[tempid].classes[y]=atoi(row[104+y]);
sp[tempid].CastingAnim=atoi(row[120]);
sp[tempid].TargetAnim=atoi(row[121]);
sp[tempid].TravelType=atoi(row[122]);
sp[tempid].SpellAffectIndex=atoi(row[123]);
sp[tempid].disallow_sit=atoi(row[124]);
sp[tempid].spacing125=atoi(row[125]);
for (y = 0; y < 16; y++)
sp[tempid].deities[y]=atoi(row[126+y]);
for (y = 0; y < 2; y++)
sp[tempid].spacing142[y]=atoi(row[142+y]);
sp[tempid].new_icon=atoi(row[144]);
sp[tempid].spellanim=atoi(row[145]);
sp[tempid].uninterruptable=atoi(row[146]);
sp[tempid].ResistDiff=atoi(row[147]);
sp[tempid].dot_stacking_exempt=atoi(row[148]);
sp[tempid].deletable=atoi(row[149]);
sp[tempid].RecourseLink = atoi(row[150]);
for(y = 0; y < 3;y++)
sp[tempid].spacing151[y]=atoi(row[151+y]);
sp[tempid].short_buff_box = atoi(row[154]);
sp[tempid].descnum = atoi(row[155]);
sp[tempid].typedescnum = atoi(row[156]);
sp[tempid].effectdescnum = atoi(row[157]);
for(y = 0; y < 4;y++)
sp[tempid].spacing158[y]=atoi(row[158+y]);
sp[tempid].bonushate=atoi(row[162]);
for(y = 0; y < 3;y++)
sp[tempid].spacing163[y]=atoi(row[163+y]);
sp[tempid].EndurCost=atoi(row[166]);
sp[tempid].EndurTimerIndex=atoi(row[167]);
sp[tempid].IsDisciplineBuff=atoi(row[168]);
for(y = 0; y < 4; y++)
sp[tempid].spacing169[y]=atoi(row[169+y]);
sp[tempid].HateAdded=atoi(row[173]);
sp[tempid].EndurUpkeep=atoi(row[174]);
sp[tempid].spacing175=atoi(row[175]);
sp[tempid].numhits = atoi(row[176]);
sp[tempid].pvpresistbase=atoi(row[177]);
sp[tempid].pvpresistcalc=atoi(row[178]);
sp[tempid].pvpresistcap=atoi(row[179]);
sp[tempid].spell_category=atoi(row[180]);
for(y = 0; y < 4;y++)
sp[tempid].spacing181[y]=atoi(row[181+y]);
sp[tempid].can_mgb=atoi(row[185]);
sp[tempid].dispel_flag = atoi(row[186]);
sp[tempid].MinResist = atoi(row[189]);
@@ -1883,14 +1932,14 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
sp[tempid].directional_start = (float)atoi(row[194]);
sp[tempid].directional_end = (float)atoi(row[195]);
sp[tempid].spellgroup=atoi(row[207]);
sp[tempid].field209=atoi(row[209]);
sp[tempid].powerful_flag=atoi(row[209]);
sp[tempid].CastRestriction = atoi(row[211]);
sp[tempid].AllowRest = atoi(row[212]) != 0;
sp[tempid].DamageShieldType = 0;
}
mysql_free_result(result);
DBLoadDamageShieldTypes(sp, max_spells);
LoadDamageShieldTypes(sp, max_spells);
} else {
_log(SPELLS__LOAD_ERR, "Error in LoadSpells query '%s' %s", query, errbuf);
safe_delete_array(query);
+6 -1
View File
@@ -16,6 +16,9 @@ struct NPCFactionList;
struct Faction;
struct LootTable_Struct;
struct LootDrop_Struct;
namespace EQEmu {
class MemoryMappedFile;
}
/*
* This object is inherited by world and zone's DB object,
@@ -94,10 +97,11 @@ public:
bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
bool DBLoadLoot();
bool DBLoadSkillCaps();
void DBLoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID);
int GetMaxSpellID();
void LoadSpells(void *data, int max_spells);
void LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID);
void LoadSkillCaps(void *data);
bool LoadSkillCaps();
@@ -125,6 +129,7 @@ protected:
uint32 npc_spells_maxid;
EQEmu::MemoryMappedFile *skill_caps_mmf;
private:
static SharedDatabase *s_usedb;
};
+38 -49
View File
@@ -18,8 +18,8 @@
#ifndef SPDAT_H
#define SPDAT_H
#include "../common/classes.h"
#include "../common/skills.h"
#include "classes.h"
#include "skills.h"
#define SPELL_UNKNOWN 0xFFFF
#define SPELLBOOK_UNKNOWN 0xFFFFFFFF //player profile spells are 32 bit
@@ -603,7 +603,7 @@ typedef enum {
//
struct SPDat_Spell_Struct
{
/* 000 */ int id; // not used
/* 000 */ //int id; // not used
/* 001 */ char name[64]; // Name of the spell
/* 002 */ char player_1[32]; // "PLAYER_1"
/* 003 */ char teleport_zone[64]; // Teleport zone, pet name summoned, or item summoned
@@ -623,93 +623,82 @@ struct SPDat_Spell_Struct
/* 017 */ uint32 buffduration;
/* 018 */ uint32 AEDuration; // sentinel, rain of something
/* 019 */ uint16 mana; // Mana Used
/* 020 */ int32 base[EFFECT_COUNT]; //various purposes
/* 032 */ int base2[EFFECT_COUNT]; //various purposes
/* 020 */ int base[EFFECT_COUNT]; //various purposes
/* 032 */ int base2[EFFECT_COUNT]; //various purposes
/* 044 */ int16 max[EFFECT_COUNT];
/* 056 */ uint16 icon; // Spell icon
/* 057 */ uint16 memicon; // Icon on membarthing
/* 056 */ //uint16 icon; // Spell icon
/* 057 */ //uint16 memicon; // Icon on membarthing
/* 058 */ int32 components[4]; // reagents
/* 062 */ int component_counts[4]; // amount of regents used
/* 066 */ signed NoexpendReagent[4]; // focus items (Need but not used; Flame Lick has a Fire Beetle Eye focus.)
/* 066 */ int NoexpendReagent[4]; // focus items (Need but not used; Flame Lick has a Fire Beetle Eye focus.)
// If it is a number between 1-4 it means components[number] is a focus and not to expend it
// If it is a valid itemid it means this item is a focus as well
/* 070 */ uint16 formula[EFFECT_COUNT]; // Spell's value formula
/* 082 */ int LightType; // probaly another effecttype flag
/* 083 */ int goodEffect; //0=detrimental, 1=Beneficial, 2=Beneficial, Group Only
/* 082 */ //int LightType; // probaly another effecttype flag
/* 083 */ int8 goodEffect; //0=detrimental, 1=Beneficial, 2=Beneficial, Group Only
/* 084 */ int Activated; // probaly another effecttype flag
/* 085 */ int resisttype;
/* 086 */ int effectid[EFFECT_COUNT]; // Spell's effects
/* 098 */ SpellTargetType targettype; // Spell's Target
/* 099 */ int basediff; // base difficulty fizzle adjustment
/* 100 */ SkillType skill;
/* 101 */ int16 zonetype; // 01=Outdoors, 02=dungeons, ff=Any
/* 102 */ uint16 EnvironmentType;
/* 103 */ int TimeOfDay;
/* 101 */ int8 zonetype; // 01=Outdoors, 02=dungeons, ff=Any
/* 102 */ int8 EnvironmentType;
/* 103 */ int8 TimeOfDay;
/* 104 */ uint8 classes[PLAYER_CLASS_COUNT]; // Classes, and their min levels
/* 120 */ uint8 CastingAnim;
/* 121 */ uint8 TargetAnim;
/* 122 */ uint32 TravelType;
/* 121 */ //uint8 TargetAnim;
/* 122 */ //uint32 TravelType;
/* 123 */ uint16 SpellAffectIndex;
/* 124 */ int disallow_sit; // 124: high-end Yaulp spells (V, VI, VII, VIII [Rk 1, 2, & 3], & Gallenite's Bark of Fury
/* 125 */ int spacing125; // 125: Words of the Skeptic
/* 124 */ int8 disallow_sit; // 124: high-end Yaulp spells (V, VI, VII, VIII [Rk 1, 2, & 3], & Gallenite's Bark of Fury
/* 125 */ // 125: Words of the Skeptic
/* 126 */ int8 deities[16]; // Deity check. 201 - 216 per http://www.eqemulator.net/wiki/wikka.php?wakka=DeityList
// -1: Restrict to Deity; 1: Restrict to Deity, but only used on non-Live (Test Server "Blessing of ...") spells; 0: Don't restrict
/* 142 */ int spacing142[2]; // 142: between 0 & 100
/* 142 */ // 142: between 0 & 100
// 143: always set to 0
/* 144 */ int16 new_icon; // Spell icon used by the client in uifiles/default/spells??.tga, both for spell gems & buff window. Looks to depreciate icon & memicon
/* 145 */ int16 spellanim; // Doesn't look like it's the same as #doanim, so not sure what this is
/* 144 */ //int16 new_icon // Spell icon used by the client in uifiles/default/spells??.tga, both for spell gems & buff window. Looks to depreciate icon & memicon
/* 145 */ //int16 spellanim; // Doesn't look like it's the same as #doanim, so not sure what this is
/* 146 */ int8 uninterruptable; // Looks like anything != 0 is uninterruptable. Values are mostly -1, 0, & 1 (Fetid Breath = 90?)
/* 147 */ int16 ResistDiff;
/* 148 */ int dot_stacking_exempt;
/* 149 */ int deletable;
/* 150 */ uint16 RecourseLink;
/* 151 */ int spacing151[3]; // 151: -1, 0, or 1
/* 148 */ //int dot_stacking_exempt;
/* 149 */ //int deletable;
/* 150 */ uint16 RecourseLink;
/* 151 */ // 151: -1, 0, or 1
// 152 & 153: all set to 0
/* 154 */ int8 short_buff_box; // != 0, goes to short buff box. Not really supported in the server code
/* 154 */ int8 short_buff_box; // != 0, goes to short buff box.
/* 155 */ int descnum; // eqstr of description of spell
/* 156 */ int typedescnum; // eqstr of type description
/* 156 */ //int typedescnum; // eqstr of type description
/* 157 */ int effectdescnum; // eqstr of effect description
/* 158 */ int spacing158[4];
/* 158 */
/* 162 */ int bonushate;
/* 163 */ int spacing163[3];
/* 163 */
/* 166 */ int EndurCost;
/* 167 */ int EndurTimerIndex;
/* 168 */ int IsDisciplineBuff; //Will goto the combat window when cast
/* 169 */ int spacing169[4];
/* 167 */ int8 EndurTimerIndex;
/* 168 */ //int IsDisciplineBuff; //Will goto the combat window when cast
/* 169 */
/* 173 */ int HateAdded;
/* 174 */ int EndurUpkeep;
/* 175 */ int spacing175;
/* 175 */
/* 176 */ int numhits;
/* 177 */ int pvpresistbase;
/* 178 */ int pvpresistcalc;
/* 179 */ int pvpresistcap;
/* 180 */ int spell_category;
/* 181 */ int spacing181[4];
/* 185 */ int can_mgb; // 0=no, -1 or 1 = yes
/* 181 */
/* 185 */ int8 can_mgb; // 0=no, -1 or 1 = yes
/* 186 */ int dispel_flag;
/* 189 */ int MinResist;
/* 190 */ int MaxResist;
/* 191 */ int viral_targets;
/* 192 */ int viral_timer;
/* 191 */ uint8 viral_targets;
/* 192 */ uint8 viral_timer;
/* 193 */ int NimbusEffect;
/* 194 */ float directional_start;
/* 195 */ float directional_end;
/* 207 */ int spellgroup;
/* 209 */ int field209; // 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
/* 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
/* 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;
/* 219 */ int maxtargets; // not in DB yet, is used for beam and ring spells for target # limits
//shared memory errors
/* 186 */ /*int8 nodispell;*/ // 0=can be dispelled, -1=can't be dispelled at all, 1=most can be cancelled w/ a cure but not dispelled
/* 187 */ /*uint8 npc_category;*/ // 0=not used, 1=AoE Detrimental, 2=DD, 3=Buffs, 4=Pets, 5=Healing, 6=Gate, 7=Debuff, 8=Dispell
/* 188 */ /*uint32 npc_usefulness;*/ // higher number = more useful, lower number = less useful
/* 189 */ /*int spacing189[18];*/
/* 207 */ /*uint32 spellgroup;*/
/* 208 */ /*int spacing208[7];*/
// Might be newer fields in the live version, which is what some of the last fields are
/* 219 */ //int maxtargets; // not in DB yet, is used for beam and ring spells for target # limits
uint8 DamageShieldType; // This field does not exist in spells_us.txt
};