mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-04 15:12:26 +00:00
Merge beaa405aa2df9cd09c33267053162c13182308c9 into 308a21e0e27792515afbdebc02e6d6cfef3f63e9
This commit is contained in:
commit
c68873c22b
4
.gitignore
vendored
4
.gitignore
vendored
@ -35,3 +35,7 @@ Build_64/
|
|||||||
build_64/
|
build_64/
|
||||||
log/
|
log/
|
||||||
logs/
|
logs/
|
||||||
|
|
||||||
|
# Patch files
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
|||||||
@ -1862,12 +1862,12 @@ bool NPC::AI_IdleCastCheck() {
|
|||||||
void Mob::StartEnrage()
|
void Mob::StartEnrage()
|
||||||
{
|
{
|
||||||
// dont continue if already enraged
|
// dont continue if already enraged
|
||||||
if (bEnraged)
|
if (bEnraged || bInfuriated)
|
||||||
return;
|
return;
|
||||||
if (SpecAttackTimers[SPECATK_ENRAGE] && !SpecAttackTimers[SPECATK_ENRAGE]->Check())
|
if (SpecAttackTimers[SPECATK_ENRAGE] && !SpecAttackTimers[SPECATK_ENRAGE]->Check())
|
||||||
return;
|
return;
|
||||||
// see if NPC has possibility to enrage
|
// see if NPC has possibility to enrage
|
||||||
if (!SpecAttacks[SPECATK_ENRAGE])
|
if (!SpecAttacks[SPECATK_ENRAGE] && !SpecAttacks[SPECATK_INFURIATE])
|
||||||
return;
|
return;
|
||||||
// check if timer exists (should be true at all times)
|
// check if timer exists (should be true at all times)
|
||||||
if (SpecAttackTimers[SPECATK_ENRAGE])
|
if (SpecAttackTimers[SPECATK_ENRAGE])
|
||||||
@ -1882,16 +1882,25 @@ void Mob::StartEnrage()
|
|||||||
}
|
}
|
||||||
// start the timer. need to call IsEnraged frequently since we dont have callback timers :-/
|
// start the timer. need to call IsEnraged frequently since we dont have callback timers :-/
|
||||||
SpecAttackTimers[SPECATK_ENRAGE]->Start();
|
SpecAttackTimers[SPECATK_ENRAGE]->Start();
|
||||||
|
if (SpecAttacks[SPECATK_ENRAGE]) {
|
||||||
bEnraged = true;
|
bEnraged = true;
|
||||||
entity_list.MessageClose_StringID(this, true, 200, MT_NPCEnrage, NPC_ENRAGE_START, GetCleanName());
|
entity_list.MessageClose_StringID(this, true, 200, MT_NPCEnrage, NPC_ENRAGE_START, GetCleanName());
|
||||||
|
} else if (SpecAttacks[SPECATK_INFURIATE]) {
|
||||||
|
bInfuriated = true;
|
||||||
|
entity_list.MessageClose(this, true, 200, MT_NPCEnrage, "%1 is infuriated.", GetCleanName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ProcessEnrage(){
|
void Mob::ProcessEnrage(){
|
||||||
if(IsEnraged()){
|
if(IsEnraged() || IsInfuriated()){
|
||||||
if(SpecAttackTimers[SPECATK_ENRAGE] && SpecAttackTimers[SPECATK_ENRAGE]->Check()){
|
if(SpecAttackTimers[SPECATK_ENRAGE] && SpecAttackTimers[SPECATK_ENRAGE]->Check()){
|
||||||
entity_list.MessageClose_StringID(this, true, 200, MT_NPCEnrage, NPC_ENRAGE_END, GetCleanName());
|
|
||||||
SpecAttackTimers[SPECATK_ENRAGE]->Start(EnragedTimer);
|
SpecAttackTimers[SPECATK_ENRAGE]->Start(EnragedTimer);
|
||||||
|
if(IsEnraged()) {
|
||||||
|
entity_list.MessageClose_StringID(this, true, 200, MT_NPCEnrage, NPC_ENRAGE_END, GetCleanName());
|
||||||
bEnraged = false;
|
bEnraged = false;
|
||||||
|
} else if(IsInfuriated()) {
|
||||||
|
entity_list.MessageClose(this, true, 200, MT_NPCEnrage,"%1 is no longer infuriated.", GetCleanName());
|
||||||
|
bInfuriated = false; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1901,6 +1910,11 @@ bool Mob::IsEnraged()
|
|||||||
return bEnraged;
|
return bEnraged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mob::IsInfuriated()
|
||||||
|
{
|
||||||
|
return bInfuriated;
|
||||||
|
}
|
||||||
|
|
||||||
bool Mob::Flurry()
|
bool Mob::Flurry()
|
||||||
{
|
{
|
||||||
// this is wrong, flurry is extra attacks on the current target
|
// this is wrong, flurry is extra attacks on the current target
|
||||||
|
|||||||
@ -382,6 +382,10 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
|||||||
damage = -3;
|
damage = -3;
|
||||||
mlog(COMBAT__DAMAGE, "I am enraged, riposting frontal attack.");
|
mlog(COMBAT__DAMAGE, "I am enraged, riposting frontal attack.");
|
||||||
}
|
}
|
||||||
|
if (IsInfuriated()) {
|
||||||
|
damage = -3;
|
||||||
|
mlog(COMBAT__DAMAGE, "I am infuriated, riposting attacks from all sides.");
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// riposte
|
// riposte
|
||||||
|
|||||||
11
zone/bot.cpp
11
zone/bot.cpp
@ -3752,6 +3752,9 @@ void Bot::AI_Process() {
|
|||||||
// Stop attacking if the target is enraged
|
// Stop attacking if the target is enraged
|
||||||
if(IsEngaged() && !BehindMob(GetTarget(), GetX(), GetY()) && GetTarget()->IsEnraged())
|
if(IsEngaged() && !BehindMob(GetTarget(), GetX(), GetY()) && GetTarget()->IsEnraged())
|
||||||
return;
|
return;
|
||||||
|
// Stop attacking if the target is infuriated
|
||||||
|
if(IsEngaged() && GetTarget()->IsInfuriated())
|
||||||
|
return;
|
||||||
|
|
||||||
if(GetBotStance() == BotStancePassive)
|
if(GetBotStance() == BotStancePassive)
|
||||||
return;
|
return;
|
||||||
@ -4080,6 +4083,9 @@ void Bot::PetAIProcess() {
|
|||||||
// Stop attacking while we are on a front arc and the target is enraged
|
// Stop attacking while we are on a front arc and the target is enraged
|
||||||
if(!botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY()) && botPet->GetTarget()->IsEnraged())
|
if(!botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY()) && botPet->GetTarget()->IsEnraged())
|
||||||
return;
|
return;
|
||||||
|
// Stop attacking while the target is infuriated
|
||||||
|
if(botPet->GetTarget()->IsInfuriated())
|
||||||
|
return;
|
||||||
|
|
||||||
if(botPet->Attack(GetTarget(), SLOT_PRIMARY)) // try the main hand
|
if(botPet->Attack(GetTarget(), SLOT_PRIMARY)) // try the main hand
|
||||||
if (botPet->GetTarget()) // Do we still have a target?
|
if (botPet->GetTarget()) // Do we still have a target?
|
||||||
@ -7842,6 +7848,11 @@ bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
|
|||||||
damage = -3;
|
damage = -3;
|
||||||
mlog(COMBAT__DAMAGE, "I am enraged, riposting frontal attack.");
|
mlog(COMBAT__DAMAGE, "I am enraged, riposting frontal attack.");
|
||||||
}
|
}
|
||||||
|
// same as enrage just no behind check needed.
|
||||||
|
if (IsInfuriated()) {
|
||||||
|
damage = -3;
|
||||||
|
mlog(COMBAT__DAMAGE, "I am infuriated, riposting attacks from all sides.");
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// riposte
|
// riposte
|
||||||
|
|||||||
@ -84,11 +84,11 @@ typedef enum { //focus types
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Used:
|
Used:
|
||||||
b,d,f,g,j,m,n,o,p,r,t
|
b,d,e,f,g,j,m,n,o,p,r,t
|
||||||
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,Q,R,S,T,U,W,Y
|
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,Q,R,S,T,U,W,Y
|
||||||
|
|
||||||
Unused:
|
Unused:
|
||||||
a,c,e,h,k,l,q,s,u,v,w,x,y,z
|
a,c,h,k,l,q,s,u,v,w,x,y,z
|
||||||
P,V,X
|
P,V,X
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -96,6 +96,7 @@ enum {
|
|||||||
SPECATK_NONE = 0,
|
SPECATK_NONE = 0,
|
||||||
SPECATK_SUMMON, // S
|
SPECATK_SUMMON, // S
|
||||||
SPECATK_ENRAGE, // E
|
SPECATK_ENRAGE, // E
|
||||||
|
SPECATK_INFURIATE, // e
|
||||||
SPECATK_RAMPAGE, // R
|
SPECATK_RAMPAGE, // R
|
||||||
SPECATK_AREA_RAMPAGE, // r
|
SPECATK_AREA_RAMPAGE, // r
|
||||||
SPECATK_FLURRY, // F
|
SPECATK_FLURRY, // F
|
||||||
|
|||||||
@ -1651,6 +1651,9 @@ void Merc::AI_Process() {
|
|||||||
// Stop attacking if the target is enraged
|
// Stop attacking if the target is enraged
|
||||||
if(IsEngaged() && !BehindMob(GetTarget(), GetX(), GetY()) && GetTarget()->IsEnraged())
|
if(IsEngaged() && !BehindMob(GetTarget(), GetX(), GetY()) && GetTarget()->IsEnraged())
|
||||||
return;
|
return;
|
||||||
|
// stop attacking if the target is infuriated
|
||||||
|
if(IsEngaged() && GetTarget()->IsInfuriated())
|
||||||
|
return;
|
||||||
//TODO: Implement Stances.
|
//TODO: Implement Stances.
|
||||||
/*if(GetBotStance() == BotStancePassive)
|
/*if(GetBotStance() == BotStancePassive)
|
||||||
return;*/
|
return;*/
|
||||||
|
|||||||
@ -648,6 +648,7 @@ public:
|
|||||||
void StartEnrage();
|
void StartEnrage();
|
||||||
void ProcessEnrage();
|
void ProcessEnrage();
|
||||||
bool IsEnraged();
|
bool IsEnraged();
|
||||||
|
bool IsInfuriated();
|
||||||
void Taunt(NPC* who, bool always_succeed, float chance_bonus = 0);
|
void Taunt(NPC* who, bool always_succeed, float chance_bonus = 0);
|
||||||
|
|
||||||
virtual void AI_Init();
|
virtual void AI_Init();
|
||||||
@ -945,6 +946,7 @@ protected:
|
|||||||
char lastname[64];
|
char lastname[64];
|
||||||
|
|
||||||
bool bEnraged;
|
bool bEnraged;
|
||||||
|
bool bInfuriated;
|
||||||
Timer *SpecAttackTimers[SPECATK_MAXNUM];
|
Timer *SpecAttackTimers[SPECATK_MAXNUM];
|
||||||
bool destructibleobject;
|
bool destructibleobject;
|
||||||
|
|
||||||
|
|||||||
@ -1447,6 +1447,9 @@ void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool rem
|
|||||||
case 'E':
|
case 'E':
|
||||||
SpecAttacks[SPECATK_ENRAGE] = (remove ? false : true);
|
SpecAttacks[SPECATK_ENRAGE] = (remove ? false : true);
|
||||||
break;
|
break;
|
||||||
|
case 'e':
|
||||||
|
SpecAttacks[SPECATK_INFURIATE] = (remove ? false : true);
|
||||||
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
SpecAttacks[SPECATK_FLURRY] = (remove ? false : true);
|
SpecAttacks[SPECATK_FLURRY] = (remove ? false : true);
|
||||||
break;
|
break;
|
||||||
@ -1592,6 +1595,10 @@ bool Mob::HasNPCSpecialAtk(const char* parse) {
|
|||||||
if (!SpecAttacks[SPECATK_ENRAGE])
|
if (!SpecAttacks[SPECATK_ENRAGE])
|
||||||
HasAllAttacks = false;
|
HasAllAttacks = false;
|
||||||
break;
|
break;
|
||||||
|
case 'e':
|
||||||
|
if (!SpecAttacks[SPECATK_INFURIATE])
|
||||||
|
HasAllAttacks = false;
|
||||||
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
if (!SpecAttacks[SPECATK_FLURRY])
|
if (!SpecAttacks[SPECATK_FLURRY])
|
||||||
HasAllAttacks = false;
|
HasAllAttacks = false;
|
||||||
|
|||||||
@ -5010,6 +5010,32 @@ XS(XS_Mob_IsEnraged)
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_IsInfuriated); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Mob_IsInfuriated)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::IsInfuriated(THIS)");
|
||||||
|
{
|
||||||
|
Mob * THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
if(THIS == NULL)
|
||||||
|
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsInfuriated();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_Mob_GetReverseFactionCon); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_Mob_GetReverseFactionCon); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_Mob_GetReverseFactionCon)
|
XS(XS_Mob_GetReverseFactionCon)
|
||||||
{
|
{
|
||||||
@ -8267,6 +8293,7 @@ XS(boot_Mob)
|
|||||||
newXSproto(strcpy(buf, "IsStunned"), XS_Mob_IsStunned, file, "$");
|
newXSproto(strcpy(buf, "IsStunned"), XS_Mob_IsStunned, file, "$");
|
||||||
newXSproto(strcpy(buf, "StartEnrage"), XS_Mob_StartEnrage, file, "$");
|
newXSproto(strcpy(buf, "StartEnrage"), XS_Mob_StartEnrage, file, "$");
|
||||||
newXSproto(strcpy(buf, "IsEnraged"), XS_Mob_IsEnraged, file, "$");
|
newXSproto(strcpy(buf, "IsEnraged"), XS_Mob_IsEnraged, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "IsInfuriated"), XS_Mob_IsInfuriated, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetReverseFactionCon"), XS_Mob_GetReverseFactionCon, file, "$$");
|
newXSproto(strcpy(buf, "GetReverseFactionCon"), XS_Mob_GetReverseFactionCon, file, "$$");
|
||||||
newXSproto(strcpy(buf, "IsAIControlled"), XS_Mob_IsAIControlled, file, "$");
|
newXSproto(strcpy(buf, "IsAIControlled"), XS_Mob_IsAIControlled, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetAggroRange"), XS_Mob_GetAggroRange, file, "$");
|
newXSproto(strcpy(buf, "GetAggroRange"), XS_Mob_GetAggroRange, file, "$");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user