PDA

View Full Version : Skills Question


Jujubeez
09-03-2011, 06:22 PM
Ok I've done a lot of hunting around on the forums so I've done my homework on adding/changing skills on a class and I understand that it's either impossible or just difficult. I'm referring to say giving Bard double attack. My question is to some of you who know more than me is if it is possible, how would you do it?

I've changed a lot of code on the server and in the database in the process of figuring out where this all lead to (that the client side is hard coded) so I have a good idea of how the server side works but how does one go about changing the client? Which file is that code in? Has anyone made a change like this before?

Just looking for someone to show me what would be required to make a change like this, I would really really like to customize my server in this way. I think this is one of the most glaring weaknesses in EQ, so many skills are class specific. Why can't a druid parry? Ok maybe it's 25% of a warriors, or 10% or whatever but it should be in there in my opinion.

Anyways does anyone have examples, or even just instructions on how to go about doing this?

ChaosSlayerZ
09-03-2011, 08:16 PM
one of the problems with giving classes skill they don't normal;y get is that Client won't recognize them.

Yes you CAN give Druid parry and double attack - SERVER SIDE, the client won't see it, but it will work

But even giving berserk dual wield server side, won't have any effect on them, cause client will not let you equip 2 weapons no matter what the server thinks.

so it works for most things, but not for all

KLS
09-03-2011, 09:16 PM
You can fill in the skillcaps file to make the client think it has those skills in many cases.

Jujubeez
09-03-2011, 11:40 PM
Which file are u referring to?

lerxst2112
09-04-2011, 12:11 AM
Pretty sure it's Skillcaps.txt in the resources directory.

KLS
09-04-2011, 12:25 AM
Yes the one in the resources.
Incase anyone's interested I had these two stupid scripts floating around, the top one exports skillcaps and the bottom one imports.

use DBI;

my $db = "eqdb";
my $user = "eq";
my $pass = "eqpass";
my $host = "localhost";
my $skill_caps_file = "SkillCaps.txt";
my $source = "DBI:mysql:database=$db;host=$host";
my $dbh = DBI->connect($source, $user, $pass) || die "Could not create db handle\n";

sub skill_usable {
my $skill_id = shift;
my $class = shift;

my $sth = $dbh->prepare("SELECT max(`cap`) FROM skill_caps WHERE `class`=$class and `skillID`=$skill_id");
$sth->execute();
if(my $val = $sth->fetch()) {
if(@$val[0] == 0) {
return 0;
} else {
return 1;
}
}

return 0;
}

sub get_skill {
my $skill_id = shift;
my $class = shift;
my $level = shift;

my $sth = $dbh->prepare("SELECT cap FROM skill_caps WHERE `class`=$class and `skillID`=$skill_id and `level`=$level");
$sth->execute();
if(my $val = $sth->fetch()) {
return @$val[0];
}

return 0;
}

open(SKILLS, ">$skill_caps_file") or die "Unable to open skills file for export: $skill_caps_file\n";

for($class_i = 1; $class_i <= 16; $class_i++) {
for($skill_i = 0; $skill_i <= 77; $skill_i++) {
print "($class_i, $skill_i)\n";
if(skill_usable($skill_i, $class_i) == 1) {
for($level_i = 1; $level_i <= 90; $level_i++) {
my $cap = get_skill($skill_i, $class_i, $level_i);
my $line = $class_i . "^" . $skill_i . "^" . $level_i . "^" . $cap . "^0\n";
print SKILLS $line;
}
}
}
}

close (SKILLS);

use DBI;

my $db = "eqdb";
my $user = "eq";
my $pass = "eqpass";
my $host = "localhost";
my $skill_caps_file = "SkillCaps.txt";

my $source = "DBI:mysql:database=$db;host=$host";
my $dbh = DBI->connect($source, $user, $pass) || die "Could not create db handle\n";
$dbh->do("delete from skill_caps");

open(SKILLS, "<$skill_caps_file") or die "Unable to open skills: $skill_caps_file\n";
#parse through SKILLS
while(<SKILLS>) {

chomp();
@s = split(/\^/);

my $query = "insert into skill_caps (class, skillID, level, cap) VALUES(";
$query .= $s[0];
$query .= ", ";
$query .= $s[1];
$query .= ", ";
$query .= $s[2];
$query .= ", ";
$query .= $s[3];
$query .= ")";

my $i = $dbh->do($query);
if($i < 1) {
printf("Error loading $skill_caps_file\n");
}
}

Jujubeez
09-04-2011, 10:06 AM
Ok not to sound like the village idiot, but I can't find that file anywhere. I've looked in all the client folders and server folders for any text file similar to that and I can't find anything. What resources folder are u referring to? If it's the one on the client I don't have that file. If that is the case, can it be added?

pfyon
09-04-2011, 10:19 AM
I found SkillCaps.txt in SoF, but not titanium. I guess it was something they added later on (perhaps so updating/changing skills wouldn't require the customer to download a whole new updated client).

edit: that is, in Resources/SkillCaps.txt

Jujubeez
09-04-2011, 10:32 AM
Would it be compatible with the titanium client or would I need to update my client to the SoF version? Any way you can send me that file?

ChaosSlayerZ
09-04-2011, 03:02 PM
yeah I am curious if this will work for T, like granting casters Dual Wield

Acara
09-04-2011, 07:20 PM
Thanks a lot for posting those scripts KLS, you saved me countless hours!

Jujubeez
09-04-2011, 10:07 PM
Hey thanks for all the help, I've made some headway. I can now see and train the new skills in the client, however they don't seem to be working. My druid doesn't ever parry or double attack. I've been looking pretty hard in the attack.cpp file but to the best I can tell it's checking the DB for whether or not a character can parry. There is some hard coded class stuff in there in the same function but it looks like that is for the NPC code and the clients check the DB. Any idea why the skills might not be working? Hope it's not also hard coded in the client.

blackdragonsdg
09-04-2011, 11:49 PM
I know I am missing something simple here but what is the catch to use those import/export scripts. I can tell I have something right cause the import script will delete my skill_caps table but it won't add anything to it.
What are the required perl packages/modules that I need to install? I currently have all DBD, DBI, mysql & sql packages excluding the DBIx packages. What am I missing?

KLS
09-05-2011, 12:32 AM
They carry same dependency as the import and export spells scripts. DBI and mysql. You do of course need to manually set the info since i don't read from the config file or anything.

trevius
09-05-2011, 12:45 AM
They should work basically the same as the import/export spell scripts, except you have to edit the DB info in them. You will need to run them from the command prompt something like this:

perl export_skillcaps.pl

Or, at least that is what I use on Linux.

blackdragonsdg
09-05-2011, 01:20 AM
I finally got the scripts to work. On Windows you can right click the file and open with Perl Command Line Interpreter. In order for the import script to work properly I had to put the SkillCaps.txt in C:\Windows\SysWOW64
Didn't figure that out till the export script ran properly...had to search my drives to find it.

It may have just been my computer configuration but I think the windows version of perl requires some additional perl packages to be installed. That may be different in some Linux versions as perl comes as part of the OS install...Ubuntu is a good example of that.

KLS
09-05-2011, 01:24 AM
I had to install the DBI stuff on windows with activeperl but otherwise worked perfectly if it can't find it in the directory its run from sounds like a perl configuration issue.

blackdragonsdg
09-05-2011, 01:29 AM
Could running the scripts from my desktop had anything to do with the file input/output location?

lerxst2112
09-05-2011, 02:41 AM
It just looks for the file in the current directory, so if your skillcaps.txt file wasn't on the desktop too then that's likely the problem.

Jujubeez
09-05-2011, 10:25 AM
But do the skills you added actually work? So far mine look the part but don't work in combat. Wondering if I need to edit the code.

Jujubeez
09-05-2011, 11:05 AM
I figured it out. You will have to edit the mob.cpp file for each skill you add.. woohoo thanks for the help guys!

NickW
06-02-2014, 04:53 PM
I am so confused here.. Wanted to find a way to give SK track skill. But, I can't make any sense out of the info here. I found the skillcaps.txt. I tried to run the script as a .vbs file. I must be screwing something up.. :confused:

Mortow
06-02-2014, 06:28 PM
To add skills to a class, you have to modify both your skill_caps table in your database and your SkillCaps.txt file. SkillCaps.txt is located in the Resources folder under your Everquest directory. I think the SkillCaps.txt file has to match on both your server and client. I know it has to be the udated one in the client Everquest folder.

If you want to add Tracking to an SK, go to your skill_caps table in your database ( I use HeidiSQL for this) and go to the data tab and hit Show All. Scroll down until you see Skill 51 (51 is Throwing) for Class 5 (5 is SK). Follow this until it ends at level 100 or whatever level yours ends at. You will see the skill column skip from 51 to 55. Insert your data here. Do not skip any levels. If you do not want your SKs to get Tracking until level 10 then fill in levels 1 thru 10 with a cap of 0, else you will be able to use it at level 1.

Next go to your SkillCaps.txt file and open it with Notepad++ the first two columns in it are reversed from the one in the database table. Scroll down in it until you see 5^51^100^400^0 or whatever is the last 5^51 in your file and insert your data here as well.

I hope that helps you.

demonstar55
06-02-2014, 08:18 PM
If you select to build the client files tools, you just run the export_client_files program after editing the database. (Note make sure you make a directory named export before running)


The Perl script failed to run as a vbs script because its a Perl script not a vbs script.

NickW
06-03-2014, 05:16 AM
To add skills to a class, you have to modify both your skill_caps table in your database and your SkillCaps.txt file. SkillCaps.txt is located in the Resources folder under your Everquest directory. I think the SkillCaps.txt file has to match on both your server and client. I know it has to be the udated one in the client Everquest folder.

If you want to add Tracking to an SK, go to your skill_caps table in your database ( I use HeidiSQL for this) and go to the data tab and hit Show All. Scroll down until you see Skill 51 (51 is Throwing) for Class 5 (5 is SK). Follow this until it ends at level 100 or whatever level yours ends at. You will see the skill column skip from 51 to 55. Insert your data here. Do not skip any levels. If you do not want your SKs to get Tracking until level 10 then fill in levels 1 thru 10 with a cap of 0, else you will be able to use it at level 1.

Next go to your SkillCaps.txt file and open it with Notepad++ the first two columns in it are reversed from the one in the database table. Scroll down in it until you see 5^51^100^400^0 or whatever is the last 5^51 in your file and insert your data here as well.

I hope that helps you.

Edit: My SK in-game has track skill and I can activate it just fine. But, nothing shows up on track. No matter how much skill in tracking I have.. Any ideas?

http://i58.tinypic.com/rapan9.jpg

I figured it out. You will have to edit the mob.cpp file for each skill you add.. woohoo thanks for the help guys!

Digging around in the mob.cpp file I can't find anything about track..



Here's both my skillcaps files after the changes:
http://i62.tinypic.com/67jd51.jpg

http://i61.tinypic.com/fn47bq.jpg

P.S. If I continue to scale track skill past 200 will it keep increasing in effectiveness? Or will I break something..?

demonstar55
06-03-2014, 11:28 AM
EntityList::MakeTrackPackets in zone/entity.cpp has some class checks.

NickW
06-03-2014, 12:29 PM
EntityList::MakeTrackPackets in zone/entity.cpp has some class checks.

I added in shadowknight.

http://i61.tinypic.com/22e49l.jpg

Still the same problem as before. Empty track window in-game. :,(

NickW
06-06-2014, 05:58 PM
http://forums.axclassic.com/viewtopic.php?f=1&t=2715

Seems like they had a similar problem. They don't say how they went about fixing it though.. :confused:

Would very much like to make this work. If anyone knows how?

Mortow
06-06-2014, 09:24 PM
Did you recompile after making the change to the entity.cpp file?

NickW
06-06-2014, 10:26 PM
Did you recompile after making the change to the entity.cpp file?

Nope. :shock:

Do I just redo step four in the guide?


"Step 4: Compiling the server.
*a) Get (Git) the source code!

Now on your main C-Drive, expand the EQ folder and then right click on the folder called Source.
From the menu that pops up, select 'GIT Bash'.
A command window should pop up (similar but not the same as the standard Windows command prompt).
Type the following EXACTLY (including the period at the end):

git clone git://github.com/EQEmu/Server.git .


*Note the . at the end of the command*, i.e. there is a space after Server.git and then a period/full-stop. This is important. It tells GIT to clone the source code into the current folder , i.e. C:\EQ\Source If you omitted the . it would create a new folder called C:\EQ\Source\Server and download the source into that.
The output of the git clone command should look similar to this:



Cloning into '.'...
remote: Counting objects: 1288, done.
remote: Compressing objects: 100% (1070/1070), done.
remote: Total 1288 (delta 225), reused 1262 (delta 199)
Receiving objects: 100% (1288/1288), 3.17 MiB | 856 KiB/s, done.
Resolving deltas: 100% (225/225), done.
Checking out files: 100% (1181/1181), done.

If you go to C:\EQ\Source in Windows Explorer, you should see a bunch of files and sub-folders have appeared, namely
CMakeLists.txt LICENSE.md cmake eqlaunch ucs zone shared_memory README.md common loginserver utils GPL.txt changelog.txt dependencies queryserv world
Note that if you want to update your source code in the future to the latest version, follow the process above, but instead of typing 'git clone ...' you would just type:

git pull


and that would check for updates to the source code and download the latest version if there have been any changes since you last did a git clone or git pull."

NatedogEZ
06-06-2014, 11:47 PM
Just open the SLN file.. and hit compile :) after you have made whatever changes to the source files.

NickW
06-07-2014, 08:56 AM
Just open the SLN file.. and hit compile :) after you have made whatever changes to the source files.

Gotcha, thanx. So I recompiled the skill_caps.cpp and entity.cpp

http://i59.tinypic.com/123phs4.jpg

http://i58.tinypic.com/30bpuuv.jpg

Still no change in-game though. No matter which zone I try there is never anything on track..

http://i62.tinypic.com/2gvlycj.jpg

Was there another step after recompiling those files?.. :confused:

lerxst2112
06-07-2014, 03:46 PM
You need to select build to build the solution (F7), then you need to copy the newly built executables to your server directory.

NickW
06-07-2014, 05:48 PM
You need to select build to build the solution (F7), then you need to copy the newly built executables to your server directory.

http://i60.tinypic.com/1z1tlwh.jpg

http://i59.tinypic.com/33xyg6c.jpg

http://i59.tinypic.com/24mwdxj.jpg

Still no change. Nothing on track regardless of track skill/distance/zone/mobs. I think the gods are against me..

lerxst2112
06-07-2014, 06:12 PM
You know, you could just say you did it, the giant screen shots add nothing to the conversation.

NatedogEZ
06-08-2014, 01:19 AM
This does work... but there are a few other areas you NEED to change!



client_packet.cpp

void Client::Handle_OP_TrackTarget(const EQApplicationPacket *app)
{
int PlayerClass = GetClass();

if((PlayerClass != RANGER) && (PlayerClass != DRUID) && (PlayerClass != BARD) && (PlayerClass != WARRIOR))
return;

if (app->size != sizeof(TrackTarget_Struct))
{
LogFile->write(EQEMuLog::Error, "Invalid size for OP_TrackTarget: Expected: %i, Got: %i",
sizeof(TrackTarget_Struct), app->size);
return;
}

TrackTarget_Struct *tts = (TrackTarget_Struct*)app->pBuffer;

TrackingID = tts->EntityID;
}

void Client::Handle_OP_Track(const EQApplicationPacket *app)
{
if(GetClass() != RANGER && GetClass() != DRUID && GetClass() != BARD && GetClass() != WARRIOR)
return;

if( GetSkill(SkillTracking)==0 )
SetSkill(SkillTracking,1);
else
CheckIncreaseSkill(SkillTracking, nullptr, 15);

if(!entity_list.MakeTrackPacket(this))
LogFile->write(EQEMuLog::Error, "Unable to generate OP_Track packet requested by client.");

return;
}




Notice all I did was add Warrior to those 2 functions .. plus I added warrior to the one you posted earlier as well..


Hopefully this helps :)








This is it working on a warrior
http://i.imgur.com/hfdUdUE.png

NickW
06-08-2014, 08:43 AM
This does work... but there are a few other areas you NEED to change!



client_packet.cpp

void Client::Handle_OP_TrackTarget(const EQApplicationPacket *app)
{
int PlayerClass = GetClass();

if((PlayerClass != RANGER) && (PlayerClass != DRUID) && (PlayerClass != BARD) && (PlayerClass != WARRIOR))
return;

if (app->size != sizeof(TrackTarget_Struct))
{
LogFile->write(EQEMuLog::Error, "Invalid size for OP_TrackTarget: Expected: %i, Got: %i",
sizeof(TrackTarget_Struct), app->size);
return;
}

TrackTarget_Struct *tts = (TrackTarget_Struct*)app->pBuffer;

TrackingID = tts->EntityID;
}

void Client::Handle_OP_Track(const EQApplicationPacket *app)
{
if(GetClass() != RANGER && GetClass() != DRUID && GetClass() != BARD && GetClass() != WARRIOR)
return;

if( GetSkill(SkillTracking)==0 )
SetSkill(SkillTracking,1);
else
CheckIncreaseSkill(SkillTracking, nullptr, 15);

if(!entity_list.MakeTrackPacket(this))
LogFile->write(EQEMuLog::Error, "Unable to generate OP_Track packet requested by client.");

return;
}




Notice all I did was add Warrior to those 2 functions .. plus I added warrior to the one you posted earlier as well..


Hopefully this helps :)








This is it working on a warrior
http://i.imgur.com/hfdUdUE.png

It works! Thank you everybody. I seriously love this community. So damn helpful! :D

You know, you could just say you did it, the giant screen shots add nothing to the conversation.

As for the screenshots. If they bother people. I will most definitely stop using them. When people who understand what's going on are trying to help someone who is clueless. In other words me.. They usually assume the person isn't following their directions correctly. And that's why it isn't working for them. The screenshots are my attempt to show exactly how I did what, where, etc.. In case i did screw something up. :)

That was my thought process anyway..

AdrianD
07-24-2015, 07:44 AM
Those screen shots help people like me who do not have the knowhow or experience to do it without a little hand holding. Don't shun it unless you want to keep the community small.

I know I necro'd this... to SHOW you I was researching it before I start a new thread with my own question! BFD, don't read it then...