|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Support::Windows Servers Support forum for Windows EQEMu users. |
|
|
|
09-22-2015, 04:45 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
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.
|
|
|
|
|
|
|
09-22-2015, 05:09 PM
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
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
|
|
|
|
09-22-2015, 05:15 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
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.
|
09-22-2015, 05:25 PM
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
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.
|
09-22-2015, 05:26 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
Grateful for that, thank you Shendare.
|
09-22-2015, 06:26 PM
|
Administrator
|
|
Join Date: May 2013
Location: United States
Posts: 1,594
|
|
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.
|
09-22-2015, 07:06 PM
|
|
Demi-God
|
|
Join Date: May 2007
Location: b
Posts: 1,447
|
|
Quote:
Originally Posted by Kingly_Krab
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.
|
09-22-2015, 07:18 PM
|
Administrator
|
|
Join Date: May 2013
Location: United States
Posts: 1,594
|
|
Quote:
Originally Posted by Secrets
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.
|
09-22-2015, 07:21 PM
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
Or a couple of rules.
Character:MaxSkillsOnCharCreate (true)
Character:MaxSkillsOnLevelUp (false)
|
09-22-2015, 10:32 PM
|
|
Demi-God
|
|
Join Date: May 2007
Location: b
Posts: 1,447
|
|
Quote:
Originally Posted by Kingly_Krab
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.
|
|
|
|
09-23-2015, 08:56 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
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
|
|
|
|
09-23-2015, 09:02 PM
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
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;
}
}
|
09-23-2015, 09:03 PM
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
Also, you're missing Beastlords. If that wasn't intended, they'd probably be grouped with Monks.
|
09-23-2015, 09:47 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
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.
|
09-23-2015, 10:04 PM
|
|
Developer
|
|
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
|
|
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
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 11:15 AM.
|
|
|
|
|
|
|
|
|
|
|
|
|