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)

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 10-16-2006, 06:20 PM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default Some stuff

Gonna try to keep most of my future small posts in this thread to avoid my name over-running the development forum.

Was rather quiet in IRC tonight so I'm gonna post the ideas I came up with tonight.

Looking at the recourse code and something seems not quite right with it, I use a SK for testing a lot and noticed torrent of pain doesn't hit either my self or my group, I think it's because of how the target types are done with the recourse code. Also I think it's not well placed in the casting sequence; the recourse code is put in before the resist check so even if your target resists the spell the recourse will still go off and this seems wrong to me.

Reference Spells:
http://lucy.allakhazam.com/spell.html?id=2486 Group v1 (ST_GroupTeleport)
http://lucy.allakhazam.com/spell.html?id=2480 Group v1 (ST_GroupTeleport)


Recourse was in Mob::SpellFinished():

at the top:

Code:
int recourse_spell=0;
little further down approx ln 1423

Code:
// Recourse means there is a spell linked to that spell in that the recourse spell will
	// be automatically casted on the casters group or the caster only depending on Targettype
	// solar: this is for things like dark empathy, shadow vortex
	recourse_spell = spells[spell_id].RecourseLink;
	if(recourse_spell != 0)
	{
		if(spells[recourse_spell].targettype == ST_Group) {
			if(IsGrouped()) {
				Group *g = entity_list.GetGroupByMob(this);;
				g->CastGroupSpell(this, recourse_spell);
			} else {
				SpellOnTarget(recourse_spell, this);
#ifdef GROUP_BUFF_PETS
				if (HasPet())
					SpellOnTarget(recourse_spell, GetPet());
#endif
			}
		} else if(spells[recourse_spell].targettype == ST_GroupTeleport) {
		// EverHood - Necro Epic 2 Pet Proc Recourse
			if(HasOwner()) {
				if(GetOwner()->IsGrouped()) {
					Group *g = entity_list.GetGroupByMob(this->GetOwner());
					g->CastGroupSpell(this, recourse_spell);
				} else {
					SpellOnTarget(recourse_spell, this->GetOwner());
				}
			}
		} else {
			SpellOnTarget(recourse_spell, this);
		}
	}

First I'd move it down to spellontarget() I suppose, right after the resist check to make sure the spell landed before the recourse goes off.

Then I'd change the code a bit to be something like:

Code:
// Recourse means there is a spell linked to that spell in that the recourse spell will
	// be automatically casted on the casters group or the caster only depending on Targettype
	// solar: this is for things like dark empathy, shadow vortex
	int recourse_spell=0;
	recourse_spell = spells[spell_id].RecourseLink;
	if(recourse_spell)
	{
		if(spells[recourse_spell].targettype == ST_Group || spells[recourse_spell].targettype == ST_GroupTeleport)
		{
			if(IsGrouped())
			{
				Group *g = entity_list.GetGroupByMob(this);
				g->CastGroupSpell(this, recourse_spell);
			}
			else if(HasOwner())
			{
				if(GetOwner->IsGrouped())
				{
					Group *g = entity_list.GetGroupByMob(GetOwner());
					g->CastGroupSpell(this, recourse_spell);
				}

			}
			else
			{
				SpellOnTarget(recourse_spell, this);
#ifdef GROUP_BUFF_PETS
				if (HasPet())
					SpellOnTarget(recourse_spell, GetPet());
#endif
			}	

		}
		else
		{
			SpellOnTarget(recourse_spell, this);
		}
	}
Another thing I want to change is a bit of code in Client::GetFocusEffect() because the focus is calculated even for duration spells, like it should be but you always get the glow message as well which is really annoying, you should really only be getting it for non duration spells, heals, nukes etc.

you'll find the lines
Code:
if (realTotal > 0 && UsedItem) {
		Message_StringID(MT_Spells, BEGINS_TO_GLOW, UsedItem->Name);
	}
I just replaced it with
Code:
if (realTotal > 0 && UsedItem && spells[spell_id].buffduration == 0) {
		Message_StringID(MT_Spells, BEGINS_TO_GLOW, UsedItem->Name);
	}
I think that should be effective in eliminating redundant spell focus spam.

Also I noticed in the last version I pulled up from source the first few lines in Client::Attack() remained unchanged despite what the changelog says. Really I think the first log statement needs to be changed because of it's potential to cause a crash.

Code:
bool Client::Attack(Mob* other, int Hand, bool bRiposte)
{
	_ZP(Client_Attack);
	
	mlog(COMBAT__ATTACKS, "Attacking %s with hand %d %s", other->GetName(), Hand, bRiposte?"(this is a riposte)":"");
	
	//SetAttackTimer();
	if (
		   (IsCasting() && GetClass() != BARD)
		|| other == NULL
		|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
		|| (GetHP() < 0)
		|| (!IsAttackAllowed(other))
		) {
		mlog(COMBAT__ATTACKS, "Attack canceled, invalid circumstances.");
		return false; // Only bards can attack while casting
	}
Perhaps it could be changed to something like

Code:
bool Client::Attack(Mob* other, int Hand, bool bRiposte)
{
	_ZP(Client_Attack);
	
	//SetAttackTimer();
	if (
		   (IsCasting() && GetClass() != BARD)
		|| other == NULL
		|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
		|| (GetHP() < 0)
		|| (!IsAttackAllowed(other))
		) {
		mlog(COMBAT__ATTACKS, "Was trying to attack someone with hand %d, but the attack was canceled because of invalid circumstances.", Hand);
		return false; // Only bards can attack while casting
	}
	else{
		mlog(COMBAT__ATTACKS, "Attacking %s with hand %d %s", other->GetName(), Hand, bRiposte?"(this is a riposte)":"");
	}
This would make sure we verify other before we attempt to access it, avoiding a potential crash.

Also in Client::Message()
Code:
void Client::Message(uint32 type, const char* message, ...) {
	va_list argptr;
	char *buffer = new char[4096];
	
	if (GetFilter(FilterSpellDamage) == FilterHide && type == MT_NonMelee)
		return;
	if (GetFilter(FilterMeleeCrits) == FilterHide && type == MT_CritMelee) //98 is self...
		return;
	if (GetFilter(FilterSpellCrits) == FilterHide && type == MT_SpellCrits)
		return;
	
	va_start(argptr, message);
	vsnprintf(buffer, 4096, message, argptr);
	va_end(argptr);
	
	uint32 len = strlen(buffer);
	
	//client dosent like our packet all the time unless
	//we make it really big, then it seems to not care that
	//our header is malformed.
	//len = 4096 - sizeof(SpecialMesg_Struct);
	
	uint32 len_packet = sizeof(SpecialMesg_Struct)+len;
	EQApplicationPacket* app = new EQApplicationPacket(OP_SpecialMesg, len_packet);
	SpecialMesg_Struct* sm=(SpecialMesg_Struct*)app->pBuffer;
	sm->header[0] = 0x00; // Header used for #emote style messages..
	sm->header[1] = 0x00; // Play around with these to see other types
	sm->header[2] = 0x00;
	//sm->msg_type = type;
	sm->msg_type = 0x0A;
Is there any reason that we fix the type to 0x0A? And I'm guessing it's preferable to use the preformatted messages where it's possible as well, since I'm guessing the packet they send is smaller?

Don't have time to compile and test this stuff tonight, I'll try to get around to it tomorrow but in the mean time if you see anything wrong with my ideas feel free to let me have it.

Last edited by KLS; 10-17-2006 at 02:32 AM..
Reply With Quote
 


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 04:52 AM.


 

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 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3