Posted Saturday, July 3rd @ 11:43:36 PM, by George Greer in the Skills dept.
Fizal writes,
"This file contains some steps on how to add in 3 new summoning spells. Don't
really know whatever it is interesting or not. I am currently helping one or two
people with creating some spells, and figured might as well submit it for others
to view." Beware line wrap.
Information:
============
This file contains some steps on how to add in 3 new summoning spells. Don't
really know whatever it is interesting or not. I am currently helping one or two
people with creating some spells, and figured might as well submit it for others
to view.
I've double-checked the codes for errors but since I'm not a pro, there
are bound to be bugs/errors/typos here and there. Especially since I did it the
first time around at night after work and finished it close to 5am :) No, I
haven't really tested this on a real mud myself, since it's something that I
cooked up for someone. So, do a backup before putting this in. Like I said
earlier, I'm not a pro....
Anyway, if anyone find some errors in it, please tell me. If someone actually
likes it and uses it, would be nice to know too :) BTW, I apologize for the bad
grammar. English is not my mother tongue :P
G'luck!
Fizal (amustapa@hotmail.com)
Spell description:
==================
Summon Familiar - A druidic spell that will summon a random animal as his
familiar. The animals used will be the ones sold at the pet shop (#3090 to
#3094), but you can add in more or change them to your liking. Casting this
spell in a field, forest, hill and mountain sectors will increase the chance of
summoning more mobs. This will be a castable spell of the summons category.
Conjure Elemental - A clerical/mage spell that will summon and bind an
elemental. This spell requires that a special item to be held by the caster.
Different item will call different type of elemental - large ruby(#5026) for
fire, glittering diamond(#5027) for air, lapis lazuli(#5029) for water and green
emerald(#5032) for earth. All these gems are found in Great Eastern Desert
(Zone#50). The elemental will be based on mob #20. This will be a castable
manual spell.
Summon Demon - A clerical/mage spell that will summon and bind a (lesser) demon.
This spell requires at least 5 corpses (as sacrifice) to be in the room. This is
an evil spell which not only be more successful if the player is evil, but will
also make the player becomes more evil. This will be a non-castable (on scroll)
spell of the summons category.
Steps to install:
=================
1. Define these in SPELLS.H file. Change AAA, BBB and CCC to whatever is
appropriate for your mud:
... [ snipped to make it shorter ]
#define SPELL_INFRAVISION 50 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_WATERWALK 51 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_SUMMON_FAMILIAR AAA /* Castable summons spell */
#define SPELL_CONJURE_ELEMENTAL BBB /* Castable manual spell */
...
/* NON-PLAYER AND OBJECT SPELLS AND SKILLS */
#define SPELL_IDENTIFY 201
#define SPELL_FIRE_BREATH 202
#define SPELL_GAS_BREATH 203
#define SPELL_FROST_BREATH 204
#define SPELL_ACID_BREATH 205
#define SPELL_LIGHTNING_BREATH 206
#define SPELL_SUMMON_DEMON CCC /* Non-castable summons spell */
And somewhere close to the end of the file:
ASPELL(spell_enchant_weapon);
ASPELL(spell_detect_poison);
ASPELL(spell_conjure_elemental);
2. If you're using bpl14 and below, you'll need to add the name of the spells
inside SPELL_PARSER.C together with the other spells. If you're using bpl15
above, then you can just add the name together with the spello() later on.
3. Create a prototype for the mobs that are needed. Since the first 2 spells use
ready-made mobs, we just need to create one for the demon. Change XXX to
something appropriate:
#XXX
demon horned~
the horned demon~
A large demon with sharp twisted horns dominates your attention!
~
You see a large demon with a leathery skin that is stretched tout
by hard muscles. Two sharp twisted horns adorn his crown while
sharp pointy teeth line his mounth. Looking into its eyes, you
can see nothing but the fiery and burning anger of a powerful
beast, trapped unwillingly.
~
bcf dk -1000 E
20 0 5 75d2+300 4d8+5
0 180000
8 8 0
BareHandAttack: 8
E
*Note: The demon will be a sentinal, scavanger and an aggro. It will also have
detect invis and infravision.
4. Create a prototype for the scroll that will have the Summon Demon spell.
Change YYY to something appropriate:
#YYY
book black~
a book in black leather binding~
A strange looking book in black leather binding has been left here.~
As $n reads from $p, fear chilled your blood and you shiver slightly.~
2 acdghj 16385
12 CCC -1 -1 <== Change CCC to the appropriate spell number.
1 5500 100
E
book black~
Touching the book somehow makes you shiver slightly. The black leather
that binds the book seems old and scaly. The browning pages inside are
full of strange angular letters in deep red which reminds you of blood,
and some fading illustrations of strange horned beasts, sigils and
pentagrams.
~
*Note: The book will be glowing, no-rent, no-donate, magical, no-drop and anti-
good. It can also be taken and held.
5. Now we add a case for the spells in mag_summons() in MAGIC.C:
case SPELL_SUMMON_FAMILIAR:
handle_corpse = FALSE;
msg = 2;
fmsg = number(2, 6); /* Random fail message. */
mob_num = number(0, 4) + 3090; /* Mob vnum used #3090 to #3094 */
/* Calc chance of failure based on char's intel and charm */
pfail = 100 - ((float) (GET_CHA(ch) + GET_INT(ch))/4.0 * 10.0);
/* Chance to summon more mobs if in following sectors */
if (SECT(IN_ROOM(ch)) >= SECT_FIELD && SECT(IN_ROOM(ch)) <= SECT_MOUNTAIN)
num += number(0, 2);
break;
case SPELL_SUMMON_DEMON:
/* We'll temporarily use num to count the corpses in the room */
for (obj = world[ch->in_room].contents, num = 0; obj && num < 5;
obj = obj->next_content)
if (IS_CORPSE(obj) && CAN_SEE(ch, obj)) num++;
/* Check how many corpses are there in the room */
if (num < 5) {
send_to_char("You don't have enough corpses for the sacrifice!", ch);
return;
} else {
/* Remove the first 5 corpses found */
for (obj = world[ch->in_room].contents, num = 0; obj && num < 5;
obj = obj->next_obj) {
next_obj = obj->next_content;
if (IS_CORPSE(obj) && CAN_SEE(ch, obj)) {
extract_obj(obj); /* This will also extract its contents */
num++;
}
}
}
num = 1; /* Reset num back to 1 */
handle_corpse = FALSE;
msg = 7;
fmsg = number(2, 6); /* Random fail message. */
mob_num = XXX; <== Change XXX to the vnum of the demon.
/* Calc chance of failure based on char's align and intel. Make char evil */
pfail = 100 - ((float) GET_INT(ch)/4.0 * 10.0) + (GET_ALIGNMENT(ch)/20);
GET_ALIGNMENT(ch) = max(-1000, GET_ALIGNMENT(ch) - 100);
break;
6. Insert this in SPELLS.C:
/*
* The reasons why this summon spell is done as manual are:
* 1. Prototype of the mob used (vnum#20) is extremely bare.
* 2. Using a single prototype instead of creating one for each
* elemental.
* 3. Can randomize the mob's level/stats/etc on every summon.
*
* Change the NEED_GEM to 0 to let caster still be able to cast the
* spell without the gems being held, at the lower success rate.
* /
#define NEED_GEM 1
ASPELL(spell_conjure_elemental)
{
int success = 0;
/* Check to make sure that caster is not charmed himself */
if (AFF_FLAGGED(ch, AFF_CHARM)) {
send_to_char("You are too giddy to have any followers!\r\n", ch);
return;
}
/* Check the item caster is holding */
if (!(obj = GET_EQ(ch, WEAR_HOLD))) {
#if NEED_GEM
send_to_char("You try to pierce the elemental realm, but your unfocused
magic failed you...\r\n", ch);
return;
#else
success = -50;
#endif
}
/* Create the mob first, and set its stats. Use victim temporarily. */
victim = read_mob(20, VIRTUAL);
IS_CARRYING_W(victim) = 0;
IS_CARRYING_N(victim) = 0;
SET_BIT(AFF_FLAGS(victim), AFF_CHARM);
GET_LEVEL(victim) = number((int) GET_LEVEL(ch)/3, GET_LEVEL(ch));
GET_MAX_HIT(victim) = number(5*GET_LEVEL(victim), 20*GET_LEVEL(victim));
GET_HIT(victim) = GET_MAX_HIT(victim);
victim->mob_specials.damnodice = GET_LEVEL(victim)/10;
victim->mob_specials.damsizedice = GET_LEVEL(victim)/6;
GET_DAMROLL(ch) = GET_LEVEL(victim)/4;
/* Check if the item being held is one of the special items required */
if (obj)
switch (GET_OBJ_VNUM(obj)) {
case 5026:
/* Item is large ruby. Create fire elemental */
victim->player.name = str_dup("fire elemental");
victim->player.short_descr = str_dup("the fire elemental");
victim->player.long_descr = str_dup("A column of burning fire is here,
brightening up the room.");
victim->mob_specials.attack_type = 12;
success = 1;
break;
case 5027:
/* Item is glittering diamon. Create air elemental */
victim->player.name = str_dup("air elemental");
victim->player.short_descr = str_dup("the air elemental");
victim->player.long_descr = str_dup("An almost translucent being is
floating around here.");
victim->mob_specials.attack_type = 7;
SET_BIT(AFF_FLAGS(victim), AFF_INVISIBLE);
SET_BIT(AFF_FLAGS(victim), AFF_SNEAK);
success = 1;
break;
case 5029:
/* Item is lapis lazuli. Create water elemental */
victim->player.name = str_dup("water elemental");
victim->player.short_descr = str_dup("the water elemental");
victim->player.long_descr = str_dup("Although it is impossible, there is
a localized whirlpool here!");
victim->mob_specials.attack_type = 2;
SET_BIT(AFF_FLAGS(victim), AFF_WATERWALK);
success = 1;
break;
case 5032:
/* Item is green emerald. Create earth elemental */
victim->player.name = str_dup("earth elemental");
victim->player.short_descr = str_dup("the earth elemental");
victim->player.long_descr = str_dup("A huge humanoid made from earth
dominates the room.");
victim->mob_specials.attack_type = 5;
success = 1;
break;
default:
#if NEED_GEM
send_to_char("You try to pierce the elemental realm, but your unfocused
magic failed you...\r\n", ch);
extract_char(victim);
return;
#else
success = -50;
#endif
}
/* Extract the gem if it's held, whether or not the spell is successful */
if (success == 1)
extract_obj(obj_from_char(unequip_char(ch, WEAR_HOLD)));
/* Check success of spell */
success += (float) (GET_INT(ch) + GET_CHA(ch))/4.0 * 10.0;
if (number(0, 101) < number(0, success)) {
act("You pierce the elemental realm with your magic, and bind $N to appear
before you and do your bidding!", FALSE, ch, 0, victim, TO_CHAR);
act("$n chants and gestures for a few minutes. A shimmering portal appears
before $m and $N steps through and bows obediently.", FALSE, ch, 0, victim,
TO_ROOM);
char_to_room(victim, IN_ROOM(ch));
add_follower(victim, ch);
} else {
send_to_char("You pierce the elemental realm with your magic. But as you try
to bind one of its dezinens, it resists you!\r\n", ch);
act("$n chants and gestures for a few minutes. You wait expectedly for
something to happen, but nothing did....", FALSE, ch, 0, 0, TO_ROOM);
extract_char(victim);
}
}
#undef NEED_GEM
7. Inside SPELL_PARSER.C under call_magic(), put a case for the manual spell:
if (IS_SET(SINFO.routines, MAG_MANUAL))
switch (spellnum) {
case SPELL_CHARM: MANUAL_SPELL(spell_charm); break;
case SPELL_CREATE_WATER: MANUAL_SPELL(spell_create_water); break;
case SPELL_DETECT_POISON: MANUAL_SPELL(spell_detect_poison); break;
case SPELL_ENCHANT_WEAPON: MANUAL_SPELL(spell_enchant_weapon); break;
case SPELL_IDENTIFY: MANUAL_SPELL(spell_identify); break;
case SPELL_LOCATE_OBJECT: MANUAL_SPELL(spell_locate_object); break;
case SPELL_SUMMON: MANUAL_SPELL(spell_summon); break;
case SPELL_WORD_OF_RECALL: MANUAL_SPELL(spell_recall); break;
case SPELL_TELEPORT: MANUAL_SPELL(spell_teleport); break;
case SPELL_CONJURE_ELEMENTAL: MANUAL_SPELL(spell_conjure_elemental); break;
}
8. Define the spells' spello() in SPELL_PARSER.C:
*Note: Under codebases bpl15 and above:
spello(SPELL_SUMMON_FAMILIAR, "summon familiar", 100, 65, 4, POS_FIGHTING,
TAR_SELF_ONLY, FALSE, MAG_SUMMONS);
spello(SPELL_CONJURE_ELEMENTAL, "conjure elemental", 150, 100, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_MANUAL);
...
/* NON-castable spells should appear below here. */
spello(SPELL_IDENTIFY, "identify", 0, 0, 0, 0,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL);
spello(SPELL_SUMMON_DEMON, "summon demon", 0, 0, 0, POS_STANDING,
TAR_SELF_ONLY, FALSE, MAG_SUMMONS);
*Note: Under codebase prior to bpl15
spello(SPELL_SUMMON_FAMILIAR, 100, 65, 4, POS_FIGHTING,
TAR_SELF_ONLY, FALSE, MAG_SUMMONS);
spello(SPELL_CONJURE_ELEMENTAL, 150, 100, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_MANUAL);
...
/* NON-castable spells should appear below here. */
spello(SPELL_IDENTIFY, 0, 0, 0, 0,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL);
spello(SPELL_SUMMON_DEMON, 0, 0, 0, POS_STANDING,
TAR_SELF_ONLY, FALSE, MAG_SUMMONS);
*Note: The reason why the target is TAR_SELF_ONLY, is to make sure that the
spell/scroll won't be used on another person. Conjure Elemental has TAR_IGNORE
since the coding itself will check for the required item. Change the mana
requirements as
you see fit.
9. Place an entry for the spell_wear_off_msg[] in CONSTANTS.C for the spells. A
"!Summon Familiar!", "!Conjure Elemental!" and "!Summon Demon!" will do. Come to
think of it, I'm not really sure about the entry for Summon Demon. Maybe it's
not needed.... Anyway, no battle message is needed for all of them.
10. Set the class and level for that can use the spell under init_spell_level()
in CLASS.C file. Since Summon Demon is non-castable, no need to set one for it.
However, I do recommend that you set Conjure Elemental spell for high level.
<< d->showstr_page Pager [by Xenobias] | Reply | Flattened | FTP Uploads 1999/07/06 >> |
|
Related Links |
|
|
|
Quick Links |
|
|
|