19 Commits

Author SHA1 Message Date
Rumble
68dd901943 Updated for 2021 release 2021-03-06 15:50:00 +00:00
Noah Cunningham
547c7ddccf Fix for pointer in fread() db.c to fix Raspberry Pi load issue (#97)
This corrects an issue encountered when loading world information on the Raspberry Pi. Sometimes, there is a ~ stored in the memory location in front of tmp char array. The for loop will decrement below the starting memory address, making it read the ~ and think it's at the end of the room, causing an error and preventing the MUD from loading.

This change checks the memory address of tmp, ensuring it is > the starting memory address before decrementing it in the for() loop. Then, the if/else checks to ensure the carriage return and newline are properly placed to prevent duplication.
2020-11-16 12:36:04 -05:00
MBourne
dceb563a9b Bug/drink containers (#94)
* Bugfix for name_from_drinkcon

* Newline at end of utils.c
2020-06-07 08:52:22 -04:00
Thomas Arp
c0fb6f8a71 Correct log message for strange room flags (#88)
Thanks to Cunning on the tba board for the bug report
https://www.tbamud.com/forum/4-development/4548-db-c-typo-in-parse-rooms#8633
2020-04-16 20:12:34 -04:00
Thomas Arp
1f520546b2 Merge pull request #84 from tbamud/crash-bug-in-object-drop-script
Crash bug in object drop script
2020-03-08 23:57:15 +01:00
Thomas Arp
6fede208d2 Gcc 9.2.1 warnings (#87)
* Make sure all followers are free'd before freeing the character list

Otherwise, the followers structs will point to free'd memory and
the stop_follower call will attempt to dereference a free'd
characters' followers list.

* fix gcc warning: truncation in strncat

In file included from /usr/include/string.h:494,
from sysdep.h:74,
from act.item.c:12:
In function ‘strncat’,
inlined from ‘name_from_drinkcon’ at act.item.c:804:5,
inlined from ‘name_from_drinkcon’ at act.item.c:769:6:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:136:10: warning: ‘__builtin_strncat’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
136 | return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
act.item.c: In function ‘name_from_drinkcon’:
act.item.c:797:16: note: length computed here
797 | cpylen = strlen(cur_name);
| ^~~~~~~~~~~~~~~~

* Whitespace cleanup before bugfix

* Fix warnings for gcc-9.2.1

Also, fixed an ancient FIXME and a known bad strcat usage.

spell_parser.c: In function ‘say_spell’:
spell_parser.c:135:75: warning: ‘%s’ directive output may be truncated writing up to 255 bytes into a region of size 216 [-Wformat-truncation=]
135 | snprintf(buf1, sizeof(buf1), "$n stares at you and utters the words, '%s'.",
| ^~
In file included from /usr/include/stdio.h:867,
from sysdep.h:69,
from spell_parser.c:12:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:67:10: note: ‘__builtin___snprintf_chk’ output between 43 and 298 bytes into a destination of size 256
2020-03-08 08:33:59 -04:00
Thomas Arp
fc223452e8 Fix typo in previous commit.
Also, inline lookup functions if possible.
2020-03-07 23:24:32 +01:00
Thomas Arp
a60f0eefb8 Minor bugfix in code that should be unreachable.
We already log that we update, but no update was taking place.
2020-03-07 23:22:01 +01:00
Thomas Arp
53870eba5d Added further failsafes to prevent dereferencing free'd objects
"obj" variable is not updated here, so we must lookup to see if it has
been free'd in script_driver().

Fixes #83
2020-03-01 01:27:57 +01:00
Thomas Arp
d5a11618f1 Remove crash bug when purging a dropped item in a wtrigger.
We're leveraging the lookup table, because it's a safer way
to see if an object has been free'd than looking at the object
itself (which while it may work may just as well fail).

Fixes #83
2020-03-01 01:19:06 +01:00
Thomas Arp
140cdc5d22 Merge branch 'master' of github.com:tbamud/tbamud 2020-02-29 14:33:30 +01:00
Thomas Arp
eb650c2811 GitHub issues 78 79 81 num aff flags off by one (#82)
* Make sure all followers are free'd before freeing the character list

Otherwise, the followers structs will point to free'd memory and
the stop_follower call will attempt to dereference a free'd
characters' followers list.

* https://github.com/tbamud/tbamud/issues/79 typo

* https://github.com/tbamud/tbamud/issues/81 nullpointer crash on syntax check run

* NUM_AFF_FLAGS fix.

Now, consistently, the NUM_AFF_FLAGS is used in the same way as other
NUM_* variables. Specifically, the the number is consistent with
how others are defined - 1 above the highest in the list.

I would like to have removed the need to start from 1 instead of 0
as well, but the loading mechanism, and thus potentially a lot of
existing object files, use 0 as a marker for "no flags set", and
we can't easily fix that. So, the places we loop through the list,
we still need to make sure we're stying within the [1;NUM_AFF_FLAGS) interval.

Simultaneously, I've checked over the other flags, and it seems like
the usage is pretty consistent there.

Fixes https://github.com/tbamud/tbamud/issues/78
2020-02-25 18:39:29 -05:00
Thomas Arp
4f875db90e Merge branch 'master' of github.com:tbamud/tbamud 2020-02-25 22:46:53 +01:00
Thomas Arp
7f0acefcb4 Confusing code fix (#76)
* Make sure all followers are free'd before freeing the character list

Otherwise, the followers structs will point to free'd memory and
the stop_follower call will attempt to dereference a free'd
characters' followers list.

* Make sure %target% works in act triggers

* code cleanup. Remove inline block, make variable names more understandable.

Ref https://www.tbamud.com/forum/4-development/4525-confused-over-piece-of-code-in-parse-room
2020-01-26 16:19:10 -05:00
Thomas Arp
28ca86645b Merge branch 'master' of github.com:tbamud/tbamud 2020-01-26 21:43:08 +01:00
Thomas Arp
1ab51a0545 Make sure all followers are free'd before freeing the character list (#75)
Otherwise, the followers structs will point to free'd memory and
the stop_follower call will attempt to dereference a free'd
characters' followers list.
2020-01-19 08:44:21 -05:00
Thomas Arp
bf31d98414 Make sure all followers are free'd before freeing the character list
Otherwise, the followers structs will point to free'd memory and
the stop_follower call will attempt to dereference a free'd
characters' followers list.
2020-01-19 14:40:33 +01:00
Rumble
934d83b829 Updating for 2020 release.
Merge branch 'master' of https://github.com/tbamud/tbamud
2020-01-14 20:08:23 +01:00
Thomas Arp
462807d9e8 Fixes for w-format-truncation. Also, export of zones work again on linux (#74) 2020-01-10 19:28:09 -05:00
32 changed files with 766 additions and 754 deletions

View File

@@ -10,6 +10,7 @@ to rec.games.mud.diku which originally announced CircleMUD as a publicly
available MUD source code. available MUD source code.
tbaMUD Release history: tbaMUD Release history:
Version 2021 release: March, 2021
Version 2020 release: January, 2020 Version 2020 release: January, 2020
Version 2019 release: January, 2019 Version 2019 release: January, 2019
Version 2018 release: January, 2018 Version 2018 release: January, 2018

View File

@@ -2893,7 +2893,7 @@ $n looks at your $t and seems to think it could use a little trimming off the to
You look at $p and think it could use a little trimming off the top. You look at $p and think it could use a little trimming off the top.
$n looks at $p and seems to think it could use a little trimming off the top. $n looks at $p and seems to think it could use a little trimming off the top.
~halo halo 0 8 8 31 ~halo halo 0 8 8 1
You whip out the ol' halo. That should prove your innocence. You whip out the ol' halo. That should prove your innocence.
$n loads a halo and dons it. $n loads a halo and dons it.
$N could use a good disguise. $N could use a good disguise.

View File

@@ -1,5 +1,5 @@
T B A M U D T B A M U D
2 0 2 0 2 0 2 1
Based on CircleMUD by Jeremy Elson and DikuMUD by Hans-Henrik Staerfeldt, Based on CircleMUD by Jeremy Elson and DikuMUD by Hans-Henrik Staerfeldt,
Katja Nyboe, Tom Madsen, Michael Seifert, and Sebastian Hammer Katja Nyboe, Tom Madsen, Michael Seifert, and Sebastian Hammer

View File

@@ -7093,31 +7093,28 @@ See also: FLAGS, PLR
#31 #31
PROMOTE PROMOTIONS ADVANCEMENTS RAISES LVLS LEVELS GAINS 31 32 33 34 RANKS RANKING HIRING JOBS STAFFING PROMOTE PROMOTIONS ADVANCEMENTS RAISES LVLS LEVELS GAINS 31 32 33 34 RANKS RANKING HIRING JOBS STAFFING
Here at The Builder Academy the level of an immortal generally denotes Here at The Builder Academy, the level of an immortal generally reflects that
their skill at building. This makes it easier for people to know who is in immortal's building skill and willingness to help others. If you have
charge, who they can ask for help, and who they should be wary of taking tips questions, you may want to ask someone whose level is at least 32. Of course,
from. I encourage everyone to help each other. Just realize that if the person everyone is encouraged to help everyone else, but know that those who are not
is not at least a Great God they may have relatively little experience. at least level 32 may have relatively little experience.
Level 31 (Immortal) Anyone who is new to TBA and is working on their trial Level 31 (Immortal) Anyone who is new to TBA and is working on their trial
vnum or zone. vnum or zone.
Level 32 (God) An experienced builder that has proven their knowledge and is Level 32 (God) An experienced builder with proven knowledge that is
willing to teach others. Level 2 and above is considered staff. willing to teach others. Immortals of level 32 and above
Level 33 (Greater God) An experienced builder that has contributed are considered staff.
significantly to TBA. Level 33 (Greater God) An experienced builder that has contributed significantly
to TBA.
Level 34 (Implementor) Current developers: Welcor, Wyld, and Opie. Level 34 (Implementor) Current developers: Welcor, Wyld, and Opie.
Do not bother asking to be advanced, and if that is why you are here, you Please do not bother asking to be advanced. If your goal is merely to rise in
are wasting your time. Note, this does not mean you are not a quality builder, the ranks, you are wasting your time. The Gods here are dedicated to helping
but TBA is not your typical MUD. On the contrary, we are here as dedicated others learn to build. Thus, those who advance in level are those who become
people to help you learn to build. Because of this the only chance of proficient builders that offer their time to teach others. If you are willing
advancement is if you are willing to learn to build and then help teach others. to give back to the tbaMUD community and have the requisite skills, you will be
If you are willing to give back to the tbaMUD community, and have the advanced and given further tools to teach others via your level. Generally, if
necessary skills to do so, you will be advanced and given further privileges you ask for a promotion, you will be less likely to receive it.
to help teach others. Generally, if you have to ask for a promotion you will be
less likely to receive it. Performance is everything here.
q
#0 #0
PROPOSALS GUIDELINES ZONE-PROPOSALS PROPOSITIONS PROPOSE REQUESTS CRITERIA PROPOSALS GUIDELINES ZONE-PROPOSALS PROPOSITIONS PROPOSE REQUESTS CRITERIA

View File

@@ -990,7 +990,6 @@ He is covered in a film of dirt and grime. He smells even worse than you.
30 900 30 900
8 8 1 8 8 1
E E
T 206
#169 #169
citizen~ citizen~
a citizen~ a citizen~

View File

@@ -128,18 +128,6 @@ Samuel himself is here, pouring the drinks and getting rich.
300 90000 300 90000
8 8 1 8 8 1
E E
#31510
postal worker postmasters~
the postal worker~
A postal worker is here, ready to send or get your mail.
~
Be careful. No sudden moves. You know how these guys get....
~
10 0 0 0 0 0 0 0 0 E
30 10 -8 6d6+300 5d5+5
300 90000
8 8 1
E
#31511 #31511
Juan pusher potion~ Juan pusher potion~
Juan the potion pusher~ Juan the potion pusher~

View File

@@ -7,28 +7,6 @@ A granite fountain is gurgling here.~
-1 2 15 0 -1 2 15 0
0 0 0 0 0 0 0 0 0 0
E E
fountain basin~
The fountain is made of black granite and the water
in it looks and inviting to drink. In the center is a
'SPADE' shaped centerstone that seems to have writing
all over it.
~
E
spade~
The spade seems to be the headstone of the center of the
fountain here. It is made of black stone and is an obelisk
in shape. It has 'Directory' on the side of it and it also
has a 'MAP' on the side of it as well.
~
E
Map~
Nth: God Hall - Nth, Inn, Post Office, Coffee Alcove
Sth: God Hall - Sth, Bus. Ctr, Bldr Brd Rm, God Hall, Ext
Est: God Hall - Est, Imm/Mrtl Brd Rm, Upr Imm Hall, Grd Lvl, God Hl - Ext
Wst: God Hall - Wst, H.O.Jst/Chpl, Mtn Rm, Upr Imm Hall, Grd Lvl, God Hl - Ext
Dwn: Midguaard
~
E
Directory~ Directory~
--------------------------------------------------------- ---------------------------------------------------------
Immortal Name: ===== Room # ====== Location: ======= Immortal Name: ===== Room # ====== Location: =======
@@ -57,6 +35,26 @@ Niamh ----------- 34351 ----------- God Hall, Southeast
Fade ----------- 34337 ------------ God Hall, West Fade ----------- 34337 ------------ God Hall, West
Angela -------- 34636 --------God Hall, South Extension Angela -------- 34636 --------God Hall, South Extension
~ ~
E
Map~
Nth: God Hall - Nth, Inn, Post Office, Coffee Alcove
Sth: God Hall - Sth, Bus. Ctr, Bldr Brd Rm, God Hall, Ext
Est: God Hall - Est, Imm/Mrtl Brd Rm, Upr Imm Hall, Grd Lvl, God Hl - Ext
Wst: God Hall - Wst, H.O.Jst/Chpl, Mtn Rm, Upr Imm Hall, Grd Lvl, God Hl - Ext
Dwn: Midguaard
~
E
spade~
The spade seems to be the headstone of the center of the fountain here. It
is made of black stone and is an obelisk in shape. It has 'Directory' on the
side of it and it also has a 'MAP' on the side of it as well.
~
E
fountain basin~
The fountain is made of black granite and the water in it looks and inviting
to drink. In the center is a 'SPADE' shaped centerstone that seems to have
writing all over it.
~
#34301 #34301
fouton~ fouton~
a Fouton(tm) ~ a Fouton(tm) ~
@@ -287,8 +285,8 @@ A plush couch is here in front of a coffee table.~
0 0 0 0 0 0 0 0 0 0
E E
couch~ couch~
The couch is long, has a frame of oak wood and a long The couch is long, has a frame of oak wood and a long blue cushion. It
blue cushion. It happens to be a Futon (tm). happens to be a Futon (tm).
~ ~
#34319 #34319
LazyBoy recliner~ LazyBoy recliner~
@@ -684,15 +682,15 @@ A toilet is here made of porclein.~
1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
E E
sign~
Be sure to Flush!
~
E
toilet toidy throne~ toilet toidy throne~
The toilet is made of white porcelien and it stands with a tank near the The toilet is made of white porcelien and it stands with a tank near the
wall. It has a wooden seat that is made of carved walnut and it has gold wall. It has a wooden seat that is made of carved walnut and it has gold
fixtures all around, which include the handles. fixtures all around, which include the handles.
~ ~
E
sign~
Be sure to Flush!
~
#34344 #34344
sink~ sink~
a sink and granite counter~ a sink and granite counter~
@@ -702,15 +700,15 @@ A sink and long granite counter is here.~
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
E E
counter~
The counters are made of granite and are immaculately carved with such
precision into a smooth flowing shape and designs all over them.
~
E
sink~ sink~
The sink is clean and white, with a shiny chrome faucet system and drain in The sink is clean and white, with a shiny chrome faucet system and drain in
the bottom. the bottom.
~ ~
E
counter~
The counters are made of granite and are immaculately carved with such
precision into a smooth flowing shape and designs all over them.
~
#34345 #34345
tub clawtub~ tub clawtub~
an old fashioned claw tub and shower~ an old fashioned claw tub and shower~
@@ -720,16 +718,16 @@ An old fashioned claw tub and shower is here.~
3 0 0 0 3 0 0 0
0 0 0 0 0 0 0 0 0 0
E E
tub~
The tub is made of iron and porcelin and it has claw feet in which it sits.
It is quite large and deep holding several meters of water.
~
E
shower~ shower~
The shower is a gold tube and a nozzle that is located on one side of the tub The shower is a gold tube and a nozzle that is located on one side of the tub
and the water pours down over the person or persons. The valve is located just and the water pours down over the person or persons. The valve is located just
above the fixture on the bottom of the tub that fills it. above the fixture on the bottom of the tub that fills it.
~ ~
E
tub~
The tub is made of iron and porcelin and it has claw feet in which it sits.
It is quite large and deep holding several meters of water.
~
#34346 #34346
bench~ bench~
a short teak bench~ a short teak bench~
@@ -752,16 +750,16 @@ A gurgling spring is here splashing into a golden basin.~
-1 2 15 0 -1 2 15 0
0 0 0 0 0 0 0 0 0 0
E E
spring~
The spring is just a free flowing stream of water that flows from the ground
with a murmuring, gurgling sound.
~
E
basin~ basin~
The basin is made of gold and it holds the water as it splashes out from the The basin is made of gold and it holds the water as it splashes out from the
spring from the ground. When full it runs into what appears to be a channel spring from the ground. When full it runs into what appears to be a channel
leading to the lagoon. leading to the lagoon.
~ ~
E
spring~
The spring is just a free flowing stream of water that flows from the ground
with a murmuring, gurgling sound.
~
#34348 #34348
statue~ statue~
a guardian statue of Rumble~ a guardian statue of Rumble~
@@ -771,6 +769,12 @@ A guardian statue of Rumble is here next to a pedistal.~
0 0 0 0 0 0 0 0
0 0 0 31 0 0 0 0 31 0
E E
pedistal~
The pedistal is made of rounded carved marble and it has unique designs,
portraying extreme power. The top of the pedistal is empty, but it seems that
something should go there.
~
E
statue Rumble rumble guardian~ statue Rumble rumble guardian~
The statue is a guardian to this shrine, it depicts one of the immortals of The statue is a guardian to this shrine, it depicts one of the immortals of
TBA and his power and influence over all who worship here. He stands clad as a TBA and his power and influence over all who worship here. He stands clad as a
@@ -778,12 +782,6 @@ Battle Mage, in flowing robes and carries a staff. His hair is long and flowing
as he seems to be raising the staff in battle. You seem to feel at ease by this as he seems to be raising the staff in battle. You seem to feel at ease by this
statue. statue.
~ ~
E
pedistal~
The pedistal is made of rounded carved marble and it has unique designs,
portraying extreme power. The top of the pedistal is empty, but it seems that
something should go there.
~
#34349 #34349
Opie~ Opie~
a guardian statue of Opie~ a guardian statue of Opie~
@@ -793,6 +791,11 @@ A guardian statue of Opie is here.~
0 0 0 0 0 0 0 0
0 0 0 31 0 0 0 0 31 0
E E
nametag~
The nametag reads Opie the Cunning and that is carved at the base of the
statue near the foot of his statue.
~
E
Opie Guardian~ Opie Guardian~
The statue is a guardian to this shine, it depicts one of the immortals of The statue is a guardian to this shine, it depicts one of the immortals of
TBA and the influence of steath and cunning to all who worhip here. He stands TBA and the influence of steath and cunning to all who worhip here. He stands
@@ -800,11 +803,6 @@ clad in carved battle armor of leather, a loose flowing shirt and a sash about
his waist. In his hand he carries a dagger that is thrust outward in a backstab his waist. In his hand he carries a dagger that is thrust outward in a backstab
motion. You feel a strange surge of adventure looking at this statue. motion. You feel a strange surge of adventure looking at this statue.
~ ~
E
nametag~
The nametag reads Opie the Cunning and that is carved at the base of the
statue near the foot of his statue.
~
#34350 #34350
Welcor~ Welcor~
a guardian statue of Welcor~ a guardian statue of Welcor~
@@ -814,6 +812,11 @@ A guardian statue of Welcor is here.~
0 0 0 0 0 0 0 0
0 0 0 31 0 0 0 0 31 0
E E
nametag~
The nametag reads Welcor the Bishop and that is carved at the base of the
statue near the foot of it.
~
E
Welcor guardian~ Welcor guardian~
The statue is a guardian to this shine, it depicts one of the immortals of The statue is a guardian to this shine, it depicts one of the immortals of
TBA and the influence of Justice to all who worship here. He/She stands clad in TBA and the influence of Justice to all who worship here. He/She stands clad in
@@ -821,9 +824,4 @@ a long flowing set of robes and he/she carries a warhammer in their hand. The
feeling of peace overwhelms the senses when you look at the statue that seems to feeling of peace overwhelms the senses when you look at the statue that seems to
be floating and glowing brightly. be floating and glowing brightly.
~ ~
E
nametag~
The nametag reads Welcor the Bishop and that is carved at the base of the
statue near the foot of it.
~
$~ $~

View File

@@ -222,14 +222,6 @@ An awl pike is here, taking up much space.~
5 0 0 0 0 an 0 0 0 0 0 0 0 5 0 0 0 0 an 0 0 0 0 0 0 0
4 3 5 3 4 3 5 3
15 750 75 0 0 15 750 75 0 0
#3927
jeweled dagger~
a jeweled dagger~
A dagger is lying here, its jewels sparkling merrily.~
~
5 0 0 0 0 an 0 0 0 0 0 0 0
5 2 3 14
4 120 12 0 0
#3928 #3928
14~ 14~
a wickedly curving dagger~ a wickedly curving dagger~

View File

@@ -127,6 +127,7 @@ Smelly Bum - M168~
* By Rumble of The Builder Academy tbamud.com 9091 * By Rumble of The Builder Academy tbamud.com 9091
* A trig to let people smell the bum from 1 room away. * A trig to let people smell the bum from 1 room away.
* For the first move there is no from_room so set it. * For the first move there is no from_room so set it.
* Not working - something broke
if !%from_room% if !%from_room%
eval from_room %self.room.vnum% eval from_room %self.room.vnum%
global from_room global from_room
@@ -157,7 +158,6 @@ end
* *
eval from_room %self.room.vnum% eval from_room %self.room.vnum%
global from_room global from_room
%echo% FROM:%from_room% TO:%inroom%
~ ~
#207 #207
Mob Blocks opening of chest~ Mob Blocks opening of chest~

View File

@@ -65,6 +65,7 @@ D1
~ ~
0 0 4 0 0 4
S S
T 56
#4 #4
The Beginning~ The Beginning~
By simply following the different halls new builders will be taught the By simply following the different halls new builders will be taught the
@@ -135,7 +136,7 @@ HELP BREATHE@n
D0 D0
~ ~
~ ~
0 0 24 0 0 -1
D1 D1
~ ~
~ ~
@@ -143,7 +144,7 @@ D1
D2 D2
~ ~
~ ~
0 0 25 0 0 -1
D3 D3
~ ~
~ ~
@@ -151,7 +152,7 @@ D3
D4 D4
~ ~
~ ~
0 0 26 0 0 -1
S S
#7 #7
Writing Good Descriptions~ Writing Good Descriptions~
@@ -215,7 +216,7 @@ D3
D4 D4
~ ~
~ ~
0 0 27 0 0 -1
S S
#9 #9
How to Use Oedit~ How to Use Oedit~
@@ -570,6 +571,7 @@ John Stuart Mill
~ ~
0 8 0 0 0 0 0 8 0 0 0 0
S S
T 308
#34 #34
Pool of Images~ Pool of Images~
A broad mosaic walkway wraps around the natural hotsprings in this cavernous A broad mosaic walkway wraps around the natural hotsprings in this cavernous
@@ -775,14 +777,14 @@ D2
~ ~
0 0 98 0 0 98
E E
sky winds~
Cold winds plunge ceaselessly at you from the dark, cloudless sky.
~
E
floor~ floor~
The stone floor is the same shade of gray as the sky and is completely plain The stone floor is the same shade of gray as the sky and is completely plain
and unscratched. It is probably too hard for anything to leave as much as a and unscratched. It is probably too hard for anything to leave as much as a
scratch on it. scratch on it.
~ ~
E
sky winds~
Cold winds plunge ceaselessly at you from the dark, cloudless sky.
~
S S
$~ $~

View File

@@ -72,7 +72,7 @@ Zone 1 is linked to the following zones:
2 Sanctus II at 199 (south) ---> 206 2 Sanctus II at 199 (south) ---> 206
~ ~
S S
T 56 T 24
#101 #101
The Temple of the Gods~ The Temple of the Gods~
This seems to be the highest point in the kingdom of Sanctus. It is from This seems to be the highest point in the kingdom of Sanctus. It is from
@@ -92,19 +92,19 @@ D5
~ ~
0 0 100 0 0 100
E E
altar~
The altar is made from black granite and has been carved into a small basin
with a high back. Almost as if it was meant to be some sort of seat.
Inscriptions in some foreign tongue are written on every square inch of the
altar. You wonder what they must say and who could have written it.
~
E
statue~ statue~
As you examine the statues more closely you realize they must resemble the As you examine the statues more closely you realize they must resemble the
two gods responsible for the creation and ongoing protection of Sanctus, Ferret two gods responsible for the creation and ongoing protection of Sanctus, Ferret
and Rumble. They both radiate a strength and power that resembles the solid and Rumble. They both radiate a strength and power that resembles the solid
white marble they were crafted from. white marble they were crafted from.
~ ~
E
altar~
The altar is made from black granite and has been carved into a small basin
with a high back. Almost as if it was meant to be some sort of seat.
Inscriptions in some foreign tongue are written on every square inch of the
altar. You wonder what they must say and who could have written it.
~
S S
T 158 T 158
T 163 T 163
@@ -240,17 +240,17 @@ D5
~ ~
0 0 142 0 0 142
E E
table~
The table is made out of cherry. It is worn from years of use. The glass
top allows for an excellent view of the map protected within.
~
E
map~ map~
The map is a geographic representation of Sanctus. Not even really a map, The map is a geographic representation of Sanctus. Not even really a map,
more of a scaled model. The walls and buildings of the city are raised higher more of a scaled model. The walls and buildings of the city are raised higher
than the rest of the map to give it a third dimension. Small soldiers are than the rest of the map to give it a third dimension. Small soldiers are
scattered around the top of the table to help the War Master place his men. scattered around the top of the table to help the War Master place his men.
~ ~
E
table~
The table is made out of cherry. It is worn from years of use. The glass
top allows for an excellent view of the map protected within.
~
S S
#109 #109
Thieves Retreat~ Thieves Retreat~
@@ -383,18 +383,18 @@ D1
~ ~
0 0 100 0 0 100
E E
hole~
You can look out over the inner wall to the western side of Sanctus. The
smell of charred human remains and smoldering plaster makes your eyes water so
it is difficult to see much else through the tiny hole.
~
E
man silhouette~ man silhouette~
The distinct outline of a human body that must have taken the brunt of the The distinct outline of a human body that must have taken the brunt of the
blast when the portal imploded. You wonder what or who it might have been. blast when the portal imploded. You wonder what or who it might have been.
You can still see pieces of cloth and bone buried deeply into the wall inside You can still see pieces of cloth and bone buried deeply into the wall inside
the shadow of the unlucky man. the shadow of the unlucky man.
~ ~
E
hole~
You can look out over the inner wall to the western side of Sanctus. The
smell of charred human remains and smoldering plaster makes your eyes water so
it is difficult to see much else through the tiny hole.
~
S S
#117 #117
Travelling Room~ Travelling Room~
@@ -530,19 +530,19 @@ D2
~ ~
0 0 129 0 0 129
E E
shrine~
A beutiful shrine. It has two white marble figures facing each other with a
painting of the city below them. The two figures seem to be looking down at
the city with looks of worry and hopelessness. An unlit candle and mirror lay
on the floor beside the small shrine.
~
E
table desk chair~ table desk chair~
The table, desk, and chair are made from solid oak of the highest quality. The table, desk, and chair are made from solid oak of the highest quality.
A thin goose down mattress and pillow are the only comfortable looking items in A thin goose down mattress and pillow are the only comfortable looking items in
the room. The desk is bare and all the drawers are empty. It is as if no one the room. The desk is bare and all the drawers are empty. It is as if no one
even lives here. even lives here.
~ ~
E
shrine~
A beutiful shrine. It has two white marble figures facing each other with a
painting of the city below them. The two figures seem to be looking down at
the city with looks of worry and hopelessness. An unlit candle and mirror lay
on the floor beside the small shrine.
~
S S
#125 #125
Plane of the Magi~ Plane of the Magi~
@@ -816,10 +816,14 @@ D0
~ ~
0 0 128 0 0 128
E E
bed~ window~
The bed is made of a sturdy pine. A thin mattress covered in a white sheet Overlooking the western gate you can see the shimmering protective dome.
with a down pillow overlaying it. The mattress is too thin to hold anything of You hope it lasts, peace and tranquility is a good thing.
value. ~
E
chair~
It's just your standard wooden chair. Uncomfortable and only real
usefulness would be as firewood.
~ ~
E E
desk~ desk~
@@ -829,14 +833,10 @@ centered on the top of the desk. The desk has three drawers. All of them are
empty. empty.
~ ~
E E
chair~ bed~
It's just your standard wooden chair. Uncomfortable and only real The bed is made of a sturdy pine. A thin mattress covered in a white sheet
usefulness would be as firewood. with a down pillow overlaying it. The mattress is too thin to hold anything of
~ value.
E
window~
Overlooking the western gate you can see the shimmering protective dome.
You hope it lasts, peace and tranquility is a good thing.
~ ~
S S
#136 #136

View File

@@ -1372,15 +1372,21 @@ D5
door~ door~
2 0 225 2 0 225
E E
sky winds~
Cold winds plunge ceaselessly at you from the dark, cloudless sky.
~
E
floor~ floor~
The stone floor is the same shade of gray as the sky and is completely plain The stone floor is the same shade of gray as the sky and is completely plain
and unscratched. It is probably too hard for anything to leave as much as a and unscratched. It is probably too hard for anything to leave as much as a
scratch on it. scratch on it.
~ ~
E S
sky winds~ #391
Cold winds plunge ceaselessly at you from the dark, cloudless sky. Bomber's Trial Vnum~
You are in an unfinished room.
~ ~
3 0 0 0 0 0
S S
#399 #399
Welcome to the Builder Academy~ Welcome to the Builder Academy~

View File

@@ -12,6 +12,11 @@ Campus Crescent continues to the east.
~ ~
0 -1 30101 0 -1 30101
E E
sign~
Campus by Matrix and The Wandering Bard
Copyright 1994 by Curious Areas Workshop
~
E
info credits~ info credits~
Campus by Matrix and The Wandering Bard Campus by Matrix and The Wandering Bard
Copyright 1994 by Curious Areas Workshop Copyright 1994 by Curious Areas Workshop
@@ -55,11 +60,6 @@ Zone 301 is linked to the following zones:
301, 302 and 303. Please ensure that any entrances into the area are flagged 301, 302 and 303. Please ensure that any entrances into the area are flagged
nomob to keep them in. - Parna for TBAMud.) nomob to keep them in. - Parna for TBAMud.)
~ ~
E
sign~
Campus by Matrix and The Wandering Bard
Copyright 1994 by Curious Areas Workshop
~
S S
#30101 #30101
Campus Crescent~ Campus Crescent~
@@ -112,13 +112,13 @@ Campus Crescent continues to the west.
~ ~
0 -1 30101 0 -1 30101
E E
dorm dormitory dormitories~
Well, they're dormitories. What else can be said?
~
E
cobblestone stone cobble~ cobblestone stone cobble~
The cobblestones are clean. The cobblestones are clean.
~ ~
E
dorm dormitory dormitories~
Well, they're dormitories. What else can be said?
~
S S
#30103 #30103
Campus Crescent~ Campus Crescent~
@@ -144,13 +144,13 @@ Campus Crescent continues to the west.
~ ~
0 -1 30102 0 -1 30102
E E
cobblestone stone cobble~
The cobblestones are clean.
~
E
caf cafeteria~ caf cafeteria~
You barely see, through the thick putrid fumes, the Mary Rotte Cafeteria. You barely see, through the thick putrid fumes, the Mary Rotte Cafeteria.
~ ~
E
cobblestone stone cobble~
The cobblestones are clean.
~
S S
#30104 #30104
The Crossroads~ The Crossroads~
@@ -214,13 +214,13 @@ The Crossroads lie to the west.
~ ~
0 -1 30104 0 -1 30104
E E
cobblestone stone cobble~
The cobblestones are clean.
~
E
building~ building~
The buildings seem warm and inviting. You almost feel like hugging one. The buildings seem warm and inviting. You almost feel like hugging one.
~ ~
E
cobblestone stone cobble~
The cobblestones are clean.
~
S S
#30106 #30106
Campus Crescent~ Campus Crescent~
@@ -251,8 +251,8 @@ Campus Crescent continues to the west.
~ ~
0 -1 30105 0 -1 30105
E E
cobblestone stone cobble~ round building~
The cobblestones are still clean. Yes... It's a round building. Go figure.
~ ~
E E
bookstore~ bookstore~
@@ -260,8 +260,8 @@ bookstore~
floor. floor.
~ ~
E E
round building~ cobblestone stone cobble~
Yes... It's a round building. Go figure. The cobblestones are still clean.
~ ~
S S
#30107 #30107
@@ -286,13 +286,13 @@ Campus Crescent and its cobblestones are to the west.
~ ~
0 -1 30106 0 -1 30106
E E
cobblestone stone cobble~
It's asphalt, you idiot! If you want to look at cobblestones, go west.
~
E
asphalt pavement~ asphalt pavement~
It's asphalt. It's asphalt.
~ ~
E
cobblestone stone cobble~
It's asphalt, you idiot! If you want to look at cobblestones, go west.
~
S S
#30108 #30108
University Avenue~ University Avenue~
@@ -316,8 +316,8 @@ The cafeteria lies to the west.
~ ~
0 -1 30128 0 -1 30128
E E
cobblestone stone cobble~ cafeteria fog~
It's a dirt road. There are NO cobblestones here, although to the north... The fog seems to be coming from the Mary Rotte Cafeteria.
~ ~
E E
dirt~ dirt~
@@ -325,8 +325,8 @@ dirt~
World Dictionary) World Dictionary)
~ ~
E E
cafeteria fog~ cobblestone stone cobble~
The fog seems to be coming from the Mary Rotte Cafeteria. It's a dirt road. There are NO cobblestones here, although to the north...
~ ~
S S
#30109 #30109
@@ -346,14 +346,14 @@ Morris House lies to the west.
~ ~
0 -1 30129 0 -1 30129
E E
dormitory dorm~
They are student living establishments.
~
E
dirt~ dirt~
It's unclean matter, such as mud, trash, earth, or soil. (Webster's New It's unclean matter, such as mud, trash, earth, or soil. (Webster's New
World Dictionary) World Dictionary)
~ ~
E
dormitory dorm~
They are student living establishments.
~
S S
#30110 #30110
University Avenue~ University Avenue~
@@ -382,8 +382,8 @@ The Engineering building, Ellis Hall, lies to the west.
~ ~
0 -1 30132 0 -1 30132
E E
cobblestone stone cobble~ building buildings~
It's a dirt road. There are NO cobblestones here, although to the south... There are two buildings here. Which one?
~ ~
E E
dirt~ dirt~
@@ -391,8 +391,8 @@ dirt~
World Dictionary) World Dictionary)
~ ~
E E
building buildings~ cobblestone stone cobble~
There are two buildings here. Which one? It's a dirt road. There are NO cobblestones here, although to the south...
~ ~
S S
#30111 #30111
@@ -422,14 +422,14 @@ The Commerce building, Dunning Hall, lies to the west.
~ ~
0 -1 30135 0 -1 30135
E E
building buildings~
There are two buildings here. Which one?
~
E
dirt~ dirt~
It's unclean matter, such as mud, trash, earth, or soil. (Webster's New It's unclean matter, such as mud, trash, earth, or soil. (Webster's New
World Dictionary) World Dictionary)
~ ~
E
building buildings~
There are two buildings here. Which one?
~
S S
#30112 #30112
University Avenue~ University Avenue~
@@ -481,23 +481,23 @@ University Avenue continues to the south.
~ ~
0 -1 30112 0 -1 30112
E E
dirt~ building~
It's unclean matter, such as mud, trash, earth, or soil. (Webster's New The student center lies to the east.
World Dictionary)
~ ~
E E
sign warning~ sign warning~
The sign says: The sign says:
Welcome to the Student Ghetto! Welcome to the Student Ghetto!
@n n
Fine $103.50 for carrying open alcohol in the streets. Fine $103.50 for carrying open alcohol in the streets.
Fine $ 53.75 for excessively loud noises. Fine $ 53.75 for excessively loud noises.
@n n
ENTER AT YOUR OWN RISK! ENTER AT YOUR OWN RISK!
~ ~
E E
building~ dirt~
The student center lies to the east. It's unclean matter, such as mud, trash, earth, or soil. (Webster's New
World Dictionary)
~ ~
S S
#30114 #30114
@@ -522,13 +522,13 @@ University Avenue lies to the west.
~ ~
0 -1 30112 0 -1 30112
E E
non-descript non descript~
(No description)
~
E
building~ building~
The student center lies to the north. The student center lies to the north.
~ ~
E
non-descript non descript~
(No description)
~
S S
#30115 #30115
Union Street~ Union Street~
@@ -557,13 +557,13 @@ Union Street continues to the west.
~ ~
0 -1 30114 0 -1 30114
E E
non-descript non descript~
(No description)
~
E
building buildings~ building buildings~
There are two buildings here. Which one? There are two buildings here. Which one?
~ ~
E
non-descript non descript~
(No description)
~
S S
#30116 #30116
Division Road~ Division Road~
@@ -588,13 +588,13 @@ Union Street is to the west.
~ ~
0 -1 30115 0 -1 30115
E E
building gym arena~
The Jock Hardy Arena lies to the north.
~
E
asphalt pavement~ asphalt pavement~
It's asphalt. It's asphalt.
~ ~
E
building gym arena~
The Jock Hardy Arena lies to the north.
~
S S
#30117 #30117
Division Road~ Division Road~
@@ -613,13 +613,13 @@ Division Road continues south.
~ ~
0 -1 30118 0 -1 30118
E E
asphalt pavement~
It's asphalt.
~
E
zork~ zork~
What would possess you to look at that? What is a zork anyways? What would possess you to look at that? What is a zork anyways?
~ ~
E
asphalt pavement~
It's asphalt.
~
S S
#30118 #30118
Division Road~ Division Road~
@@ -643,14 +643,14 @@ The Campus bookstore lies to the west.
~ ~
0 -1 30141 0 -1 30141
E E
asphalt pavement~
It's asphalt.
~
E
bookstore building~ bookstore building~
The bookstore is a 2-story cubical building, loud noises emanate from the top The bookstore is a 2-story cubical building, loud noises emanate from the top
floor. floor.
~ ~
E
asphalt pavement~
It's asphalt.
~
S S
#30119 #30119
Division Road~ Division Road~
@@ -669,13 +669,13 @@ Division Road continues south.
~ ~
0 -1 30120 0 -1 30120
E E
asphalt pavement~
It's asphalt.
~
E
zork~ zork~
What would possess you to look at that? What is a zork anyways? What would possess you to look at that? What is a zork anyways?
~ ~
E
asphalt pavement~
It's asphalt.
~
S S
#30120 #30120
Division Road~ Division Road~
@@ -694,14 +694,14 @@ Division Road continues south.
~ ~
0 -1 30121 0 -1 30121
E E
asphalt pavement~
It's asphalt.
~
E
tree~ tree~
It has been placed here just to relieve the monotony. It serves no other It has been placed here just to relieve the monotony. It serves no other
purpose whatsoever. purpose whatsoever.
~ ~
E
asphalt pavement~
It's asphalt.
~
S S
#30121 #30121
Division Road~ Division Road~
@@ -721,16 +721,16 @@ Wally World sits to the east.
~ ~
0 -1 30142 0 -1 30142
E E
asphalt pavement~
It's asphalt.
~
E
dorm dormitory~ dorm dormitory~
This is a rather tall dormitory. You'd guess that in real life, it's This is a rather tall dormitory. You'd guess that in real life, it's
probably 11-stories high, but since that would take an absurd amount of time to probably 11-stories high, but since that would take an absurd amount of time to
program, you don't think that there are that many floors in this replica of the program, you don't think that there are that many floors in this replica of the
building. building.
~ ~
E
asphalt pavement~
It's asphalt.
~
S S
#30122 #30122
The Northern Campus Entrance~ The Northern Campus Entrance~
@@ -747,6 +747,12 @@ The Student GHETTO... Beware!
~ ~
0 -1 30123 0 -1 30123
E E
gate gateway pillar~
The gateway is made of limestone and covered in ivy. As you already knew
that you feel rather silly wasting your time looking at it. There is a sign on
the left pillar.
~
E
sign plaque~ sign plaque~
The nicely polished brass plaque reads: The nicely polished brass plaque reads:
@@ -754,12 +760,6 @@ sign plaque~
ENTER AT YOUR OWN RISK ENTER AT YOUR OWN RISK
~ ~
E
gate gateway pillar~
The gateway is made of limestone and covered in ivy. As you already knew
that you feel rather silly wasting your time looking at it. There is a sign on
the left pillar.
~
S S
#30123 #30123
The Ghetto~ The Ghetto~
@@ -834,14 +834,14 @@ There is a locked door leading to a stairwell.
door~ door~
1 30105 30295 1 30105 30295
E E
mailbox mailboxes~
All of the mailboxes are all empty ... Just like normal you think.
~
E
tiles floor~ tiles floor~
The floor is covered with tiles that are so ugly, you have a difficult time The floor is covered with tiles that are so ugly, you have a difficult time
keeping your lunch down keeping your lunch down
~ ~
E
mailbox mailboxes~
All of the mailboxes are all empty ... Just like normal you think.
~
S S
#30127 #30127
Mary Rotte Cafeteria Entrance~ Mary Rotte Cafeteria Entrance~
@@ -868,14 +868,14 @@ There is a doorway leading to the kitchen.
door doorway~ door doorway~
1 -1 30143 1 -1 30143
E E
cafeteria caf~
Yes, this is the cafeteria.
~
E
door doorway~ door doorway~
You believe that the doorway leads to the kitchen. Let's give our You believe that the doorway leads to the kitchen. Let's give our
compliments to the chef... *grin* compliments to the chef... *grin*
~ ~
E
cafeteria caf~
Yes, this is the cafeteria.
~
S S
#30128 #30128
Mary Rotte Cafeteria Entrance~ Mary Rotte Cafeteria Entrance~
@@ -902,14 +902,14 @@ The dining hall lies to the west... Beware!
~ ~
0 -1 30148 0 -1 30148
E E
cafeteria caf~
Yes, this is the cafeteria.
~
E
door doorway~ door doorway~
You believe that the doorway leads to the kitchen. Let's give our You believe that the doorway leads to the kitchen. Let's give our
compliments to the chef... *grin* compliments to the chef... *grin*
~ ~
E
cafeteria caf~
Yes, this is the cafeteria.
~
S S
#30129 #30129
Morris House~ Morris House~
@@ -959,16 +959,16 @@ The hallway continues west.
~ ~
0 -1 30324 0 -1 30324
E E
round circle circular~
Yes, it's round.
~
E
footnote~ footnote~
Yes, believe it or not, this is a reasonably accurate representation of the Yes, believe it or not, this is a reasonably accurate representation of the
Physics building, Stirling Hall at our university. The lecture halls are Physics building, Stirling Hall at our university. The lecture halls are
numbered in the same manner as represented and it is in fact round, so that you numbered in the same manner as represented and it is in fact round, so that you
can walk in one direction all the way around the building. can walk in one direction all the way around the building.
~ ~
E
round circle circular~
Yes, it's round.
~
S S
#30131 #30131
The Student Health Services Entrance~ The Student Health Services Entrance~
@@ -1038,13 +1038,13 @@ University Avenue lies to the west.
~ ~
0 -1 30110 0 -1 30110
E E
halls hallways hall hallway~
They are twisting alright.
~
E
minds mind great greatest~ minds mind great greatest~
All of whom were probably smarter than you. All of whom were probably smarter than you.
~ ~
E
halls hallways hall hallway~
They are twisting alright.
~
S S
#30134 #30134
Corry-Mack Hall~ Corry-Mack Hall~
@@ -1065,13 +1065,13 @@ Campus Crescent lies to the south.
~ ~
0 -1 30105 0 -1 30105
E E
halls hallways hall hallway~
They are twisting alright.
~
E
minds mind great greatest~ minds mind great greatest~
All of whom were probably smarter than you. All of whom were probably smarter than you.
~ ~
E
halls hallways hall hallway~
They are twisting alright.
~
S S
#30135 #30135
Dunning Hall Lobby~ Dunning Hall Lobby~
@@ -1163,7 +1163,7 @@ You can distinctly see a post office here, it might have a message in it, but
you are not quite sure. you are not quite sure.
~ ~
~ ~
0 -1 30170 0 -1 -1
D1 D1
There are electronic sounds coming from the east. There are electronic sounds coming from the east.
~ ~
@@ -1208,18 +1208,18 @@ A long hallway lies to the west.
~ ~
0 -1 30153 0 -1 30153
E E
plaque plaques~
They are rather boring. A bunch of people you don't know.
~
E
sign~ sign~
The sign says: The sign says:
@n n
Gym -> North Gym -> North
Arena -> East Arena -> East
Locker Rooms -> West Locker Rooms -> West
Exit -> South Exit -> South
~ ~
E
plaque plaques~
They are rather boring. A bunch of people you don't know.
~
S S
#30140 #30140
The Grant Hall Building~ The Grant Hall Building~
@@ -1308,13 +1308,13 @@ The kitchen continues south.
~ ~
0 -1 30144 0 -1 30144
E E
door doorway~
You stare intently at the door. Its wooden frame enthrals you.
~
E
food~ food~
Believe me, you don't want to look at that! Believe me, you don't want to look at that!
~ ~
E
door doorway~
You stare intently at the door. Its wooden frame enthrals you.
~
S S
#30144 #30144
The Kitchen~ The Kitchen~
@@ -1357,13 +1357,13 @@ The dining hall continues south.
~ ~
0 -1 30147 0 -1 30147
E E
food~
Believe me, you don't want to look at that!
~
E
students poor~ students poor~
You feel sorry for them. You feel sorry for them.
~ ~
E
food~
Believe me, you don't want to look at that!
~
S S
#30146 #30146
Dining Hall~ Dining Hall~
@@ -1384,13 +1384,13 @@ The dining hall continues west.
~ ~
0 -1 30145 0 -1 30145
E E
food~
Believe me, you don't want to look at that!
~
E
students poor~ students poor~
You feel sorry for them. You feel sorry for them.
~ ~
E
food~
Believe me, you don't want to look at that!
~
S S
#30147 #30147
Dining Hall~ Dining Hall~
@@ -1411,13 +1411,13 @@ The dining hall continues east.
~ ~
0 -1 30148 0 -1 30148
E E
food~
Believe me, you don't want to look at that!
~
E
students poor~ students poor~
You feel sorry for them. You feel sorry for them.
~ ~
E
food~
Believe me, you don't want to look at that!
~
S S
#30148 #30148
Dining Hall~ Dining Hall~
@@ -1443,13 +1443,13 @@ The dining hall continues west.
~ ~
0 -1 30147 0 -1 30147
E E
food~
Believe me, you don't want to look at that!
~
E
students poor~ students poor~
You feel sorry for them. You feel sorry for them.
~ ~
E
food~
Believe me, you don't want to look at that!
~
S S
#30149 #30149
Kitchen~ Kitchen~
@@ -1470,13 +1470,13 @@ There is a storeroom beyond the door to the south.
door doorway~ door doorway~
1 -1 30150 1 -1 30150
E E
food~
Believe me, you don't want to look at that!
~
E
door doorway~ door doorway~
It's a door. It has a nice steel frame surrounding a metallic door. It's a door. It has a nice steel frame surrounding a metallic door.
~ ~
E
food~
Believe me, you don't want to look at that!
~
S S
#30150 #30150
A Storeroom~ A Storeroom~
@@ -1491,16 +1491,16 @@ These stairs lead back to the door to the kitchen.
door doorway~ door doorway~
1 -1 30149 1 -1 30149
E E
food~ door doorway~
Well, it's food. It's a door. It has a nice steel frame surrounding a metallic door.
~ ~
E E
spam pre-made packages ingredients uninteresting stuff~ spam pre-made packages ingredients uninteresting stuff~
It's rather uninteresting. It's rather uninteresting.
~ ~
E E
door doorway~ food~
It's a door. It has a nice steel frame surrounding a metallic door. Well, it's food.
~ ~
S S
#30151 #30151
@@ -1522,13 +1522,13 @@ The kitchen continues west.
~ ~
0 -1 30149 0 -1 30149
E E
door doorway~
You stare intently at the door. Its wooden frame enthrals you.
~
E
food~ food~
Believe me, you don't want to look at that! Believe me, you don't want to look at that!
~ ~
E
door doorway~
You stare intently at the door. Its wooden frame enthrals you.
~
S S
#30152 #30152
Stairway~ Stairway~
@@ -1829,13 +1829,13 @@ The only way out is down.
~ ~
0 -1 30165 0 -1 30165
E E
zorpa~
You see nothing special. Now what is a zorpa anyways?
~
E
moshing mosh~ moshing mosh~
All you can see is a mass of bodies moving up and down, up and down... All you can see is a mass of bodies moving up and down, up and down...
~ ~
E
zorpa~
You see nothing special. Now what is a zorpa anyways?
~
S S
#30167 #30167
The Infobank~ The Infobank~
@@ -1856,17 +1856,17 @@ D5
plank~ plank~
1 -1 30171 1 -1 30171
E E
map~
This map shows absolutely nothing, further proving the value of student
governments to you.
~
E
list~ list~
The list reads: The list reads:
<name scratched out> President <name scratched out> President
<name scratched out> Vice-President <name scratched out> Vice-President
Seems as though everyone is claiming ignorance today. Seems as though everyone is claiming ignorance today.
~ ~
E
map~
This map shows absolutely nothing, further proving the value of student
governments to you.
~
S S
#30168 #30168
The Games Room~ The Games Room~
@@ -1899,34 +1899,6 @@ You can see the central annex to the east.
~ ~
0 -1 30137 0 -1 30137
S S
#30170
The Post Office~
This seems to be the standard post office given to any university by the
wonderful XXX government. You can tell that it is a university post office
because of the surplus amount of obscene graffiti upon the walls. The back
hall is south of here.
~
301 8 0 0 0 0
D2
You can see the back hall from here complete with humming bank machines.
~
~
0 -1 30138
E
graffiti~
You really don't want to read this! (if you want to continue reading type
"look wirt")
~
E
wirt~
You really are a sucker for punishment now aren't you? If you still want to
read it type "look prawn"
~
E
prawn~
You see nothing special. The Prawn is in excellent condition.
~
S
#30171 #30171
The Special Hidden Room~ The Special Hidden Room~
This room is completely empty except for the things you can see in it. The This room is completely empty except for the things you can see in it. The
@@ -2002,15 +1974,15 @@ be interesting.
~ ~
0 -1 30180 0 -1 30180
E E
neat engineering devices~
You see lots of neat engineering devices which were used in the real world at
some point or another. At least you think they were.
~
E
award awards~ award awards~
These are awards for various Engineering competitions which the university These are awards for various Engineering competitions which the university
entered at one time or another. entered at one time or another.
~ ~
E
neat engineering devices~
You see lots of neat engineering devices which were used in the real world at
some point or another. At least you think they were.
~
S S
#30175 #30175
Hallway~ Hallway~
@@ -2047,9 +2019,12 @@ The hallway you probably entered from is handily located to the west.
~ ~
0 -1 30175 0 -1 30175
E E
stage~ goalie~
The stage is located at the west end of the room. In one corner of the How did you know it was a goalie stick? Have you been reading the keywords?
stage, there is a hockey stick lying on the ground. ~
E
crest~
The crest seems to be the crest belonging to the class of `97.
~ ~
E E
hockey stick~ hockey stick~
@@ -2057,12 +2032,9 @@ hockey stick~
crest prominently displayed. crest prominently displayed.
~ ~
E E
crest~ stage~
The crest seems to be the crest belonging to the class of `97. The stage is located at the west end of the room. In one corner of the
~ stage, there is a hockey stick lying on the ground.
E
goalie~
How did you know it was a goalie stick? Have you been reading the keywords?
~ ~
S S
#30177 #30177
@@ -2270,13 +2242,13 @@ This leads into the building.
door~ door~
2 30101 30178 2 30101 30178
E E
pathway~
The path is well worn, but there are no discernible footsteps upon it.
~
E
building~ building~
This is the back side of Ellis Hall, the Engineering building. This is the back side of Ellis Hall, the Engineering building.
~ ~
E
pathway~
The path is well worn, but there are no discernible footsteps upon it.
~
S S
#30188 #30188
A Pathway~ A Pathway~

View File

@@ -105,10 +105,10 @@ S
#34306 #34306
The Social Gathering Room~ The Social Gathering Room~
This is the Main Social Gathering Room of the Immortals. It is circular in This is the Main Social Gathering Room of the Immortals. It is circular in
design and it connects four foyers in all directions to the north, south, east, design, and it connects four foyers in all directions to the north, south, east,
and west. The room is quite plush with many fountains, couches, and carpeted and west. The room is quite plush with many fountains, couches, and carpeted
areas, also with a few planters filled with thick green bushes and trees. The areas, also with a few planters filled with thick green bushes and trees. The
fountain seems to be glowing best to look at it. fountain seems to be glowing.
~ ~
343 28 0 0 0 0 343 28 0 0 0 0
D0 D0
@@ -159,10 +159,10 @@ D3
S S
#34308 #34308
Eastern Foyer~ Eastern Foyer~
This is the Eastern End of the Gathering Hall. This foyer continues to the You are in the Eastern End of the Gathering Hall. Several pillars line this
east into what appears to be a hallway and west into a circular central room. room. The foyer continues east into what looks like a hallway and west into a
Several pillars line the room here, Archways north and south lead into the circular central room. Archways north and south lead into the Immortal Board
Immortal Board Room and the Mortal Board Room. Room and the Mortal Board Room.
~ ~
343 24 0 0 0 0 343 24 0 0 0 0
D0 D0

View File

@@ -52,11 +52,12 @@ static void wear_message(struct char_data *ch, struct obj_data *obj, int where);
static void perform_put(struct char_data *ch, struct obj_data *obj, struct obj_data *cont) static void perform_put(struct char_data *ch, struct obj_data *obj, struct obj_data *cont)
{ {
long object_id = obj_script_id(obj);
if (!drop_otrigger(obj, ch)) if (!drop_otrigger(obj, ch))
return; return;
if (!obj) /* object might be extracted by drop_otrigger */ if (!has_obj_by_uid_in_lookup_table(object_id)) /* object might be extracted by drop_otrigger */
return; return;
if ((GET_OBJ_VAL(cont, 0) > 0) && if ((GET_OBJ_VAL(cont, 0) > 0) &&
@@ -409,24 +410,27 @@ static void perform_drop_gold(struct char_data *ch, int amount, byte mode, room_
WAIT_STATE(ch, PULSE_VIOLENCE); /* to prevent coin-bombing */ WAIT_STATE(ch, PULSE_VIOLENCE); /* to prevent coin-bombing */
obj = create_money(amount); obj = create_money(amount);
if (mode == SCMD_DONATE) { if (mode == SCMD_DONATE) {
send_to_char(ch, "You throw some gold into the air where it disappears in a puff of smoke!\r\n"); send_to_char(ch, "You throw some gold into the air where it disappears in a puff of smoke!\r\n");
act("$n throws some gold into the air where it disappears in a puff of smoke!", act("$n throws some gold into the air where it disappears in a puff of smoke!",
FALSE, ch, 0, 0, TO_ROOM); FALSE, ch, 0, 0, TO_ROOM);
obj_to_room(obj, RDR); obj_to_room(obj, RDR);
act("$p suddenly appears in a puff of orange smoke!", 0, 0, obj, 0, TO_ROOM); act("$p suddenly appears in a puff of orange smoke!", 0, 0, obj, 0, TO_ROOM);
} else { } else {
char buf[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH];
long object_id = obj_script_id(obj);
if (!drop_wtrigger(obj, ch)) { if (!drop_wtrigger(obj, ch)) {
extract_obj(obj); if (has_obj_by_uid_in_lookup_table(object_id))
extract_obj(obj);
return; return;
} }
snprintf(buf, sizeof(buf), "$n drops %s.", money_desc(amount)); snprintf(buf, sizeof(buf), "$n drops %s.", money_desc(amount));
act(buf, TRUE, ch, 0, 0, TO_ROOM); act(buf, TRUE, ch, 0, 0, TO_ROOM);
send_to_char(ch, "You drop some gold.\r\n"); send_to_char(ch, "You drop some gold.\r\n");
obj_to_room(obj, IN_ROOM(ch)); obj_to_room(obj, IN_ROOM(ch));
} }
} else { } else {
char buf[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH];
@@ -447,13 +451,20 @@ static int perform_drop(struct char_data *ch, struct obj_data *obj,
{ {
char buf[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH];
int value; int value;
long object_id = obj_script_id(obj);
if (!drop_otrigger(obj, ch)) if (!drop_otrigger(obj, ch))
return 0; return 0;
if (!has_obj_by_uid_in_lookup_table(object_id))
return 0; // item was extracted by script
if ((mode == SCMD_DROP) && !drop_wtrigger(obj, ch)) if ((mode == SCMD_DROP) && !drop_wtrigger(obj, ch))
return 0; return 0;
if (!has_obj_by_uid_in_lookup_table(object_id))
return 0; // item was extracted by script
if (OBJ_FLAGGED(obj, ITEM_NODROP) && !PRF_FLAGGED(ch, PRF_NOHASSLE)) { if (OBJ_FLAGGED(obj, ITEM_NODROP) && !PRF_FLAGGED(ch, PRF_NOHASSLE)) {
snprintf(buf, sizeof(buf), "You can't %s $p, it must be CURSED!", sname); snprintf(buf, sizeof(buf), "You can't %s $p, it must be CURSED!", sname);
act(buf, FALSE, ch, obj, 0, TO_CHAR); act(buf, FALSE, ch, obj, 0, TO_CHAR);
@@ -768,45 +779,19 @@ void weight_change_object(struct obj_data *obj, int weight)
void name_from_drinkcon(struct obj_data *obj) void name_from_drinkcon(struct obj_data *obj)
{ {
char *new_name, *cur_name, *next;
const char *liqname; const char *liqname;
int liqlen, cpylen; char *new_name;
if (!obj || (GET_OBJ_TYPE(obj) != ITEM_DRINKCON && GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN)) if (!obj || (GET_OBJ_TYPE(obj) != ITEM_DRINKCON && GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN))
return; return;
liqname = drinknames[GET_OBJ_VAL(obj, 2)]; liqname = drinknames[GET_OBJ_VAL(obj, 2)];
if (!isname(liqname, obj->name)) {
log("SYSERR: Can't remove liquid '%s' from '%s' (%d) item.", liqname, obj->name, obj->item_number); remove_from_string(obj->name, liqname);
/* SYSERR_DESC: From name_from_drinkcon(), this error comes about if the new_name = right_trim_whitespace(obj->name);
* object noted (by keywords and item vnum) does not contain the liquid free(obj->name);
* string being searched for. */
return;
}
liqlen = strlen(liqname);
CREATE(new_name, char, strlen(obj->name) - strlen(liqname)); /* +1 for NUL, -1 for space */
for (cur_name = obj->name; cur_name; cur_name = next) {
if (*cur_name == ' ')
cur_name++;
if ((next = strchr(cur_name, ' ')))
cpylen = next - cur_name;
else
cpylen = strlen(cur_name);
if (!strn_cmp(cur_name, liqname, liqlen))
continue;
if (*new_name)
strcat(new_name, " "); /* strcat: OK (size precalculated) */
strncat(new_name, cur_name, cpylen); /* strncat: OK (size precalculated) */
}
if (GET_OBJ_RNUM(obj) == NOTHING || obj->name != obj_proto[GET_OBJ_RNUM(obj)].name)
free(obj->name);
obj->name = new_name; obj->name = new_name;
} }
void name_to_drinkcon(struct obj_data *obj, int type) void name_to_drinkcon(struct obj_data *obj, int type)

View File

@@ -922,7 +922,7 @@ static void do_stat_character(struct char_data *ch, struct char_data *k)
if (aff->bitvector[0] || aff->bitvector[1] || aff->bitvector[2] || aff->bitvector[3]) { if (aff->bitvector[0] || aff->bitvector[1] || aff->bitvector[2] || aff->bitvector[3]) {
if (aff->modifier) if (aff->modifier)
send_to_char(ch, ", "); send_to_char(ch, ", ");
for (i=0; i<NUM_AFF_FLAGS; i++) { for (i=1; i<NUM_AFF_FLAGS; i++) {
if (IS_SET_AR(aff->bitvector, i)) { if (IS_SET_AR(aff->bitvector, i)) {
send_to_char(ch, "sets %s, ", affected_bits[i]); send_to_char(ch, "sets %s, ", affected_bits[i]);
} }

View File

@@ -2495,7 +2495,7 @@ void perform_act(const char *orig, struct char_data *ch, struct obj_data *obj,
const char *i = NULL; const char *i = NULL;
char lbuf[MAX_STRING_LENGTH], *buf, *j; char lbuf[MAX_STRING_LENGTH], *buf, *j;
bool uppercasenext = FALSE; bool uppercasenext = FALSE;
struct char_data *dg_victim = NULL; struct char_data *dg_victim = (to == vict_obj) ? vict_obj : NULL;
struct obj_data *dg_target = NULL; struct obj_data *dg_target = NULL;
char *dg_arg = NULL; char *dg_arg = NULL;

View File

@@ -24,7 +24,7 @@
* @todo cpp_extern isn't needed here (or anywhere) as the extern reserved word * @todo cpp_extern isn't needed here (or anywhere) as the extern reserved word
* works correctly with C compilers (at least in my Experience) * works correctly with C compilers (at least in my Experience)
* Jeremy Osborne 1/28/2008 */ * Jeremy Osborne 1/28/2008 */
cpp_extern const char *tbamud_version = "tbaMUD 2020"; cpp_extern const char *tbamud_version = "tbaMUD 2021";
/* strings corresponding to ordinals/bitvectors in structs.h */ /* strings corresponding to ordinals/bitvectors in structs.h */
/* (Note: strings for class definitions in class.c instead of here) */ /* (Note: strings for class definitions in class.c instead of here) */

View File

@@ -501,15 +501,22 @@ static void free_extra_descriptions(struct extra_descr_data *edesc)
void destroy_db(void) void destroy_db(void)
{ {
ssize_t cnt, itr; ssize_t cnt, itr;
struct char_data *chtmp; struct char_data *chtmp, *i = character_list;
struct obj_data *objtmp; struct obj_data *objtmp;
/* Active Mobiles & Players */ /* Active Mobiles & Players */
while (i) {
chtmp = i;
i = i->next;
if (chtmp->master)
stop_follower(chtmp);
}
while (character_list) { while (character_list) {
chtmp = character_list; chtmp = character_list;
character_list = character_list->next; character_list = character_list->next;
if (chtmp->master)
stop_follower(chtmp);
free_char(chtmp); free_char(chtmp);
} }
@@ -1232,6 +1239,24 @@ static bitvector_t asciiflag_conv_aff(char *flag)
return (flags); return (flags);
} }
/* Fix for crashes in the editor when formatting. E-descs are assumed to
* end with a \r\n. -Welcor */
void ensure_newline_terminated(struct extra_descr_data* new_descr) {
char *with_term, *end;
if (new_descr->description == NULL) {
return;
}
end = strchr(new_descr->description, '\0');
if (end > new_descr->description && *(end - 1) != '\n') {
CREATE(with_term, char, strlen(new_descr->description) + 3);
sprintf(with_term, "%s\r\n", new_descr->description); /* snprintf ok : size checked above*/
free(new_descr->description);
new_descr->description = with_term;
}
}
/* load the rooms */ /* load the rooms */
void parse_room(FILE *fl, int virtual_nr) void parse_room(FILE *fl, int virtual_nr)
{ {
@@ -1301,7 +1326,7 @@ void parse_room(FILE *fl, int virtual_nr)
world[room_nr].room_flags[2] = asciiflag_conv(flags3); world[room_nr].room_flags[2] = asciiflag_conv(flags3);
world[room_nr].room_flags[3] = asciiflag_conv(flags4); world[room_nr].room_flags[3] = asciiflag_conv(flags4);
sprintf(flags, "object #%d", virtual_nr); /* sprintf: OK (until 399-bit integers) */ sprintf(flags, "room #%d", virtual_nr); /* sprintf: OK (until 399-bit integers) */
for(taeller=0; taeller < AF_ARRAY_MAX; taeller++) for(taeller=0; taeller < AF_ARRAY_MAX; taeller++)
check_bitvector_names(world[room_nr].room_flags[taeller], room_bits_count, flags, "room"); check_bitvector_names(world[room_nr].room_flags[taeller], room_bits_count, flags, "room");
@@ -1339,17 +1364,8 @@ void parse_room(FILE *fl, int virtual_nr)
CREATE(new_descr, struct extra_descr_data, 1); CREATE(new_descr, struct extra_descr_data, 1);
new_descr->keyword = fread_string(fl, buf2); new_descr->keyword = fread_string(fl, buf2);
new_descr->description = fread_string(fl, buf2); new_descr->description = fread_string(fl, buf2);
/* Fix for crashes in the editor when formatting. E-descs are assumed to ensure_newline_terminated(new_descr);
* end with a \r\n. -Welcor */
{
char *end = strchr(new_descr->description, '\0');
if (end > new_descr->description && *(end-1) != '\n') {
CREATE(end, char, strlen(new_descr->description)+3);
sprintf(end, "%s\r\n", new_descr->description); /* snprintf ok : size checked above*/
free(new_descr->description);
new_descr->description = end;
}
}
new_descr->next = world[room_nr].ex_description; new_descr->next = world[room_nr].ex_description;
world[room_nr].ex_description = new_descr; world[room_nr].ex_description = new_descr;
break; break;
@@ -2857,12 +2873,16 @@ char *fread_string(FILE *fl, const char *error)
/* If there is a '~', end the string; else put an "\r\n" over the '\n'. */ /* If there is a '~', end the string; else put an "\r\n" over the '\n'. */
/* now only removes trailing ~'s -- Welcor */ /* now only removes trailing ~'s -- Welcor */
point = strchr(tmp, '\0'); point = strchr(tmp, '\0');
for (point-- ; (*point=='\r' || *point=='\n'); point--); for (point-- ; (*point=='\r' || *point=='\n') && point > tmp; point--);
if (*point=='~') { if (*point=='~') {
*point='\0'; *point='\0';
done = 1; done = 1;
} else { } else {
*(++point) = '\r'; if (*point == '\n' || *point == '\r')
*point = '\r';
else
*(++point) = '\r';
*(++point) = '\n'; *(++point) = '\n';
*(++point) = '\0'; *(++point) = '\0';
} }

View File

@@ -151,7 +151,8 @@ long event_time(struct event *event)
/** Frees all events from event_q. */ /** Frees all events from event_q. */
void event_free_all(void) void event_free_all(void)
{ {
queue_free(event_q); if (event_q != NULL)
queue_free(event_q);
} }
/** Boolean function to tell whether an event is queued or not. Does this by /** Boolean function to tell whether an event is queued or not. Does this by

View File

@@ -2994,12 +2994,23 @@ void init_lookup_table(void)
} }
} }
static struct char_data *find_char_by_uid_in_lookup_table(long uid) static inline struct lookup_table_t *get_bucket_head(long uid)
{ {
int bucket = (int) (uid & (BUCKET_COUNT - 1)); int bucket = (int) (uid & (BUCKET_COUNT - 1));
struct lookup_table_t *lt = &lookup_table[bucket]; return &lookup_table[bucket];
}
static inline struct lookup_table_t *find_element_by_uid_in_lookup_table(long uid)
{
struct lookup_table_t *lt = get_bucket_head(uid);
for (;lt && lt->uid != uid ; lt = lt->next) ; for (;lt && lt->uid != uid ; lt = lt->next) ;
return lt;
}
static struct char_data *find_char_by_uid_in_lookup_table(long uid)
{
struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
if (lt) if (lt)
return (struct char_data *)(lt->c); return (struct char_data *)(lt->c);
@@ -3010,10 +3021,7 @@ static struct char_data *find_char_by_uid_in_lookup_table(long uid)
static struct obj_data *find_obj_by_uid_in_lookup_table(long uid) static struct obj_data *find_obj_by_uid_in_lookup_table(long uid)
{ {
int bucket = (int) (uid & (BUCKET_COUNT - 1)); struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
struct lookup_table_t *lt = &lookup_table[bucket];
for (;lt && lt->uid != uid ; lt = lt->next) ;
if (lt) if (lt)
return (struct obj_data *)(lt->c); return (struct obj_data *)(lt->c);
@@ -3022,10 +3030,16 @@ static struct obj_data *find_obj_by_uid_in_lookup_table(long uid)
return NULL; return NULL;
} }
int has_obj_by_uid_in_lookup_table(long uid)
{
struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
return lt != NULL;
}
void add_to_lookup_table(long uid, void *c) void add_to_lookup_table(long uid, void *c)
{ {
int bucket = (int) (uid & (BUCKET_COUNT - 1)); struct lookup_table_t *lt = get_bucket_head(uid);
struct lookup_table_t *lt = &lookup_table[bucket];
if (lt && lt->uid == uid) { if (lt && lt->uid == uid) {
log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->c, c); log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->c, c);
@@ -3036,6 +3050,7 @@ void add_to_lookup_table(long uid, void *c)
for (;lt && lt->next; lt = lt->next) for (;lt && lt->next; lt = lt->next)
if (lt->next->uid == uid) { if (lt->next->uid == uid) {
log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->next->c, c); log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->next->c, c);
lt->next->c = c;
return; return;
} }
@@ -3054,9 +3069,7 @@ void remove_from_lookup_table(long uid)
if (uid == 0) if (uid == 0)
return; return;
for (;lt;lt = lt->next) flt = find_element_by_uid_in_lookup_table(uid);
if (lt->uid == uid)
flt = lt;
if (flt) { if (flt) {
for (lt = &lookup_table[bucket];lt->next != flt;lt = lt->next) for (lt = &lookup_table[bucket];lt->next != flt;lt = lt->next)

View File

@@ -449,6 +449,8 @@ void wld_command_interpreter(room_data *room, char *argument);
// id helpers // id helpers
extern long char_script_id(char_data *ch); extern long char_script_id(char_data *ch);
extern long obj_script_id(obj_data *obj); extern long obj_script_id(obj_data *obj);
extern int has_obj_by_uid_in_lookup_table(long uid);
#define room_script_id(room) ((long)(room)->number + ROOM_ID_BASE) #define room_script_id(room) ((long)(room)->number + ROOM_ID_BASE)
#endif /* _DG_SCRIPTS_H_ */ #endif /* _DG_SCRIPTS_H_ */

View File

@@ -462,6 +462,7 @@ int receive_mtrigger(char_data *ch, char_data *actor, obj_data *obj)
trig_data *t; trig_data *t;
char buf[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH];
int ret_val; int ret_val;
long object_id = obj_script_id(obj);
if (!SCRIPT_CHECK(ch, MTRIG_RECEIVE) || AFF_FLAGGED(ch, AFF_CHARM)) if (!SCRIPT_CHECK(ch, MTRIG_RECEIVE) || AFF_FLAGGED(ch, AFF_CHARM))
return 1; return 1;
@@ -471,9 +472,10 @@ int receive_mtrigger(char_data *ch, char_data *actor, obj_data *obj)
(rand_number(1, 100) <= GET_TRIG_NARG(t))){ (rand_number(1, 100) <= GET_TRIG_NARG(t))){
ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0); ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0);
ADD_UID_VAR(buf, t, obj_script_id(obj), "object", 0); ADD_UID_VAR(buf, t, object_id, "object", 0);
ret_val = script_driver(&ch, t, MOB_TRIGGER, TRIG_NEW); ret_val = script_driver(&ch, t, MOB_TRIGGER, TRIG_NEW);
if (DEAD(actor) || DEAD(ch) || obj->carried_by != actor) // check for purged item before dereferencing.
if (DEAD(actor) || DEAD(ch) || !has_obj_by_uid_in_lookup_table(object_id) || obj->carried_by != actor)
return 0; return 0;
else else
return ret_val; return ret_val;
@@ -1118,6 +1120,7 @@ int drop_wtrigger(obj_data *obj, char_data *actor)
trig_data *t; trig_data *t;
char buf[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH];
int ret_val; int ret_val;
long object_id = obj_script_id(obj);
if (!actor || !SCRIPT_CHECK(&world[IN_ROOM(actor)], WTRIG_DROP)) if (!actor || !SCRIPT_CHECK(&world[IN_ROOM(actor)], WTRIG_DROP))
return 1; return 1;
@@ -1127,9 +1130,10 @@ int drop_wtrigger(obj_data *obj, char_data *actor)
if (TRIGGER_CHECK(t, WTRIG_DROP) && if (TRIGGER_CHECK(t, WTRIG_DROP) &&
(rand_number(1, 100) <= GET_TRIG_NARG(t))) { (rand_number(1, 100) <= GET_TRIG_NARG(t))) {
ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0); ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0);
ADD_UID_VAR(buf, t, obj_script_id(obj), "object", 0); ADD_UID_VAR(buf, t, object_id, "object", 0);
ret_val = script_driver(&room, t, WLD_TRIGGER, TRIG_NEW); ret_val = script_driver(&room, t, WLD_TRIGGER, TRIG_NEW);
if (obj->carried_by != actor) // check for purged object before dereferencing.
if (!has_obj_by_uid_in_lookup_table(object_id) || obj->carried_by != actor)
return 0; return 0;
else else
return ret_val; return ret_val;

View File

@@ -522,7 +522,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
* and waiting for it to fade, for example. */ * and waiting for it to fade, for example. */
if (IS_NPC(victim) && !affected_by_spell(victim, spellnum)) { if (IS_NPC(victim) && !affected_by_spell(victim, spellnum)) {
for (i = 0; i < MAX_SPELL_AFFECTS; i++) { for (i = 0; i < MAX_SPELL_AFFECTS; i++) {
for (j=0; j<NUM_AFF_FLAGS; j++) { for (j=1; j<NUM_AFF_FLAGS; j++) {
if (IS_SET_AR(af[i].bitvector, j) && AFF_FLAGGED(victim, j)) { if (IS_SET_AR(af[i].bitvector, j) && AFF_FLAGGED(victim, j)) {
send_to_char(ch, "%s", CONFIG_NOEFFECT); send_to_char(ch, "%s", CONFIG_NOEFFECT);
return; return;

View File

@@ -396,8 +396,8 @@ static void medit_disp_aff_flags(struct descriptor_data *d)
get_char_colors(d->character); get_char_colors(d->character);
clear_screen(d); clear_screen(d);
/* +1 since AFF_FLAGS don't start at 0. */ /* +1/-1 antics needed because AFF_FLAGS doesn't start at 0. */
column_list(d->character, 0, affected_bits + 1, NUM_AFF_FLAGS, TRUE); column_list(d->character, 0, affected_bits + 1, NUM_AFF_FLAGS - 1, TRUE);
sprintbitarray(AFF_FLAGS(OLC_MOB(d)), affected_bits, AF_ARRAY_MAX, flags); sprintbitarray(AFF_FLAGS(OLC_MOB(d)), affected_bits, AF_ARRAY_MAX, flags);
write_to_output(d, "\r\nCurrent flags : %s%s%s\r\nEnter aff flags (0 to quit) : ", write_to_output(d, "\r\nCurrent flags : %s%s%s\r\nEnter aff flags (0 to quit) : ",
cyn, flags, nrm); cyn, flags, nrm);
@@ -577,8 +577,8 @@ void medit_parse(struct descriptor_data *d, char *arg)
case 'q': case 'q':
case 'Q': case 'Q':
if (OLC_VAL(d)) { /* Anything been changed? */ if (OLC_VAL(d)) { /* Anything been changed? */
write_to_output(d, "Do you wish to save your changes? : "); write_to_output(d, "Do you wish to save your changes? : ");
OLC_MODE(d) = MEDIT_CONFIRM_SAVESTRING; OLC_MODE(d) = MEDIT_CONFIRM_SAVESTRING;
} else } else
cleanup_olc(d, CLEANUP_ALL); cleanup_olc(d, CLEANUP_ALL);
return; return;
@@ -603,8 +603,8 @@ void medit_parse(struct descriptor_data *d, char *arg)
send_editor_help(d); send_editor_help(d);
write_to_output(d, "Enter mob description:\r\n\r\n"); write_to_output(d, "Enter mob description:\r\n\r\n");
if (OLC_MOB(d)->player.description) { if (OLC_MOB(d)->player.description) {
write_to_output(d, "%s", OLC_MOB(d)->player.description); write_to_output(d, "%s", OLC_MOB(d)->player.description);
oldtext = strdup(OLC_MOB(d)->player.description); oldtext = strdup(OLC_MOB(d)->player.description);
} }
string_write(d, &OLC_MOB(d)->player.description, MAX_MOB_DESC, 0, oldtext); string_write(d, &OLC_MOB(d)->player.description, MAX_MOB_DESC, 0, oldtext);
OLC_VAL(d) = 1; OLC_VAL(d) = 1;
@@ -898,7 +898,7 @@ void medit_parse(struct descriptor_data *d, char *arg)
case MEDIT_AFF_FLAGS: case MEDIT_AFF_FLAGS:
if ((i = atoi(arg)) <= 0) if ((i = atoi(arg)) <= 0)
break; break;
else if (i <= NUM_AFF_FLAGS) else if (i < NUM_AFF_FLAGS)
TOGGLE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), i); TOGGLE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), i);
/* Remove unwanted bits right away. */ /* Remove unwanted bits right away. */

View File

@@ -936,7 +936,7 @@ void oedit_parse(struct descriptor_data *d, char *arg)
case OEDIT_PERM: case OEDIT_PERM:
if ((number = atoi(arg)) == 0) if ((number = atoi(arg)) == 0)
break; break;
if (number > 0 && number <= NUM_AFF_FLAGS) { if (number > 0 && number < NUM_AFF_FLAGS) {
/* Setting AFF_CHARM on objects like this is dangerous. */ /* Setting AFF_CHARM on objects like this is dangerous. */
if (number != AFF_CHARM) { if (number != AFF_CHARM) {
TOGGLE_BIT_AR(GET_OBJ_AFFECT(OLC_OBJ(d)), number); TOGGLE_BIT_AR(GET_OBJ_AFFECT(OLC_OBJ(d)), number);

View File

@@ -847,7 +847,7 @@ static void load_affects(FILE *fl, struct char_data *ch)
af.bitvector[2] = num7; af.bitvector[2] = num7;
af.bitvector[3] = num8; af.bitvector[3] = num8;
} else if (n_vars == 5) { /* Old 32-bit conversion version */ } else if (n_vars == 5) { /* Old 32-bit conversion version */
if (num5 > 0 && num5 <= NUM_AFF_FLAGS) /* Ignore invalid values */ if (num5 > 0 && num5 < NUM_AFF_FLAGS) /* Ignore invalid values */
SET_BIT_AR(af.bitvector, num5); SET_BIT_AR(af.bitvector, num5);
} else { } else {
log("SYSERR: Invalid affects in pfile (%s), expecting 5 or 8 values", GET_NAME(ch)); log("SYSERR: Invalid affects in pfile (%s), expecting 5 or 8 values", GET_NAME(ch));

View File

@@ -60,7 +60,7 @@ void sort_spells(void)
static const char *how_good(int percent) static const char *how_good(int percent)
{ {
if (percent < 0) if (percent < 0)
return " error)"; return " (error)";
if (percent == 0) if (percent == 0)
return " (not learned)"; return " (not learned)";
if (percent <= 10) if (percent <= 10)

View File

@@ -1,12 +1,12 @@
/************************************************************************** /**************************************************************************
* File: spell_parser.c Part of tbaMUD * * File: spell_parser.c Part of tbaMUD *
* Usage: Top-level magic routines; outside points of entry to magic sys. * * Usage: Top-level magic routines; outside points of entry to magic sys. *
* * * *
* All rights reserved. See license for complete information. * * All rights reserved. See license for complete information. *
* * * *
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
**************************************************************************/ **************************************************************************/
#include "conf.h" #include "conf.h"
#include "sysdep.h" #include "sysdep.h"
@@ -28,8 +28,11 @@ char cast_arg2[MAX_INPUT_LENGTH];
const char *unused_spellname = "!UNUSED!"; /* So we can get &unused_spellname */ const char *unused_spellname = "!UNUSED!"; /* So we can get &unused_spellname */
/* Local (File Scope) Function Prototypes */ /* Local (File Scope) Function Prototypes */
static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch, struct obj_data *tobj); static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch,
static void spello(int spl, const char *name, int max_mana, int min_mana, int mana_change, int minpos, int targets, int violent, int routines, const char *wearoff); struct obj_data *tobj);
static void spello(int spl, const char *name, int max_mana, int min_mana,
int mana_change, int minpos, int targets, int violent, int routines,
const char *wearoff);
static int mag_manacost(struct char_data *ch, int spellnum); static int mag_manacost(struct char_data *ch, int spellnum);
/* Local (File Scope) Variables */ /* Local (File Scope) Variables */
@@ -37,112 +40,100 @@ struct syllable {
const char *org; const char *org;
const char *news; const char *news;
}; };
static struct syllable syls[] = { static struct syllable syls[] = { { " ", " " }, { "ar", "abra" },
{" ", " "}, { "ate", "i" }, { "cau", "kada" }, { "blind", "nose" }, { "bur", "mosa" }, {
{"ar", "abra"}, "cu", "judi" }, { "de", "oculo" }, { "dis", "mar" },
{"ate", "i"}, { "ect", "kamina" }, { "en", "uns" }, { "gro", "cra" }, { "light", "dies" },
{"cau", "kada"}, { "lo", "hi" }, { "magi", "kari" }, { "mon", "bar" }, { "mor", "zak" }, {
{"blind", "nose"}, "move", "sido" }, { "ness", "lacri" }, { "ning", "illa" }, { "per",
{"bur", "mosa"}, "duda" }, { "ra", "gru" }, { "re", "candus" }, { "son", "sabru" }, {
{"cu", "judi"}, "tect", "infra" }, { "tri", "cula" }, { "ven", "nofo" }, { "word of",
{"de", "oculo"}, "inset" }, { "a", "i" }, { "b", "v" }, { "c", "q" }, { "d", "m" }, {
{"dis", "mar"}, "e", "o" }, { "f", "y" }, { "g", "t" }, { "h", "p" }, { "i", "u" }, {
{"ect", "kamina"}, "j", "y" }, { "k", "t" }, { "l", "r" }, { "m", "w" }, { "n", "b" }, {
{"en", "uns"}, "o", "a" }, { "p", "s" }, { "q", "d" }, { "r", "f" }, { "s", "g" }, {
{"gro", "cra"}, "t", "h" }, { "u", "e" }, { "v", "z" }, { "w", "x" }, { "x", "n" }, {
{"light", "dies"}, "y", "l" }, { "z", "k" }, { "", "" } };
{"lo", "hi"},
{"magi", "kari"},
{"mon", "bar"},
{"mor", "zak"},
{"move", "sido"},
{"ness", "lacri"},
{"ning", "illa"},
{"per", "duda"},
{"ra", "gru"},
{"re", "candus"},
{"son", "sabru"},
{"tect", "infra"},
{"tri", "cula"},
{"ven", "nofo"},
{"word of", "inset"},
{"a", "i"}, {"b", "v"}, {"c", "q"}, {"d", "m"}, {"e", "o"}, {"f", "y"}, {"g", "t"},
{"h", "p"}, {"i", "u"}, {"j", "y"}, {"k", "t"}, {"l", "r"}, {"m", "w"}, {"n", "b"},
{"o", "a"}, {"p", "s"}, {"q", "d"}, {"r", "f"}, {"s", "g"}, {"t", "h"}, {"u", "e"},
{"v", "z"}, {"w", "x"}, {"x", "n"}, {"y", "l"}, {"z", "k"}, {"", ""}
};
static int mag_manacost(struct char_data *ch, int spellnum) {
static int mag_manacost(struct char_data *ch, int spellnum)
{
return MAX(SINFO.mana_max - (SINFO.mana_change * return MAX(SINFO.mana_max - (SINFO.mana_change *
(GET_LEVEL(ch) - SINFO.min_level[(int) GET_CLASS(ch)])), (GET_LEVEL(ch) - SINFO.min_level[(int) GET_CLASS(ch)])),
SINFO.mana_min); SINFO.mana_min);
} }
static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch, static char *obfuscate_spell(const char *unobfuscated) {
struct obj_data *tobj) static char obfuscated[200];
{ int maxlen = 200;
char lbuf[256], buf[256], buf1[256], buf2[256]; /* FIXME */
const char *format;
struct char_data *i;
int j, ofs = 0; int j, ofs = 0;
*buf = '\0'; *obfuscated = '\0';
strlcpy(lbuf, skill_name(spellnum), sizeof(lbuf));
while (lbuf[ofs]) { while (unobfuscated[ofs]) {
for (j = 0; *(syls[j].org); j++) { for (j = 0; *(syls[j].org); j++) {
if (!strncmp(syls[j].org, lbuf + ofs, strlen(syls[j].org))) { if (!strncmp(syls[j].org, unobfuscated + ofs, strlen(syls[j].org))) {
strcat(buf, syls[j].news); /* strcat: BAD */ if (strlen(syls[j].news) < maxlen) {
ofs += strlen(syls[j].org); strncat(obfuscated, syls[j].news, maxlen);
maxlen -= strlen(syls[j].news);
} else {
log("No room in obfuscated version of '%s' (currently obfuscated to '%s') to add syllable '%s'.",
unobfuscated, obfuscated, syls[j].news);
}
ofs += strlen(syls[j].org);
break; break;
} }
} }
/* i.e., we didn't find a match in syls[] */ /* i.e., we didn't find a match in syls[] */
if (!*syls[j].org) { if (!*syls[j].org) {
log("No entry in syllable table for substring of '%s'", lbuf); log("No entry in syllable table for substring of '%s' starting at '%s'.", unobfuscated, unobfuscated + ofs);
ofs++; ofs++;
} }
} }
return obfuscated;
}
static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch,
struct obj_data *tobj) {
const char *format, *spell = skill_name(spellnum);
char act_buf_original[256], act_buf_obfuscated[256], *obfuscated = obfuscate_spell(spell);
struct char_data *i;
if (tch != NULL && IN_ROOM(tch) == IN_ROOM(ch)) { if (tch != NULL && IN_ROOM(tch) == IN_ROOM(ch)) {
if (tch == ch) if (tch == ch)
format = "$n closes $s eyes and utters the words, '%s'."; format = "$n closes $s eyes and utters the words, '%s'.";
else else
format = "$n stares at $N and utters the words, '%s'."; format = "$n stares at $N and utters the words, '%s'.";
} else if (tobj != NULL && } else if (tobj != NULL
((IN_ROOM(tobj) == IN_ROOM(ch)) || (tobj->carried_by == ch))) && ((IN_ROOM(tobj) == IN_ROOM(ch)) || (tobj->carried_by == ch)))
format = "$n stares at $p and utters the words, '%s'."; format = "$n stares at $p and utters the words, '%s'.";
else else
format = "$n utters the words, '%s'."; format = "$n utters the words, '%s'.";
snprintf(buf1, sizeof(buf1), format, skill_name(spellnum)); snprintf(act_buf_original, sizeof(act_buf_original), format, spell);
snprintf(buf2, sizeof(buf2), format, buf); snprintf(act_buf_obfuscated, sizeof(act_buf_obfuscated), format, obfuscated);
for (i = world[IN_ROOM(ch)].people; i; i = i->next_in_room) { for (i = world[IN_ROOM(ch)].people; i; i = i->next_in_room) {
if (i == ch || i == tch || !i->desc || !AWAKE(i)) if (i == ch || i == tch || !i->desc || !AWAKE(i))
continue; continue;
if (GET_CLASS(ch) == GET_CLASS(i)) if (GET_CLASS(ch) == GET_CLASS(i))
perform_act(buf1, ch, tobj, tch, i); perform_act(act_buf_original, ch, tobj, tch, i);
else else
perform_act(buf2, ch, tobj, tch, i); perform_act(act_buf_obfuscated, ch, tobj, tch, i);
} }
if (tch != NULL && tch != ch && IN_ROOM(tch) == IN_ROOM(ch)) { if (tch != NULL && tch != ch && IN_ROOM(tch) == IN_ROOM(ch)) {
snprintf(buf1, sizeof(buf1), "$n stares at you and utters the words, '%s'.", snprintf(act_buf_original, sizeof(act_buf_original), "$n stares at you and utters the words, '%s'.",
GET_CLASS(ch) == GET_CLASS(tch) ? skill_name(spellnum) : buf); GET_CLASS(ch) == GET_CLASS(tch) ? spell : obfuscated);
act(buf1, FALSE, ch, NULL, tch, TO_VICT); act(act_buf_original, FALSE, ch, NULL, tch, TO_VICT);
} }
} }
/* This function should be used anytime you are not 100% sure that you have /* This function should be used anytime you are not 100% sure that you have
* a valid spell/skill number. A typical for() loop would not need to use * a valid spell/skill number. A typical for() loop would not need to use
* this because you can guarantee > 0 and <= TOP_SPELL_DEFINE. */ * this because you can guarantee > 0 and <= TOP_SPELL_DEFINE. */
const char *skill_name(int num) const char *skill_name(int num) {
{
if (num > 0 && num <= TOP_SPELL_DEFINE) if (num > 0 && num <= TOP_SPELL_DEFINE)
return (spell_info[num].name); return (spell_info[num].name);
else if (num == -1) else if (num == -1)
@@ -151,8 +142,7 @@ const char *skill_name(int num)
return ("UNDEFINED"); return ("UNDEFINED");
} }
int find_skill_num(char *name) int find_skill_num(char *name) {
{
int skindex, ok; int skindex, ok;
char *temp, *temp2; char *temp, *temp2;
char first[256], first2[256], tempbuf[256]; char first[256], first2[256], tempbuf[256];
@@ -162,12 +152,12 @@ int find_skill_num(char *name)
return (skindex); return (skindex);
ok = TRUE; ok = TRUE;
strlcpy(tempbuf, spell_info[skindex].name, sizeof(tempbuf)); /* strlcpy: OK */ strlcpy(tempbuf, spell_info[skindex].name, sizeof(tempbuf)); /* strlcpy: OK */
temp = any_one_arg(tempbuf, first); temp = any_one_arg(tempbuf, first);
temp2 = any_one_arg(name, first2); temp2 = any_one_arg(name, first2);
while (*first && *first2 && ok) { while (*first && *first2 && ok) {
if (!is_abbrev(first2, first)) if (!is_abbrev(first2, first))
ok = FALSE; ok = FALSE;
temp = any_one_arg(temp, first); temp = any_one_arg(temp, first);
temp2 = any_one_arg(temp2, first2); temp2 = any_one_arg(temp2, first2);
} }
@@ -185,8 +175,7 @@ int find_skill_num(char *name)
* point for non-spoken or unrestricted spells. Spellnum 0 is legal but silently * point for non-spoken or unrestricted spells. Spellnum 0 is legal but silently
* ignored here, to make callers simpler. */ * ignored here, to make callers simpler. */
int call_magic(struct char_data *caster, struct char_data *cvict, int call_magic(struct char_data *caster, struct char_data *cvict,
struct obj_data *ovict, int spellnum, int level, int casttype) struct obj_data *ovict, int spellnum, int level, int casttype) {
{
int savetype; int savetype;
if (spellnum < 1 || spellnum > TOP_SPELL_DEFINE) if (spellnum < 1 || spellnum > TOP_SPELL_DEFINE)
@@ -204,8 +193,7 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
act("$n's magic fizzles out and dies.", FALSE, caster, 0, 0, TO_ROOM); act("$n's magic fizzles out and dies.", FALSE, caster, 0, 0, TO_ROOM);
return (0); return (0);
} }
if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_PEACEFUL) && if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_PEACEFUL) && (SINFO.violent || IS_SET(SINFO.routines, MAG_DAMAGE))) {
(SINFO.violent || IS_SET(SINFO.routines, MAG_DAMAGE))) {
send_to_char(caster, "A flash of white light fills the room, dispelling your violent magic!\r\n"); send_to_char(caster, "A flash of white light fills the room, dispelling your violent magic!\r\n");
act("White light from no particular source suddenly fills the room, then vanishes.", FALSE, caster, 0, 0, TO_ROOM); act("White light from no particular source suddenly fills the room, then vanishes.", FALSE, caster, 0, 0, TO_ROOM);
return (0); return (0);
@@ -232,7 +220,7 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
if (IS_SET(SINFO.routines, MAG_DAMAGE)) if (IS_SET(SINFO.routines, MAG_DAMAGE))
if (mag_damage(level, caster, cvict, spellnum, savetype) == -1) if (mag_damage(level, caster, cvict, spellnum, savetype) == -1)
return (-1); /* Successful and target died, don't cast again. */ return (-1); /* Successful and target died, don't cast again. */
if (IS_SET(SINFO.routines, MAG_AFFECTS)) if (IS_SET(SINFO.routines, MAG_AFFECTS))
mag_affects(level, caster, cvict, spellnum, savetype); mag_affects(level, caster, cvict, spellnum, savetype);
@@ -266,15 +254,42 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
if (IS_SET(SINFO.routines, MAG_MANUAL)) if (IS_SET(SINFO.routines, MAG_MANUAL))
switch (spellnum) { switch (spellnum) {
case SPELL_CHARM: MANUAL_SPELL(spell_charm); break; case SPELL_CHARM:
case SPELL_CREATE_WATER: MANUAL_SPELL(spell_create_water); break; MANUAL_SPELL(spell_charm)
case SPELL_DETECT_POISON: MANUAL_SPELL(spell_detect_poison); break; ;
case SPELL_ENCHANT_WEAPON: MANUAL_SPELL(spell_enchant_weapon); break; break;
case SPELL_IDENTIFY: MANUAL_SPELL(spell_identify); break; case SPELL_CREATE_WATER:
case SPELL_LOCATE_OBJECT: MANUAL_SPELL(spell_locate_object); break; MANUAL_SPELL(spell_create_water)
case SPELL_SUMMON: MANUAL_SPELL(spell_summon); break; ;
case SPELL_WORD_OF_RECALL: MANUAL_SPELL(spell_recall); break; break;
case SPELL_TELEPORT: MANUAL_SPELL(spell_teleport); 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;
} }
return (1); return (1);
@@ -289,9 +304,7 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
* potion - [0] level [1] spell num [2] spell num [3] spell num * potion - [0] level [1] spell num [2] spell num [3] spell num
* Staves and wands will default to level 14 if the level is not specified; the * Staves and wands will default to level 14 if the level is not specified; the
* DikuMUD format did not specify staff and wand levels in the world files */ * DikuMUD format did not specify staff and wand levels in the world files */
void mag_objectmagic(struct char_data *ch, struct obj_data *obj, void mag_objectmagic(struct char_data *ch, struct obj_data *obj, char *argument) {
char *argument)
{
char arg[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH];
int i, k; int i, k;
struct char_data *tch = NULL, *next_tch; struct char_data *tch = NULL, *next_tch;
@@ -300,7 +313,7 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
one_argument(argument, arg); one_argument(argument, arg);
k = generic_find(arg, FIND_CHAR_ROOM | FIND_OBJ_INV | FIND_OBJ_ROOM | k = generic_find(arg, FIND_CHAR_ROOM | FIND_OBJ_INV | FIND_OBJ_ROOM |
FIND_OBJ_EQUIP, ch, &tch, &tobj); FIND_OBJ_EQUIP, ch, &tch, &tobj);
switch (GET_OBJ_TYPE(obj)) { switch (GET_OBJ_TYPE(obj)) {
case ITEM_STAFF: case ITEM_STAFF:
@@ -322,38 +335,40 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
/* Area/mass spells on staves can cause crashes. So we use special cases /* Area/mass spells on staves can cause crashes. So we use special cases
* for those spells spells here. */ * for those spells spells here. */
if (HAS_SPELL_ROUTINE(GET_OBJ_VAL(obj, 3), MAG_MASSES | MAG_AREAS)) { if (HAS_SPELL_ROUTINE(GET_OBJ_VAL(obj, 3), MAG_MASSES | MAG_AREAS)) {
for (i = 0, tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room) for (i = 0, tch = world[IN_ROOM(ch)].people; tch;
i++; tch = tch->next_in_room)
while (i-- > 0) i++;
call_magic(ch, NULL, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF); while (i-- > 0)
call_magic(ch, NULL, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF);
} else { } else {
for (tch = world[IN_ROOM(ch)].people; tch; tch = next_tch) { for (tch = world[IN_ROOM(ch)].people; tch; tch = next_tch) {
next_tch = tch->next_in_room; next_tch = tch->next_in_room;
if (ch != tch) if (ch != tch)
call_magic(ch, tch, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF); call_magic(ch, tch, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF);
} }
} }
} }
break; break;
case ITEM_WAND: case ITEM_WAND:
if (k == FIND_CHAR_ROOM) { if (k == FIND_CHAR_ROOM) {
if (tch == ch) { if (tch == ch) {
act("You point $p at yourself.", FALSE, ch, obj, 0, TO_CHAR); act("You point $p at yourself.", FALSE, ch, obj, 0, TO_CHAR);
act("$n points $p at $mself.", FALSE, ch, obj, 0, TO_ROOM); act("$n points $p at $mself.", FALSE, ch, obj, 0, TO_ROOM);
} else { } else {
act("You point $p at $N.", FALSE, ch, obj, tch, TO_CHAR); act("You point $p at $N.", FALSE, ch, obj, tch, TO_CHAR);
if (obj->action_description) if (obj->action_description)
act(obj->action_description, FALSE, ch, obj, tch, TO_ROOM); act(obj->action_description, FALSE, ch, obj, tch, TO_ROOM);
else else
act("$n points $p at $N.", TRUE, ch, obj, tch, TO_ROOM); act("$n points $p at $N.", TRUE, ch, obj, tch, TO_ROOM);
} }
} else if (tobj != NULL) { } else if (tobj != NULL) {
act("You point $p at $P.", FALSE, ch, obj, tobj, TO_CHAR); act("You point $p at $P.", FALSE, ch, obj, tobj, TO_CHAR);
if (obj->action_description) if (obj->action_description)
act(obj->action_description, FALSE, ch, obj, tobj, TO_ROOM); act(obj->action_description, FALSE, ch, obj, tobj, TO_ROOM);
else else
act("$n points $p at $P.", TRUE, ch, obj, tobj, TO_ROOM); act("$n points $p at $P.", TRUE, ch, obj, tobj, TO_ROOM);
} else if (IS_SET(spell_info[GET_OBJ_VAL(obj, 3)].routines, MAG_AREAS | MAG_MASSES)) { } else if (IS_SET(spell_info[GET_OBJ_VAL(obj, 3)].routines,
MAG_AREAS | MAG_MASSES)) {
/* Wands with area spells don't need to be pointed. */ /* Wands with area spells don't need to be pointed. */
act("You point $p outward.", FALSE, ch, obj, NULL, TO_CHAR); act("You point $p outward.", FALSE, ch, obj, NULL, TO_CHAR);
act("$n points $p outward.", TRUE, ch, obj, NULL, TO_ROOM); act("$n points $p outward.", TRUE, ch, obj, NULL, TO_ROOM);
@@ -370,18 +385,18 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
GET_OBJ_VAL(obj, 2)--; GET_OBJ_VAL(obj, 2)--;
WAIT_STATE(ch, PULSE_VIOLENCE); WAIT_STATE(ch, PULSE_VIOLENCE);
if (GET_OBJ_VAL(obj, 0)) if (GET_OBJ_VAL(obj, 0))
call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3), call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3), GET_OBJ_VAL(obj, 0),
GET_OBJ_VAL(obj, 0), CAST_WAND); CAST_WAND);
else else
call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3), call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3),
DEFAULT_WAND_LVL, CAST_WAND); DEFAULT_WAND_LVL, CAST_WAND);
break; break;
case ITEM_SCROLL: case ITEM_SCROLL:
if (*arg) { if (*arg) {
if (!k) { if (!k) {
act("There is nothing to here to affect with $p.", FALSE, act("There is nothing to here to affect with $p.", FALSE, ch, obj, NULL,
ch, obj, NULL, TO_CHAR); TO_CHAR);
return; return;
} }
} else } else
tch = ch; tch = ch;
@@ -394,9 +409,9 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
WAIT_STATE(ch, PULSE_VIOLENCE); WAIT_STATE(ch, PULSE_VIOLENCE);
for (i = 1; i <= 3; i++) for (i = 1; i <= 3; i++)
if (call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, i), if (call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, i), GET_OBJ_VAL(obj, 0),
GET_OBJ_VAL(obj, 0), CAST_SCROLL) <= 0) CAST_SCROLL) <= 0)
break; break;
if (obj != NULL) if (obj != NULL)
extract_obj(obj); extract_obj(obj);
@@ -404,7 +419,7 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
case ITEM_POTION: case ITEM_POTION:
tch = ch; tch = ch;
if (!consume_otrigger(obj, ch, OCMD_QUAFF)) /* check trigger */ if (!consume_otrigger(obj, ch, OCMD_QUAFF)) /* check trigger */
return; return;
act("You quaff $p.", FALSE, ch, obj, NULL, TO_CHAR); act("You quaff $p.", FALSE, ch, obj, NULL, TO_CHAR);
@@ -415,16 +430,16 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
WAIT_STATE(ch, PULSE_VIOLENCE); WAIT_STATE(ch, PULSE_VIOLENCE);
for (i = 1; i <= 3; i++) for (i = 1; i <= 3; i++)
if (call_magic(ch, ch, NULL, GET_OBJ_VAL(obj, i), if (call_magic(ch, ch, NULL, GET_OBJ_VAL(obj, i), GET_OBJ_VAL(obj, 0),
GET_OBJ_VAL(obj, 0), CAST_POTION) <= 0) CAST_POTION) <= 0)
break; break;
if (obj != NULL) if (obj != NULL)
extract_obj(obj); extract_obj(obj);
break; break;
default: default:
log("SYSERR: Unknown object_type %d in mag_objectmagic.", log("SYSERR: Unknown object_type %d in mag_objectmagic.",
GET_OBJ_TYPE(obj)); GET_OBJ_TYPE(obj));
break; break;
} }
} }
@@ -434,31 +449,30 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
* prints the words, etc. Entry point for NPC casts. Recommended entry point * prints the words, etc. Entry point for NPC casts. Recommended entry point
* for spells cast by NPCs via specprocs. */ * for spells cast by NPCs via specprocs. */
int cast_spell(struct char_data *ch, struct char_data *tch, int cast_spell(struct char_data *ch, struct char_data *tch,
struct obj_data *tobj, int spellnum) struct obj_data *tobj, int spellnum) {
{
if (spellnum < 0 || spellnum > TOP_SPELL_DEFINE) { if (spellnum < 0 || spellnum > TOP_SPELL_DEFINE) {
log("SYSERR: cast_spell trying to call spellnum %d/%d.", spellnum, log("SYSERR: cast_spell trying to call spellnum %d/%d.", spellnum,
TOP_SPELL_DEFINE); TOP_SPELL_DEFINE);
return (0); return (0);
} }
if (GET_POS(ch) < SINFO.min_position) { if (GET_POS(ch) < SINFO.min_position) {
switch (GET_POS(ch)) { switch (GET_POS(ch)) {
case POS_SLEEPING: case POS_SLEEPING:
send_to_char(ch, "You dream about great magical powers.\r\n"); send_to_char(ch, "You dream about great magical powers.\r\n");
break; break;
case POS_RESTING: case POS_RESTING:
send_to_char(ch, "You cannot concentrate while resting.\r\n"); send_to_char(ch, "You cannot concentrate while resting.\r\n");
break; break;
case POS_SITTING: case POS_SITTING:
send_to_char(ch, "You can't do this sitting!\r\n"); send_to_char(ch, "You can't do this sitting!\r\n");
break; break;
case POS_FIGHTING: case POS_FIGHTING:
send_to_char(ch, "Impossible! You can't concentrate enough!\r\n"); send_to_char(ch, "Impossible! You can't concentrate enough!\r\n");
break; break;
default: default:
send_to_char(ch, "You can't do much of anything like this!\r\n"); send_to_char(ch, "You can't do much of anything like this!\r\n");
break; break;
} }
return (0); return (0);
} }
@@ -488,8 +502,7 @@ int cast_spell(struct char_data *ch, struct char_data *tch,
* determines the spell number and finds a target, throws the die to see if * determines the spell number and finds a target, throws the die to see if
* the spell can be cast, checks for sufficient mana and subtracts it, and * the spell can be cast, checks for sufficient mana and subtracts it, and
* passes control to cast_spell(). */ * passes control to cast_spell(). */
ACMD(do_cast) ACMD(do_cast) {
{
struct char_data *tch = NULL; struct char_data *tch = NULL;
struct obj_data *tobj = NULL; struct obj_data *tobj = NULL;
char *s, *t; char *s, *t;
@@ -507,7 +520,8 @@ ACMD(do_cast)
} }
s = strtok(NULL, "'"); s = strtok(NULL, "'");
if (s == NULL) { if (s == NULL) {
send_to_char(ch, "Spell names must be enclosed in the Holy Magic Symbols: '\r\n"); send_to_char(ch,
"Spell names must be enclosed in the Holy Magic Symbols: '\r\n");
return; return;
} }
t = strtok(NULL, "\0"); t = strtok(NULL, "\0");
@@ -546,51 +560,52 @@ ACMD(do_cast)
number = get_number(&t); number = get_number(&t);
if (!target && (IS_SET(SINFO.targets, TAR_CHAR_ROOM))) { if (!target && (IS_SET(SINFO.targets, TAR_CHAR_ROOM))) {
if ((tch = get_char_vis(ch, t, &number, FIND_CHAR_ROOM)) != NULL) if ((tch = get_char_vis(ch, t, &number, FIND_CHAR_ROOM)) != NULL)
target = TRUE; target = TRUE;
} }
if (!target && IS_SET(SINFO.targets, TAR_CHAR_WORLD)) if (!target && IS_SET(SINFO.targets, TAR_CHAR_WORLD))
if ((tch = get_char_vis(ch, t, &number, FIND_CHAR_WORLD)) != NULL) if ((tch = get_char_vis(ch, t, &number, FIND_CHAR_WORLD)) != NULL)
target = TRUE; target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_INV)) if (!target && IS_SET(SINFO.targets, TAR_OBJ_INV))
if ((tobj = get_obj_in_list_vis(ch, t, &number, ch->carrying)) != NULL) if ((tobj = get_obj_in_list_vis(ch, t, &number, ch->carrying)) != NULL)
target = TRUE; target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_EQUIP)) { if (!target && IS_SET(SINFO.targets, TAR_OBJ_EQUIP)) {
for (i = 0; !target && i < NUM_WEARS; i++) for (i = 0; !target && i < NUM_WEARS; i++)
if (GET_EQ(ch, i) && isname(t, GET_EQ(ch, i)->name)) { if (GET_EQ(ch, i) && isname(t, GET_EQ(ch, i)->name)) {
tobj = GET_EQ(ch, i); tobj = GET_EQ(ch, i);
target = TRUE; target = TRUE;
} }
} }
if (!target && IS_SET(SINFO.targets, TAR_OBJ_ROOM)) if (!target && IS_SET(SINFO.targets, TAR_OBJ_ROOM))
if ((tobj = get_obj_in_list_vis(ch, t, &number, world[IN_ROOM(ch)].contents)) != NULL) if ((tobj = get_obj_in_list_vis(ch, t, &number,
target = TRUE; world[IN_ROOM(ch)].contents)) != NULL)
target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_WORLD)) if (!target && IS_SET(SINFO.targets, TAR_OBJ_WORLD))
if ((tobj = get_obj_vis(ch, t, &number)) != NULL) if ((tobj = get_obj_vis(ch, t, &number)) != NULL)
target = TRUE; target = TRUE;
} else { /* if target string is empty */ } else { /* if target string is empty */
if (!target && IS_SET(SINFO.targets, TAR_FIGHT_SELF)) if (!target && IS_SET(SINFO.targets, TAR_FIGHT_SELF))
if (FIGHTING(ch) != NULL) { if (FIGHTING(ch) != NULL) {
tch = ch; tch = ch;
target = TRUE; target = TRUE;
} }
if (!target && IS_SET(SINFO.targets, TAR_FIGHT_VICT)) if (!target && IS_SET(SINFO.targets, TAR_FIGHT_VICT))
if (FIGHTING(ch) != NULL) { if (FIGHTING(ch) != NULL) {
tch = FIGHTING(ch); tch = FIGHTING(ch);
target = TRUE; target = TRUE;
} }
/* if no target specified, and the spell isn't violent, default to self */ /* if no target specified, and the spell isn't violent, default to self */
if (!target && IS_SET(SINFO.targets, TAR_CHAR_ROOM) && if (!target && IS_SET(SINFO.targets, TAR_CHAR_ROOM) && !SINFO.violent) {
!SINFO.violent) {
tch = ch; tch = ch;
target = TRUE; target = TRUE;
} }
if (!target) { if (!target) {
send_to_char(ch, "Upon %s should the spell be cast?\r\n", send_to_char(ch, "Upon %s should the spell be cast?\r\n",
IS_SET(SINFO.targets, TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_WORLD | TAR_OBJ_EQUIP) ? "what" : "who"); IS_SET(SINFO.targets, TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_WORLD | TAR_OBJ_EQUIP) ?
"what" : "who");
return; return;
} }
} }
@@ -617,34 +632,34 @@ ACMD(do_cast)
if (mana > 0) if (mana > 0)
GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - (mana / 2))); GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - (mana / 2)));
if (SINFO.violent && tch && IS_NPC(tch)) if (SINFO.violent && tch && IS_NPC(tch))
hit(tch, ch, TYPE_UNDEFINED); hit(tch, ch, TYPE_UNDEFINED);
} else { /* cast spell returns 1 on success; subtract mana & set waitstate */ } else { /* cast spell returns 1 on success; subtract mana & set waitstate */
if (cast_spell(ch, tch, tobj, spellnum)) { if (cast_spell(ch, tch, tobj, spellnum)) {
WAIT_STATE(ch, PULSE_VIOLENCE); WAIT_STATE(ch, PULSE_VIOLENCE);
if (mana > 0) if (mana > 0)
GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - mana)); GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - mana));
} }
} }
} }
void spell_level(int spell, int chclass, int level) void spell_level(int spell, int chclass, int level) {
{
int bad = 0; int bad = 0;
if (spell < 0 || spell > TOP_SPELL_DEFINE) { if (spell < 0 || spell > TOP_SPELL_DEFINE) {
log("SYSERR: attempting assign to illegal spellnum %d/%d", spell, TOP_SPELL_DEFINE); log("SYSERR: attempting assign to illegal spellnum %d/%d", spell,
TOP_SPELL_DEFINE);
return; return;
} }
if (chclass < 0 || chclass >= NUM_CLASSES) { if (chclass < 0 || chclass >= NUM_CLASSES) {
log("SYSERR: assigning '%s' to illegal class %d/%d.", skill_name(spell), log("SYSERR: assigning '%s' to illegal class %d/%d.", skill_name(spell),
chclass, NUM_CLASSES - 1); chclass, NUM_CLASSES - 1);
bad = 1; bad = 1;
} }
if (level < 1 || level > LVL_IMPL) { if (level < 1 || level > LVL_IMPL) {
log("SYSERR: assigning '%s' to illegal level %d/%d.", skill_name(spell), log("SYSERR: assigning '%s' to illegal level %d/%d.", skill_name(spell),
level, LVL_IMPL); level, LVL_IMPL);
bad = 1; bad = 1;
} }
@@ -652,11 +667,10 @@ void spell_level(int spell, int chclass, int level)
spell_info[spell].min_level[chclass] = level; spell_info[spell].min_level[chclass] = level;
} }
/* Assign the spells on boot up */ /* Assign the spells on boot up */
static void spello(int spl, const char *name, int max_mana, int min_mana, static void spello(int spl, const char *name, int max_mana, int min_mana,
int mana_change, int minpos, int targets, int violent, int routines, const char *wearoff) int mana_change, int minpos, int targets, int violent, int routines,
{ const char *wearoff) {
int i; int i;
for (i = 0; i < NUM_CLASSES; i++) for (i = 0; i < NUM_CLASSES; i++)
@@ -672,8 +686,7 @@ static void spello(int spl, const char *name, int max_mana, int min_mana,
spell_info[spl].wear_off_msg = wearoff; spell_info[spl].wear_off_msg = wearoff;
} }
void unused_spell(int spl) void unused_spell(int spl) {
{
int i; int i;
for (i = 0; i < NUM_CLASSES; i++) for (i = 0; i < NUM_CLASSES; i++)
@@ -713,8 +726,7 @@ void unused_spell(int spl)
* See the documentation for a more detailed description of these fields. You * See the documentation for a more detailed description of these fields. You
* only need a spello() call to define a new spell; to decide who gets to use * only need a spello() call to define a new spell; to decide who gets to use
* a spell or skill, look in class.c. -JE */ * a spell or skill, look in class.c. -JE */
void mag_assign_spells(void) void mag_assign_spells(void) {
{
int i; int i;
/* Do not change the loop below. */ /* Do not change the loop below. */
@@ -723,225 +735,183 @@ void mag_assign_spells(void)
/* Do not change the loop above. */ /* Do not change the loop above. */
spello(SPELL_ANIMATE_DEAD, "animate dead", 35, 10, 3, POS_STANDING, spello(SPELL_ANIMATE_DEAD, "animate dead", 35, 10, 3, POS_STANDING,
TAR_OBJ_ROOM, FALSE, MAG_SUMMONS, TAR_OBJ_ROOM, FALSE, MAG_SUMMONS, NULL);
NULL);
spello(SPELL_ARMOR, "armor", 30, 15, 3, POS_FIGHTING, spello(SPELL_ARMOR, "armor", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You feel less protected.");
"You feel less protected.");
spello(SPELL_BLESS, "bless", 35, 5, 3, POS_STANDING, spello(SPELL_BLESS, "bless", 35, 5, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel less righteous."); "You feel less righteous.");
spello(SPELL_BLINDNESS, "blindness", 35, 25, 1, POS_STANDING, spello(SPELL_BLINDNESS, "blindness", 35, 25, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_NOT_SELF, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_NOT_SELF, FALSE, MAG_AFFECTS,
"You feel a cloak of blindness dissolve."); "You feel a cloak of blindness dissolve.");
spello(SPELL_BURNING_HANDS, "burning hands", 30, 10, 3, POS_FIGHTING, spello(SPELL_BURNING_HANDS, "burning hands", 30, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_CALL_LIGHTNING, "call lightning", 40, 25, 3, POS_FIGHTING, spello(SPELL_CALL_LIGHTNING, "call lightning", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_CHARM, "charm person", 75, 50, 2, POS_FIGHTING, spello(SPELL_CHARM, "charm person", 75, 50, 2, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL, TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL,
"You feel more self-confident."); "You feel more self-confident.");
spello(SPELL_CHILL_TOUCH, "chill touch", 30, 10, 3, POS_FIGHTING, spello(SPELL_CHILL_TOUCH, "chill touch", 30, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_AFFECTS, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_AFFECTS,
"You feel your strength return."); "You feel your strength return.");
spello(SPELL_CLONE, "clone", 80, 65, 5, POS_STANDING, spello(SPELL_CLONE, "clone", 80, 65, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_SUMMONS, TAR_IGNORE, FALSE, MAG_SUMMONS, NULL);
NULL);
spello(SPELL_COLOR_SPRAY, "color spray", 30, 15, 3, POS_FIGHTING, spello(SPELL_COLOR_SPRAY, "color spray", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_CONTROL_WEATHER, "control weather", 75, 25, 5, POS_STANDING, spello(SPELL_CONTROL_WEATHER, "control weather", 75, 25, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_MANUAL, TAR_IGNORE, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_CREATE_FOOD, "create food", 30, 5, 4, POS_STANDING, spello(SPELL_CREATE_FOOD, "create food", 30, 5, 4, POS_STANDING,
TAR_IGNORE, FALSE, MAG_CREATIONS, TAR_IGNORE, FALSE, MAG_CREATIONS, NULL);
NULL);
spello(SPELL_CREATE_WATER, "create water", 30, 5, 4, POS_STANDING, spello(SPELL_CREATE_WATER, "create water", 30, 5, 4, POS_STANDING,
TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL, TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_CURE_BLIND, "cure blind", 30, 5, 2, POS_STANDING, spello(SPELL_CURE_BLIND, "cure blind", 30, 5, 2, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_UNAFFECTS, TAR_CHAR_ROOM, FALSE, MAG_UNAFFECTS, NULL);
NULL);
spello(SPELL_CURE_CRITIC, "cure critic", 30, 10, 2, POS_FIGHTING, spello(SPELL_CURE_CRITIC, "cure critic", 30, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS, TAR_CHAR_ROOM, FALSE, MAG_POINTS, NULL);
NULL);
spello(SPELL_CURE_LIGHT, "cure light", 30, 10, 2, POS_FIGHTING, spello(SPELL_CURE_LIGHT, "cure light", 30, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS, TAR_CHAR_ROOM, FALSE, MAG_POINTS, NULL);
NULL);
spello(SPELL_CURSE, "curse", 80, 50, 2, POS_STANDING, spello(SPELL_CURSE, "curse", 80, 50, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel more optimistic."); "You feel more optimistic.");
spello(SPELL_DARKNESS, "darkness", 30, 5, 4, POS_STANDING, spello(SPELL_DARKNESS, "darkness", 30, 5, 4, POS_STANDING,
TAR_IGNORE, FALSE, MAG_ROOMS, TAR_IGNORE, FALSE, MAG_ROOMS, NULL);
NULL);
spello(SPELL_DETECT_ALIGN, "detect alignment", 20, 10, 2, POS_STANDING, spello(SPELL_DETECT_ALIGN, "detect alignment", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, "You feel less aware.");
"You feel less aware.");
spello(SPELL_DETECT_INVIS, "detect invisibility", 20, 10, 2, POS_STANDING, spello(SPELL_DETECT_INVIS, "detect invisibility", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"Your eyes stop tingling."); "Your eyes stop tingling.");
spello(SPELL_DETECT_MAGIC, "detect magic", 20, 10, 2, POS_STANDING, spello(SPELL_DETECT_MAGIC, "detect magic", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"The detect magic wears off."); "The detect magic wears off.");
spello(SPELL_DETECT_POISON, "detect poison", 15, 5, 1, POS_STANDING, spello(SPELL_DETECT_POISON, "detect poison", 15, 5, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL,
"The detect poison wears off."); "The detect poison wears off.");
spello(SPELL_DISPEL_EVIL, "dispel evil", 40, 25, 3, POS_FIGHTING, spello(SPELL_DISPEL_EVIL, "dispel evil", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_DISPEL_GOOD, "dispel good", 40, 25, 3, POS_FIGHTING, spello(SPELL_DISPEL_GOOD, "dispel good", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_EARTHQUAKE, "earthquake", 40, 25, 3, POS_FIGHTING, spello(SPELL_EARTHQUAKE, "earthquake", 40, 25, 3, POS_FIGHTING,
TAR_IGNORE, TRUE, MAG_AREAS, TAR_IGNORE, TRUE, MAG_AREAS, NULL);
NULL);
spello(SPELL_ENCHANT_WEAPON, "enchant weapon", 150, 100, 10, POS_STANDING, spello(SPELL_ENCHANT_WEAPON, "enchant weapon", 150, 100, 10, POS_STANDING,
TAR_OBJ_INV, FALSE, MAG_MANUAL, TAR_OBJ_INV, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_ENERGY_DRAIN, "energy drain", 40, 25, 1, POS_FIGHTING, spello(SPELL_ENERGY_DRAIN, "energy drain", 40, 25, 1, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_MANUAL, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_MANUAL, NULL);
NULL);
spello(SPELL_GROUP_ARMOR, "group armor", 50, 30, 2, POS_STANDING, spello(SPELL_GROUP_ARMOR, "group armor", 50, 30, 2, POS_STANDING,
TAR_IGNORE, FALSE, MAG_GROUPS, TAR_IGNORE, FALSE, MAG_GROUPS, NULL);
NULL);
spello(SPELL_FIREBALL, "fireball", 40, 30, 2, POS_FIGHTING, spello(SPELL_FIREBALL, "fireball", 40, 30, 2, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_FLY, "fly", 40, 20, 2, POS_FIGHTING, spello(SPELL_FLY, "fly", 40, 20, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You drift slowly to the ground.");
"You drift slowly to the ground.");
spello(SPELL_GROUP_HEAL, "group heal", 80, 60, 5, POS_STANDING, spello(SPELL_GROUP_HEAL, "group heal", 80, 60, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_GROUPS, TAR_IGNORE, FALSE, MAG_GROUPS, NULL);
NULL);
spello(SPELL_HARM, "harm", 75, 45, 3, POS_FIGHTING, spello(SPELL_HARM, "harm", 75, 45, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_HEAL, "heal", 60, 40, 3, POS_FIGHTING, spello(SPELL_HEAL, "heal", 60, 40, 3, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_UNAFFECTS, TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_UNAFFECTS, NULL);
NULL);
spello(SPELL_INFRAVISION, "infravision", 25, 10, 1, POS_STANDING, spello(SPELL_INFRAVISION, "infravision", 25, 10, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"Your night vision seems to fade."); "Your night vision seems to fade.");
spello(SPELL_INVISIBLE, "invisibility", 35, 25, 1, POS_STANDING, spello(SPELL_INVISIBLE, "invisibility", 35, 25, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE,
"You feel yourself exposed."); MAG_AFFECTS | MAG_ALTER_OBJS, "You feel yourself exposed.");
spello(SPELL_LIGHTNING_BOLT, "lightning bolt", 30, 15, 1, POS_FIGHTING, spello(SPELL_LIGHTNING_BOLT, "lightning bolt", 30, 15, 1, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_LOCATE_OBJECT, "locate object", 25, 20, 1, POS_STANDING, spello(SPELL_LOCATE_OBJECT, "locate object", 25, 20, 1, POS_STANDING,
TAR_OBJ_WORLD, FALSE, MAG_MANUAL, TAR_OBJ_WORLD, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_MAGIC_MISSILE, "magic missile", 25, 10, 3, POS_FIGHTING, spello(SPELL_MAGIC_MISSILE, "magic missile", 25, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_POISON, "poison", 50, 20, 3, POS_STANDING, spello(SPELL_POISON, "poison", 50, 20, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV, TRUE, TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV, TRUE,
MAG_AFFECTS | MAG_ALTER_OBJS, MAG_AFFECTS | MAG_ALTER_OBJS, "You feel less sick.");
"You feel less sick.");
spello(SPELL_PROT_FROM_EVIL, "protection from evil", 40, 10, 3, POS_STANDING, spello(SPELL_PROT_FROM_EVIL, "protection from evil", 40, 10, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less protected."); "You feel less protected.");
spello(SPELL_REMOVE_CURSE, "remove curse", 45, 25, 5, POS_STANDING, spello(SPELL_REMOVE_CURSE, "remove curse", 45, 25, 5, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE,
MAG_UNAFFECTS | MAG_ALTER_OBJS, MAG_UNAFFECTS | MAG_ALTER_OBJS, NULL);
NULL);
spello(SPELL_REMOVE_POISON, "remove poison", 40, 8, 4, POS_STANDING, spello(SPELL_REMOVE_POISON, "remove poison", 40, 8, 4, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_UNAFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE,
NULL); MAG_UNAFFECTS | MAG_ALTER_OBJS, NULL);
spello(SPELL_SANCTUARY, "sanctuary", 110, 85, 5, POS_STANDING, spello(SPELL_SANCTUARY, "sanctuary", 110, 85, 5, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "The white aura around your body fades.");
"The white aura around your body fades.");
spello(SPELL_SENSE_LIFE, "sense life", 20, 10, 2, POS_STANDING, spello(SPELL_SENSE_LIFE, "sense life", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less aware of your surroundings."); "You feel less aware of your surroundings.");
spello(SPELL_SHOCKING_GRASP, "shocking grasp", 30, 15, 3, POS_FIGHTING, spello(SPELL_SHOCKING_GRASP, "shocking grasp", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_SLEEP, "sleep", 40, 25, 5, POS_STANDING, spello(SPELL_SLEEP, "sleep", 40, 25, 5, POS_STANDING,
TAR_CHAR_ROOM, TRUE, MAG_AFFECTS, TAR_CHAR_ROOM, TRUE, MAG_AFFECTS, "You feel less tired.");
"You feel less tired.");
spello(SPELL_STRENGTH, "strength", 35, 30, 1, POS_STANDING, spello(SPELL_STRENGTH, "strength", 35, 30, 1, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You feel weaker.");
"You feel weaker.");
spello(SPELL_SUMMON, "summon", 75, 50, 3, POS_STANDING, spello(SPELL_SUMMON, "summon", 75, 50, 3, POS_STANDING,
TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL, TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_TELEPORT, "teleport", 75, 50, 3, POS_STANDING, spello(SPELL_TELEPORT, "teleport", 75, 50, 3, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_WATERWALK, "waterwalk", 40, 20, 2, POS_STANDING, spello(SPELL_WATERWALK, "waterwalk", 40, 20, 2, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "Your feet seem less buoyant.");
"Your feet seem less buoyant.");
spello(SPELL_WORD_OF_RECALL, "word of recall", 20, 10, 2, POS_FIGHTING, spello(SPELL_WORD_OF_RECALL, "word of recall", 20, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_IDENTIFY, "identify", 50, 25, 5, POS_STANDING, spello(SPELL_IDENTIFY, "identify", 50, 25, 5, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
/* NON-castable spells should appear below here. */ /* NON-castable spells should appear below here. */
spello(SPELL_IDENTIFY, "identify", 0, 0, 0, 0, spello(SPELL_IDENTIFY, "identify", 0, 0, 0, 0,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
/* you might want to name this one something more fitting to your theme -Welcor*/ /* you might want to name this one something more fitting to your theme -Welcor*/
spello(SPELL_DG_AFFECT, "Script-inflicted", 0, 0, 0, POS_SITTING, spello(SPELL_DG_AFFECT, "Script-inflicted", 0, 0, 0, POS_SITTING,
TAR_IGNORE, TRUE, 0, TAR_IGNORE, TRUE, 0, NULL);
NULL);
/* Declaration of skills - this actually doesn't do anything except set it up /* Declaration of skills - this actually doesn't do anything except set it up
* so that immortals can use these skills by default. The min level to use * so that immortals can use these skills by default. The min level to use

View File

@@ -268,7 +268,7 @@
/* Affect bits: used in char_data.char_specials.saved.affected_by */ /* Affect bits: used in char_data.char_specials.saved.affected_by */
/* WARNING: In the world files, NEVER set the bits marked "R" ("Reserved") */ /* WARNING: In the world files, NEVER set the bits marked "R" ("Reserved") */
#define AFF_DONTUSE 0 /**< DON'T USE! */ #define AFF_DONTUSE 0 /**< DON'T USE! This allows 0 to mean "no bits set" in the database */
#define AFF_BLIND 1 /**< (R) Char is blind */ #define AFF_BLIND 1 /**< (R) Char is blind */
#define AFF_INVISIBLE 2 /**< Char is invisible */ #define AFF_INVISIBLE 2 /**< Char is invisible */
#define AFF_DETECT_ALIGN 3 /**< Char is sensitive to align */ #define AFF_DETECT_ALIGN 3 /**< Char is sensitive to align */
@@ -291,8 +291,8 @@
#define AFF_HIDE 20 /**< Char is hidden */ #define AFF_HIDE 20 /**< Char is hidden */
#define AFF_FREE 21 /**< Room for future expansion */ #define AFF_FREE 21 /**< Room for future expansion */
#define AFF_CHARM 22 /**< Char is charmed */ #define AFF_CHARM 22 /**< Char is charmed */
/** Total number of affect flags not including the don't use flag. */ /** Total number of affect flags */
#define NUM_AFF_FLAGS 22 #define NUM_AFF_FLAGS 23
/* Modes of connectedness: used by descriptor_data.state */ /* Modes of connectedness: used by descriptor_data.state */
#define CON_PLAYING 0 /**< Playing - Nominal state */ #define CON_PLAYING 0 /**< Playing - Nominal state */

View File

@@ -977,11 +977,6 @@ void column_list(struct char_data *ch, int num_cols, const char **list, int list
/* Ensure that the number of columns is in the range 1-10 */ /* Ensure that the number of columns is in the range 1-10 */
num_cols = MIN(MAX(num_cols,1), 10); num_cols = MIN(MAX(num_cols,1), 10);
/* Work out the longest list item */
for (i=0; i<list_length; i++)
if (max_len < strlen(list[i]))
max_len = strlen(list[i]);
/* Calculate the width of each column */ /* Calculate the width of each column */
if (IS_NPC(ch)) col_width = 80 / num_cols; if (IS_NPC(ch)) col_width = 80 / num_cols;
else col_width = (GET_SCREEN_WIDTH(ch)) / num_cols; else col_width = (GET_SCREEN_WIDTH(ch)) / num_cols;
@@ -1494,3 +1489,68 @@ char * convert_from_tabs(char * string)
parse_tab(buf); parse_tab(buf);
return(buf); return(buf);
} }
/* This removes all trailing whitespace from the end of a string */
char *right_trim_whitespace(const char *string)
{
char *r = strdup(string);
if (r != NULL)
{
char *fr = r + strlen(string) - 1;
while( (isspace(*fr) || !isprint(*fr) || *fr == 0) && fr >= r) --fr;
*++fr = 0;
}
return r;
}
/**
* Remove all occurrences of a given word in string.
*/
void remove_from_string(char *string, const char *to_remove)
{
int i, j, string_len, to_remove_len;
int found;
string_len = strlen(string); // Length of string
to_remove_len = strlen(to_remove); // Length of word to remove
for(i=0; i <= string_len - to_remove_len; i++)
{
/* Match word with string */
found = 1;
for(j=0; j<to_remove_len; j++)
{
if(string[i + j] != to_remove[j])
{
found = 0;
break;
}
}
/* If it is not a word */
if(string[i + j] != ' ' && string[i + j] != '\t' && string[i + j] != '\n' && string[i + j] != '\0')
{
found = 0;
}
/*
* If word is found then shift all characters to left
* and decrement the string length
*/
if(found == 1)
{
for(j=i; j<=string_len - to_remove_len; j++)
{
string[j] = string[j + to_remove_len];
}
string_len = string_len - to_remove_len;
// We will match next occurrence of word from current index.
i--;
}
}
}

View File

@@ -70,6 +70,8 @@ void new_affect(struct affected_type *af);
int get_class_by_name(char *classname); int get_class_by_name(char *classname);
char * convert_from_tabs(char * string); char * convert_from_tabs(char * string);
int count_non_protocol_chars(char * str); int count_non_protocol_chars(char * str);
char *right_trim_whitespace(const char *string);
void remove_from_string(char *string, const char *to_remove);
/* Public functions made available form weather.c */ /* Public functions made available form weather.c */
void weather_and_time(int mode); void weather_and_time(int mode);