Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

coding/loading specific entities through a script file? Goto page 1, 2, 3 Next

| Inside3d Forums Forum Index -> QuakeC Programming

View previous topic :: View next topic
Author | Message
--- | ---
ceriux Joined: 06 Sep 2008 Posts: 969 Location: Florida, USA |

Posted: Mon Oct 13, 2008 5:39 pm Post subject: coding/loading specific entities through a script file? |

basically //monster monster.name = name monster.hp = x/x monster.atk = x
monster.skills = (skill1,skill2,skill3,ect...)
monster.drops = (item.drop)
monster.gold = x
monster.xp = x
//items
item.name = name
item.atk = x
item.sell = x
item.buy = x
item.atrrib = (atb1,atb2,ect)
item.slot = (slot)
i think you get the idea from that....
just wanting to know if its possible... and if so can anyone help me out with it... its a little advanced for me... but iv always wanted my own rpg mod. so... it would be nice if anyone can help.
_________________
QuakeDB - Quake ModDB Group

Back to top |

MeTcHsteekle Joined: 15 May 2008 Posts: 397 Location: its a secret |

Posted: Mon Oct 13, 2008 7:15 pm Post subject: |

try forum digging http://forums.inside3d.com/viewtopic.php?t=990 i'm not sure if it will help though :/ _________________ bah

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Mon Oct 13, 2008 7:37 pm Post subject: |

There are three methods that come to mind. 1) The first is to make a script like Frikbot's waypoint files, or TomazQuake's character files. It's basically a series of impulses telling the code each bit of data. You can have an html file with javascript that lets you set all the properties of the monster/item/etc, and then it generates the config file that you need to place in your mod directory (and maybe add its filename to a main config file).
The problem with this method is the map tends to be already loaded before such a config file could run, so then you have to delay having the monsters spawn until the script finishes, and that can create model/sound precache issues etc. However, this method is normal quake friendly, requiring no special engine features.
2) A variation of the first method, this method uses an engine like darkplaces to create a bunch of cvars for the script to set. The script would need to run before the level is allowed to load, to avoid the problem above, but it could be done. And this way, your config file is a bit more user-friendly and you might not need a web page to write it for you.
3)*** FRIK_FILE all the way (recommended if you're not dedicated to compatibility with all engines). FRIK_FILE is an engine feature supported by darkplaces and others, giving you some fairly powerful file read/write tools. Conquest uses this feature to write a file containing the player's weapons and other data, so that it can carry information between maps that wouldn't fit in the parms. I can point you over to this code if it will help you.
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

ceriux Joined: 06 Sep 2008 Posts: 969 Location: Florida, USA |

Posted: Mon Oct 13, 2008 8:43 pm Post subject: |

i can check it out, is there any tutorials or anything that shows you how to use frikfile? it seems to be the best from what iv seen alot of mods use it. _________________ QuakeDB - Quake ModDB Group

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Tue Oct 14, 2008 3:51 am Post subject: |

NOTE: long post ahead. The first section explains FRIK_FILE and describes conquest's load code as an example. The second half of the post describes options for your file format and gives example code. I can't find any frik_file tutorials on inside3d. That would be a good thing for someone to write. The commands are very similar to file input/output commands in other languages like C and PHP, so I guess most people with a programmer background don't think about writing a tutorial for people who aren't familiar with that stuff already.
Conquest has its file input/output code in src/file.qc, if that helps. Some of that code may confuse you though so here's the gist of how it works:
The first step is to open the file. In this example we'll be loading data from a file, but writing data out to a file isn't too different. This code is near the start of the PlayerLoadFile function.

Code:
local string filename, temp; local float fhandle; filename = "yourfilenamehere.txt"; fhandle = fopen(filename, FILE_READ); if(fhandle < 0)
return 2;

This code creates a couple of strings (temp will be used later) and a float for the "file handle". Then it loads the file and assigns a "file handler" to the variable fhandle. We'll use this file handler later in the code when we want to read from the file. If fhandle is negative, that means there was an error trying to open the file and we should quit out (in this example, returning a non-zero number from this function tells the function above that there was an error).
Now my Conquest file format isn't super-archaic and unfriendly, but it's probably not the type of config file you're looking for. I'll continue with the example, and then describe ways you can do a more conventional and reader-friendly config file.
Next, my code calls the LoadStats function. It's just a series of "load a string, convert it to a float" pieces of code.

Code:
float(float fhandle) LoadStats = { local string temp; // get health temp = fgets(fhandle);
self.health = stof(temp);
// get max health
temp = fgets(fhandle);
self.max_health = stof(temp);
// get armortype
temp = fgets(fhandle);
self.armortype = stof(temp);
// get armorvalue
temp = fgets(fhandle);
self.armorvalue = stof(temp);
// get credits
temp = fgets(fhandle);
self.credits = stof(temp);
// get gold
temp = fgets(fhandle);
self.cgold = stof(temp);
return FALSE; // no errors
};

The function "fgets" is short for "file get string". It grabs one line of text and returns it as a string. It stores the pointer to this string in the temp variable. Then it uses stof ("string to float") to convert it and store it in one of the float variables for the player. My file format is not very self-describing, it's just one float value after another in a certain order, with sections separated by special strings like "*WPN*" and "*END*". Those strings are there to make the file a little more easy for me to read, and so the file load code can look for them and make sure it's on the right track (error checking, I'll discuss that below).
Here's an example conquest save file:

Code:
50 100 0 0 1201
0
*WPN*
0
0
0
4
111
0
21
8
0
0
0
0
0
0
0
*SH*
1
3
100
1
3
100
1
2
100
*MN*
*END*
*ITEM*
*END*
*EOF*

The top 6 lines before *WPN* are the ones the code above loaded, in the order of health, max health, armortype, armorvalue, credits, gold. Each use of fgets moves your current location in the file down by 1 line, so that the next call to fgets automatically grabs the line after it (you don't have to manually say where to read from the file each time).
Back in the PlayerLoadFile function, after the LoadStats function finishes, my code does a check to make sure the file isn't corrupted or wrong in some other way:

Code:
// check if we've reached weapons now temp = fgets(fhandle); if(temp != "*WPN*") return 4; // something is wrong with the file

Basically, this is a sanity check to make sure we know where we are in the file and we won't be loading bad data in by continuing. If there's something wrong and it doesn't load the *WPN* string, it returns out of the function with an error code (in this case, 4).
This is not necessary, but it helped me to debug my code and figure out what I was doing wrong. I do think it's something you'll be doing in your config files because humans will be editing the file by hand and mistakes can be made, and mistakes can lead to bad data being loaded if you don't check for them. So, it's a good think to look for (note that your checks will look different though; I'll show you more later).
The next bit of code just calls the function to grab the weapon block, which stores the weapons and ammo amounts etc the player has in each slot. The same for shields in the next few lines.

Code:
// check if we've reached weapons now temp = fgets(fhandle); if(temp != "*WPN*") return 4; // something is wrong with the file if(LoadWeapons(fhandle))
return 5;
// check if we've reached shields now
temp = fgets(fhandle);
if(temp != "*SH*")
return 4; // something is wrong with the file
if(LoadShields(fhandle))
return 6;

The next couple of sections in this function may be of interest to you. In Conquest I was planning on letting the player have one or more "pets", or monsters that follow him around and fight along side him. I'm still considering it, in fact. However, this is, as of yet, unimplemented. Look at the next section of the code anyway:

Code:
// Start loading monsters temp = fgets(fhandle); while(temp == "*MN*") { if(LoadPets(fhandle))
return 7; // something is wrong with the file
temp = fgets(fhandle);
}

This section of code allows multiple sections that start with the *MN* tag. This means you could have a *MN* block for a rottweiler followed by a *MN* tag for a shambler, and so on. The code will continue to read the monster data until it encounters something else. The final fgets that's called when the loop finishes grabs the *END* line, which is just there as junk data for the file reader to consume without making my day more difficult.
Finally, we reach the end. We close the file, and leave the function:

Code:
fclose(fhandle);

--------------------------
And now for your monster and item configuration files, which are much cooler than my save files imo...
You have a few options. You could write a config file that looks like mine, and just assumes the person writing the configs knows what order the numbers go in and what should go in it. It's rather user-unfriendly, but it gets the job done. Since Conquest's save files are not meant to be changed by hand normally (you could do it to cheat, but you don't need to touch it otherwise), that's a very good solution for that mod. Your mod is different.
The next option is to do a rigid structure as above, but to have a label above each line so the user knows what to place there. For example, monsters/shambler.txt:

Code:
NAME Shambler MODEL progs/shambler.mdl HP
600
ATK
35
SKILL1
Claw
SKILL2
Thunderbolt
SKILL3
DROPS
items/health_pack3.txt
GOLD
1200
XP
6400

The code for this would look very similar to mine, except that before it grabs each piece of data it first does a fgets to grab the label above it. Before getting the string "Shambler", it needs to get the string "NAME". Most likely, it throws this string away, but it's really not a bad idea to also do sanity checks and file format validation with it like I do below.

Code:
float(float fhandle, entity e) LoadMonster = { local string temp; // get name temp = fgets(fhandle);
if(temp != "NAME")
return 1;
temp = fgets(fhandle);
e.netname = temp;
// get model
temp = fgets(fhandle);
if(temp != "MODEL")
return 1;
temp = fgets(fhandle);
e.model = temp;
// get health
temp = fgets(fhandle);
if(temp != "HP")
return 1;
temp = fgets(fhandle);
e.health = stof(temp);
// get attack power
temp = fgets(fhandle);
if(temp != "ATK")
return 1;
temp = fgets(fhandle);
e.attack = stof(temp);
// LoadMonsterSkill loads the skill string, then decides which
// skill that correlates to and sets the skill property on e.
// If a skill is empty, that is not an error since not all
// monsters have 3 skills.
// get skill1
if(LoadMonsterSkill(fhandle, e, 1))
return 1; // error loading skill!
// get skill2
if(LoadMonsterSkill(fhandle, e, 2))
return 1; // error loading skill!
// get skill3
if(LoadMonsterSkill(fhandle, e, 3))
return 1; // error loading skill!
// get filename for item dropped.
// We could call an additional function to load in that item's
// info right now (which may be a good idea if we need to precache
// any files), or we could load it on demand when the monster dies
// and drops its item.
temp = fgets(fhandle);
if(temp != "DROPS")
return 1;
temp = fgets(fhandle);
e.itemRewardFilename = temp;
// get gold reward
temp = fgets(fhandle);
if(temp != "GOLD")
return 1;
temp = fgets(fhandle);
e.gold = stof(temp);
// get xp reward
temp = fgets(fhandle);
if(temp != "XP")
return 1;
temp = fgets(fhandle);
e.xp = stof(temp);
return FALSE; // no errors
};

Note that I'm pulling something tricky here. Since items are custom too, I just point to the item's filename. This means I don't necessarily have any ITEM_HEALTH3 stuff defined in code anywhere, it could be all custom stuff in the file. You don't have to do it that way, but I thought it could lead to an elegant solution.
Also note that I'm being lazy with the SKILL1, SKILL2, SKILL3 stuff. We could instead load skills in the same way that we load monsters in conquest: use a loop to load 1 or more skills. The loop quits when it reaches the end tag instead of another SKILL tag. But this was just an example, and you can implement your real code a number of ways.
The LoadMonsterSkill function itself is a little less generic than the previous function. It needs to turn a string (like Thunderbolt or Explosives Resistance) into a function name or float, or some other data that the code can use to determine what that skill *does* in-game. It could be something like this:

Code:
float(float fhandle, entity e, float slot) LoadMonsterSkill = { local string temp; local float skillNum; if(slot < 1 || slot > 3)
return 1; // invalid slot
// get name
temp = fgets(fhandle);
if(!(temp == "SKILL1" && slot == 1) && !(temp == "SKILL2" && slot == 2) && !(temp == "SKILL3" && slot == 3))
return 1;
temp = fgets(fhandle);
// determine if it's a recognized skill name
if(temp == "") // blank means no skill
skillNum = 0; // no skill in this slot
else if(temp == "Thunderbolt")
skillNum = SKILL_THUNDERBOLT;
else if(temp == "Claw Frenzy")
skillNum = SKILL_CLAWFRENZY;
else if(temp == "Flame Spikes")
skillNum = SKILL_FLAMESPIKES;
// add more skills here
// if it wasn't recognized
else skillNum = 0; // no skill in this slot
if(slot == 1)
e.skill1 = skillNum;
else if(slot == 2)
e.skill2 = skillNum;
else e.skill3 = skillNum;
return 0; // no errors
}

Another option is to have the skill entry for your monster point to yet another config file that specifies a bunch of information about the skill. The filename would contain the id of the base skill, and everything from there would be customizable. Then you'd have a system similar to Warcraft III's ability editor. You can take any existing ability (like the firebolt spell), make a copy of it, and set new values.
That, however, is much more complex and should be saved for later.
SO, this gives you some ideas. The code I gave you may help, but it's completely uncompiled and untested so I'm not able to guarantee its usability out-of-the-box. Note that Prydon Gate (a mod by FrikaC and a number of other folks in the community) may have a similar system for defining monsters. You might ask Frik and company about it -- their system may be much better developed and easier to use.
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

ceriux Joined: 06 Sep 2008 Posts: 969 Location: Florida, USA |

Posted: Tue Oct 14, 2008 5:45 am Post subject: |

wow.... o.O im going to have to read this like 20 times hehe... ill eventually get it. but im dedicated! since i knew modding exsited iv wanted to make a rpg ! IM GOING TO DO IT! lol sorry thanks im sorta blown -.- _________________ QuakeDB - Quake ModDB Group

Back to top |

Spike Joined: 05 Nov 2004 Posts: 944 Location: UK |

Posted: Tue Oct 14, 2008 9:43 am Post subject: |

Alternatively you can use the tokenize builtin. void(string fname) readstuff = { file = fopen(fname, FILE_READ); while(1)
{
str = fgets(file);
if (str) {} else
break; //found an eof
tokenize(fgets(file));
switch(argv(0))
{
case ""://blank line
break;
case "MONSTER"://monster line
name = argv(1);
hp = argv(2);
atk = argv(3);
skill1 = argv(4);
skill2 = argv(5);
drops = argv(6);
gold = argv(7);
xp = argv(8);
dostuff(name, hp, atk, skill1, skill2);
break;
case "PET":
yourcodehere = argv(1);
dostuff2(yourcodehere);
break;
default:
dprint("I don't know what you mean by ", argv(0));
break;
}
}//while(1)
fclose(file);
};
Then you can use a tab-seperated/quoted file with nice alignment and its easier to compare the different monsters etc. Use a double slash as a comment. No need to constantly check for eof, just once per item. Although its not so convienient when you have lots of items.
Really it depends how many items you're gonna have in your database type file.
Tokenizing like that is more awkward if you wish to write the file in qc, but it does simplify the code slightly.
Whatever works.
Enjoy!
the if (str) {} else thing looks weird, yeah...
fgets in DP/FTE distinguishes between an empty string and a null string to show blank line or end-of-file. Although I don't remember this part being documented in the extension...
if (str) checks its bitwise value, while if (!str) is equivelent to the more conventional if (str =="")... which is not what you want, as that makes no distinction between null and empty, as null is empty in quakec.
Hexenc notation allows if not(str) but only fteqcc supports that. And hexenc compilers too, but mneh, they don't count.
_________________
What's a signature?

Back to top |

jim Joined: 05 Aug 2005 Posts: 400 Location: In The Sun |

Posted: Tue Oct 14, 2008 4:58 pm Post subject: |

Here's how I've used to save and load stuff for player, currently they only save and load float values, but they could be easily modified to load strings and stuff for other entities:

Code:
//============================================================================== // P_SaveStats // save player external data for level change //============================================================================== void(string filename, string stuffname, float value) P_SaveStats =
{
local float fhandle;
// open file, and start adding stuff
fhandle = fopen (filename, FILE_APPEND);
fputs(fhandle, stuffname);
fputs(fhandle, " ");
fputs(fhandle, ftos(value));
fputs(fhandle, "\n");
fclose(fhandle);
};
//==============================================================================
// P_LoadStats
// load player external data for level change
// returns value for player, this doesn't set the value to the right float
// can load values with max 10 numbers
//==============================================================================
float(string filename, string stuffname) P_LoadStats =
{
local float fhandle, stufflength, value;
local string str1, str2, str3;
// length of the stuff
stufflength = strlen(stuffname);
// open the file
fhandle = fopen(filename, FILE_READ);
// go through the file until found stuffname
while(str2 != stuffname)
{
// whole string
str1 = fgets(fhandle);
// found a string
if(str1)
{
}
// didn't find the string
else
return 0;
// name of the string
str2 = substring(str1, 0, stufflength);
// value of the string, add one to stufflength, because there's a space after the name
str3 = substring(str1, stufflength + 1, 10);
value = stof(str3);
}
fclose(fhandle);
// return the value of the stat for player
return value;
};

Then this is how they're being used in SetChangeParms:

Code:
// clear the stats file first by doing an empty write: fhandle = fopen ("player_stats.txt", FILE_WRITE); fclose(fhandle); // now start saving the stats, every line append to the freshly cleared file P_SaveStats("player_stats.txt", "ammo_needles_poison", self.ammo_needles_poison);
P_SaveStats("player_stats.txt", "wpn_egun", self.wpn_egun);
P_SaveStats("player_stats.txt", "rld_egun_right", self.rld_egun_right);
P_SaveStats("player_stats.txt", "rld_egun_left", self.rld_egun_left);

Then this how they're loaded in DecodeLevelParms:

Code:
// load player external stats self.ammo_needles_poison = P_LoadStats("player_stats.txt", "ammo_needles_poison"); self.wpn_egun = P_LoadStats("player_stats.txt", "wpn_egun"); self.rld_egun_right = P_LoadStats("player_stats.txt", "rld_egun_right");
self.rld_egun_left = P_LoadStats("player_stats.txt", "rld_egun_left");

They generate a text file that looks like this:

Code:
ammo_needles_poison 240 wpn_egun 2 rld_egun_right 4 rld_egun_left 18

edit: slightly edited.. the file now got a space after the name of the string
_________________
zbang!

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Tue Oct 14, 2008 8:14 pm Post subject: |

jim: That looks more user-friendly because you can load specific values independently, but it seems like that would be a very inefficient way to load all the stats at once (since it has to reopen the file and read some distance through it for each stat you want to load). That code would be really good if you only needed to load individual bits of information at different times during the game, but if you need all of the information it's best to load them all with a single file read.
Still, a good option to consider if he'll be using that kind of stuff in his mod.
Spike:
I was wondering if there was a tokenize function out there. That would let him have a file format like this:

Code:
name Shambler model progs/shambler.mdl hp 600 (etc)

_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Tue Oct 14, 2008 8:17 pm Post subject: |

Oh, and ceriux, I hope it's not too exhausting. Let us know if you need any help understanding or implementing this, we're happy to assist. It's really cool to see someone dedicated to making his dream mod. _________________ When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

ceriux Joined: 06 Sep 2008 Posts: 969 Location: Florida, USA |

Posted: Tue Oct 14, 2008 8:28 pm Post subject: |

well like i said when i was ehh.... (yeah...) im just going to have to read it a few times... i dont want to have to ask you guys to help me too much. im sure im going to have to ask for help eventually though, im sure of it. the last thing you mentioned though would help out though a mod similar to what i want to make (but completely different than what i want) uses script files ill see if i can get a hold of one so u can see what theirs looked like. But it was a hl1 mod so -.- i dont know if its 100% possible.
oh and here's a basic idea of how i want leveling up to work , cause i started thinking and i think my script files will have to be tied into it -.-
basically the player gets to choose to level up there mains stats by adding points into them.
// Main stats
str 0
int 0
agi 0
then players also have their ablility skills, ability skills determine how efficient a player will be with something. like so:
//Ability skills
Sword 0
shield 0
bow 0
axe 0
blunt 0
//magic ability skills
restore 0
destroy 0
alter 0
// parry skill
parry 0 - anyone who doesnt use a shield would get this. some weapons would also raise it more than others.
ability skills are leveled in a different way than the mains stats when ever you use an item or magic skill, so much of the exp goes into that skill till it levels up, so a user who always uses a sword will be murch more effeicent with it than a user who likes magic.
your mains stats also play a big role in how well you use a certain item, if your str is lets say 10 and ur int is only 1 and your trying to cast magic alot to raise your magic skill, you will be aloud to and your magic will get stronger but it will never be as strong as a user who raises int and not str.
this allows for a multiple veriety of gamer styles and even someone who likes to do a little more of everything.
id also like to implement a trade skill group which wouldnt tie into either of the other skill types and neither would effect the trade skills either.
//trade skills
mining 0
alchemy 0
smithing 0
ect...
_________________
QuakeDB - Quake ModDB Group
Last edited by ceriux on Tue Oct 14, 2008 8:51 pm; edited 1 time in total

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Tue Oct 14, 2008 8:31 pm Post subject: |

I imagine it's very possible. You could even do a custom scripting language for the monster abilities or spells in this way, but it would be very complicated to implement even for someone like me. But for the cfg files you wanted, the file format I listed in that latest post is very doable and should actually be quite easy with Spike's tokenize code.
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

ceriux Joined: 06 Sep 2008 Posts: 969 Location: Florida, USA |

Posted: Tue Oct 14, 2008 8:53 pm Post subject: |

iv updated my info on what im doing a little bit in the post before yours wazat, i dont know if anyone would notice because i updated it while u were posting, but would all of that be possible? _________________ QuakeDB - Quake ModDB Group

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Tue Oct 14, 2008 9:08 pm Post subject: |

Well, rather than edit the post it may have been better to simply make a new post so it wouldn't break thread continuity and be confusing to people reading the posts after... But anyway, everything you're talking about is possible. The easiest is the stats that build automatically with use -- when you hit an enemy with a sword, for example, it adds some fraction to your proficiency with swords. edit: likewise, when you hit an enemy with a sword it checks your proficiency with swords to determine how much damage you deal.
Ability scores that require the user to choose where points go are a little more difficult. You need to provide some form of menu for the player. You could do Conquest-styled QC menus, or something like this, depending on which you prefer to try to implement and which would be best for the user, etc. You'll also want menus for simply viewing their ability scores, inventory, etc.
Then, any time you swing a sword, cast a spell, etc, it just checks the relevant ability scores, skills, etc that affect your damage or effectiveness with that action.
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

ceriux Joined: 06 Sep 2008 Posts: 969 Location: Florida, USA |

Posted: Tue Oct 14, 2008 9:18 pm Post subject: |

Awsome... now time to start figuring out how im going accomplish all of this... anyway here's the re-post of what im going to be doing so others dont get confused and can fallow whats happening.

Quote:
oh and here's a basic idea of how i want leveling up to work , cause i started thinking and i think my script files will have to be tied into it -.- basically the player gets to choose to level up there mains stats by adding points into them.
// Main stats
str 0
int 0
agi 0
then players also have their ablility skills, ability skills determine how efficient a player will be with something. like so:
//Ability skills
Sword 0
shield 0
bow 0
axe 0
blunt 0
//magic ability skills
restore 0
destroy 0
alter 0
// parry skill
parry 0 - anyone who doesnt use a shield would get this. some weapons would also raise it more than others.
ability skills are leveled in a different way than the mains stats when ever you use an item or magic skill, so much of the exp goes into that skill till it levels up, so a user who always uses a sword will be murch more effeicent with it than a user who likes magic.
your mains stats also play a big role in how well you use a certain item, if your str is lets say 10 and ur int is only 1 and your trying to cast magic alot to raise your magic skill, you will be aloud to and your magic will get stronger but it will never be as strong as a user who raises int and not str.
this allows for a multiple veriety of gamer styles and even someone who likes to do a little more of everything.
id also like to implement a trade skill group which wouldnt tie into either of the other skill types and neither would effect the trade skills either.
//trade skills
mining 0
alchemy 0
smithing 0
ect...

_________________
QuakeDB - Quake ModDB Group

Back to top |

Display posts from previous:

| Inside3d Forums Forum Index -> QuakeC Programming | All times are GMT Goto page 1, 2, 3 Next
Page 1 of 3

Jump to:

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2004 phpBB Group