Blogs

How to add a wear slot

This is a little outdated, but it should still be pretty accurate.

Earthwolf

Although CircleMUD has many wear slots, it''s always fun to
add your own. I can think of some great wear-slots that I''d
rather not mention :-)

Earthwolf''s "Add a wear-slot" text v1.0
earthwolf@anti-social.com

Table Of Contents
-----------------
1. Introduction
2. Your step-by-step
3. How to contact me

INTRODUCTION
------------
You''ll all have to excuse any inability I show in writing
code snippet tutorials, this is my first :-). Being new to
coding I''m not yet great at fixing patches, modifying other''s
snippets, etc. It was because of the trouble I had of modifying
my Circle30bpl17 source by following other people''s instructions
that I set out to learn everything from scratch. I''m sure it''s
the best thing you can do for yourself: Learn how to add things
yourself, without other''s tutorials. Now that I think about it,
it doesn''t make sense while I''m writing this. Anyway, this is
a relatively simple process for beginners. Read on and enjoy!

NOTE: I''m not sure how well this will work for distributions
other than Circle30bpl17

STEP-BY-STEP How to add Wear-Slots
----------------------------------
Although CircleMUD has many wear slots, it''s always fun to
add your own. I can think of some great wear-slots that I''d
rather not mention :-). For this tutorial, we''ll be adding
one for the ankle. Not even for both, just one. After reading
this you should be able to add as many as you see fit.

files used (in alphtabetical order):
act.item.c, constants.c, objsave.c, structs.h

Modifications to act.item.c
--------------------------
Goto line 1165 and you should see the following code:

{"$n grabs $p.",
"You grab $p."}

};

That is the line for the description of what you and others
will see when you HOLD something. Since our ankle slot is
new we''ll just put it after the hold one.

So, add a comma to the bracket after the hold strings, and
then add what people and you will see when you wear your
anklet. The code will now look like this:

{"$n grabs $p.",
"You grab $p."},

{"$n fastens $p around $s ankle.",
"You fasten $p around your ankle."}

};

Make sure that you leave the "};" At the very end. If you did
not know, when the game is running variables with a ''$'' before
them will be replaced with some differant text. For example,
$n is replaced with the user''s name and $p is replaced with
what the item is called.

Ok, now head on down to line 1185 were you''ll see a big block
of code looking like this:

int wear_bivectors[] = {
ITEM_WEAR_TAKE, ITEM_WEAR_FINGER, ITEM_WEAR_FINGER, ITEM_WEAR_NECK
ITEM_WEAR_NECK, ITEM_WEAR_BODY, ITEM_WEAR_HEAD, ITE_WEAR_LEGS,
ITE_WEAR_FEET, ITEM_WEAR_HANDS, ITEM_WEAR_ARMS, ITE_WEAR_SHIELD,
ITEM_WEAR_ABOUT, ITEM_WEAR_WAIST, ITEM_WEAR_WRIST, ITEM_WEAR_WRIST,
ITEM_WEAR_WIELD, ITEM_WEAR_TAKE
};

Again, all we want to do is add more to this array. SLAP down a
comma after ITEM_WEAR_TAKE and add yourself an ITEM_WEAR_ANKLE.
Your code should magically now look like this:

int wear_bivectors[] = {
ITEM_WEAR_TAKE, ITEM_WEAR_FINGER, ITEM_WEAR_FINGER, ITEM_WEAR_NECK
ITEM_WEAR_NECK, ITEM_WEAR_BODY, ITEM_WEAR_HEAD, ITE_WEAR_LEGS,
ITE_WEAR_FEET, ITEM_WEAR_HANDS, ITEM_WEAR_ARMS, ITE_WEAR_SHIELD,
ITEM_WEAR_ABOUT, ITEM_WEAR_WAIST, ITEM_WEAR_WRIST, ITEM_WEAR_WRIST,
ITEM_WEAR_WIELD, ITEM_WEAR_TAKE, ITEM_WEAR_ANKLE
};

You see we just added our ankle information ITEM_WEAR_ANKLE to the
end of an already existing array. Ready to do it again? Well, jump
on down to line number 1211 where we''ll append the the big string
array. You should already see this:

"You''re already holding something\r\n"
};

You want to change this to:

"You''re already holding something\r\n",
"You''ve already got something around your ankle\r\n"
};

The MUD knows what''s up now if you try to wear an anklet twice.
Because of the code above all of the newbies shall be told.
Ok, now go down to line 1260 and we''ll just slide our ankle
into the end like we always do. (that didn''t sound right)

"\r!RESERVED!",
"\r!RESERVED!",
"\n"
};

So, to not have a crash we''ll just change the code above to
this code below:

"\r!RESERVED!",
"\r!RESERVED!",
"ankle",
"\n"
};

Well now that you have that done we must add some error checking
to the MUD to keep on making sure the MUD doesn''t try to wear
to anklets on the same slot:

if (CAN_WEAR(obj, ITEM_WEAR_WRIST)) where = WEAR_WRIST_R;
} else {

We''re just going to add some of our ankle code to this. You might
of already guessed, but all we need to do is make the code so
it looks like this:

if (CAN_WEAR(obj, ITEM_WEAR_WRIST)) where = WEAR_WRIST_R;
if (CAN_WEAR(obj, ITEM_WEAR_ANKLE)) where = WEAR_ANKLE;
} else {

We be done with act.item.c!

Modifications to constants.c
----------------------------
If you didn''t think that was very hard, then you''ll get through
the rest of this fine. We''ll just be adding some strings to
some existing arrays so that the MUD will notify us about what
we''re doing when we try to wear something on our ankle.

Ok, jump on down to line 264 where we''ll add some more stuff
after that ol'' hold slot friend of ours. On line 264 you''ll
see some code that looks like this:

" ",
" "
};

We just want to plug in another slot for the ankle. Simply
modify your code to look like what''s below, and don''t forget
the comma!

" ",
" ",
" "
};

By now you should be getting the picture, but if you don''t
then that''s ok. Our next step is very very similar to the
last one. Warp on down to line 289 and you''ll see some
code look''n just like ''dis:

"Wielded",
"Held",
"\n"
};

We want to jump inbetween the "Held" and the "\n" to make
ourselves an ankle sandwhich. We be jammin now! Use that
voodoo that you do and change your code to

"Wielded",
"Held",
"Worn around ankle",
"\n"
};

Don''t worry, we''re getting there. Go to line 340 and you''ll
see some very similar code:

"WIELD",
"HOLD",
"\n"
};

Ok, let''s just put our ankle slot after the HOLD slot like we''ve
been doing. Your code will now look like this:

"WIELD",
"HOLD",
"ANKLE"
"\n"
};

Oh my GOD, we did it! Well almost, you''re now done with
constants.c. There''s still some more to go. If you need to
get up, stretch out, play some Bob Marley, and do some
Tai Chi or something.

Modifying objsave.c, Friend or Foe?
-----------------------------------
Just by noticing the name of this file, I''m guessing that
this is what helps the computer save information about
objects :-). The only thing that we''re going to be worrying
about is helping the MUD know if you can actually wear
the obj on your ankle or not. Scroll down all the way
to line 162. There you''ll see a bunch of similar blocks of
code for each differant wear-slot. For easy installation
we''re gonna stick our code right after the WEAR_LEGS info
because it doesn''t really matter.

case WEAR_LEGS:
if (!CAN_WEAR(obj, ITEM_WEAR_LEGS))
location == LOC_INVENTORY;
break;
case WEAR_FEET:

So, with simple text editing program change the code above
to look like the code below:

case WEAR_LEGS:
if (!CAN_WEAR(obj, ITEM_WEAR_LEGS))
location = LOCINVENTORY;
break;
case WEAR_ANKLE:
if (!CAN_WEAR(obj, ITEM_WEAR_ANKLE))
location = LOC_INVENTORY;
break;
case WEAR_FEET:

Didn''t really take much to modify objsave.c did it? We only
have one more file to edit before you and your faithful
mortals can start wearing stuff on your ankle!

Modifying structs.h "It''s structurific!"
----------------------------------------
Remember all of those WEAR_ANKLE and ITEM_WEAR_ANKLE flags
we''ve been throwing around so haphazzardly? Well, we''re
actually going to define them now.

NOTE: It''s better to define things first :-)

I now you''re ready to implement, so cruise on down to
line 127 where all of the cool code hangs out. There
you''ll see some code like this:

#define WEAR_WIELD 16
#define WEAR_HOLD 17

#define NUM_WEARS 18

We''re not only going to through in our ankle slot, but also
increment the NUM_WEARS constant. So, modify your code to
the following, remembering to change NUM_WEARS:

#define WEAR_WIELD 16
#define WEAR_HOLD 17
#define WEAR_ANKLE 18

#define NUM_WEARS 19

We''re now ready for our last bit of code modification, and I
can''t beleave I''ve already written a 258 line text file!
Boy the time has been passing quickly hasn''t it? For your
last addition go on down to line 321 where you should see
the following code:

#define ITEM_WEAR_HOLD (1 << 14) /* Can be held */

Just change that to this and you''re done:

#define ITEM_WEAR_HOLD (1 << 14) /* Can be held */
#define ITEM_WEAR_ANKLE (1 << 15)

Ok, you''re completely done adding the wear slots now! When
you''re editing your objects from now on set your
War Bivector as ''p'' to make the equipment for your ankle.
(without the quotes)

HOW TO CONTACT ME
-----------------
As I''m sure you''ve noticed, adding wear slots was a really
easy thing to do. As for all you newbie coders like myself
though, it''s a great excersize for more familiarizing yourself
with the CircleMUD code. If you still have any questions, or
I made a mistake just e-mail me or go to my website. My
website will be updated with tutorials I write.

earthwolf@anti-social.com
http://www.geocities.com/earthwolf_0

Server malfunction.

At about 9:41 CET this morning (October 26th) a RAM-module failed in the builderacademy server.

As one might guess, this caused some pretty weird results in the system, one of which was a system lockup.

The server has been rebooted, and works as it is supposed to at the moment. The system makes sure it keeps running, and just doesn't use memory marked as bad. Thus, currently, the server runs on 511.9MB instead of 512MB. I expect a new RAM block to arrive within a reasonable timeframe.

MUDlists

MUDlists.com has added the tbaMUD codebase to all of their listing so if you have a tbaMUD listed as a CircleMUD you can now change it.

Minimalistic tbaMUD 3.57

Since it will assuredly be requested and has been for every release so far here's an alternate download of tbaMUD 3.57 with only zones 0, 12, and 30. Also removed are the special procedure assignments for the zones that were removed and the file castle.c was entirely removed as all it contains is special procedures for the zone "King Welmar's Castle". Also the zones 0 and 30 were modified to no longer reference scripts, objects and mobs from zones 1 and 31 so that there are no errors at bootup.

EDIT: Realized the Port # wasn't 4000 any longer in the autorun because I'd booted it on slayn where I only have access to ports 8000-8002, now reverted.

tbaMUD 3.57

Download tbaMUD 3.57 here!
http://www.tbamud.com/filebrowser/patches/releases

Many bug fixes and more code clean-up!

Full changelog: tbaMUD 3.57
[Aug 11 2008] - Rumble
Updated World and files for 3.57 release.
[Aug 10 2008] - Fizban
Added sanity checks to zedit new. (Can no longer make zones that include negative vnums, also get the proper message when you have 3 of the 4 arguments.)
You can now put objects in and remove objects from closed containers as an imm with nohassle.
You can now walk through closed doors as an imm with nohassle on.
You can now open locked containers and doors without unlocking them as an immortal with nohassle.
You can now examine the contents of closed containers as an imm with nohassle.
Made zedit new added the .qst file to the index file.
Fixed various qedit related bugs. (thanks Mirad and Jamdog)
Removed deprecated "murder" code.
When pkill is on players can now order charmed mobs to attack other players.
Fixed 'toggle automap'.
Added a sacrifice command instead of their being autosac only. Also replaced Zizazat's name with more generic "The Gods" as it had obviously been ported from CWG previously.
Fixed Warning relating to Automap.
[Aug 03 2008] - Rumble
You can now see your own communications while sleeping for gos, auc, gra, etc. (thanks Drefs)
changed str_and_map to use target_room instead of IN_ROOM(ch). (thanks Vatiken)
[Aug 02 2008] - Welcor
Fixed a one-line bug in act.movement.c - caused crashes when moving into FLIGHT rooms.
[Jul 26 2008] - Rumble
Fixed autosplit to properly award gold to the person delivering the killing blow and then split it with the group. (thanks Maclir)
Added checks to qedit for questmaster not being set. (thanks Jamdog)
[Jul 08 2008] - Rumble
Removed duplicate questpoints listing in stat char. (thanks Mirad)
Fix to qedit for deleting all quests. (thanks Jamdog)
[Jul 06 2008] - Rumble
Changed sedit no trade with from undefined to nobits. (thanks Mirad)
[Jul 03 2008] - Rumble
Fixed lib/messages to properly display skill, spell, and damage messages. (thanks Tink)
[Jun 28 2008] - Rumble
Added player ability to cancel queued commands. i.e. player spammed kick while fighting but needs to flee so they type '--' to cancel so they can flee. (thanks Jamdog)
[Jun 28 2008] - Fizban
Merged Jamdog's moblist code into the pre-existing mlist command. (thanks Jamdog)
[Jun 14 2008] - Rumble
Made immortals immune to blinding.
Fixed bug in qedit where quest completion would try to load an object with vnum NOTHING. (thanks Jamdog)
Fixed log when builder tries to edit a zone without permission.
[Jun 12 2008] - Rumble
Fixed toggle quest to toggle correctly.
Fixed bug in dg find_replacement to call text_processed at the beginning, regardless of whether something matching the variable is found or not. (thanks Laoris)
Fixed log error that was using rnum instead of vnum. (thanks Jamdog)
[Jun 11 2008] - Rumble
Added notification via prompt for new MOTD and news entries. (thanks Jamdog)
Added all option to the restore command. (thanks Jamdog)
Added new trigger variable hasattached. (thanks Fizban)
[Jun 10 2008] - Rumble
Added spec proc type under stat. (thanks Jamdog)
Only allow immortals to talk while invis and be displayed as "someone." (thanks Frenze)
[May 27 2008] - Rumble
Fixed list_obj_to_char from only checking invisibility on first object of the same vnum. (thanks Laoris)
Added object stacking when looking at a character's inventory. (thanks Jamdog)
[May 22 2008] - Rumble
Added zone name to where command. (thanks Jamdog)
[May 21 2008] - Rumble
Rewrite of void script_vlog to prevent possible crash bug on some OS's. (thanks Jamdog)
[May 17 2008] - Rumble
Fixed a possible crash bug in qedit. (thanks Jamdog)
Bug fix: Page command was paging when the character was not found and sending a NOPERSON message when he was found.
[May 15 2008] - Rumble
Fixed a bug where deleting the last quest in qedit caused a crash. (thanks Jamdog)
Updated autorun to fix a random syslog numbering bug. (thanks Zizazat)
[May 10 2008] - Rumble
Fixed another typo, added a check for !NPC do_gen_comm, and changed do_return to only run autowiz if level changes. (thanks Fizban)
[May 08 2008] - Rumble
Cleaned up numerous warnings found by adding -Wextra -Wcast-qual -Wshadow -Wno-unused flags.
[May 05 2008] - Rumble
Changed command do_list_llog_entries to normal function, it was not being used as a command. (thanks Rhade)
Removed several useless if checks. (thanks Elanthis)
Fixed zmalloc to work on 64 bit machines.
[May 04 2008] - Rumble
Fixed numerous warnings for gcc -g -O2 -W -Wshadow -Wcast-qual flags.
Fixed zpurge mudlog to use zone vnum not rnum. (thanks Jamdog)
Fix to parse_mobile conversion to 128 bits. (thanks Jamdog)
Changed autorun.sh from 9091 to 4000. (thanks John Smith)
[Apr 27 2008] - Rumble
Removed some defunct gemote code. (thanks Fizban)
[Apr 26 2008] - Rumble
Added README.BSD. (thanks Blix)
Cleaned up act.comm.c, mobs can now use comm channels. (thanks Rhade)

On Vacation

My turn for a vacation, I'll be gone for one week. Checking in occasionally. As usual email myself and Welcor if there are any problems with the server or the game is down. Shamra is in charge with Fizban and Tink to back him up when he is not around. Have a good week everyone. tbaMUD 3.57 will be coming in August.

Difference between CircleMUD

This question came up again so here is an incomplete list of differences between stock CircleMUD 3.1 and tbaMUD: http://www.tbamud.com/files/changelog.txt

Creating Area Spells

Introduction

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.

The Code

*** 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.

Updated Fishing Snippet

Introduction

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.

FIXES

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.)

Fishing Snippet

*** 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 Help File

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!

Creating Damaging Spells

Introduction

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.

The Code

*** 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.
Syndicate content