I've done something similar, borrowing from the school and sphere
concept from AD&D. DGC also does something similar with the rune
magic system it uses.
The way I did it was to add two variables to the spell_info struct
(long school; long sphere;) then created two separate lists of
bitvectors accordingly (SCHOOL_INVOCATION (1 << 0)
SPHERE_HEALING (1 << 1) etc.) This way I could have a spell belong
to more than one school or sphere, and could have a spell belong to
both schools AND spheres :)
Bitvector manipulation is probably easier here anyway, as if you want
to add more schools or sphere, you just add a new entry to the
bitvector list, instead of adding directly to the spell_info struct.
>----------
>From: Christoffer Lundberg[SMTP:avatar@ORION.BODEN.SE]
>Sent: Friday, January 16, 1998 4:32 AM
>To: CIRCLE@POST.QUEENSU.CA
>Subject: [CODE]: Spheres for spells
>
>All of you out there that have played TCS (The Creator's Shadow)
>and wondered: How could I add a sphere-system to my MUD?
>
>Well, have no fear, Avatar is here.
>
>-=-=-=-=-=-=-=-
>+ means add this line
>- means remove this line
>! means change this line
>& this is how the change (!) should look afterwards
>-=-=-=-=-=-=-=-
>First, you must add the spheres to the struct spell_info_type in spells.h
>
>struct spell_info_type {
> byte min_position; /* Position for caster */
> int mana_min; /* Min amount of mana used by a spell (highest lev)
>*/
> int mana_max; /* Max amount of mana used by a spell (lowest lev) */
> int mana_change; /* Change in mana used by spell from lev to lev */
>
> int min_level[NUM_CLASSES];
> int routines;
> byte violent;
> int targets; /* See below for use with TAR_XXX */
>+ int fire;
>+ int water;
>+ int air;
>+ int earth;
>};
>
>-=-=-=-=-=-=-=-
>Second, you must add a lot of numbers and stuff in spell_parser.c
>
>/* Assign the spells on boot up */
>void spello(int spl, int max_mana, int min_mana, int mana_change, int minpos,
> int targets, int violent, int routines,
>+ int fire, int water, int air, int earth)
>{
> int i;
>
> for (i = 0; i < NUM_CLASSES; i++)
> spell_info[spl].min_level[i] = LVL_IMMORT;
> spell_info[spl].mana_max = max_mana;
> spell_info[spl].mana_min = min_mana;
> spell_info[spl].mana_change = mana_change;
> spell_info[spl].min_position = minpos;
> spell_info[spl].targets = targets;
> spell_info[spl].violent = violent;
> spell_info[spl].routines = routines;
>+ spell_info[spl].fire = fire;
>+ spell_info[spl].water = water;
>+ spell_info[spl].air = air;
>+ spell_info[spl].earth = earth;
>}
>
>void unused_spell(int spl)
>{
> int i;
>
> for (i = 0; i < NUM_CLASSES; i++)
> spell_info[spl].min_level[i] = LVL_IMPL + 1;
> spell_info[spl].mana_max = 0;
> spell_info[spl].mana_min = 0;
> spell_info[spl].mana_change = 0;
> spell_info[spl].min_position = 0;
> spell_info[spl].targets = 0;
> spell_info[spl].violent = 0;
> spell_info[spl].routines = 0;
>+ spell_info[spl].fire = 0;
>+ spell_info[spl].water = 0;
>+ spell_info[spl].air = 0;
>+ spell_info[spl].earth = 0;
>}
>
>! define skillo(skill) spello(skill, 0, 0, 0, 0, 0, 0, 0);
>
>& define skillo(skill) spello(skill, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
> ^ ^ ^ ^
> | | | |
> Fi Wa Ai Ea
>
>Now, you must change ALL spello(SPELL_???.......
>to match the above base define.
>
>example. spello(SPELL_HEAL, 50, 20, 2, POS_STANDING,
> TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_UNAFFECTS,
> 0, 100, 50, 0);
>
>This means that SPELL_HEAL is the name, it costs 50 mana when you receive
>it, minimum-cost is 20 and the mana-cost is reduced with 2 every level
>beyond the one you receive it. It can be directed to anyone in the room,
>and can only be casted when you are standing. It is not aggressive, it
>has the function to restore points(in this case Hitpoints), and to remove
>blindness on the target.
>The limit of Fire is 0 (no fire needed for healing or removing of
>blindness), Water is 100 (water is the source of healing and restoration),
>Air is 50 (removal and disenchanting) and Earth is 0 (not needed).
>
>You can come up with your own system when it comes to the Sphere-limits.
>Ours is more than level-based. You can seek out the Great Elemental Kings
>to learn some of their knowledges, and more...
>
>-=-=-=-=-=-=
>Then, in the function do_cast, add the following checks after the check if
>you have enough mana.
>
>if (SPHERE(ch, FIRE) < SINFO.fire) {
> send_to_char(The message you like to have.\r\n", ch);
> return;
>}
>if (SPHERE(ch, WATER) < SINFO.water) {
> send_to_char(The message you like to have.\r\n", ch);
> return;
>}
>if (SPHERE(ch, AIR) < SINFO.air) {
> send_to_char(The message you like to have.\r\n", ch);
> return;
>}
>if (SPHERE(ch, EARTH) < SINFO.earth) {
> send_to_char(The message you like to have.\r\n", ch);
> return;
>}
>-=-=-=-=-=-=-=-=-
>Add the structure of the spheres to structs.h. Use one of the free ubyte
>places.
>
>ubyte spheres[4];
>-=-=-=-=-=-=-=-=-=-=-
>In utils.h, add the structure of locating the spheres for checks and
>stuff.
>
>#define SPHERE(ch, i)
>
>and, define the spheres
>
>#define FIRE 1
>#define WATER 2
>#define AIR 3
>#define EARTH 4
>-=-=-=-=-=-=-=-=-=-=-
>If you have any problems, email me at avatar@orion.boden.se
>If you use this code, please add me to the credits
>
>/Avatar
>
+------------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
| http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
+------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/15/00 PST