Go Back   EQEmulator Home > EQEmulator Forums > Support > Support::Windows Servers

Support::Windows Servers Support forum for Windows EQEMu users.

Reply
 
Thread Tools Display Modes
  #1  
Old 09-22-2015, 04:45 PM
AdrianD
Discordant
 
Join Date: Dec 2013
Posts: 297
Default Acceptable/efficient syntax

I made a small change to remove max lvl 1 starting skills in client.cpp.

It appears to work after logging in but, I want to be certain the syntax is correct and if it could be done better.

My comments inside:

Code:
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{
	for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
		if (pp->skills[i] == 0); /* added ; just before this comment  commented out 9-22-15 to test starting skills (I do not want max skills at lvl 1)
								{
			// Skip specialized, tradeskills (fishing excluded), Alcohol Tolerance, and Bind Wound
			if (EQEmu::IsSpecializedSkill((SkillUseTypes)i) ||
					(EQEmu::IsTradeskill((SkillUseTypes)i) && i != SkillFishing) ||
					i == SkillAlcoholTolerance || i == SkillBindWound)
				continue;

			pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
		} */
	}
}
Thank you.

EDIT: I notice the client shows skills with values > 0 but the DB does not. I suppose the addition of quite a few more lines of code will be needed to account for the removal of the segment above to make accurate.

If this doesn't belong here please move it, thanks.
Reply With Quote
  #2  
Old 09-22-2015, 05:09 PM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Default

The client will often display hard-coded level 1 starting stats no matter what you code into the server and enter into the database. I haven't tested to see if it corrects to what the server tells it at level two.

I'd say the very easiest thing to do in that method would simply be to add a return statement after the very first opening brace. Hehe.

Code:
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{
	return;
	for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
		if (pp->skills[i] == 0) {
			// Skip specialized, tradeskills (fishing excluded), Alcohol Tolerance, and Bind Wound
			if (EQEmu::IsSpecializedSkill((SkillUseTypes)i) ||
					(EQEmu::IsTradeskill((SkillUseTypes)i) && i != SkillFishing) ||
					i == SkillAlcoholTolerance || i == SkillBindWound)
				continue;

			pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
		}
	}
}
But that's assuming you're okay with getting 1359 compilation warnings instead of 1358. :P
Reply With Quote
  #3  
Old 09-22-2015, 05:15 PM
AdrianD
Discordant
 
Join Date: Dec 2013
Posts: 297
Default

Superb! Thank you.

I'll have to add something that states something along the lines of: set 1hb = 5 if class = a,b,c,d... and set 1hs = 5 if class = e,f..

I'll have to look at similar to see what the syntax would look like.

Thanks again.
Reply With Quote
  #4  
Old 09-22-2015, 05:25 PM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Default

In the C++ code they have a couple of shortcuts so you don't have to go by individual classes, too.

IsWarriorClass() returns true for WAR, ROG, MNK, PAL, SHD, RNG, BST, BER, BRD.

GetArchectype() returns ARCHETYPE_MELEE, _CASTER, or _HYBRID depending on the class. If you aren't clear on who is and isn't a hybrid, you can see the full list in zone/mob.cpp around line 862.
Reply With Quote
  #5  
Old 09-22-2015, 05:26 PM
AdrianD
Discordant
 
Join Date: Dec 2013
Posts: 297
Default

Grateful for that, thank you Shendare.
Reply With Quote
  #6  
Old 09-22-2015, 06:26 PM
Kingly_Krab
Administrator
 
Join Date: May 2013
Location: United States
Posts: 1,589
Default

Likely, this would be easier done in Perl because it would be done as soon as the player logged in, rather than being handled by something that may or may not be hard-coded client-side, such as start skills and stuff like that.
Reply With Quote
  #7  
Old 09-22-2015, 07:06 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Quote:
Originally Posted by Kingly_Krab View Post
Likely, this would be easier done in Perl because it would be done as soon as the player logged in, rather than being handled by something that may or may not be hard-coded client-side, such as start skills and stuff like that.
Easier, yes, but efficient, no. Perl loops are horrible for performance as it locks the entire zone thread in what's basically a VM to a C++ interface.
Reply With Quote
  #8  
Old 09-22-2015, 07:18 PM
Kingly_Krab
Administrator
 
Join Date: May 2013
Location: United States
Posts: 1,589
Default

Quote:
Originally Posted by Secrets View Post
Easier, yes, but efficient, no. Perl loops are horrible for performance as it locks the entire zone thread in what's basically a VM to a C++ interface.
Yeah, super fun to lock a zone thread by creating a endless loop when using a 'while' loop. But I'm sure this could be simplified in C++ and added to the level up code by creating a client method like Client::MaxSkills or something.
Reply With Quote
  #9  
Old 09-22-2015, 07:21 PM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Default

Or a couple of rules.

Character:MaxSkillsOnCharCreate (true)
Character:MaxSkillsOnLevelUp (false)
Reply With Quote
  #10  
Old 09-22-2015, 10:32 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Quote:
Originally Posted by Kingly_Krab View Post
Yeah, super fun to lock a zone thread by creating a endless loop when using a 'while' loop. But I'm sure this could be simplified in C++ and added to the level up code by creating a client method like Client::MaxSkills or something.
No; The loop wouldn't be endless, it would end, but freeze the entire zone while it is processing. This is unacceptable by anyone's standards.

Note clients would still receive data as that's handled in another thread entirely.

The point I was making is it'd be faster to make a method in C++ that you can call from Perl as opposed from looping in Perl.
Reply With Quote
  #11  
Old 09-23-2015, 08:56 PM
AdrianD
Discordant
 
Join Date: Dec 2013
Posts: 297
Default

Below are the changes I made, it seems to work but, curious if everything looks right.

Also, I couldn't figure out how to do this using <GetArchectype>. If someone could throw me a bone, I'd appreciate it.

Code:
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{
	
			switch (pp->class_)	
			{
			case WARRIOR:
				{
				pp->skills[Skill1HSlashing] = 5;
				break;
				}
			case PALADIN:
				{
				pp->skills[Skill1HSlashing] = 5;
				break;
				}
			case RANGER:
				{
				pp->skills[Skill1HSlashing] = 5;
				break;
				}
			case SHADOWKNIGHT:
				{
				pp->skills[Skill1HSlashing] = 5;
				break;
				}
			case BARD:
				{
				pp->skills[Skill1HSlashing] = 5;
				break;
				}
			case CLERIC:
				{
				pp->skills[Skill1HBlunt] = 5;
				break;
				}
			case DRUID:
				{
				pp->skills[Skill1HBlunt] = 5;
				break;
				}
			case MONK:
				{
				pp->skills[Skill1HBlunt] = 5;
				pp->skills[SkillHandtoHand] = 5;
				break;
				}
			case SHAMAN:
				{
				pp->skills[Skill1HBlunt] = 5;
				break;
				}
			case ROGUE:
				{
				pp->skills[Skill1HPiercing] = 5;
				break;
				}
			case NECROMANCER:
				{
				pp->skills[Skill1HPiercing] = 5;
				break;
				}
			case WIZARD:
				{
				pp->skills[Skill1HPiercing] = 5;
				break;
				}
			case MAGICIAN:
				{
				pp->skills[Skill1HPiercing] = 5;
				break;
				}
			case ENCHANTER:
				{
				pp->skills[Skill1HPiercing] = 5;
				break;
				}
			case BERSERKER:
				{
				pp->skills[Skill2HSlashing] = 5;
				break;
				}
			}
}
Is it necessary to have <break;> or <continue;> at the end?

Thanks
Reply With Quote
  #12  
Old 09-23-2015, 09:02 PM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Default

Do you anticipate that you'll want to make changes on a per-class level later?

If not, you could group them together to clean it up a tad.

Code:
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{
	switch (pp->class_)	
	{
		case WARRIOR:
		case PALADIN:
		case RANGER:
		case SHADOWKNIGHT:
		case BARD:
			pp->skills[Skill1HSlashing] = 5;
			break;
		case CLERIC:
		case DRUID:
		case SHAMAN:
			pp->skills[Skill1HBlunt] = 5;
			break;
		case MONK:
			pp->skills[Skill1HBlunt] = 5;
			pp->skills[SkillHandtoHand] = 5;
			break;
		case ROGUE:
		case NECROMANCER:
		case WIZARD:
		case MAGICIAN:
		case ENCHANTER:
			pp->skills[Skill1HPiercing] = 5;
			break;
		case BERSERKER:
			pp->skills[Skill2HSlashing] = 5;
			break;
	}
}
Reply With Quote
  #13  
Old 09-23-2015, 09:03 PM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Default

Also, you're missing Beastlords. If that wasn't intended, they'd probably be grouped with Monks.
Reply With Quote
  #14  
Old 09-23-2015, 09:47 PM
AdrianD
Discordant
 
Join Date: Dec 2013
Posts: 297
Default

BST - oversight, thanks (and clarifying starting skill)

Quote:
Do you anticipate that you'll want to make changes on a per-class level later?
No, I desire <easy-mode eq: off> and I think, as far as starting skills go, this accomplishes that.

I appreciate your help =)

EDIT: I understand the implications of the corrections, for the most part. I am most thankful for that.
Reply With Quote
  #15  
Old 09-23-2015, 10:04 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

Yes, Shendare's method is more efficient!


Switch statements essentially create a jump table entry (per case value) and code paths for each entry listed in the machine code.

If no exit clause is specified, the code path will 'fall-through' every line of code until it reaches the default exit clause..meaning that every case between case entry and
default exit will be processed as true.


The fall-through behavior can be very useful for grouping like singular and progressive-compound methodologies..but, it can also be a trap if that behavior is not desired.
__________________
Uleat of Bertoxxulous

Compilin' Dirty
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 07:13 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 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3