I wrote this guide to help people add in more sector types to their OLC, which as you can see is pretty simple. Just don't forget to change the number flags any time you add one. This code is written, tested, and works on stock tbaMUD. It may or may not work if your game is heavily modified or from an older version of CWG.
*** In constants.c scroll down to where it lists the basic sector types.
*** (Inside, City, Field, Forest, etc.) and add to the bottom of the list.
const char *sector_types[] = {
"Inside",
"City",
"Field",
"Forest",
"Hills",
"Mountains",
"Water (Swim)",
"Water (No Swim)",
"In Flight",
"Underwater",
+ "Desert",
"\n",
};
*** Further down in constants.c (under int movement_loss) you'll want to define how much
*** movement is lost per step with your new terrain type.
*** Note: Make sure the last line doesn't have the comma after the number, but all the previous ones do.
int movement_loss[] =
{
1, /* Inside */
1, /* City */
2, /* Field */
3, /* Forest */
4, /* Hills */
6, /* Mountains */
4, /* Swimming */
1, /* Unswimable */
1, /* Flying */
- 5 /* Underwater */
+ 5, /* Underwater */
+ 3 /* Desert */
};
*** In structs.h scroll down to where the list is again, for basic sector types.
/* Sector types: used in room_data.sector_type */
#define SECT_INSIDE 0 /**< Indoors, connected to SECT macro. */
#define SECT_CITY 1 /**< In a city */
#define SECT_FIELD 2 /**< In a field */
#define SECT_FOREST 3 /**< In a forest */
#define SECT_HILLS 4 /**< In the hills */
#define SECT_MOUNTAIN 5 /**< On a mountain */
#define SECT_WATER_SWIM 6 /**< Swimmable water */
#define SECT_WATER_NOSWIM 7 /**< Water - need a boat */
#define SECT_FLYING 8 /**< Flying */
#define SECT_UNDERWATER 9 /**< Underwater */
+ #define SECT_DESERT 10 /**< Desert */
*** Be sure to bump up NUM_SPELLS by 1
+ #define NUM_ROOM_SECTORS 11
*** In asciimap.c scroll down to the first instance of sector types.
*** At the next -1 at the bottom fill in your new sector type.
static struct map_info_type map_info[] =
{
{ SECT_INSIDE, "@c[@n.@c]@n" }, /* 0 */
{ SECT_CITY, "@c[@wC@c]@n" },
{ SECT_FIELD, "@c[@g,@c]@n" },
{ SECT_FOREST, "@c[@gY@c]@n" },
{ SECT_HILLS, "@c[@Mm@c]@n" },
{ SECT_MOUNTAIN, "@c[@rM@c]@n" }, /* 5 */
{ SECT_WATER_SWIM, "@c[@c~@c]@n" },
{ SECT_WATER_NOSWIM, "@c[@b=@c]@n" },
{ SECT_FLYING, "@c[@C^@c]@n" },
{ SECT_UNDERWATER, "@c[@bU@c]@n" },
- { -1, "" }, /* 10 */
+ { SECT_DESERT, "@c[@Y-@c]@n" }, /* 10 */
*** Scroll down a bit more to the next set and do the same.
*** Since we used @Y- for the symbol above, use it again here.
static struct map_info_type world_map_info[] =
{
{ SECT_INSIDE, "@n." }, /* 0 */
{ SECT_CITY, "@wC" },
{ SECT_FIELD, "@g," },
{ SECT_FOREST, "@gY" },
{ SECT_HILLS, "@Mm" },
{ SECT_MOUNTAIN, "@rM" }, /* 5 */
{ SECT_WATER_SWIM, "@c~" },
{ SECT_WATER_NOSWIM, "@b=" },
{ SECT_FLYING, "@C^" },
{ SECT_UNDERWATER, "@bU" },
- { -1, "" }, /* 10 */
+ { SECT_DESERT, "@y-" }, /* 10 */
*** Finally, jump down even more to where they're listed again like this, and add your new sector.
count += sprintf(buf + count, "@n%s Swim\\\\", map_info[SECT_WATER_SWIM].disp);
count += sprintf(buf + count, "@n%s Boat\\\\", map_info[SECT_WATER_NOSWIM].disp);
count += sprintf(buf + count, "@n%s Flying\\\\", map_info[SECT_FLYING].disp);
count += sprintf(buf + count, "@n%s Underwater\\\\", map_info[SECT_UNDERWATER].disp);
+ count += sprintf(buf + count, "@n%s Desert\\\\", map_info[SECT_DESERT].disp);
I wrote this guide to help people add in basic area spells. It is not meant to be a guide for advanced spells or any other type of spell. It is written, tested, and works on stock tbaMUD. It may or may not work if your game is heavily modified or from an older version of CWG.
*** In spells.h scroll down to the bottom of the spell list and define a
*** new one. Make sure it is +1 from the previous spell.
#define SPELL_WATERWALK 51 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_METEOR 52 /* Meteor of DOOM! */
+ #define SPELL_TREMOR 53 /* A miniature Earthquake */
*** In spells.h, right under that, there should be #define NUM_SPELLS. Make
*** sure you add one to that since you have defined a new one.
+ #define NUM_SPELLS 53
*** In magic.c search Area Spells (commented out). You should see Earthquake,
*** which is a great example for an area spell. Tremor, the new spell, acts like
*** Earthquake but only weaker.
/* Area spells */
case SPELL_EARTHQUAKE:
dam = dice(2, 8) + level;
break;
+ case SPELL_TREMOR:
+ dam = dice(1, 4) + level;
+ break;
**( In magic.c still, search for another instance of Earthquake. It will look
*** something like below. Add in another case for the new area spell.
switch (spellnum) {
case SPELL_EARTHQUAKE:
to_char = "You gesture and the earth begins to shake all around you!";
to_room ="$n gracefully gestures and the earth begins to shake violently!";
break;
+ case SPELL_TREMOR:
+ to_char = "You gesture and cause a tremor to shake the ground beneath you!";
+ to_room = "$n gracefully gestures, causing a tremor to shake the ground beneath you!";
+ break;
}
*** In spell_parser.c search for Earthquake since it is an area spell.
*** It will be listed many lines below mag_assign_spells.
*** 40, 25, 3 in Earthquake stands for minimum mana cost of 25, maximum mana cost
*** of 40. Every level the mana cost decreases by 3 but it will never go
*** below 25. So in Tremor the new spell, I lowered the cost because it is weaker.
spello(SPELL_EARTHQUAKE, "earthquake", 40, 25, 3, POS_FIGHTING,
TAR_IGNORE, TRUE, MAG_AREAS,
NULL);
+ spello(SPELL_TREMOR, "tremor", 30, 15, 2, POS_FIGHTING,
+ TAR_IGNORE, TRUE, MAG_AREAS,
+ NULL);
*** In class.c search for init_spell_levels and add in your new
*** spell into that list. CLASS_CLERIC can be any of the classes that
*** are built into your game. Level "8" is the level of which the Cleric
*** will learn Tremor.
spell_level(SPELL_WORD_OF_RECALL, CLASS_CLERIC, 12);
spell_level(SPELL_EARTHQUAKE, CLASS_CLERIC, 12);
+ spell_level(SPELL_TREMOR, CLASS_CLERIC, 8);
spell_level(SPELL_DISPEL_EVIL, CLASS_CLERIC, 14);
*** Back out of the src directory, and enter the lib director, then
*** misc. Open the file messages, search for the damaging spells, and add
*** in the messages for your new spell. Be sure the number above the messages
*** match the spell number from spells.h.
*** Note: Don't forget the "M" on the line just above the spell number!!!
+ * Tremor
+ M
+ 53
+ A small crack opens beneath $N's feet and swallows $M whole!
+ A small crack opens beneath your feet and swallows you whole!
+ A small crack opens beneath $N's feet and swallows $M whole!
+ $N desperately tries to keep $S balance as the earth tremors beneath $S feet!
+ You desperately try to keep your balance as the earth tremors beneath your feet!
+ $N desperately tries to keep $S balance as the earth tremors beneath $S feet!
+ $N falls down and hurts $Mself!
+ You fall down and hurt yourself!
+ $N falls down and hurts $Mself!
+ $N holds $S ground as you send a tremor $S way.
+ You hold your ground as the tremor shakes the place.
+ $N holds $S ground as a tremor shakes the place.
I was looking to add in fishing on the new AstoriaTBA port, to help bide some time with the conversion, so I Googled for some snippets.
I came up with an old snippet, which I've seen done on some other MUDs, and figured why not. The snippet I found and modified here.
I wrote this guide to help people add in basic fishing for players. It is not meant to be a guide for advanced fishing and I am not claiming the original idea for it, nor even the code. It is written, tested, and works on stock tbaMUD. It may or may not work if your game is heavily modified or from an older version of CWG.
send_to_chars were backwards.
Example: send_to_char("You need to be holding a fishing pole first.\r\n", ch);
should be:
send_to_char(ch, "You need to be holding a fishing pole first.\r\n");
number should be rand_number
Example: bite = number(1, 10);
should be:
bite = rand_number(1, 10);
Changed sprintf to send_to_char
Example: sprintf(buf, "You reel in %s! Nice catch!\r\n", fish->short_description);
should be:
send_to_char(ch, "You reel in %s! Nice catch!\r\n", fish->short_description);
Added in some things to interpreter.c and act.h as well
So here it is, revised, with all of the fixes. (Much thanks go to Fizban for helping squash several of the errors. His scripting website is here if anyone has any script related questions.)
*** In structs.h, with all your player flags, add this to the bottom.
#define PLR_CRYO 15 /**< Player is cryo-saved (purge prog) */
#define PLR_NOTDEADYET 16 /**< (R) Player being extracted */
+ #define PLR_FISHING 17 /**< Player has a line in the water */
+ #define PLR_FISH_ON 18 /**< Player has a fish on their line */
*** In structs.h, with your item types, add this to the bottom.
#define ITEM_FOUNTAIN 23 /**< Item is a fountain */
+ #define ITEM_POLE 24 /**< Item is a fishing pole */
*** Be sure to increase #define NUM_ITEM_TYPES by one.
+ #define NUM_ITEM_TYPES 25
*** In structs.h, with your flags, add this to the bottom. Be sure to
*** increase NUM_ROOM_FLAGS by one.
#define ROOM_BFS_MARK 15 /**< (R) breath-first srch mrk */
#define ROOM_WORLDMAP 16 /**< World-map style maps here */
+ #define ROOM_SALTWATER_FISH 17 /**< Fish are saltwater */
+ #define ROOM_FRESHWATER_FISH 18 /**< Fish are freshwater */
*** In constants.c, add to const char *room_bits[] at bottom,
*** before "\n".
"WORLDMAP",
+ "SALTWATER_FISH",
+ "FRESHWATER_FISH",
"\n"
*** In constants.c, add to const char *player_bits[] at bottom,
*** before "\n"
"UNUSED5",
+ "FISHING",
+ "FISH_ON",
"\n"
*** In constants.c, add to const char *item_types[] at bottom,
*** before "\n"
"FOUNTAIN",
+ "FISHING POLE",
"\n"
*** In act.item.c add at the bottom.
ACMD(do_castout)
{
struct obj_data *pole;
int fail;
if (PLR_FLAGGED(ch, PLR_FISHING)) {
send_to_char(ch, "You are already fishing!\r\n");
return;
}
if (!(pole = GET_EQ(ch, WEAR_HOLD)) ||
(GET_OBJ_TYPE(pole) != ITEM_POLE)) {
send_to_char(ch, "You need to be holding a fishing pole first.\r\n");
return;
}
if (!ROOM_FLAGGED(ch->in_room, ROOM_SALTWATER_FISH) &&
!ROOM_FLAGGED(ch->in_room, ROOM_FRESHWATER_FISH)) {
send_to_char(ch, "This is not a good place to fish, you'll want to find a "
"better spot.\r\n");
return;
}
fail = rand_number(1, 10);
if (fail <= 3) {
send_to_char(ch, "You pull your arm back and try to cast out your line, but "
"it gets all tangled up.\r\nTry again.\r\n");
act("$n pulls $s arm back, trying to cast $s fishing line out into the "
"water,\r\nbut ends up just a bit tangled.\r\n",
FALSE, ch, 0, 0, TO_ROOM);
return;
}
/* Ok, now they've gone through the checks, now set them fishing */
SET_BIT_AR(PLR_FLAGS(ch), PLR_FISHING);
send_to_char(ch, "You cast your line out into the water, hoping for a bite.\r\n");
act("$n casts $s line out into the water, hoping to catch some food.\r\n",
FALSE, ch, 0, 0, TO_ROOM);
return;
}
ACMD(do_reelin)
{
int success, f_num, fish_num;
struct obj_data *fish;
if (!PLR_FLAGGED(ch, PLR_FISHING)) {
send_to_char(ch, "You aren't even fishing!\r\n");
return;
}
if (!PLR_FLAGGED(ch, PLR_FISH_ON)) {
send_to_char(ch, "You reel in your line, but alas... nothing on the end.\r\n"
"Better luck next time.\r\n");
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_FISHING);
act("$n reels $s line in, but with nothing on the end.\r\n",
FALSE, ch, 0, 0, TO_ROOM);
return;
}
/* Ok, they are fishing and have a fish on */
success = rand_number(1, 10);
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_FISHING);
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_FISH_ON);
if (success <= 6) {
send_to_char(ch, "You reel in your line, putting up a good fight, but you "
"lose him!\r\nTry again?\r\n");
act("$n reels $s line in, fighting with whatever is on the end, but loses "
"the catch.\r\n", FALSE, ch, 0, 0, TO_ROOM);
return;
}
/* We used object vnums 10030-10050 for our fish that people could
* catch. The below numbers reflect that use. If you wish to change
* the vnums of the fish, just change the numbers below. You can
* see that we seperated the type of fish by freshwater and salt
* water.
*/
if (ROOM_FLAGGED(ch->in_room, ROOM_SALTWATER_FISH)) {
fish_num = rand_number(10030, 10039);
f_num = real_object(fish_num);
fish = read_object(f_num, REAL);
send_to_char(ch, "You reel in %s! Nice catch!\r\n",fish->short_description);
act("Wow! $n reels in a helluva catch! Looks like $p!\r\n",
FALSE, ch, fish, 0, TO_ROOM);
obj_to_char(fish, ch);
return;
} else
if (ROOM_FLAGGED(ch->in_room, ROOM_FRESHWATER_FISH)) {
fish_num = rand_number(10040, 10050);
f_num = real_object(fish_num);
fish = read_object(f_num, REAL);
send_to_char(ch, "You reel in %s! Nice catch!\r\n", fish->short_description);
act("Wow! $n reels in a helluva catch! Looks like a $p!\r\n",
FALSE, ch, fish, 0, TO_ROOM);
obj_to_char(fish, ch);
return;
} else
send_to_char(ch, "You should never see this message, please report it.\r\n");
return;
}
*** Now, in comm.c add to your voids at the top of the file.
void check_fishing();
*** In comm.c in, before PULSE_DG_SCRIPT, add:
if (!(pulse % (40 * PASSES_PER_SEC)))
check_fishing();
*** In weather.c at the bottom, add:
void check_fishing() {
struct descriptor_data *d;
int bite;
for (d = descriptor_list; d; d = d->next) {
if (d->connected) continue;
if (PLR_FLAGGED(d->character, PLR_FISHING) &&
(!ROOM_FLAGGED(d->character->in_room, ROOM_SALTWATER_FISH) &&
!ROOM_FLAGGED(d->character->in_room, ROOM_FRESHWATER_FISH)))
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_FISHING);
if (PLR_FLAGGED(d->character, PLR_FISHING) &&
!PLR_FLAGGED(d->character, PLR_FISH_ON)) {
bite = rand_number(1, 10);
if (bite >= 7 && bite <= 8) {
send_to_char(d->character, "Time goes by... not even a nibble.\r\n");
} else if (bite >= 6) {
send_to_char(d->character, "You feel a slight jiggle on your line.\r\n");
} else if (bite >= 4) {
send_to_char(d->character, "You feel a very solid pull on your line!\r\n");
SET_BIT_AR(PLR_FLAGS(d->character), PLR_FISH_ON);
} else if (bite >= 2) {
send_to_char(d->character, "Your line suddenly jumps to life, FISH ON!!!\r\n");
SET_BIT_AR(PLR_FLAGS(d->character), PLR_FISH_ON);
}
}
}
}
*** In act.movement.c, in do_simple_move add the below snippet just
*** above char_from_room:
if ((ROOM_FLAGGED(ch->in_room, ROOM_SALTWATER_FISH) ||
ROOM_FLAGGED(ch->in_room, ROOM_FRESHWATER_FISH)) &&
(PLR_FLAGGED(ch, PLR_FISHING) || PLR_FLAGGED(ch, PLR_FISH_ON))) {
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_FISHING);
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_FISH_ON);
send_to_char(ch, "\r\nYou pack up your fishing gear and move on.\r\n\r\n");
}
*** In fight.c in void damage, just under the Sanctuary check, add:
/* Cut damage in half if victim has sanct, to a minimum 1 */
if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2)
dam /= 2;
/* Player Fishing */
+ if (PLR_FLAGGED(victim, PLR_FISHING) && dam >= 4)
+ dam = ((float) dam * 1.5);
*** New: In interpreter.c under "cast" add:
{ "cast" , "c" , POS_SITTING , do_cast , 1, 0 },
+ { "castout" , "castout" , POS_SITTING , do_castout , 0, 0 },
*** New! In interpreter.c under "receive" add:
{ "receive" , "rece" , POS_STANDING, do_not_here , 1, 0 },
+ { "reelin" , "reelin" , POS_SITTING , do_reelin , 0, 0 },
*** New! In act.h add this below the other ACMD's of functions without subcommands:
ACMD(do_rescue);
/* Fishing */
+ ACMD(do_castout);
+ ACMD(do_reelin);
FISHING CASTOUT REELIN
Usage: castout
reelin
To fish, you must be near water, in a room specified as such. Also, you
must be holding a fishing pole. If you move from your original place of
fishing, you automatically pack up your gear and move on.
Anyone can fish, all you need is a fishing pole and patience.
Note: If you are fishing and get attacked, your fighting skills are
severely impeded, and you will take more than your average
damage until you reel your line in.
Happy fishing everyone!
I wrote this guide to help people add in basic damaging spells. It is not meant to be a guide for advanced spells or any other type of spell. It is written, tested, and works on stock tbaMUD. It may or may not work if your game is heavily modified or from an older version of CWG.
*** In spells.h scroll down to the bottom of the spell list and define a
*** new one. Make sure it is +1 from the previous spell.
#define SPELL_INFRAVISION 50 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_WATERWALK 51 /* Reserved Skill[] DO NOT CHANGE */
+ #define SPELL_METEOR 52 /* Meteor of DOOM! */
*** In spells.h, right under that, there should be #define NUM_SPELLS. Make
*** sure you add one to that since you have defined a new one.
+ #define NUM_SPELLS 52
*** In magic.c search mag_damage and scroll past the spellnum.
*** The spells here should be damaging spells like Fireball, Magic Missile,
*** and Chill Touch. Add in the new spell beneath it.
*** Note: If the spell affects the character casting in any way it must be
*** added to man_damage (with spells like Armor and Blindness) but in this
*** example the spell does not.
case SPELL_FIREBALL:
if (IS_MAGIC_USER(ch))
dam = dice(11, 8) + 11;
else
dam = dice(11, 6) + 11;
break;
+ case SPELL_METEOR:
+ dam = dice(25, 15) + 15;
+ break;
*** In spell_parser.c search for another damaging spell. I used Fireball as
*** my template. These spells should be listed a few lines below
*** mag_assign_spells.
spello(SPELL_FIREBALL, "fireball", 40, 30, 2, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
+ spello(SPELL_METEOR, "meteor", 40, 30, 2, POS_FIGHTING,
+ TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
+ NULL);
*** In class.c search for init_spell_levels and add in your new
*** spell into that list. CLASS_MAGIC_USER can be any of the classes that
*** are built into your game, but since Mages are the unpredictable spell
*** casters I chose to assign it to them. "30" is the level of which the Mage
*** will learn that spell.
spell_level(SPELL_FIREBALL, CLASS_MAGIC_USER, 15);
+ spell_level(SPELL_METEOR, CLASS_MAGIC_USER, 30);
spell_level(SPELL_CHARM, CLASS_MAGIC_USER, 16);
*** Back out of the src directory, and enter the lib director, then
*** misc. Open the file messages, search for the damaging spells, and add
*** in the messages for your new spell. Be sure the number above the messages
*** match the spell number from spells.h.
*** Note: Don't forget the "M" on the line just above the spell number!!!
+ * Meteor
+ M
+ 52
+ Your meteor hits $N with full force, causing an immediate death!
+ A meteor summoned by $n hits you with full force. What a way to go...
+ $N summons a meteor on $n's head, causing instant death. Booyah!
+ The meteor you summoned seems to have...disintegrated.
+ The meteor $n summoned seems to have disintegrated. Whew!
+ The meteor $n summoned upon $N's head seems to have disintegrated. Oops!
+ You summon a meteor from the sky and reign it down upon the doomed head of $N!
+ $n has summoned a flaming meteor down upon your head. Ping!
+ $N has summoned a flaming meteor from the sky upon the doomed head of $N!
+ Hah, the Gods -made- the meteors!
+ Laugh, $n has tried summoning a meteor to hit you!
+ $N gracefully disintegrates the meteor that $n has tried to summon.