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.
Thanks to Tink from Astoria for pointing out that spell messages were not working properly. Corrected messages file attached below. It turns out I did a find and replace (sed) to get rid of several ^M's leftover from MSDOS formatting. It also stripped the required M prior to every block of messages.
I just wanted to take the time to welcome Astoria on to the tbaMUD band wagon. Jamdog is a major contributor to the tbaMUD codebase. Tink and Detta have been helping builders for years on TBA. I am looking forward to our continued joint ventures!
tbaMUD's:
The Builder Academy
Astoria
CrackWhip
Paragon
AderonMud
Azereth
Dragonball Fate
Smallville Untold Stories
Dragonball Awakening
Sermon MUD
Twilight's Failings
Let me know what tbaMUD's I missed.
The Mudconnector recently added the tbaMUD codebase to its list of MUD codebases. Those of you using tbaMUD can now update your TMC listing to show the proper codebase.
Jamdog added an excellent patch here for those wanting to add more directions to tbaMUD.
http://cwg.lazuras.org/modules.php?name=Forums&file=viewtopic&t=2108
I have granted SVN write access to a select few trusted individuals and wish to post the ground rules here so there is no confusion about what is to be expected.
First we have standardized our commenting and format of files per Jeremy's post so please follow them:
http://www.tbamud.com/content/source-code-documentation-project
To checkout the SVN:
svn checkout http://tbamud.com/svn/circlemud/circlemud tbamud
When ready to make a change to the codebase always do an "svn update" prior to your modifications and to decrease the possibilities of conflicts run an "svn commit """ or "svn commit --file " as soon after as possible. Now any change you make in game be sure to test and then comment the details in the changelog via the in game command "changelog " then copy and paste the same text into a commit or a file to commit. All changes must be described in detail to prevent confusion. I will be checking all changes by looking at the different revisions. i.e. "svn diff -96:97" to see what was done.
If there are any questions don't hesitate to ask. The great part about SVN is we can easily track all changes and revert them if necessary.
If you have already contributed heavily to tbaMUD and desire SVN access please contact me on TBA.
Thanks to Dan Blix for submitting this, it will be in the /doc directory next release. Here until then.
Compiling tbaMUD under BSD
based on UNIX readme for circlemud
by Jeremy Elson
For help, visit http://www.tbamud.com
Compiling tbaMUD is easy using FreeBSD. If you plan on compiling on a
FreeBSD machine, these instructions are for you. If not, check the main
README file to get a list of other operating systems that can be used to
compile and run tbaMUD.
Current versions of tbaMUD use the GNU 'autoconf' package to
automatically determine most of the important characteristics of your
system, so chances are good that tbaMUD will compile correctly on any
UNIX system -- even one that we have never seen before. However, if you
do have problems, please visit http://www.tbamud.com so that we
can try to make tbaMUD work with your system.
1) Download the latest version of tbaMUD. You can always find the
latest version at the following site:
2) Unpack the archive. If you have the .tar.gz version, uncompress it
using gzip (GNU unzip) and the tar archiver. (Both of these utilities
can be downloaded from ftp.gnu.ai.mit.edu:/pub/gnu if you don't have
them.) To unpack the archive on a UNIX system, type:
gzip -dc tbaMUD-xxxx.tgz | tar xvf -
3) Configure tbaMUD for your system. tbaMUD must be configured using
the 'configure' program which attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a 'Makefile' and a header file called 'conf.h'.
From tbaMUD's root directory, type
./configure
If you're using 'csh' on an old version of System V, csh might try to
execute 'configure' itself, giving you a message like "Permission denied"
when you try to run "./configure". If so, type "sh ./configure" instead.
'configure' can take several minutes if you're using a slow computer.
'configure' will attempt to use the 'gcc' compiler if it exists; if not,
it will try 'cc'. If you want to use a different compiler, set the
'CC' environment variable to the name of the compiler you wish to use.
For example, if you want to use the 'xlc' compiler, and your shell is
csh or tcsh:
setenv CC xlc
./configure
Or, if you want to use the 'xlc' compiler, and your shell is sh or bash:
CC=xlc ./configure
This will tell 'configure' to use the 'xlc' compiler instead of 'gcc'.
4) Build the tbaMUD server. This must be done from the 'src' directory.
Type:
cd src; gmake all
This will build tbaMUD proper as well as its 10 or so ancillary
utilities, which can take anywhere from 5 minutes to an hour depending
on the speed of your computer.
Note that in the future, when you need to recompile tbaMUD as you make
changes to the code, it is NOT necessary to run 'configure' again (it
should only be run once, after the first time you unpack tbaMUD from
its .tar file). If you move the source code to a different computer,
you should reconfigure it by deleting the file 'config.cache' and
running 'configure' again.
The first time you try to compile tbaMUD, you will be asked to read the
tbaMUD license. Please read it!
5) Go back to tbaMUD's root directory (by typing "cd ..") and run the
tbaMUD server. The easiest way to do this the first time is
to use the 'autorun' script, which can be run in the background by
typing:
./autorun &
Make sure to do this in tbaMUD's root directory, not the src directory
that you used for the previous step. A file called 'syslog' will start
growing in the same directory that contains tbaMUD's log messages.
If you're using 'csh' on an old version of System V, csh might try to
execute 'autorun' itself, giving you a message like "Permission denied"
when you try to run "./autorun". If so, type "sh ./autorun &" instead.
6) Wait until the line 'No connections. Going to sleep.' appears in the
syslog. This indicates that the server is ready and waiting for
connections. It shouldn't take more than about 30 seconds for the MUD
to reach this state, though performance will vary depending on how fast
your computer is.
If a file appears called 'syslog.CRASH', the MUD has terminated
(probably abnormally). Check the contents of syslog.CRASH to see
what error was encountered.
7) Type 'telnet localhost 4000' to connect. The first person to log in
will be made an implementor (level 34) with all powers.
(write to help@tbamud.com for help)
TBA's sixth release of the codebase formerly known as CircleMUD. Special thanks this release to Jeremy Osborne for his major contributions.
Download here: http://tbamud.com/filebrowser/patches/releases
Full changelog here: http://tbamud.com/files/changelog.txt