/* *************************************************************************** * Original Author: Jason Yarber (jasonyarber@hotmail.com) * Rewritten by: Jeremy Maloney (jkm4802@hotmail.com) aka Armageddon * Purpose: Changes exp, thaco and saving throw tables to formulas. * File to edit: class.c * Date of Origin: Sept 20, 2001 - revised Oct 23, 2002 (JM) * ************************************************************************* */ ------------------------------------------------------------------------------ STEP ONE - Death to Saving Throw Tables! MUHAHAHA! ------------------------------------------------------------------------------ * [Instruction #1] * First open class.c in your favorite editor. * [Instruction #2] * Do a search for byte_saving_throws(int class_num, int type, int level) * Now below byte_saving_throws your going to see your case statements for * Saving throws first. They look like this: ** This is an Example ** { switch (class_num) { case CLASS_MAGIC_USER: switch (type) { case SAVING_PARA: /* Paralyzation */ switch (level) { case 0: return 90; case 1: return 70; etc. etc. etc. default: log("SYSERR: Missing level for mage paralyzation saving throw."); break; } * [Instruction #3] * Now, what you need to do is replace every switch(level) { to this: * However, you need to take note of a few things, first the ##'s at the end * of the statement block are supposed to be modified to your tastes. Now, * what you should do is write down the saving throw in your case statements for * level 1. That number should be put where the ##'s are. ** Example: case SAVING_PARA: /* Paralyzation */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (## - ((## * level) / (LVL_IMMORT - 1))); } * Your Saving Throws cases should now look something simliar to this: * (NOTE: Don't cut and paste this code, you'll want to do this right or * otherwise, you may end up with saving throw values you don't want.) byte saving_throws(int class_num, int type, int level) { switch (class_num) { case CLASS_MAGIC_USER: switch (type) { case SAVING_PARA: /* Paralyzation */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (70 - ((70 * level) / (LVL_IMMORT - 1))); } case SAVING_ROD: /* Rods */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (55 - ((55 * level) / (LVL_IMMORT - 1))); } case SAVING_PETRI: /* Petrification */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (65 - ((65 * level) / (LVL_IMMORT - 1))); } case SAVING_BREATH: /* Breath weapons */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (75 - ((75 * level) / (LVL_IMMORT - 1))); } case SAVING_SPELL: /* Generic spells */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (60 - ((60 * level) / (LVL_IMMORT - 1))); } default: log("SYSERR: Invalid saving throw type."); break; } break; case CLASS_CLERIC: switch (type) { case SAVING_PARA: /* Paralyzation */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (60 - ((60 * level) / (LVL_IMMORT - 1))); } case SAVING_ROD: /* Rods */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (70 - ((70 * level) / (LVL_IMMORT - 1))); } case SAVING_PETRI: /* Petrification */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (65 - ((65 * level) / (LVL_IMMORT - 1))); } case SAVING_BREATH: /* Breath weapons */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (80 - ((80 * level) / (LVL_IMMORT - 1))); } case SAVING_SPELL: /* Generic spells */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (70 - ((70 * level) / (LVL_IMMORT - 1))); } default: log("SYSERR: Invalid saving throw type."); break; } break; case CLASS_THIEF: switch (type) { case SAVING_PARA: /* Paralyzation */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (65 - ((65 * level) / (LVL_IMMORT - 1))); } case SAVING_ROD: /* Rods */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (70 - ((70 * level) / (LVL_IMMORT - 1))); } case SAVING_PETRI: /* Petrification */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (60 - ((60 * level) / (LVL_IMMORT - 1))); } case SAVING_BREATH: /* Breath weapons */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (80 - ((80 * level) / (LVL_IMMORT - 1))); } case SAVING_SPELL: /* Generic spells */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (75 - ((75 * level) / (LVL_IMMORT - 1))); } default: log("SYSERR: Invalid saving throw type."); break; } break; case CLASS_WARRIOR: switch (type) { case SAVING_PARA: /* Paralyzation */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (70 - ((70 * level) / (LVL_IMMORT - 1))); } case SAVING_ROD: /* Rods */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (80 - ((80 * level) / (LVL_IMMORT - 1))); } case SAVING_PETRI: /* Petrification */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (75 - ((75 * level) / (LVL_IMMORT - 1))); } case SAVING_BREATH: /* Breath weapons */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (85 - ((85 * level) / (LVL_IMMORT - 1))); } case SAVING_SPELL: /* Generic spells */ if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (85 - ((85 * level) / (LVL_IMMORT - 1))); } default: log("SYSERR: Invalid saving throw type."); break; } default: log("SYSERR: Invalid class saving throw."); break; } /* Should not get here unless something is wrong. */ return 100; } ------------------------------------------------------------------------------ STEP TWO - Termination of the Thaco Table! Woohoo! ------------------------------------------------------------------------------ * [Instruction #1] * First, search for int thaco(int class_num, int level) - you will once again * see the horrendously obnoxious list of thaco cases (shudder). * [Instruction #2] * Now, once again you'll see the switch (level) { statement, and you can * probably guess what comes next. Once again we get to replace that entire switch * with a formula! * This is what you should see: ** Example: /* THAC0 for classes and levels. (To Hit Armor Class 0) */ int thaco(int class_num, int level) { switch (class_num) { case CLASS_MAGIC_USER: switch (level) { case 0: return 100; case 1: return 20; etc. etc. etc. default: log("SYSERR: Missing level for mage thac0."); } * [Instruction #3] * Now it's time to replace the entire switch. To do so, all you have to do is * replace the whole switch with the following code, keep in mind the ##'s have * to be set to either your tastes or the default is using the Thaco value for a * level 1. ie. case 1: return 20: which would indicate that level 1's value is 20. if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (# - ((# * level) / (LVL_IMMORT - 1))); } * Now, after you have successfully replaced the code it should look something like * this: /* THAC0 for classes and levels. (To Hit Armor Class 0) */ int thaco(int class_num, int level) { switch (class_num) { case CLASS_MAGIC_USER: if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (20 - ((20 * level) / (LVL_IMMORT - 1))); } case CLASS_CLERIC: if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (20 - ((20 * level) / (LVL_IMMORT - 1))); } case CLASS_THIEF: if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (20 - ((20 * level) / (LVL_IMMORT - 1))); } case CLASS_WARRIOR: if (level == 0) return 100; if (level >= LVL_IMMORT) { return 0; } else { return (20 - ((20 * level) / (LVL_IMMORT - 1))); } default: log("SYSERR: Unknown class in thac0 chart."); } /* Will not get there unless something is wrong. */ return 100; } * That should do it for Thaco formulas. :) ------------------------------------------------------------------------------ STEP THREE - Redfine your EXP_MAX ------------------------------------------------------------------------------ Find the line that starts with #define EXP_MAX and change the number to 1500000000 The maximum value you can use is 2147483600, but I used 1500000000 to prevent overloading the integer. You can increase this number if you desire. ------------------------------------------------------------------------------ STEP FOUR - The Experience Formula! ------------------------------------------------------------------------------ * [Instruction #1] * Do a search for switch (chclass) { * Now, this is a bit different. There are several ways to handle the problem * you will undoubtedly run into when you try to compile this snippet. * Your going to basically replace the whole switch for (chclass) { with * the following code, HOWEVER, read the stuff below this code example before * you do. ** Example: /* * Adjust the mod values below to guarantee that the higest immortal level * does not exceed the value the value of EXP_MAX. * The higher the mod value you use, the more exp is needed per level. */ switch (chclass) { case CLASS_MAGIC_USER: mod = 45; return ((level * mod)*(level * mod)); break; case CLASS_CLERIC: mod = 44; return ((level * mod)*(level * mod)); break; case CLASS_THIEF: mod = 43; return ((level * mod)*(level * mod)); break; case CLASS_WARRIOR: mod = 42; return ((level * mod)*(level * mod)); break; } * You'll notice that the mod value in return((level * mod)*(level * mod)); * is not set. If you know anything at all about code, you know that mod is * a variable. Now, we have to declare a variable with a type and value, * which the original author neglected to add in. Don't know why, don't care, * I'm gonna tell you how I did it, and how others said to do it. * I modified the code by removing the mod = ##: code altogether. Why? because * it didn't make any sense to me to have a variable declaration above a * mathematical formula... Why bother with mod = 45; when you can simply * change return ((level * mod)*(level * mod)); * to: return ((level * 45)*(level * 45)); I'm sure someone can argue this * so I'll show you how others suggested this code be put in: /* * Adjust the mod values below to guarantee that the higest immortal level * does not exceed the value the value of EXP_MAX. * The higher the mod value you use, the more exp is needed per level. */ int mod = 1; /* Notice I added the variable declaration? */ switch (chclass) { case CLASS_MAGIC_USER: mod = 45; return ((level * mod)*(level * mod)); break; case CLASS_CLERIC: mod = 44; return ((level * mod)*(level * mod)); break; case CLASS_THIEF: mod = 43; return ((level * mod)*(level * mod)); break; case CLASS_WARRIOR: mod = 42; return ((level * mod)*(level * mod)); break; } * How you do this is really up to you, personally, my way compiles and * suits me just fine, but everyone is different. ** Important: * When you change your mod values (modifiers) you want to make absolutely * sure they don't exceed the maximum level for your mud which you defined * earlier as being #define EXP_MAX 1500000000 * To check this, take the highest Immortal level (The Implementor level) * and multiply it by your mod. As an example, if you have 100 total levels * on your mod, then your highest mod could be 50. Below, there is a * simple formula to determine this: .. I hope this helps you new guys cuz I typed my A*s off and didn't have half the quality snippet you guys now do. :P