Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

Reply
 
Thread Tools Display Modes
  #16  
Old 03-01-2008, 09:01 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default

One word about the previous hooks (and some coming others) : I did not indent the hook code as should normally be. the reason is that it avoids getting changes in diffs on all the regular code I enclosed in "ifs".
Reply With Quote
  #17  
Old 03-01-2008, 09:03 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Hook 3 : More item bonuses computation

Index: bonuses.cpp
================================================== =================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/bonuses.cpp,v
retrieving revision 1.7.2.15
diff -u -b -B -r1.7.2.15 bonuses.cpp
--- bonuses.cpp 21 Feb 2007 16:04:20 -0000 1.7.2.15
+++ bonuses.cpp 2 Mar 2008 09:06:47 -0000
@@ -25,6 +25,7 @@
#include "../common/skills.h"
#include "../common/bodytypes.h"
#include "../common/classes.h"
+#include "../common/rulesys.h"
#include <math.h>
#include <assert.h>
#ifndef WIN32
@@ -277,6 +278,9 @@
for(i = 0; i < MAX_AUGMENT_SLOTS; i++) {
AddItemBonuses(inst->GetAugment(i),newbon);
}
+
+ if(RuleH(Character, PostAddItemBonuses) != NULL)
+ ((Hook_Character_PostAddItemBonuses) RuleH(Character, PostAddItemBonuses))(inst, newbon);
}

void Client::CalcEdibleBonuses(StatBonuses* newbon) {

Last edited by Bulle; 03-02-2008 at 05:07 AM.. Reason: Replacing mistake post
Reply With Quote
  #18  
Old 03-01-2008, 09:08 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Hook 4 : Tweak skill-up chance

Index: client.cpp
================================================== =================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/client.cpp,v
retrieving revision 1.36.2.51
diff -u -b -B -r1.36.2.51 client.cpp
--- client.cpp 21 Feb 2007 16:04:20 -0000 1.36.2.51
+++ client.cpp 2 Mar 2008 09:08:20 -0000
@@ -1654,9 +1654,15 @@
if (skillval < maxskill)
{
// the higher your current skill level, the harder it is
- sint16 Chance = 10 + chancemodi + ((252 - skillval) / 20);
+ sint16 Chance;
+if(RuleH(Character, ChanceOfSkillIncrease) != NULL)
+ Chance = ((Hook_Character_ChanceOfSkillIncrease) RuleH(Character, ChanceOfSkillIncrease))(skillid, skillval, maxskill, chancemodi);
+else
+{
+ Chance = 10 + chancemodi + ((252 - skillval) / 20);
if (Chance < 1)
Chance = 1; // Make it always possible
+}
if(MakeRandomFloat(0, 99) < Chance)
{
SetSkill(skillid, GetRawSkill(skillid) + 1);
Reply With Quote
  #19  
Old 03-01-2008, 09:12 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Hook 5 : Tweak AC calculation

Index: client_mods.cpp
================================================== =================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/client_mods.cpp,v
retrieving revision 1.6.4.19
diff -u -b -B -r1.6.4.19 client_mods.cpp
--- client_mods.cpp 21 Feb 2007 16:04:20 -0000 1.6.4.19
+++ client_mods.cpp 2 Mar 2008 09:11:32 -0000
@@ -28,6 +28,7 @@
#include "../common/moremath.h"
#include "../common/guilds.h"
#include "../common/logsys.h"
+#include "../common/rulesys.h"
#include "StringIDs.h"
#include "NpcAI.h"

@@ -714,7 +715,10 @@
// AC from spells are not included (cant even cast spells yet..)
sint16 Client::CalcAC() {

- // new formula
+if(RuleH(Character, CalcAC) != NULL)
+ AC = ((Hook_Character_CalcAC) RuleH(Character, CalcAC))(GetLevel(), GetSkill(DEFENSE), itembonuses.AC, spellbonuses.AC);
+else
+{ // new formula
int avoidance = 0;
avoidance = (acmod() + ((GetSkill(DEFENSE)*16)/9));
if (avoidance < 0)
@@ -749,8 +753,8 @@

//spell AC bonuses are added directly to natural total
displayed += spellbonuses.AC;
-
AC = displayed;
+}
return(AC);
}
Reply With Quote
  #20  
Old 03-01-2008, 09:15 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Hook 6 : Tweak Mana pool computation

Index: client_process.cpp
================================================== =================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/client_process.cpp,v
retrieving revision 1.50.2.23
diff -u -b -B -r1.50.2.23 client_process.cpp
--- client_process.cpp 21 Feb 2007 16:04:21 -0000 1.50.2.23
+++ client_process.cpp 2 Mar 2008 09:13:34 -0000
@@ -1466,7 +1466,13 @@
return;
int32 level=GetLevel();
int32 regen = 0;
- if (IsSitting()) { //this should be changed so we dont med while camping, etc...
+
+if(RuleH(Character, ManaRegen) != NULL)
+{ regen = ((Hook_Character_ManaRegen) RuleH(Character, ManaRegen))(IsSitting(), GetLevel(), GetMaxMana(), GetINT(), GetSkill(MEDITATE), itembonuses.ManaRegen, spellbonuses.ManaRegen);
+ medding = IsSitting() && HasSkill(MEDITATE);
+}
+else
+{ if (IsSitting()) { //this should be changed so we dont med while camping, etc...
if(HasSkill(MEDITATE)) {
medding = true;
regen = (((GetSkill(MEDITATE)/10)+(level-(level/4)))/4)+4;
@@ -1480,12 +1486,13 @@
medding = false;
regen = 2+spellbonuses.ManaRegen+itembonuses.ManaRegen+(le vel/5);
}
+}
regen += GetAA(aaMentalClarity);
regen += GetAA(aaBodyAndMindRejuvenation);
regen = (regen * RuleI(Character, ManaRegenMultiplier)) / 100;

SetMana(GetMana() + regen);
Reply With Quote
  #21  
Old 03-01-2008, 09:18 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Hook 7 : Pre-XP change hook and Tweak XP per level value

Index: exp.cpp
================================================== =================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/exp.cpp,v
retrieving revision 1.2.2.14
diff -u -b -B -r1.2.2.14 exp.cpp
--- exp.cpp 16 Jan 2007 04:04:53 -0000 1.2.2.14
+++ exp.cpp 2 Mar 2008 09:17:01 -0000
@@ -34,7 +34,6 @@
void Client::AddEXP(int32 add_exp, int8 conlevel, bool resexp) {
if (m_epp.perAA<0 || m_epp.perAA>100)
m_epp.perAA=0; // stop exploit with sanity check
-
int32 add_aaxp;
if(resexp) {
add_aaxp = 0;
@@ -117,6 +116,8 @@
return; // Must be invalid class/race
}

+ if(RuleH(XP, PreChange) != NULL)
+ ((Hook_XP_PreChange) RuleH(XP, PreChange))(this, set_exp, set_aaxp, isrezzexp, m_pp.exp, m_pp.expAA);

if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
if (isrezzexp)
@@ -312,7 +320,10 @@
uint32 Client::GetEXPForLevel(int16 check_level)
{

- int16 check_levelm1 = check_level-1;
+if(RuleH(Character, EXPForLevel) != NULL)
+ return ((Hook_Character_EXPForLevel) RuleH(Character, EXPForLevel))(check_level, GetBaseRace(), GetClass());
+else
+{ int16 check_levelm1 = check_level-1;
float mod;
if (check_level < 31)
mod = 1.0;
@@ -368,6 +379,7 @@

return(uint32(base * mod));
}
+}

void Group::SplitExp(uint32 exp, Mob* other) {
if( other->CastToNPC()->MerchantType != 0 ) // Ensure NPC isn't a merchant
Reply With Quote
  #22  
Old 03-01-2008, 09:25 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Hooks 8 : Tweak fizzle and resist chance

Index: spells.cpp
================================================== =================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/spells.cpp,v
retrieving revision 1.14.2.44
diff -u -b -B -r1.14.2.44 spells.cpp
--- spells.cpp 21 Feb 2007 16:04:23 -0000 1.14.2.44
+++ spells.cpp 2 Mar 2008 09:24:51 -0000
@@ -480,7 +480,8 @@
}

bool Client::CheckFizzle(int16 spell_id)
-{
+{ float fizzlechance, diff;
+
// GMs don't fizzle
if (GetGM()) return(true);

@@ -516,7 +517,12 @@
//is there any sort of focus that affects fizzling?


- // neotokyo: this is my try to get something going
+if(RuleH(Spells, FizzleChance) != NULL)
+{ fizzlechance = ((Hook_Spells_FizzleChance) RuleH(Spells, FizzleChance))(this, spells, spell_id);
+ diff = 0;
+}
+else
+{ // neotokyo: this is my try to get something going
int par_skill;
int act_skill;

@@ -556,7 +562,7 @@
// > 0 --> skill is lower, higher chance of fizzle
// < 0 --> skill is better, lower chance of fizzle
// the max that diff can be is +- 235
- float diff = par_skill + spells[spell_id].basediff - act_skill;
+ diff = par_skill + spells[spell_id].basediff - act_skill;

// if you have high int/wis you fizzle less, you fizzle more if you are stupid
if (GetCasterClass() == 'W')
@@ -566,10 +572,11 @@

// base fizzlechance is lets say 5%, we can make it lower for AA skills or whatever
float basefizzle = 10;
- float fizzlechance = basefizzle - specialize + diff / 5.0;
+ fizzlechance = basefizzle - specialize + diff / 5.0;

// always at least 5% chance to fail or succeed
fizzlechance = fizzlechance < 5 ? 5 : (fizzlechance > 95 ? 95 : fizzlechance);
+}
float fizzle_roll = MakeRandomFloat(0, 100);

mlog(SPELLS__CASTING, "Check Fizzle %s spell %d fizzlechance: %0.2f%% diff: %0.2f roll: %0.2f", GetName(), spell_id, fizzlechance, diff, fizzle_roll);
@@ -2717,7 +2724,24 @@
break;
}

- // value in spell to adjust base resist by
+if(RuleH(Spells, FinalResistChance) != NULL)
+{ struct _Hook_Spells_FinalResistChance_Parameters Parameters;
+ Parameters.AttackerIsClient = caster->IsClient();
+ Parameters.AttackerLevel = caster->GetLevel();
+ Parameters.AttackerCha = caster->GetCHA();
+ if(Parameters.AttackerIsClient)
+ Parameters.AttackerMeditation = caster->GetSkill(MEDITATE);
+ Parameters.DefenderIsClient = this->IsClient();
+ Parameters.DefenderLevel = this->GetLevel();
+ Parameters.DefenderResist = resist;
+ Parameters.spells = spells;
+ Parameters.spell_id = spell_id;
+ resistchance = ((Hook_Spells_FinalResistChance) RuleH(Spells, FinalResistChance))(&Parameters);
+ if(caster->IsClient())
+ caster->CastToClient()->CheckIncreaseSkill(MEDITATE);
+}
+else
+{ // value in spell to adjust base resist by
if(spell_id != 0)
resist += spells[spell_id].ResistDiff;

@@ -2743,7 +2767,7 @@
resistchance -= (lvldiff)*0.8;
}
}
-
+}
/*The idea is we come up with 3 ranges of numbers and a roll between 0 and 100
[[[Empty Space above the resistchance line]]] - If the roll lands up here the spell wasn't resisted, the lower the resist chance the larger this range is
[[[Space between resistchance line and full resist chance line]]] - If the roll ends up here then the spell is resisted but only partially, we take the roll in porportion to where it landed in this range to det how
Reply With Quote
  #23  
Old 03-01-2008, 09:31 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default common/default_hooks.h

I forgot the default_hooks.h file that contains the hook function declaractions. It is required for the changes in the rulexxx files to compile :

#ifndef DEFAULT_RULES_H_
#define DEFAULT_RULES_H_


/** A hook can be a function pointer of any type. So we define it as void *.
* Hooks are cast to their actual function type when they are called.
*/
typedef void *Hook;

/** Macro used to check the compliance of hook functions with the definition of the hook.
* It ensures the hook function has the correct signature.
* It can be very useful to avoid mistakes, and when a hook signature changes.
* The compiler can then issue an error.
* If no signature check is done, a badly-defined hook function will probably crash the server.
* usage: add a line after the hook function definition (in the *.cpp file)
* CheckHookSignature(CharacterCreation, ChangeCreationInfo, default_CharacterCreation_ChangeCreationInfo);
*/

#define CheckHookSignature(cat, rule, hook) \
static Hook_##cat##_##rule CheckSignature_##hook = hook


/************************************************** ******************************************/
/* Common hooks. Only hooks implemented in both the world and zone must go in this section. */
/************************************************** ******************************************/
/**
*/
typedef double (*Hook_Random_RandomFloat)(double low, double high);



/************************************************** ***************************************/
/* World-related hooks. Only hooks (and includes) used in World must go to this section. */
/************************************************** ***************************************/
#ifdef WORLD
#include "../common/eq_packet_structs.h"

/** Called during character creation right after the CharCreate structure has been checked for correctness.
* Allows the world builder to tweak the values sent by the client prior to the actual character creation.
*/
typedef void (*Hook_CharacterCreation_ChangeCreationInfo)(CharC reate_Struct *cc);


#endif /* WORLD */



/************************************************** ***************************************/
/* Zone-related hooks. Only hooks (and includes) used in Zone must go to this section. */
/************************************************** ***************************************/
#ifdef ZONE
#include "../zone/client.h"

typedef struct _Hook_Attack_ToHitChance_Parameters
{ bool IsPvp;

bool AttackerIsClient;
int8 AttackerLevel;
sint16 AttackerDex;
uint16 AttackerWeaponSkill; /* not applicable if !AttackerIsClient */
uint16 AttackerOffense; /* not applicable if !AttackerIsClient */

bool DefenderIsClient;
int8 DefenderLevel;
sint16 DefenderAgi;
uint16 DefenderDefense; /* not applicable if !DefenderIsClient */
} *Hook_Attack_ToHitChance_Parameters;

/** Called during the function checking whether an attack actualy hits.
* Computes the percentage chance of hitting based on level, weapon skill, DEX and AGI.
* The regular rules will be used for the rest of the hit chance (mods, AAs etc).
* 'Paramters' contains all information available for the computation.
*/
typedef float (*Hook_Attack_ToHitChance)(Hook_Attack_ToHitChance _Parameters Parameters);


typedef struct _Hook_Attack_ClientDamageRange_Parameters
{ sint16 AttackerStr;
int8 AttackerLevel;
int AttackerWeaponDamage;
int AttackerWeaponDelay;

int8 DefenderLevel;

int MinHit; /* output only */
int MaxHit; /* output only */
} *Hook_Attack_ClientDamageRange_Parameters;

/**
* 'Parameters' contains all information available for the computation.
*/
typedef void (*Hook_Attack_ClientDamageRange)(Hook_Attack_Clien tDamageRange_Parameters Parameters);


typedef struct _Hook_Attack_NpcDamageRange_Parameters
{ sint16 AttackerStr;
int8 AttackerLevel;
int AttackerMaxDamage;
int AttackerDelay;

int8 DefenderLevel;

int MinHit; /* output only */
int MaxHit; /* output only */
} *Hook_Attack_NpcDamageRange_Parameters;

/**
* 'Parameters' contains all information available for the computation.
*/
typedef void (*Hook_Attack_NpcDamageRange)(Hook_Attack_NpcDamag eRange_Parameters Parameters);


typedef struct _Hook_Attack_Mitigation_Parameters
{ bool AttackerIsClient;
int8 AttackerLevel;
uint16 AttackerOffense; /* not applicable if !AttackerIsClient */

bool DefenderIsClient;
int8 DefenderLevel;
sint16 DefenderAC;
uint16 DefenderDefense; /* not applicable if !DefenderIsClient */

sint32 Damage; /* input-output */
} *Hook_Attack_Mitigation_Parameters;

/**
* 'Parameters' contains all information available for the computation.
*/
typedef void (*Hook_Attack_Mitigation)(Hook_Attack_Mitigation_P arameters Parameters);


/** Called at the end of the function where the bonuses given by an item are cumulated to the current item bonuses a character receives.
* 'inst' is the item to evaluate.
* 'newbon' is the current set of bonuses received from items by the character.
*/
typedef void (*Hook_Character_PostAddItemBonuses)(const ItemInst *inst, StatBonuses* newbon);


/**
*/
typedef sint16 (*Hook_Character_CalcAC)(uint8 Level, uint16 Defense, sint16 ItemsAC, sint16 SpellsAC);


/**
*/
typedef uint32 (*Hook_Character_EXPForLevel)(uint8 Level, int16 CharacterRace, int8 CharacterClass);


/**
*/
typedef int32 (*Hook_Character_ManaRegen)(bool IsSitting, uint8 Level, sint32 MaxMana, sint16 Int, uint16 MeditateSkill, sint32 ItemsManaRegen, sint32 SpellsManaRegen);


/**
*/
typedef sint16 (*Hook_Character_ChanceOfSkillIncrease)(SkillType skillid, int CurrentSkill, int MaxSkill, int chancemodi);


/** Called right before the fizzle roll is made, to compute the percentage of chance to fizzle.
* 'ThisClient' is the character casting the spell.
* 'spell_id' is the ID of the spell being cast.
* The check whether the caster can never fizzle due to AAs has already been done.
*/
typedef float (*Hook_Spells_FizzleChance)(Client *ThisClient, const SPDat_Spell_Struct *spells, int16 spell_id);


typedef struct _Hook_Spells_FinalResistChance_Parameters
{ bool AttackerIsClient;
int8 AttackerLevel;
sint16 AttackerCha;
uint16 AttackerMeditation; /* not applicable if !AttackerIsClient */

bool DefenderIsClient;
int8 DefenderLevel;
sint16 DefenderResist;

const SPDat_Spell_Struct *spells;
int16 spell_id;
} *Hook_Spells_FinalResistChance_Parameters;

/**
*/
typedef float (*Hook_Spells_FinalResistChance)(Hook_Spells_Final ResistChance_Parameters Parameters);


/** Called during exprience change, before the new XP values are set. Ideal place to show a custom message with the numeric XP values.
* The XP for the current client is going to be set to 'set_exp' and 'set_aaxp'.
* The client currently has 'orig_exp' XP and 'orig_aaxp'.
* 'isrezzexp' indicates whether this is XP regained after a rez.
* The hook cannot affect the XP change in any way. The XP will be changed normally after the hook returns.
*/
typedef void (*Hook_XP_PreChange)(Client *ThisClient, int32 set_exp, int32 set_aaxp, bool isrezzexp, int32 orig_exp, int32 orig_aaxp);


#endif /* ZONE */


#endif /*DEFAULT_RULES_H_*/
Reply With Quote
  #24  
Old 03-01-2008, 09:35 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Implementing the hooks

What has been explained since the beginning of this post is still still somewhat applicable, with some changes. To implement one (or more) hooks you need to :
- create a shared library with the hook functions implementation. You want to separate "world" and "zone", so it means two shared libraries (in my case hero_world and hero_zone).
- add an entry in the rule_values database for each hook to activate
Reply With Quote
  #25  
Old 03-01-2008, 09:39 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default World Hooks

Here is my code for the hero_world.dll library (hero_world_Hooks.cpp) :
#include "../common/debug.h"
#include "../common/default_Hooks.h"
#include "../common/classes.h"
#include "../common/races.h"


#ifdef WIN32
#define exportfunc extern "C" __declspec(dllexport)
#else
#define exportfunc extern "C"
#endif


/** Makes all newly-created characters Rangers - It is the class chosen for heroes as it can cast spells
* and have dual-wield. After all, aren't all rangers heroes ?
*/
exportfunc void hero_world_CharacterCreation_ChangeCreationInfo(Ch arCreate_Struct *cc)
{ cc->class_ = RANGER;

/* Adjust the stats to provide a similar amount of points per race.
* Good or neutral races get 535 points total, evil races 555.
*/
switch(cc->race)
{ case BARBARIAN: break;
case DARK_ELF: cc->CHA += 23; break;
case DWARF: cc->CHA += 7; break;
case ERUDITE: cc->CHA += 5; break;
case FROGLOK: cc->CHA -= 15; break;
case GNOME: cc->CHA += 10; break;
case HALF_ELF: cc->CHA += 10; break;
case HALFLING: cc->CHA += 3; break;
case HIGH_ELF: cc->AGI -= 7; break;
case HUMAN: cc->CHA += 10; break;
case IKSAR: break;
case OGRE: cc->CHA += 1; break;
case TROLL: cc->DEX += 10; cc->STA += 18; break;
case VAHSHIR: cc->DEX += 10; break;
case WOOD_ELF: break;
default: printf("unknown race %d\n", cc->race);
}
}
CheckHookSignature(CharacterCreation, ChangeCreationInfo, hero_world_CharacterCreation_ChangeCreationInfo);

Enlarge one column in the database to allow specifying looong values :
ALTER TABLE rule_values MODIFY rule_value VARCHAR(256);

The hook is activated with the following SQL query in the database :
INSERT INTO rule_values VALUES ('1','(world) CharacterCreation:ChangeCreationInfo','hero_world: hero_world_CharacterCreation_ChangeCreationInfo');

The entry name is of the form "(world) <hook>" for world hooks. The value is the name of the shared library (no extension, for Unix compatibility) then the name of the function implementing the hook.
Reply With Quote
  #26  
Old 03-01-2008, 09:44 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default Zone Hooks

There are many more zone hooks. They are implemented in hero_zone_Hooks.cpp, which generates the hero_world.dll shared library.
I removed a couple hooks of mine as they rely on other non-hook related changes on my server.

Those custom hooks are of course only there as examples. You do not want them on your own server

#include "../common/debug.h"
#include "../common/default_Hooks.h"
#include "../common/MiscFunctions.h"
#include <math.h>

#ifdef WIN32
#define exportfunc extern "C" __declspec(dllexport)
#else
#define exportfunc extern "C"
#endif

#define SkillRegulationMod (+20)
#define StatRegulationMod (-50)

#define ZeroIfNegative(x) ((x) < 0 ? 0 : (x))


/** The to-hit chance is computed as :
* 100 - 100 * (DEF AGI + StatRegulationMod) / ( (DEF AGI + StatRegulationMod) + (ATK DEX + StatRegulationMod) + (ATK Skill + SkillRegulationMod) )
* If one of the opponent is not a client then its skill is equal to (Level + 1) * 5.
*/
exportfunc float hero_zone_Attack_ToHitChance(Hook_Attack_ToHitChan ce_Parameters Parameters)
{ float Result;
uint16 AttackerWeaponSkill;
//printf("Bulle-ToHit-Hook-01 : PVP=%d / ATK CLT=%d / ATK LVL=%d / ATK DEX=%d / ATK WEA=%d / ATK OFF=%d\n", Parameters->IsPvp, Parameters->AttackerIsClient, Parameters->AttackerLevel, Parameters->AttackerDex, Parameters->AttackerIsClient?Parameters->AttackerWeaponSkill : -1, Parameters->AttackerIsClient?Parameters->AttackerOffense : -1);
//printf("Bulle-ToHit-Hook-02 : PVP=%d / DEF CLT=%d / DEF LVL=%d / DEF AGI=%d / DEF OFF=%d\n", Parameters->IsPvp, Parameters->DefenderIsClient, Parameters->DefenderLevel, Parameters->DefenderAgi, Parameters->AttackerIsClient?Parameters->DefenderDefense : -1);

if(Parameters->AttackerIsClient)
AttackerWeaponSkill = Parameters->AttackerWeaponSkill;
else
AttackerWeaponSkill = (Parameters->AttackerLevel + 1) * 5;

Result = 100.0 - 100.0 * ZeroIfNegative(Parameters->DefenderAgi + StatRegulationMod) /
( ZeroIfNegative(Parameters->DefenderAgi + StatRegulationMod)
+ ZeroIfNegative(Parameters->AttackerDex + StatRegulationMod)
+ ZeroIfNegative(AttackerWeaponSkill + SkillRegulationMod) / 2
+ 1 /* avoids division by zero */
);
printf("Bulle-ToHit-Hook-03 : to hit=%f\n", Result);
return Result;
}
CheckHookSignature(Attack, ToHitChance, hero_zone_Attack_ToHitChance);


/** The damage range is computed as :
* MinHit = (ATK STR + StatRegulationMod) * ATK WEAP DLY / 100
* MaxHit = MinHit + 3 * ATK WEAP DMG
*/
exportfunc void hero_zone_Attack_ClientDamageRange(Hook_Attack_Cli entDamageRange_Parameters Parameters)
{
//printf("Bulle-ClientDamageRange-Hook-01 : ATK STR=%d / ATK LVL=%d / ATK DLY=%d / ATK DMG=%d / DEF LVL=%d\n", Parameters->AttackerStr, Parameters->AttackerLevel, Parameters->AttackerWeaponDelay, Parameters->AttackerWeaponDamage, Parameters->DefenderLevel);

Parameters->MinHit = (int) (ZeroIfNegative(Parameters->AttackerStr + StatRegulationMod) * Parameters->AttackerWeaponDelay / 100.0);
Parameters->MaxHit = Parameters->MinHit + 3 * Parameters->AttackerWeaponDamage;
printf("Bulle-ClientDamageRange-Hook-02 : min_hit=%d max_hit=%d\n", Parameters->MinHit, Parameters->MaxHit);
}
CheckHookSignature(Attack, ClientDamageRange, hero_zone_Attack_ClientDamageRange);


/** The damage range is computed as :
* MinHit = (ATK STR + StatRegulationMod) * ATK DLY / 100
* MaxHit = MinHit + 2 * ATK MAXDMG
*/
exportfunc void hero_zone_Attack_NpcDamageRange(Hook_Attack_NpcDam ageRange_Parameters Parameters)
{
//printf("Bulle-NpcDamageRange-Hook-01 : ATK STR=%d / ATK LVL=%d / ATK DLY=%d / ATK MAXDMG=%d / DEF LVL=%d\n", Parameters->AttackerStr, Parameters->AttackerLevel, Parameters->AttackerDelay, Parameters->AttackerMaxDamage, Parameters->DefenderLevel);

Parameters->MinHit = (int) (ZeroIfNegative(Parameters->AttackerStr + StatRegulationMod) * Parameters->AttackerDelay / 100.0);
Parameters->MaxHit = Parameters->MinHit + 2 * Parameters->AttackerMaxDamage;
printf("Bulle-NpcDamageRange-Hook-02 : min_hit=%d max_hit=%d\n", Parameters->MinHit, Parameters->MaxHit);
}
CheckHookSignature(Attack, NpcDamageRange, hero_zone_Attack_NpcDamageRange);


exportfunc void hero_zone_Attack_Mitigation(Hook_Attack_Mitigation _Parameters Parameters)
{ sint32 InitialDamage = Parameters->Damage;
float Mitigation;
uint16 AttackerOffense, DefenderDefense;
double AdjustedDefenderAC;
//printf("Bulle-Mitigation-Hook-01 : ATK CLT=%d / ATK LVL=%d / ATK OFF=%d / DEF CLT=%d / DEF LVL=%d / DEF AC=%d / DEF DEF=%d\n", Parameters->AttackerIsClient, Parameters->AttackerLevel, Parameters->AttackerIsClient ? Parameters->AttackerOffense : -1, Parameters->DefenderIsClient, Parameters->DefenderLevel, Parameters->DefenderAC, Parameters->DefenderIsClient ? Parameters->DefenderDefense : -1);

if(Parameters->AttackerIsClient)
AttackerOffense = Parameters->AttackerOffense;
else
AttackerOffense = (Parameters->AttackerLevel + 1) * 5;

if(Parameters->DefenderIsClient)
{ DefenderDefense = Parameters->DefenderDefense;
AdjustedDefenderAC = Parameters->DefenderAC;
}
else
{ DefenderDefense = (Parameters->DefenderLevel + 1 )* 5;
AdjustedDefenderAC = pow(Parameters->DefenderAC * 1.0, 0.9);
}

Mitigation = (AdjustedDefenderAC + ZeroIfNegative(DefenderDefense + SkillRegulationMod) * 1.25) /
(AdjustedDefenderAC + ZeroIfNegative(DefenderDefense + SkillRegulationMod) * 1.25 + ZeroIfNegative(AttackerOffense + SkillRegulationMod) * 5);
Parameters->Damage = (int) ((1.0 - Mitigation) * InitialDamage);
printf("Bulle-Mitigation-Hook-02 : dmgbfr=%d mitig=%f dmgaft=%d\n", InitialDamage, Mitigation, Parameters->Damage);
}
CheckHookSignature(Attack, Mitigation, hero_zone_Attack_Mitigation);


exportfunc sint16 hero_zone_Character_CalcAC(uint8 Level, uint16 Defense, sint16 ItemsAC, sint16 SpellsAC)
{ sint16 Result = ItemsAC + SpellsAC;
return Result;
}
CheckHookSignature(Character, CalcAC, hero_zone_Character_CalcAC);


exportfunc uint32 hero_zone_Character_EXPForLevel(uint8 Level, int16 CharacterRace, int8 CharacterClass)
{ uint32 Result = 100.0 * pow(1.2, Level + 10);
printf("Bulle-EXPForLevel-Hook-01 : level=%d XP=%d\n", Level, Result);
return Result;
}
CheckHookSignature(Character, EXPForLevel, hero_zone_Character_EXPForLevel);


exportfunc int32 hero_zone_Character_ManaRegen(bool IsSitting, uint8 Level, sint32 MaxMana, sint16 Int, uint16 MeditateSkill, sint32 ItemsManaRegen, sint32 SpellsManaRegen)
{ sint16 Result;

Result = MaxMana * Int / 4000;
if(!IsSitting)
Result = Result / 10;
Result += 2 + ItemsManaRegen + SpellsManaRegen;
//printf("Bulle-ManaRegen-Hook-01 : regen=%d\n", Result);
return Result;
}
CheckHookSignature(Character, ManaRegen, hero_zone_Character_ManaRegen);


/** Base chance is a linear function such that base chance is 25% when skill is 0, and 0% when skill is 250.
* The final chance is the base chance plus the chance modifier, or 5%, whichever is greater.
*/
exportfunc sint16 hero_zone_Character_ChanceOfSkillIncrease(SkillTyp e skillid, int CurrentSkill, int MaxSkill, int chancemodi)
{ sint16 Result;

Result = (25 * (250 - CurrentSkill) + 1250) / 300 + chancemodi;
if(Result < 5)
Result = 5;

printf("Bulle-ChanceOfSkillIncrease-Hook-01 : skill=%d chance=%d\n", CurrentSkill, Result);
return Result;
}
CheckHookSignature(Character, ChanceOfSkillIncrease, hero_zone_Character_ChanceOfSkillIncrease);


exportfunc float hero_zone_Spells_FinalResistChance(Hook_Spells_Fin alResistChance_Parameters Parameters)
{ float Result;
uint16 AttackerMeditation;

if(Parameters->AttackerIsClient)
AttackerMeditation = Parameters->AttackerMeditation;
else
AttackerMeditation = (Parameters->AttackerLevel + 1) * 5;

Result = 100.0 * Parameters->DefenderResist /
(1 + ZeroIfNegative(1.0 * Parameters->DefenderResist + (Parameters->AttackerCha + StatRegulationMod)
+ (AttackerMeditation + SkillRegulationMod) - Parameters->spells[Parameters->spell_id].ResistDiff));

printf("Bulle-Resist-Hook-01 : resist=%f\n", Result);
return Result;
}
CheckHookSignature(Spells, FinalResistChance, hero_zone_Spells_FinalResistChance);


/** Displays numeric XP value gains (or loss).
*/
exportfunc void hero_zone_XP_PreChange(Client *ThisClient, int32 set_exp, int32 set_aaxp, bool isrezzexp, int32 orig_exp, int32 orig_aaxp)
{ if(set_exp - orig_exp > 0)
ThisClient->Message(15, "You have gained %d XP.", set_exp - orig_exp);
else if(set_exp - orig_exp < 0)
ThisClient->Message(15, "You have lost %d XP.", set_exp - orig_exp);

if(set_aaxp - orig_aaxp > 0)
ThisClient->Message(15, "You have gained %d AA XP.", set_aaxp - orig_aaxp);
else if(set_aaxp - orig_aaxp < 0)
ThisClient->Message(15, "You have lost %d AA XP.", set_aaxp - orig_aaxp);
//printf("Bulle-XPPreChange-Hook-01 : XP:%d->%d AA:%d->%d\n", orig_exp, set_exp, orig_aaxp, set_aaxp);
}
CheckHookSignature(XP, PreChange, hero_zone_XP_PreChange);
Reply With Quote
  #27  
Old 03-01-2008, 09:44 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default SQL code to activate the zone hooks

INSERT INTO rule_values VALUES ('1','(zone) Attack:ToHitChance','hero_zone:hero_zone_Attack_To HitChance');
INSERT INTO rule_values VALUES ('1','(zone) Attack:ClientDamageRange','hero_zone:hero_zone_Att ack_ClientDamageRange');
INSERT INTO rule_values VALUES ('1','(zone) Attack:NpcDamageRange','hero_zone:hero_zone_Attack _NpcDamageRange');
INSERT INTO rule_values VALUES ('1','(zone) Attack:Mitigation','hero_zone:hero_zone_Attack_Mit igation');
INSERT INTO rule_values VALUES ('1','(zone) Character:CalcAC','hero_zone:hero_zone_Character_C alcAC');
INSERT INTO rule_values VALUES ('1','(zone) Character:EXPForLevel','hero_zone:hero_zone_Charac ter_EXPForLevel');
INSERT INTO rule_values VALUES ('1','(zone) Character:ManaRegen','hero_zone:hero_zone_Characte r_ManaRegen');
INSERT INTO rule_values VALUES ('1','(zone) Character:ChanceOfSkillIncrease','hero_zone:hero_z one_Character_ChanceOfSkillIncrease');
INSERT INTO rule_values VALUES ('1','(zone) XP:PreChange','hero_zone:hero_zone_XP_PreChange');
INSERT INTO rule_values VALUES ('1','(zone) Spells:FinalResistChance','hero_zone:hero_zone_Spe lls_FinalResistChance');
Reply With Quote
  #28  
Old 03-01-2008, 09:48 PM
Bulle
Hill Giant
 
Join Date: Jan 2008
Posts: 102
Default

Now you can probably understand why I was so quiet about the topic
This code submission is quite huge, I will understand if noone can find the time to try it out (especially as I may have introduced errors when porting the code back to CVS from my SVN repository, and weeding out the other unnecessary change I made).

If I make other interesting changes to the server I will make sure to post them somewhere else. Now after all this effort it is Zebu server time

Bulle
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 10:10 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3