mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-02 04:16:46 +00:00
Skill caps load with new smem scheme
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define COMMON_PROFILE_H
|
||||
|
||||
#ifdef ZONE
|
||||
#include "../zone/features.h"
|
||||
#include "../common/features.h"
|
||||
|
||||
#ifndef EQPROFILE
|
||||
#ifdef COMMON_PROFILE
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user