Merge remote-tracking branch 'origin/master' into confusing-code-fix

This commit is contained in:
Thomas Arp 2025-07-02 22:01:32 +02:00
commit ad6d51200d
66 changed files with 2082 additions and 1275 deletions

19
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: C/C++ CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: configure
run: ./configure
- name: build
run: cd src && touch .accepted && make

85
.gitignore vendored
View file

@ -10,3 +10,88 @@ src/util/Makefile
src/.accepted
src/depend
src/util/depend
build/*
!build/create_solution.bat
!build/README.md
# Do not commit files from players
lib/plrfiles/A-E/*
lib/plrfiles/F-J/*
lib/plrfiles/K-O/*
lib/plrfiles/P-T/*
lib/plrfiles/U-Z/*
lib/plrfiles/ZZZ/*
lib/plrfiles/index
# but do commit the placeholders
!lib/plrfiles/A-E/00
!lib/plrfiles/F-J/00
!lib/plrfiles/K-O/00
!lib/plrfiles/P-T/00
!lib/plrfiles/U-Z/00
!lib/plrfiles/ZZZ/00
# or vars
lib/plrvars/A-E/*
lib/plrvars/F-J/*
lib/plrvars/K-O/*
lib/plrvars/P-T/*
lib/plrvars/U-Z/*
lib/plrvars/ZZZ/*
lib/plrvars/index
# except the placeholders
!lib/plrvars/A-E/00
!lib/plrvars/F-J/00
!lib/plrvars/K-O/00
!lib/plrvars/P-T/00
!lib/plrvars/U-Z/00
!lib/plrvars/ZZZ/00
# or objects
lib/plrobjs/A-E/*
lib/plrobjs/F-J/*
lib/plrobjs/K-O/*
lib/plrobjs/P-T/*
lib/plrobjs/U-Z/*
lib/plrobjs/ZZZ/*
lib/plrobjs/index
# except the placeholders
!lib/plrobjs/A-E/00
!lib/plrobjs/F-J/00
!lib/plrobjs/K-O/00
!lib/plrobjs/P-T/00
!lib/plrobjs/U-Z/00
!lib/plrobjs/ZZZ/00
# also not autogenerated config file
/lib/etc/config
# or the list of last logins
/lib/etc/last
# or mail
lib/etc/plrmail
#or time
lib/etc/time
# test object files, etc
src/test/depend
src/test/*.o
src/test/testfile
# ide etc.
.vscode
.project
.settings
.idea
.cproject
# macOS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

15
build/README.md Normal file
View file

@ -0,0 +1,15 @@
### Overview
This guide describes how to build TbaMUD in the Visual Studio through the new experimental CMake environment.
### Prerequisites
* [Visual Studio 2022+](https://visualstudio.microsoft.com/ru/vs/)
* [CMake 3.27+](https://cmake.org/)
### Build Steps
1. Goto the folder `src` and copy `conf.h.win` to `conf.h`.
2. Goto the folder `build` and execute `create_solution.bat`.
3. Open `build/circle.sln` in Visual Studio.
4. Compile and run.

View file

@ -0,0 +1 @@
cmake -B . -S ..\src -G "Visual Studio 17 2022"

71
configure vendored
View file

@ -1227,18 +1227,28 @@ if eval "test \"`echo '$ac_cv_func_'crypt`\" = yes"; then
cat >> confdefs.h <<\EOF
#define CIRCLE_CRYPT 1
EOF
CRYPTLIB="-lcrypt"
echo "CRYPTLIB set to: $CRYPTLIB" 1>&6
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
echo "configure:1235: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
echo "configure:1235: checking for crypt in -lcrypt" >&5
OS_NAME=$(uname)
if [ "$OS_NAME" = "Darwin" ]; then
# macOS: No need for -lcrypt
CRYPTLIB=""
echo "CRYPTLIB not needed on macOS" 1>&6
else
# Other systems (Linux): Use -lcrypt
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1243 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
@ -1250,30 +1260,29 @@ int main() {
crypt()
; return 0; }
EOF
if { (eval echo configure:1254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
if { (eval echo configure:1254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
#define CIRCLE_CRYPT 1
EOF
CRYPTLIB="-lcrypt"
else
echo "$ac_t""no" 1>&6
fi
CRYPTLIB="-lcrypt"
echo "CRYPTLIB set to: $CRYPTLIB on Linux" 1>&6
else
echo "$ac_t""no" 1>&6
fi
fi
fi

View file

@ -257,6 +257,9 @@ http://tbamud.com
All donated areas have been added to the latest version of tbaMUD. If you
wish to donate some of your own work stop by the Builder Academy.
https://github.com/rds1983 has generated maps of all the existing areas,
and they can be found here: https://mudmapbuilder.github.io/
2.3. I have questions about tbaMUD. Where should I go?
Stop by The Builder Academy at tbamud.com 9091 or the website at:

View file

@ -1,7 +1,7 @@
Updated: Apr 2007
tbaMUD README
-------------
All requests for help or bugs should be reported to: builderacademy.net 9091.
All requests for help or bugs should be reported to: tbamud.com 9091.
Information about CircleMUD can be found at the CircleMUD Home Page and FTP:
http://www.circlemud.org

View file

@ -24,7 +24,7 @@ Contents
1.1 Overview
The act() function is used to process and send strings of text to characters
in a room. It can be used to send the same basic string to a number of
characters filling in certain segments designated by control characters
characters filling in certain segments designated by control characters
in different ways, dependant on what each character can see and who each
character is. Once the text string passed to the function has been parsed, it
is capitalized and a newline is added to its tail.
@ -38,17 +38,17 @@ struct obj_data *obj, const void *vict_obj, int type)
These pieces are used as follows:
str: This is the basic string, a null terminated character array, including
control characters (see section 1.4 on Control Characters), to be sent to
control characters (see section 1.4 on Control Characters), to be sent to
characters designated by the targets.
hide_invisible: A TRUE or FALSE value indicating whether or not to hide the
entire output from any characters that cannot see the “performing character”.
entire output from any characters that cannot see the “performing character”.
ch: The “performing character”. This is the character that the output string
ch: The “performing character”. This is the character that the output string
is associated with. The character is used to determine the room for the output
of the action in question.
obj: An object (an actual item obj_data) used in the course of the action.
obj: An object (an actual item obj_data) used in the course of the action.
vict_obj: This can be either a character involved in the action, another
object, or even a predefined string of text.
@ -73,7 +73,7 @@ The next parameter vict_objcan be a number of things ranging from a game object
null terminated character array (char *).
Do note, however, that obj and vict_obj are both ignored if there is no control
character reference (see section 1.4 Control Characters) to them and the type
character reference (see section 1.4 Control Characters) to them and the type
is set to TO_ROOM or TO_CHAR. In these cases, NULL should be supplied as the
input to the function.
@ -96,7 +96,7 @@ TO_CHAR: Finally, this option sends the output to the ch.
TO_SLEEP: This is a special option that must be combined with one of the above
options. It tells act() that the output is to be sent even to characters that
are sleeping. It is combined with a bitwise or. i.e. TO_VICT | TO_SLEEP.
are sleeping. It is combined with a bitwise or. i.e. TO_VICT | TO_SLEEP.
When the string has been parsed, it is capitalized and a newline is added.
@ -105,20 +105,20 @@ In a manner similar to the printf() family of functions, act() uses control
characters. However, instead of using the % symbol, act() uses the $ character
to indicate control characters.
$n Write name, short description, or “someone”, for ch, depending on whether
$n Write name, short description, or “someone”, for ch, depending on whether
ch is a PC, a NPC, or an invisible PC/NPC.
$N Like $n, except insert the text for vict_obj.*
$m “him,” “her,” or “it,” depending on the gender of ch.
$m “him,” “her,” or “it,” depending on the gender of ch.
$M Like $m, for vict_obj.*
$s “his,” “her,”or “it,” depending on the gender of ch.
$s “his,” “her,”or “it,” depending on the gender of ch.
$S Like $s, for vict_obj.*
$e “he,” “she,” “it,” depending on the gender of ch.
$e “he,” “she,” “it,” depending on the gender of ch.
$E Like $e, for vict_obj.*
$o Name or “something” for obj, depending on visibility.
$o Name or “something” for obj, depending on visibility.
$O Like $o, for vict_obj.*
$p Short description or “something” for obj.
$p Short description or “something” for obj.
$P Like $p for vict_obj.*
$a “an” or“a”, depending on the first character of objs name.
$a “an” or“a”, depending on the first character of objs name.
$A Like $a, for vict_obj.*
$T Prints the string pointed to by vict_obj.*
$F Processes the string pointed to by vict_obj with the fname() function prior
@ -129,7 +129,7 @@ no action is taken.
$U Processes the buffer and uppercases the first letter of the following word
(the word immediately after to the control code). If there is no following
word, no action is taken.
$$ Print the character $.
$$ Print the character $.
NOTE*: vict_obj must be a pointer of type struct char_data *.

View file

@ -9,8 +9,8 @@ to players in color in the tbaMUD game engine. Its intended audience is for
Coders of tbaMUD.
tbaMUD allows you to create colorful messages by using ANSI control sequences.
Each player may select what “level” of color he/she desires from the four
levels “off,” “brief,” “normal,” and “complete.” Each player can select his/her
Each player may select what “level” of color he/she desires from the four
levels “off,” “brief,” “normal,” and “complete.” Each player can select his/her
color level by using the TOGGLE COLOR command from within the MUD; you as the
programmer must decide which messages will be colored for each of the color
levels.
@ -21,17 +21,17 @@ All files in which you wish to use color must have the line:
This should be put in after all other includes in the beginning of the file.
There are 8 colors available “normal,” red, green, yellow, blue, magenta,
There are 8 colors available “normal,” red, green, yellow, blue, magenta,
cyan and white. They are accessible by sending control sequences as part of
another string, for example:
sprintf(buf, "If youre %shappy%s and you know it clap "
sprintf(buf, "If youre %shappy%s and you know it clap "
"%d of your hands.\n\r", x, y, num_of_hands);
send_to_char(ch, buf);
In this example, x and y are the “on” and “off” sequences for the color you
want. There are 2 main series of color macros available for you to use (dont
actually use “x” and “y,” of course!): the K series and the CC series. The CC
In this example, x and y are the “on” and “off” sequences for the color you
want. There are 2 main series of color macros available for you to use (dont
actually use “x” and “y,” of course!): the K series and the CC series. The CC
(Conditional Color) series is recommended for most general use.
The name of the actual sequence starts with the name of its series, plus a
@ -51,21 +51,21 @@ CCBLU() (arguments defined below).
The K series requires no arguments, and is simply a macro to the ANSI color
code. Therefore, if you use a K-series color code, the color will ALWAYS be
sent, even if the person youre sending it to has color off. This can very bad.
sent, even if the person youre sending it to has color off. This can very bad.
Some people who do not have ANSI-compatible terminals will see garbage
characters instead of colors. If the terminal correctly ignores ANSI color
codes, then nothing will show up on their screen at all. The K series is mainly
used to print colors to a string if the players color level will later be
used to print colors to a string if the players color level will later be
tested manually (for an example, see do_gen_com in act.comm.c).
The recommended series is the CC series (i.e. CCNRM(), CCRED(), etc.) The CC
series macros require two arguments a pointer to the character to whom the
series macros require two arguments a pointer to the character to whom the
string is being sent, and the minimum color level the player must be set to in
order to see the color. Color sent as 'brief' (formerly known as sparse it was
changed for consistency with the syslog command) (C_SPR) will be seen by people
with color set to sparse, normal, or complete; color sent as normal (C_NRM)
with color set to sparse, normal, or complete; color sent as normal (C_NRM)
will be seen only by people with color set to normal or complete; color sent as
complete (C_CMP) will be seen only by people with color set to complete.
complete (C_CMP) will be seen only by people with color set to complete.
To illustrate the above, an example is in order:
@ -76,29 +76,29 @@ ACMD(do_showcolor)
{
char buf[300];
sprintf(buf, "Dont you just love %scolor%s, %scolor%s, " "%sCOLOR%s!\n\r",
sprintf(buf, "Dont you just love %scolor%s, %scolor%s, " "%sCOLOR%s!\n\r",
CCBLU(ch, C_CMP), CCNRM(ch, C_CMP), CCYEL(ch, C_NRM), CCNRM(ch, C_NRM),
CCRED(ch, C_SPR), CCNRM(ch, C_SPR));
send_to_char(ch, buf);
}
What does this do? For people with color set to Complete, it prints:
Dont you just love color, color, COLOR! (blue) (yellow) (red)
Dont you just love color, color, COLOR! (blue) (yellow) (red)
People who have color set to Normal will see:
Dont you just love color, color, COLOR! (yellow) (red)
Dont you just love color, color, COLOR! (yellow) (red)
People who have color set to Sparse will see:
Dont you just love color, color, COLOR! (red)
Dont you just love color, color, COLOR! (red)
People who have color set to Off will see:
Dont you just love color, color, COLOR! (no color, as youd expect)
Dont you just love color, color, COLOR! (no color, as youd expect)
There are several common pitfalls with using the CC series of color macros:
Do not confuse CCNRM with C_NRM. CCNRM() is a macro to turn the color back to
normal; C_NRMis a color level of “normal.” Always make sure that every pair of
“on” and “off” codes are at the same color level. For example:
normal; C_NRMis a color level of “normal.” Always make sure that every pair of
“on” and “off” codes are at the same color level. For example:
WRONG: sprintf(buf, "%sCOLOR%s\n\r", CCBLU(ch, C_NRM), CCNRM(ch, C_CMP));
@ -110,14 +110,14 @@ WRONG: sprintf(buf, "%sCOLOR%s\n\r", CCBLU(ch, C_CMP), CCNRM(ch, C_NRM));
The above statement is also wrong, although not as bad. In this case, someone
with color set to Normal will (correctly) not get the CCBLU code, but will then
unnecessarily get the CCNRM code. Never send a color code if you dont have to.
unnecessarily get the CCNRM code. Never send a color code if you dont have to.
The codes are several bytes long, and cause a noticeable pause at 2400 baud.
This should go without saying, but dont ever send color at the C_OFF level.
This should go without saying, but dont ever send color at the C_OFF level.
Special precautions must be taken when sending a colored string to a large
group of people. You cant use the color level of “ch” (the person sending the
string) each person receiving the string must get a string appropriately
group of people. You cant use the color level of “ch” (the person sending the
string) each person receiving the string must get a string appropriately
colored for his/her level. In such cases, it is usually best to set up two
strings (one colored and one not), and test each players color level
strings (one colored and one not), and test each players color level
individually (see do_gen_comin act.comm.c for an example).

View file

@ -4,14 +4,14 @@ Builder Academy at telnet://tbamud.com:9091 or email rumble@tbamud.com -- Rumble
The Art of Debugging
Originally by Michael Chastain and Sammy
The following documentation is excerpted from Merc 2.0s hacker.txt file. It
The following documentation is excerpted from Merc 2.0s hacker.txt file. It
was written by Furey of MERC Industries and is included here with his
permission. We have packaged it with tbaMUD (changed in a couple of places,
such as specific filenames) because it offers good advice and insight into the
art and science of software engineering. More information about tbaMUD,
can be found at the tbaMUD home page http://tbamud.com.
1 “Im running a Mud so I can learn C programming!”
1 “Im running a Mud so I can learn C programming!”
Yeah, right. The purpose of this document is to record some of our knowledge,
experience and philosophy. No matter what your level, we hope that this
@ -31,11 +31,11 @@ Play with it some more.
Read documentation again.
Get the idea?
The idea is that your mind can accept only so much “new data” in a single
session. Playing with something doesnt introduce very much new data, but it
does transform data in your head from the “new” category to the “familiar”
category. Reading documentation doesnt make anything “familiar,” but it
refills your “new” hopper.
The idea is that your mind can accept only so much “new data” in a single
session. Playing with something doesnt introduce very much new data, but it
does transform data in your head from the “new” category to the “familiar”
category. Reading documentation doesnt make anything “familiar,” but it
refills your “new” hopper.
Most people, if they even read documentation in the first place, never return
to it. They come to a certain minimum level of proficiency and then never
@ -47,17 +47,17 @@ through the two-step learning cycle many times to master it.
man gives you online manual pages.
grep stands for “global regular expression print;” searches for strings in text
grep stands for “global regular expression print;” searches for strings in text
files.
vi, emacs, jove use whatever editor floats your boat, but learn the hell out
of it; you should know every command in your editor.
ctags mags “tags” for your editor which allows you to go to functions by name
ctags mags “tags” for your editor which allows you to go to functions by name
in any source file.
>, >>, <, | input and output redirection at the command line; get someone to
show you, or dig it out of “man csh”
show you, or dig it out of “man csh”
These are the basic day-in day-out development tools. Developing without
knowing how to use all of these well is like driving a car without knowing
@ -70,21 +70,21 @@ the hypothesis, run the program and provide it experimental input, observe its
behavior, and confirm or refute the hypothesis.
A good hypothesis is one which makes surprising predictions which then come
true; predictions that other hypotheses dont make.
true; predictions that other hypotheses dont make.
The first step in debugging is not to write bugs in the first place. This
sounds obvious, but sadly, is all too often ignored.
If you build a program, and you get any errors or any warnings, you should fix
them before continuing. C was designed so that many buggy ways of writing code
are legal, but will draw warnings from a suitably smart compiler (such as “gcc”
are legal, but will draw warnings from a suitably smart compiler (such as “gcc”
with the -Wall flag enabled). It takes only minutes to check your warnings and
to fix the code that generates them, but it takes hours to find bugs otherwise.
“Desk checking” (proof reading) is almost a lost art these days. Too bad. You
“Desk checking” (proof reading) is almost a lost art these days. Too bad. You
should desk check your code before even compiling it, and desk-check it again
periodically to keep it fresh in mind and find new errors. If you have someone
in your group whose only job it is to desk-check other peoples code, that
in your group whose only job it is to desk-check other peoples code, that
person will find and fix more bugs than everyone else combined.
One can desk-check several hundred lines of code per hour. A top-flight
@ -95,20 +95,20 @@ fixing technique. Compare that to all the hours you spend screwing around with
broken programs trying to find one bug at a time.
The next technique beyond desk-checking is the time-honored technique of
inserting “print” statements into the code, and then watching the logged
inserting “print” statements into the code, and then watching the logged
values. Within tbaMUD code, you can call printf(), fprintf(), or log()to dump
interesting values at interesting times. Where and when to dump these values
is an art, which you will learn only with practice.
If you dont already know how to redirect output in your operating system, now
is the time to learn. On Unix, type the command “man csh”, and read the part
about the “>” operator. You should also learn the difference between “standard
output” (for example, output from “printf”) and “standard error” (for example,
output from “fprintf(stderr, ...)”).
If you dont already know how to redirect output in your operating system, now
is the time to learn. On Unix, type the command “man csh”, and read the part
about the “>” operator. You should also learn the difference between “standard
output” (for example, output from “printf”) and “standard error” (for example,
output from “fprintf(stderr, ...)”).
Ultimately, you cannot fix a program unless you understand how it is operating
in the first place. Powerful debugging tools will help you collect data, but
they cant interpret it, and they cant fix the underlying problems. Only you
they cant interpret it, and they cant fix the underlying problems. Only you
can do that.
When you find a bug... your first impulse will be to change the code, kill the
@ -117,9 +117,9 @@ observe is often just the symptom of a deeper bug. You should keep pursuing the
bug, all the way down. You should grok the bug and cherish it in fullness
before causing its discorporation.
Also, when finding a bug, ask yourself two questions: “What design and
programming habits led to the introduction of the bug in the first place?” And:
“What habits would systematically prevent the introduction of bugs like this?”
Also, when finding a bug, ask yourself two questions: “What design and
programming habits led to the introduction of the bug in the first place?” And:
“What habits would systematically prevent the introduction of bugs like this?”
5 Debugging: Tools
@ -127,20 +127,20 @@ When a Unix process accesses an invalid memory location, or (more rarely)
executes an illegal instruction, or (even more rarely) something else goes
wrong, the Unix operating system takes control. The process is incapable of
further execution and must be killed. Before killing the process, however, the
operating system does something for you: it opens a file named “core” and
operating system does something for you: it opens a file named “core” and
writes the entire data space of the process into it.
Thus, “dumping core” is not a cause of problems, or even an effect of problems.
Its something the operating system does to help you find fatal problems which
Thus, “dumping core” is not a cause of problems, or even an effect of problems.
Its something the operating system does to help you find fatal problems which
have rendered your process unable to continue.
One reads a “core” file with a debugger. The two most popular debuggers on Unix
One reads a “core” file with a debugger. The two most popular debuggers on Unix
are adb and gdb, although occasionally one finds dbx. Typically one starts a
debugger like this: “gdb bin/circle” or “gdb bin/circle lib/core”.
debugger like this: “gdb bin/circle” or “gdb bin/circle lib/core”.
The first thing, and often the only thing, you need to do inside the debugger
is take a stack trace. In adb, the command for this is “$c”. In gdb, the
command is “backtrace”. In dbx, the command is “where”. The stack trace will
is take a stack trace. In adb, the command for this is “$c”. In gdb, the
command is “backtrace”. In dbx, the command is “where”. The stack trace will
tell you what function your program was in when it crashed, and what functions
were calling it. The debugger will also list the arguments to these functions.
Interpreting these arguments, and using more advanced debugger features,
@ -343,12 +343,12 @@ new tools.
7 Profiling
Another useful technique is “profiling,” to find out where your program is
Another useful technique is “profiling,” to find out where your program is
spending most of its time. This can help you to make a program more efficient.
Here is how to profile a program:
1. Remove all the .o files and the “circle” executable:
1. Remove all the .o files and the “circle” executable:
make clean
2. Edit your Makefile, and change the PROFILE=line:
@ -359,25 +359,25 @@ make
4. Run circle as usual. Shutdown the game with the shutdown command when you
have run long enough to get a good profiling base under normal usage
conditions. If you crash the game, or kill the process externally, you wont
conditions. If you crash the game, or kill the process externally, you wont
get profiling information.
5. Run the profcommand:
prof bin/circle > prof.out
6. Read prof.out. Run “man prof” to understand the format of the output. For
advanced profiling, you can use “PROFILE = -pg” in step 2, and use the “gprof”
command in step 5. The “gprof” form of profiling gives you a report which lists
6. Read prof.out. Run “man prof” to understand the format of the output. For
advanced profiling, you can use “PROFILE = -pg” in step 2, and use the “gprof”
command in step 5. The “gprof” form of profiling gives you a report which lists
exactly how many times any function calls any other function. This information
is valuable for debugging as well as performance analysis.
Availability of “prof” and “gprof” varies from system to system. Almost every
Unix system has “prof”. Only some systems have “gprof”.
Availability of “prof” and “gprof” varies from system to system. Almost every
Unix system has “prof”. Only some systems have “gprof”.
7 Books for Serious Programmers
Out of all the thousands of books out there, three stand out:
Kernighan and Plaugher, “The Elements of Programming Style”
Kernighan and Ritchie, “The C Programming Language”
Brooks, “The Mythical Man Month”
Kernighan and Plaugher, “The Elements of Programming Style”
Kernighan and Ritchie, “The C Programming Language”
Brooks, “The Mythical Man Month”

View file

@ -3,7 +3,7 @@ Builder Academy at telnet://tbamud.com:9091 or email rumble@tbamud.com -- Rumble
tbaMUD File Manifest
The main tbaMUD/ directory has the following subdirectories and files:
The main tbaMUD/ directory has the following subdirectories and files:
autorun - Shell script to run the MUD (./autorun &).
FAQ - Frequently Aske Questions with answers.
@ -16,7 +16,7 @@ lib/ - MUD data.
log/ - System logs.
src/ - Source code.
The bin/directory contains only binaries: circle (the main MUD) and its
The bin/directory contains only binaries: circle (the main MUD) and its
utilities, which are described in utils.txt.
The doc/ directory has its own README file, describing the contents of each
@ -51,12 +51,12 @@ time - Where the MUD time is saved.
The lib/misc/ directory contains the following files:
bugs - Bugs reported by players with the bug command.
ideas - Ideas from players from idea command.
bugs - Bugs reported by players with the bug command.
ideas - Ideas from players from idea command.
messages - Spell and skill damage messages.
socials - Text file with text of the socials.
socials.new - New format of socials you can edit via AEDIT.
typos - Typos reported by players with the typo command.
typos - Typos reported by players with the typo command.
xnames - Text file of invalid names.
The lib/plrobjs/ contains the following files and directories:
@ -80,18 +80,18 @@ zzz/
The lib/text/ directory contains the following files:
background - Background story (for option 3 from main menu).
credits - Text for credits command.
credits - Text for credits command.
greetings - Greeting message.
handbook - Text for Immortal Handbook (handbook command).
immlist - Text for immlist command.
handbook - Text for Immortal Handbook (handbook command).
immlist - Text for immlist command.
imotd - Immortal MOTD --seen by immortals on login.
info - Text for info command.
info - Text for info command.
motd - MOTD --seen by mortals on login.
news - Text for news command.
policies - Text for policy command.
wizlist - Text for wizlist command.
/help/screen - Text for help command as a mortal with no arguments.
/help/iscreen - Text for help command an an immortal with no arguments.
news - Text for news command.
policies - Text for policy command.
wizlist - Text for wizlist command.
/help/screen - Text for help command as a mortal with no arguments.
/help/iscreen - Text for help command an an immortal with no arguments.
The lib/world/directory contains the following subdirectories:
@ -103,8 +103,8 @@ wld - Contains *.wld files (world files)
zon - Contains *.zon files (zone files)
Each of the 6 subdirectories in the lib/world/ directory also contains two
additional files one called index, which specifies which files in that
directory should be loaded when the MUD boots, and index.mini, which
additional files one called index, which specifies which files in that
directory should be loaded when the MUD boots, and index.mini, which
specifies which files should be loaded if the MUD is booted with the -m
(mini-mud) option.
@ -128,6 +128,6 @@ trigger - Trigedit log messages.
usage - Mud system usage (player load & memory usage info).
The src/ directory contains all of the C and header files for the MUD, along
with a Makefile. The src/util/ directory contains source for tbaMUDs utility
with a Makefile. The src/util/ directory contains source for tbaMUDs utility
programs. See admin.txt for more information on how to compile the MUD. See
utils.txt for more information on how to use tbaMUDs utilities.
utils.txt for more information on how to use tbaMUDs utilities.

View file

@ -9,16 +9,16 @@ every platform that exists. This document is for experienced programmers
trying to make tbaMUD work on their platform.
tbaMUD should work on most UNIX platforms without any modifications; simply run
the “configure” script and it should automatically detect what type of system
the “configure” script and it should automatically detect what type of system
you have and anything that may be strange about it. These findings are all
stored in a header file called conf.h which is created in the src directory
from a template called conf.h.in. A Makefile is also created from the template
Makefile.in.
Non-UNIX platforms are a problem. Some cant run tbaMUD at all. However, any
Non-UNIX platforms are a problem. Some cant run tbaMUD at all. However, any
multitasking OS that has an ANSI C compiler, and supports non-blocking I/O and
socket-based TCP/IP networking, should theoretically be able to run tbaMUD; for
example, OS/2, AmigaOS, Mac OS (Classic versions; Mac OS X supports tbaMUDs
example, OS/2, AmigaOS, Mac OS (Classic versions; Mac OS X supports tbaMUDs
configure script from the command line), and all versions of Windows.
The port can be very easy or very difficult, depending mainly on whether or nor
@ -26,7 +26,7 @@ your OS supports the Berkeley socket API.
The general steps for porting tbaMUD to a non-UNIX platform are listed below. A
number of tips for porting can be found after the porting steps. Note that we
have already ported tba to Windows, so if youre confused as to how to perform
have already ported tba to Windows, so if youre confused as to how to perform
some of these steps, you can look at what we have done as an example (see the
files README.CYGWIN).
@ -36,11 +36,11 @@ trying to port the code.
Porting the Code
Step 1. Create a “conf.h” file for your system. Copy the template “conf.h.in”
to “conf.h”, and then define or undefine each item as directed by the comments
Step 1. Create a “conf.h” file for your system. Copy the template “conf.h.in”
to “conf.h”, and then define or undefine each item as directed by the comments
and based on the characteristics of your system. To write the conf.h file,
youll need to know which header files are included with your system, the
return type of signals, whether or not your compiler supports the const
youll need to know which header files are included with your system, the
return type of signals, whether or not your compiler supports the const
keyword, and whether or not you have various functions such as crypt()and
random(). Also, you can ignore the HAVE_LIBxxx and HAVE_xxx_PROTO constants at
the end of conf.h.in; they are not used in the code (they are part of UNIX
@ -58,12 +58,12 @@ be in the source file comm.c.
Step 4. Test your changes! Make sure that multiple people can log in
simultaneously and that they can all type commands at the same time. No player
should ever have a “frozen” screen just because another is waiting at a prompt.
should ever have a “frozen” screen just because another is waiting at a prompt.
Leave the MUD up for at least 24 hours, preferably with people playing it, to
make sure that your changes are stable. Make sure that automatic events such as
zone resets, point regeneration, and corpse decomposition are being timed
correctly (a tick should be about 75 seconds). Try resetting all the zones
repeatedly by typing “zr *” many times. Play the MUD and make sure that the
repeatedly by typing “zr *” many times. Play the MUD and make sure that the
basic commands (killing mobs as a mortal, casting spells, etc.) work correctly.
Step 5. If you are satisfied that your changes work correctly, you are
@ -71,20 +71,20 @@ encouraged to submit them to be included as part of the tbaMUD distribution so
that future releases of tbaMUD will support your platform. This prevents you
from re-porting the code every time a new version is released and allows other
people who use your platform to enjoy tbaMUD as well. To submit your changes
you must make a patch file using the GNU diff program. diff will create a
patch file which can be later used with the patch utility to incorporate
you must make a patch file using the GNU diff program. diff will create a
patch file which can be later used with the patch utility to incorporate
your changes into the stock tbaMUD distribution. For example, if you have a
copy of tbaMUD in the “stock-tba” directory, and your changes are in “my-tba”,
copy of tbaMUD in the “stock-tba” directory, and your changes are in “my-tba”,
you can create a patch file like this:
diff -u --new-file --recursive stock-tba/src my-tba/src > patch
This will create a file called patch with your patches. You should then try
to use the patch program (the inverse of diff) on a copy of tbaMUD to make
This will create a file called patch with your patches. You should then try
to use the patch program (the inverse of diff) on a copy of tbaMUD to make
sure that tbaMUD is correctly changed to incorporate your patches. This step is
very important: if you dont create these patches correctly, your work will be
very important: if you dont create these patches correctly, your work will be
useless because no one will be able to figure out what you did! Make sure to
read the documentation to diff and patch if you dont understand how to use
read the documentation to diff and patch if you dont understand how to use
them. If your patches work, CELEBRATE!!
Step 6. Write a README file for your operating system that describes everything
@ -107,7 +107,7 @@ Each system to which tba is already ported has a CIRCLE_xx constant associated
with it: CIRCLE_UNIX for plain vanilla UNIX tbaMUD, CIRCLE_WINDOWS for MS
Windows, CIRCLE_OS2 for IBM OS/2, and CIRCLE_AMIGA for the Amiga. You must use
a similar constant for your system. At the top of your conf.h, make sure to
comment out “#define CIRCLE_UNIX” and add “#define CIRCLE_YOUR_SYSTEM”.
comment out “#define CIRCLE_UNIX” and add “#define CIRCLE_YOUR_SYSTEM”.
3.2 ANSI C and GCC
As long as your system has an ANSI C compiler, all of the code (except for
@ -122,22 +122,22 @@ you use gcc.
Make absolutely sure to use non-blocking I/O; i.e. make sure to enable the
option so that the read() system call will immediately return with an error if
there is no data available. If you do not use non-blocking I/O, read() will
“block,” meaning it will wait infinitely for one particular player to type
“block,” meaning it will wait infinitely for one particular player to type
something even if other players are trying to enter commands. If your system
does not implement non-blocking I/O correctly, try using the
POSIX_NONBLOCK_BROKEN constant in sysdep.h.
3.4 Timing
tbaMUD needs a fairly precise (on the order of 5 or 10 ms) timer in order to
correctly schedule events such as zone resets, point regeneration (“ticks”),
correctly schedule events such as zone resets, point regeneration (“ticks”),
corpse decomposition, and other automatic tasks. If your system supports the
select() system call with sufficient precision, the default timing code should
work correctly. If not, youll have to find out which system calls your system
work correctly. If not, youll have to find out which system calls your system
supports for determining how much time has passed and replace the select()
timing method.
3.5 Signals and Signal Handlers
A note about signals: Most systems dont support the concept of signals in the
A note about signals: Most systems dont support the concept of signals in the
same way that UNIX does. Since signals are not a critical part of how tbaMUD
works anyway (they are only used for updating the wizlist and some other
trivial things), all signal handling is turned off by default when compiling
@ -147,7 +147,7 @@ conf.h file and all signal code will be ignored automatically.
4 Final Note
IMPORTANT: Remember to keep any changes you make surrounded by #ifdef
statements (i.e. “#ifdef CIRCLE_WINDOWS ... #endif”). If you make absolutely
statements (i.e. “#ifdef CIRCLE_WINDOWS ... #endif”). If you make absolutely
sure to mark all of your changes with #ifdef statements, then your patches
(once you get them to work) will be suitable for incorporation into the
tbaMUD distribution, meaning that tbaMUD will officially support your platform.

View file

@ -10,6 +10,9 @@ to rec.games.mud.diku which originally announced CircleMUD as a publicly
available MUD source code.
tbaMUD Release history:
Version 2025 release: January, 2025
Version 2023 release: January, 2023
Version 2021 release: March, 2021
Version 2020 release: January, 2020
Version 2019 release: January, 2019
Version 2018 release: January, 2018
@ -140,7 +143,7 @@ communication channels
totally ignores all commands from that player until they are thawed.
--Even handier DELETE flag allows you to delete players on the fly.
--"set" command (mentioned above) allows you to freeze/unfreeze/
delete/siteok/un-siteok players --even if they arent logged in!
delete/siteok/un-siteok players --even if they arent logged in!
--Bad password attempts are written to the system log and saved;
if someone tries to hack your account, you see "4 LOGIN FAILURES
SINCE LAST SUCCESSFUL LOGIN" next time you log on.

View file

@ -110,12 +110,12 @@ is being specified. The command sort name is the shortest part of the command a
player must type for it to match. The hide-flag can be either 0 or 1; if 1, the
social is hidden from OTHERS if they cannot see the character performing the
social. The action is not hidden from the VICTIM, even if s/he cannot see the
character performing the social, although in such cases the characters name
will, of course, be replaced with “someone”. The min positions should be set to
character performing the social, although in such cases the characters name
will, of course, be replaced with “someone”. The min positions should be set to
dictate the minimum position a player must be in to target the victim and
perform the social. Min level allows you to further customize who can use what
socials.Where it makes sense to do so, text fields may be left empty. If
editing manually you should by put a # in the first column on the line. Aedit
editing manually you should by put a # in the first column on the line. Aedit
does this automatically.
Examples:

View file

@ -34,7 +34,7 @@ older CircleMUD data files to the versions used in CircleMUD v3, while others
are used to convert currently existing files into different formats.
Overall, these utilities have been created in an attempt to make the tbaMUD
administrators life a bit easier, and to give the administrator some ideas of
administrators life a bit easier, and to give the administrator some ideas of
further and more grandiose utilities to create. Some are no longer applicable
but are retained as examples.
@ -61,7 +61,7 @@ the second, and so forth.
The split utility is designed to split large world files into smaller, zone
sized files that are easier to manage and maintain. The utility reads its input
from the standard input and writes the output to files with names specified
within the larger world file. This is done by inserting =filename into the
within the larger world file. This is done by inserting =filename into the
world file at the appropriate points, where filename is the name of the file
for the following section.
@ -141,8 +141,8 @@ The command line syntax for autowiz is as follows:
autowiz <wizlev> <wizlistfile> <immlev> <immlistfile> [pid to signal]
where <wizlev> is equal to whatever LVL_GOD is set to in your tbaMUD server,
<wizlistfile> is the filename for the file containing the games Wizlist.
<immlev> should be set to your games LVL_IMMORT, while <immlistfile>
<wizlistfile> is the filename for the file containing the games Wizlist.
<immlev> should be set to your games LVL_IMMORT, while <immlistfile>
is the name of the Immlist file.
This utility must be recompiled if you make any changes to the player file structure.

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.
$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.
$n loads a halo and dons it.
$N could use a good disguise.
@ -6109,7 +6109,7 @@ $n looks around for a victim to strangle.
You throw yourself against $N's throat, trying to squeeze the life out.
$n throws $mself after $N's throat.
$n throws $mself after your throat, you try to defend yourself.
AARGH! They must have left... #&%£@!
AARGH! They must have left...
You put your hands around your throat and stop breathing.
$n tries to strangle $mself, making a very strange noise and getting blue in the face.
You strangle $M $t.

View file

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

View file

@ -3312,7 +3312,7 @@ the earthquake spell.
See also: WATERWALK, EARTHQUAKE
#0
FOLLOWERS
FOLLOWERS UNFOLLOW
Usage: follow <leader>
@ -3350,7 +3350,7 @@ The 3rd number is liquid type from the following:
value 1: Initial drink units. Must be 1 or greater.
value 2: see below
value 3: 0 for not poisoned. Otherwise, the number of hours until the poison
burns off?
burns off.
value 2: The type of liquid in the drink-container, one of:
@ -7093,31 +7093,28 @@ See also: FLAGS, PLR
#31
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
their skill at building. This makes it easier for people to know who is in
charge, who they can ask for help, and who they should be wary of taking tips
from. I encourage everyone to help each other. Just realize that if the person
is not at least a Great God they may have relatively little experience.
Level 31 (Immortal) Anyone who is new to TBA and is working on their trial
vnum or zone.
Level 32 (God) An experienced builder that has proven their knowledge and is
willing to teach others. Level 2 and above is considered staff.
Level 33 (Greater God) An experienced builder that has contributed
significantly to TBA.
Here at The Builder Academy, the level of an immortal generally reflects that
immortal's building skill and willingness to help others. If you have
questions, you may want to ask someone whose level is at least 32. Of course,
everyone is encouraged to help everyone else, but know that those who are not
at least level 32 may have relatively little experience.
Level 31 (Immortal) Anyone who is new to TBA and is working on their trial
vnum or zone.
Level 32 (God) An experienced builder with proven knowledge that is
willing to teach others. Immortals of level 32 and above
are considered staff.
Level 33 (Greater God) An experienced builder that has contributed significantly
to TBA.
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
are wasting your time. Note, this does not mean you are not a quality builder,
but TBA is not your typical MUD. On the contrary, we are here as dedicated
people to help you learn to build. Because of this the only chance of
advancement is if you are willing to learn to build and then help teach others.
If you are willing to give back to the tbaMUD community, and have the
necessary skills to do so, you will be advanced and given further privileges
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
Please do not bother asking to be advanced. If your goal is merely to rise in
the ranks, you are wasting your time. The Gods here are dedicated to helping
others learn to build. Thus, those who advance in level are those who become
proficient builders that offer their time to teach others. If you are willing
to give back to the tbaMUD community and have the requisite skills, you will be
advanced and given further tools to teach others via your level. Generally, if
you ask for a promotion, you will be less likely to receive it.
#0
PROPOSALS GUIDELINES ZONE-PROPOSALS PROPOSITIONS PROPOSE REQUESTS CRITERIA
@ -9882,6 +9879,7 @@ tbalim test 61165
return
toggle nohassle on
To list empty zones "show zone none"
To setup test with zone 348
return
saveall

View file

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

View file

@ -7,28 +7,6 @@ A granite fountain is gurgling here.~
-1 2 15 0
0 0 0 0 0
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~
---------------------------------------------------------
Immortal Name: ===== Room # ====== Location: =======
@ -57,6 +35,26 @@ Niamh ----------- 34351 ----------- God Hall, Southeast
Fade ----------- 34337 ------------ God Hall, West
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
fouton~
a Fouton(tm) ~
@ -287,8 +285,8 @@ A plush couch is here in front of a coffee table.~
0 0 0 0 0
E
couch~
The couch is long, has a frame of oak wood and a long
blue cushion. It happens to be a Futon (tm).
The couch is long, has a frame of oak wood and a long blue cushion. It
happens to be a Futon (tm).
~
#34319
LazyBoy recliner~
@ -684,15 +682,15 @@ A toilet is here made of porclein.~
1 0 0 0
0 0 0 0 0
E
sign~
Be sure to Flush!
~
E
toilet toidy throne~
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
fixtures all around, which include the handles.
~
E
sign~
Be sure to Flush!
~
#34344
sink~
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
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~
The sink is clean and white, with a shiny chrome faucet system and drain in
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
tub clawtub~
an old fashioned claw tub and shower~
@ -720,16 +718,16 @@ An old fashioned claw tub and shower is here.~
3 0 0 0
0 0 0 0 0
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~
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
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
bench~
a short teak bench~
@ -752,16 +750,16 @@ A gurgling spring is here splashing into a golden basin.~
-1 2 15 0
0 0 0 0 0
E
spring~
The spring is just a free flowing stream of water that flows from the ground
with a murmuring, gurgling sound.
~
E
basin~
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
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
statue~
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 31 0
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~
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
@ -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
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
Opie~
a guardian statue of Opie~
@ -793,6 +791,11 @@ A guardian statue of Opie is here.~
0 0 0 0
0 0 0 31 0
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~
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
@ -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
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
Welcor~
a guardian statue of Welcor~
@ -814,6 +812,11 @@ A guardian statue of Welcor is here.~
0 0 0 0
0 0 0 31 0
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~
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
@ -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
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

@ -231,7 +231,7 @@ A dagger is lying here, its jewels sparkling merrily.~
5 2 3 14
4 120 12 0 0
#3928
14~
curving dagger~
a wickedly curving dagger~
A dagger lies here on the ground, its curve looking particularly wicked.~
~

View file

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

View file

@ -65,6 +65,7 @@ D1
~
0 0 4
S
T 56
#4
The Beginning~
By simply following the different halls new builders will be taught the
@ -135,7 +136,7 @@ HELP BREATHE@n
D0
~
~
0 0 24
0 0 -1
D1
~
~
@ -143,7 +144,7 @@ D1
D2
~
~
0 0 25
0 0 -1
D3
~
~
@ -151,7 +152,7 @@ D3
D4
~
~
0 0 26
0 0 -1
S
#7
Writing Good Descriptions~
@ -215,7 +216,7 @@ D3
D4
~
~
0 0 27
0 0 -1
S
#9
How to Use Oedit~
@ -570,6 +571,7 @@ John Stuart Mill
~
0 8 0 0 0 0
S
T 308
#34
Pool of Images~
A broad mosaic walkway wraps around the natural hotsprings in this cavernous
@ -775,14 +777,14 @@ D2
~
0 0 98
E
sky winds~
Cold winds plunge ceaselessly at you from the dark, cloudless sky.
~
E
floor~
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
scratch on it.
~
E
sky winds~
Cold winds plunge ceaselessly at you from the dark, cloudless sky.
~
S
$~

View file

@ -72,7 +72,7 @@ Zone 1 is linked to the following zones:
2 Sanctus II at 199 (south) ---> 206
~
S
T 56
T 24
#101
The Temple of the Gods~
This seems to be the highest point in the kingdom of Sanctus. It is from
@ -92,19 +92,19 @@ D5
~
0 0 100
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~
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
and Rumble. They both radiate a strength and power that resembles the solid
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
T 158
T 163
@ -240,17 +240,17 @@ D5
~
0 0 142
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~
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
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.
~
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
#109
Thieves Retreat~
@ -383,18 +383,18 @@ D1
~
0 0 100
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~
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.
You can still see pieces of cloth and bone buried deeply into the wall inside
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
#117
Travelling Room~
@ -530,19 +530,19 @@ D2
~
0 0 129
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~
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
the room. The desk is bare and all the drawers are empty. It is as if no one
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
#125
Plane of the Magi~
@ -816,10 +816,14 @@ D0
~
0 0 128
E
bed~
The bed is made of a sturdy pine. A thin mattress covered in a white sheet
with a down pillow overlaying it. The mattress is too thin to hold anything of
value.
window~
Overlooking the western gate you can see the shimmering protective dome.
You hope it lasts, peace and tranquility is a good thing.
~
E
chair~
It's just your standard wooden chair. Uncomfortable and only real
usefulness would be as firewood.
~
E
desk~
@ -829,14 +833,10 @@ centered on the top of the desk. The desk has three drawers. All of them are
empty.
~
E
chair~
It's just your standard wooden chair. Uncomfortable and only real
usefulness would be as firewood.
~
E
window~
Overlooking the western gate you can see the shimmering protective dome.
You hope it lasts, peace and tranquility is a good thing.
bed~
The bed is made of a sturdy pine. A thin mattress covered in a white sheet
with a down pillow overlaying it. The mattress is too thin to hold anything of
value.
~
S
#136

View file

@ -1372,15 +1372,21 @@ D5
door~
2 0 225
E
sky winds~
Cold winds plunge ceaselessly at you from the dark, cloudless sky.
~
E
floor~
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
scratch on it.
~
E
sky winds~
Cold winds plunge ceaselessly at you from the dark, cloudless sky.
S
#391
Bomber's Trial Vnum~
You are in an unfinished room.
~
3 0 0 0 0 0
S
#399
Welcome to the Builder Academy~

View file

@ -12,6 +12,11 @@ Campus Crescent continues to the east.
~
0 -1 30101
E
sign~
Campus by Matrix and The Wandering Bard
Copyright 1994 by Curious Areas Workshop
~
E
info credits~
Campus by Matrix and The Wandering Bard
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
nomob to keep them in. - Parna for TBAMud.)
~
E
sign~
Campus by Matrix and The Wandering Bard
Copyright 1994 by Curious Areas Workshop
~
S
#30101
Campus Crescent~
@ -112,13 +112,13 @@ Campus Crescent continues to the west.
~
0 -1 30101
E
dorm dormitory dormitories~
Well, they're dormitories. What else can be said?
~
E
cobblestone stone cobble~
The cobblestones are clean.
~
E
dorm dormitory dormitories~
Well, they're dormitories. What else can be said?
~
S
#30103
Campus Crescent~
@ -144,13 +144,13 @@ Campus Crescent continues to the west.
~
0 -1 30102
E
cobblestone stone cobble~
The cobblestones are clean.
~
E
caf cafeteria~
You barely see, through the thick putrid fumes, the Mary Rotte Cafeteria.
~
E
cobblestone stone cobble~
The cobblestones are clean.
~
S
#30104
The Crossroads~
@ -214,13 +214,13 @@ The Crossroads lie to the west.
~
0 -1 30104
E
cobblestone stone cobble~
The cobblestones are clean.
~
E
building~
The buildings seem warm and inviting. You almost feel like hugging one.
~
E
cobblestone stone cobble~
The cobblestones are clean.
~
S
#30106
Campus Crescent~
@ -251,8 +251,8 @@ Campus Crescent continues to the west.
~
0 -1 30105
E
cobblestone stone cobble~
The cobblestones are still clean.
round building~
Yes... It's a round building. Go figure.
~
E
bookstore~
@ -260,8 +260,8 @@ bookstore~
floor.
~
E
round building~
Yes... It's a round building. Go figure.
cobblestone stone cobble~
The cobblestones are still clean.
~
S
#30107
@ -286,13 +286,13 @@ Campus Crescent and its cobblestones are to the west.
~
0 -1 30106
E
cobblestone stone cobble~
It's asphalt, you idiot! If you want to look at cobblestones, go west.
~
E
asphalt pavement~
It's asphalt.
~
E
cobblestone stone cobble~
It's asphalt, you idiot! If you want to look at cobblestones, go west.
~
S
#30108
University Avenue~
@ -316,8 +316,8 @@ The cafeteria lies to the west.
~
0 -1 30128
E
cobblestone stone cobble~
It's a dirt road. There are NO cobblestones here, although to the north...
cafeteria fog~
The fog seems to be coming from the Mary Rotte Cafeteria.
~
E
dirt~
@ -325,8 +325,8 @@ dirt~
World Dictionary)
~
E
cafeteria fog~
The fog seems to be coming from the Mary Rotte Cafeteria.
cobblestone stone cobble~
It's a dirt road. There are NO cobblestones here, although to the north...
~
S
#30109
@ -346,14 +346,14 @@ Morris House lies to the west.
~
0 -1 30129
E
dormitory dorm~
They are student living establishments.
~
E
dirt~
It's unclean matter, such as mud, trash, earth, or soil. (Webster's New
World Dictionary)
~
E
dormitory dorm~
They are student living establishments.
~
S
#30110
University Avenue~
@ -382,8 +382,8 @@ The Engineering building, Ellis Hall, lies to the west.
~
0 -1 30132
E
cobblestone stone cobble~
It's a dirt road. There are NO cobblestones here, although to the south...
building buildings~
There are two buildings here. Which one?
~
E
dirt~
@ -391,8 +391,8 @@ dirt~
World Dictionary)
~
E
building buildings~
There are two buildings here. Which one?
cobblestone stone cobble~
It's a dirt road. There are NO cobblestones here, although to the south...
~
S
#30111
@ -422,14 +422,14 @@ The Commerce building, Dunning Hall, lies to the west.
~
0 -1 30135
E
building buildings~
There are two buildings here. Which one?
~
E
dirt~
It's unclean matter, such as mud, trash, earth, or soil. (Webster's New
World Dictionary)
~
E
building buildings~
There are two buildings here. Which one?
~
S
#30112
University Avenue~
@ -481,23 +481,23 @@ University Avenue continues to the south.
~
0 -1 30112
E
dirt~
It's unclean matter, such as mud, trash, earth, or soil. (Webster's New
World Dictionary)
building~
The student center lies to the east.
~
E
sign warning~
The sign says:
Welcome to the Student Ghetto!
@n
n
Fine $103.50 for carrying open alcohol in the streets.
Fine $ 53.75 for excessively loud noises.
@n
n
ENTER AT YOUR OWN RISK!
~
E
building~
The student center lies to the east.
dirt~
It's unclean matter, such as mud, trash, earth, or soil. (Webster's New
World Dictionary)
~
S
#30114
@ -522,13 +522,13 @@ University Avenue lies to the west.
~
0 -1 30112
E
non-descript non descript~
(No description)
~
E
building~
The student center lies to the north.
~
E
non-descript non descript~
(No description)
~
S
#30115
Union Street~
@ -557,13 +557,13 @@ Union Street continues to the west.
~
0 -1 30114
E
non-descript non descript~
(No description)
~
E
building buildings~
There are two buildings here. Which one?
~
E
non-descript non descript~
(No description)
~
S
#30116
Division Road~
@ -588,13 +588,13 @@ Union Street is to the west.
~
0 -1 30115
E
building gym arena~
The Jock Hardy Arena lies to the north.
~
E
asphalt pavement~
It's asphalt.
~
E
building gym arena~
The Jock Hardy Arena lies to the north.
~
S
#30117
Division Road~
@ -613,13 +613,13 @@ Division Road continues south.
~
0 -1 30118
E
asphalt pavement~
It's asphalt.
~
E
zork~
What would possess you to look at that? What is a zork anyways?
~
E
asphalt pavement~
It's asphalt.
~
S
#30118
Division Road~
@ -643,14 +643,14 @@ The Campus bookstore lies to the west.
~
0 -1 30141
E
asphalt pavement~
It's asphalt.
~
E
bookstore building~
The bookstore is a 2-story cubical building, loud noises emanate from the top
floor.
~
E
asphalt pavement~
It's asphalt.
~
S
#30119
Division Road~
@ -669,13 +669,13 @@ Division Road continues south.
~
0 -1 30120
E
asphalt pavement~
It's asphalt.
~
E
zork~
What would possess you to look at that? What is a zork anyways?
~
E
asphalt pavement~
It's asphalt.
~
S
#30120
Division Road~
@ -694,14 +694,14 @@ Division Road continues south.
~
0 -1 30121
E
asphalt pavement~
It's asphalt.
~
E
tree~
It has been placed here just to relieve the monotony. It serves no other
purpose whatsoever.
~
E
asphalt pavement~
It's asphalt.
~
S
#30121
Division Road~
@ -721,16 +721,16 @@ Wally World sits to the east.
~
0 -1 30142
E
asphalt pavement~
It's asphalt.
~
E
dorm dormitory~
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
program, you don't think that there are that many floors in this replica of the
building.
~
E
asphalt pavement~
It's asphalt.
~
S
#30122
The Northern Campus Entrance~
@ -747,6 +747,12 @@ The Student GHETTO... Beware!
~
0 -1 30123
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~
The nicely polished brass plaque reads:
@ -754,12 +760,6 @@ sign plaque~
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
#30123
The Ghetto~
@ -834,14 +834,14 @@ There is a locked door leading to a stairwell.
door~
1 30105 30295
E
mailbox mailboxes~
All of the mailboxes are all empty ... Just like normal you think.
~
E
tiles floor~
The floor is covered with tiles that are so ugly, you have a difficult time
keeping your lunch down
~
E
mailbox mailboxes~
All of the mailboxes are all empty ... Just like normal you think.
~
S
#30127
Mary Rotte Cafeteria Entrance~
@ -868,14 +868,14 @@ There is a doorway leading to the kitchen.
door doorway~
1 -1 30143
E
cafeteria caf~
Yes, this is the cafeteria.
~
E
door doorway~
You believe that the doorway leads to the kitchen. Let's give our
compliments to the chef... *grin*
~
E
cafeteria caf~
Yes, this is the cafeteria.
~
S
#30128
Mary Rotte Cafeteria Entrance~
@ -902,14 +902,14 @@ The dining hall lies to the west... Beware!
~
0 -1 30148
E
cafeteria caf~
Yes, this is the cafeteria.
~
E
door doorway~
You believe that the doorway leads to the kitchen. Let's give our
compliments to the chef... *grin*
~
E
cafeteria caf~
Yes, this is the cafeteria.
~
S
#30129
Morris House~
@ -959,16 +959,16 @@ The hallway continues west.
~
0 -1 30324
E
round circle circular~
Yes, it's round.
~
E
footnote~
Yes, believe it or not, this is a reasonably accurate representation of the
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
can walk in one direction all the way around the building.
~
E
round circle circular~
Yes, it's round.
~
S
#30131
The Student Health Services Entrance~
@ -1038,13 +1038,13 @@ University Avenue lies to the west.
~
0 -1 30110
E
halls hallways hall hallway~
They are twisting alright.
~
E
minds mind great greatest~
All of whom were probably smarter than you.
~
E
halls hallways hall hallway~
They are twisting alright.
~
S
#30134
Corry-Mack Hall~
@ -1065,13 +1065,13 @@ Campus Crescent lies to the south.
~
0 -1 30105
E
halls hallways hall hallway~
They are twisting alright.
~
E
minds mind great greatest~
All of whom were probably smarter than you.
~
E
halls hallways hall hallway~
They are twisting alright.
~
S
#30135
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.
~
~
0 -1 30170
0 -1 -1
D1
There are electronic sounds coming from the east.
~
@ -1208,18 +1208,18 @@ A long hallway lies to the west.
~
0 -1 30153
E
plaque plaques~
They are rather boring. A bunch of people you don't know.
~
E
sign~
The sign says:
@n
n
Gym -> North
Arena -> East
Locker Rooms -> West
Exit -> South
~
E
plaque plaques~
They are rather boring. A bunch of people you don't know.
~
S
#30140
The Grant Hall Building~
@ -1308,13 +1308,13 @@ The kitchen continues south.
~
0 -1 30144
E
door doorway~
You stare intently at the door. Its wooden frame enthrals you.
~
E
food~
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
#30144
The Kitchen~
@ -1357,13 +1357,13 @@ The dining hall continues south.
~
0 -1 30147
E
food~
Believe me, you don't want to look at that!
~
E
students poor~
You feel sorry for them.
~
E
food~
Believe me, you don't want to look at that!
~
S
#30146
Dining Hall~
@ -1384,13 +1384,13 @@ The dining hall continues west.
~
0 -1 30145
E
food~
Believe me, you don't want to look at that!
~
E
students poor~
You feel sorry for them.
~
E
food~
Believe me, you don't want to look at that!
~
S
#30147
Dining Hall~
@ -1411,13 +1411,13 @@ The dining hall continues east.
~
0 -1 30148
E
food~
Believe me, you don't want to look at that!
~
E
students poor~
You feel sorry for them.
~
E
food~
Believe me, you don't want to look at that!
~
S
#30148
Dining Hall~
@ -1443,13 +1443,13 @@ The dining hall continues west.
~
0 -1 30147
E
food~
Believe me, you don't want to look at that!
~
E
students poor~
You feel sorry for them.
~
E
food~
Believe me, you don't want to look at that!
~
S
#30149
Kitchen~
@ -1470,13 +1470,13 @@ There is a storeroom beyond the door to the south.
door doorway~
1 -1 30150
E
food~
Believe me, you don't want to look at that!
~
E
door doorway~
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
#30150
A Storeroom~
@ -1491,16 +1491,16 @@ These stairs lead back to the door to the kitchen.
door doorway~
1 -1 30149
E
food~
Well, it's food.
door doorway~
It's a door. It has a nice steel frame surrounding a metallic door.
~
E
spam pre-made packages ingredients uninteresting stuff~
It's rather uninteresting.
~
E
door doorway~
It's a door. It has a nice steel frame surrounding a metallic door.
food~
Well, it's food.
~
S
#30151
@ -1522,13 +1522,13 @@ The kitchen continues west.
~
0 -1 30149
E
door doorway~
You stare intently at the door. Its wooden frame enthrals you.
~
E
food~
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
#30152
Stairway~
@ -1829,13 +1829,13 @@ The only way out is down.
~
0 -1 30165
E
zorpa~
You see nothing special. Now what is a zorpa anyways?
~
E
moshing mosh~
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
#30167
The Infobank~
@ -1856,17 +1856,17 @@ D5
plank~
1 -1 30171
E
map~
This map shows absolutely nothing, further proving the value of student
governments to you.
~
E
list~
The list reads:
<name scratched out> President
<name scratched out> Vice-President
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
#30168
The Games Room~
@ -1899,34 +1899,6 @@ You can see the central annex to the east.
~
0 -1 30137
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
The Special Hidden Room~
This room is completely empty except for the things you can see in it. The
@ -1957,6 +1929,34 @@ pamphlet leaflet photograph photo~
even your stomach... Blech!
~
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
#30173
De-Tox Unit~
This room seems to be the place where people get "detoxified". Although it
@ -2002,15 +2002,15 @@ be interesting.
~
0 -1 30180
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~
These are awards for various Engineering competitions which the university
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
#30175
Hallway~
@ -2047,9 +2047,12 @@ The hallway you probably entered from is handily located to the west.
~
0 -1 30175
E
stage~
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.
goalie~
How did you know it was a goalie stick? Have you been reading the keywords?
~
E
crest~
The crest seems to be the crest belonging to the class of `97.
~
E
hockey stick~
@ -2057,12 +2060,9 @@ hockey stick~
crest prominently displayed.
~
E
crest~
The crest seems to be the crest belonging to the class of `97.
~
E
goalie~
How did you know it was a goalie stick? Have you been reading the keywords?
stage~
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.
~
S
#30177
@ -2270,13 +2270,13 @@ This leads into the building.
door~
2 30101 30178
E
pathway~
The path is well worn, but there are no discernible footsteps upon it.
~
E
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
#30188
A Pathway~

View file

@ -1,6 +1,6 @@
#30200
The Top Of The Greasepole~
You've made it to the top! All you have to do now is get down...
The Top of the Greasepole~
You've made it to the top! All you have to do now is get down.
~
302 4 0 0 0 5
D5
@ -9,6 +9,11 @@ It's a long slide down.
~
0 -1 30192
E
pole greasepole~
The pole still looks pretty bad, but it doesn't look quite as bad as before.
~
E
info credits~
See zone description room for Campus.
Zone 302 is linked to the following zones:
@ -48,11 +53,6 @@ Links: 64e to catacombs
(Mobs Stay_Zone flags have all been disabled to allow free access between
301, 302 and 303. Please ensure that any entrances into the area are flagged
nomob to keep them in. - Parna for TBAMud.)
~
E
pole greasepole~
The pole still looks pretty bad, but it doesn't look quite as bad as before.
~
S
#30201
@ -71,13 +71,13 @@ D2
~
0 -1 30142
E
mail~
Why are you trying to look at the mail, it's private!
~
E
hooks hook key keys~
Unfortunately you don't see any keys hanging off of any of the hooks.
~
E
mail~
Why are you trying to look at the mail, it's private!
~
S
#30202
Main Office~
@ -92,9 +92,10 @@ This way leads back to the reception desk.
door~
1 30103 30201
E
chair~
The chair is not unusual in any way whatsoever. The chair is in excellent
condition.
filing cabinet files~
Looking through the files you see that Wally World was originally slated to
have at least eleven levels but the designers got sick and tired of it and gave
up after just a few levels.
~
E
desk~
@ -102,10 +103,9 @@ desk~
excellent condition.
~
E
filing cabinet files~
Looking through the files you see that Wally World was originally slated to
have at least eleven levels but the designers got sick and tired of it and gave
up after just a few levels.
chair~
The chair is not unusual in any way whatsoever. The chair is in excellent
condition.
~
S
#30203
@ -230,14 +230,14 @@ You can't tell where this leads.
door~
1 -1 30210
E
door~
The door on the west has the number 206 and the door on the east, 205.
~
E
floor carpet~
This is a nice, groovy, red patterned carpet which extends all the way down
the hall.
~
E
door~
The door on the west has the number 206 and the door on the east, 205.
~
S
#30209
Private Room 205~
@ -300,15 +300,15 @@ You can't tell where this leads.
door~
1 -1 30213
E
door~
The door on the west has the number 204 and the door on the east, 203 while
the door to the north has the number 201.
~
E
floor carpet~
This is a nice, groovy, red patterned carpet which extends all the way down
the hall.
~
E
door~
The door on the west has the number 204 and the door on the east, 203 while
the door to the north has the number 201.
~
S
#30212
Private Room 203~
@ -388,14 +388,14 @@ You can't tell where this leads.
door~
1 -1 30217
E
door~
The door on the west has the number 208 and the door on the east, 207.
~
E
floor carpet~
This is a nice, groovy, red patterned carpet which extends all the way down
the hall.
~
E
door~
The door on the west has the number 208 and the door on the east, 207.
~
S
#30216
Private Room 207~
@ -458,15 +458,15 @@ You can't tell where this leads.
door~
1 -1 30220
E
door~
The door on the west has the number 210 and the door on the east, 209 and the
door to the south has the number 202.
~
E
floor carpet~
This is a nice, groovy, red patterned carpet which extends all the way down
the hall.
~
E
door~
The door on the west has the number 210 and the door on the east, 209 and the
door to the south has the number 202.
~
S
#30219
Private Room 209~
@ -654,14 +654,14 @@ The trapdoor leads up... beyond that, you aren't sure where it goes.
trapdoor door~
1 -1 30233
E
trapdoor~
The trapdoor is neatly fastened with a small hook.
~
E
desk chair plush~
The desk and chairs are neatly arranged as if in preparation for an upcoming
meeting or something of the sort.
~
E
trapdoor~
The trapdoor is neatly fastened with a small hook.
~
S
#30229
Hallway~
@ -770,13 +770,13 @@ A chute leads down from this room.
~
0 -1 30235
E
chute~
The chute is rather smooth and looks to be a fun ride.
~
E
grate~
Beyond the grate you can see the attic.
~
E
chute~
The chute is rather smooth and looks to be a fun ride.
~
S
#30235
The Chute~
@ -871,13 +871,13 @@ An exit from this hellhole.
~
0 -1 30240
E
mess~
Need you ask?
~
E
hell hole hellhole~
Never seen one before?
~
E
mess~
Need you ask?
~
S
#30240
The Ghetto~
@ -897,13 +897,13 @@ A run-down house lies to the west.
~
0 -1 30239
E
house run-down~
It's in bad shape.
~
E
overturned police policemobile mobile~
It is blocking the road quite nicely. Maybe it is meant to impede passage.
~
E
house run-down~
It's in bad shape.
~
S
#30241
The Ghetto Intersection~
@ -1344,16 +1344,16 @@ The auditorium is to the north.
~
0 -1 30259
E
drab brown curtains curtain~
They are just your average, everyday, drab brown curtains.
sturdy wooden plank planks~
They are sturdy. They are wooden. They are planks.
~
E
cords cord pulley pulleys~
Hey! It can make you look like you are flying!
~
E
sturdy wooden plank planks~
They are sturdy. They are wooden. They are planks.
drab brown curtains curtain~
They are just your average, everyday, drab brown curtains.
~
S
#30262
@ -1403,13 +1403,13 @@ It's the same stairwell.
~
0 -1 30257
E
cobweb cobwebs web webs~
Don't disturb them now!
~
E
huge stone door~
The huge stone door looks very inviting.
~
E
cobweb cobwebs web webs~
Don't disturb them now!
~
S
#30265
The Grant Hall Clock~
@ -1785,10 +1785,6 @@ It is too dark to tell.
~
0 -1 30276
E
door~
This door is covered with all types of non-magical sigils.
~
E
sigils~
The sigils seem to form some strange shapes:
SSSSS
@ -1805,6 +1801,10 @@ sigils~
SSSSS
I wonder what it could be?
~
E
door~
This door is covered with all types of non-magical sigils.
~
S
#30281
A Classroom~
@ -1851,13 +1851,13 @@ You are repulsed by this exit since the exit to the east is well lit.
~
0 -1 30274
E
light~
It's nice, warm, and inviting.
~
E
dark~
Are you mad?
~
E
light~
It's nice, warm, and inviting.
~
S
#30283
The Exit~
@ -1875,13 +1875,13 @@ Back into darkness, I don't think so!
~
0 -1 30282
E
light~
It's nice, warm, and inviting.
~
E
dark~
Are you mad?
~
E
light~
It's nice, warm, and inviting.
~
S
#30284
Mob Chute A~
@ -1916,10 +1916,6 @@ This is just an exit.
~
0 -1 30106
E
door~
This door is covered with all types of non-magical sigils.
~
E
sigils~
The sigils seem to form some strange shapes:
MMM MMM OOO OOO !!
@ -1929,6 +1925,10 @@ sigils~
MM M MM OO OO OO OO
MM MM OOO OOO !!
~
E
door~
This door is covered with all types of non-magical sigils.
~
S
#30285
Mob Chute B~

View file

@ -105,10 +105,10 @@ S
#34306
The Social Gathering Room~
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
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
D0
@ -159,10 +159,10 @@ D3
S
#34308
Eastern Foyer~
This is the Eastern End of the Gathering Hall. This foyer continues to the
east into what appears to be a hallway and west into a circular central room.
Several pillars line the room here, Archways north and south lead into the
Immortal Board Room and the Mortal Board Room.
You are in the Eastern End of the Gathering Hall. Several pillars line this
room. The foyer continues east into what looks like a hallway and west into a
circular central room. Archways north and south lead into the Immortal Board
Room and the Mortal Board Room.
~
343 24 0 0 0 0
D0

View file

@ -103,8 +103,6 @@ E 1 30135 4 16 (a T-square of Death)
O 0 30100 1 30176 (a red key)
O 0 30101 1 30186 (a brass key)
O 0 30102 5 30150 (an Oreo(tm) cookie)
O 0 30111 99 30172 (a condom)
O 0 30122 8 30171 (Magebane)
O 0 30129 1 30110 (the extension cord)
O 0 30129 1 30111 (the extension cord)
O 0 30129 1 30112 (the extension cord)
@ -129,7 +127,6 @@ D 0 30155 1 1 (Locker Room)
D 0 30165 0 1 (Campus Pub Stairwell)
D 0 30141 2 1 (Campus Bookstore)
D 0 30167 5 1 (The Infobank)
D 0 30171 4 1 (The Special Hidden Room)
D 0 30177 0 1 (Hallway)
D 0 30179 2 1 (Library)
D 0 30178 3 2 (The Back Exit)

View file

@ -2,6 +2,8 @@
Matrix of C.A.W.~
Campus II~
30200 30299 30 2
R 0 30200 30112 -1 (a tam)
O 1 30112 99 30200 (a tam)
M 0 30105 4 30284 (Security)
E 1 30115 99 16 (a flashlight)
M 0 30105 4 30284 (Security)
@ -32,8 +34,6 @@ M 0 30132 1 30284 (Chris)
M 0 30137 1 30284 (Alex)
M 0 30138 1 30284 (Steve)
M 0 30145 10 30284 (a copy of Golden World)
R 0 30200 30112 -1 (a tam)
O 1 30112 99 30200 (a tam)
M 0 30139 1 30245 (Bob the storekeeper)
G 1 30136 99 -1 (a pale apple)
G 1 30140 99 -1 (a can of PopCoke)

View file

@ -1,6 +1,6 @@
#4
Unknown~
Jade Forest~
trunks shaoden~
Rename~
400 499 30 2 d 0 0 0 10 25
M 0 481 1 481 (Zachary)
G 1 403 99 -1 (rawhide whip)

View file

@ -1,5 +1,5 @@
#6
Unknown~
q~
Sea of Souls~
600 699 30 2 d 0 0 0 10 25
M 0 600 1 600 (a snail)

81
power_curve.ipynb Normal file

File diff suppressed because one or more lines are too long

26
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.27)
# Set the project name
project(circle)
# Global definitions
if(MSVC)
# using Visual Studio C++
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
endif()
# circle itself
file(GLOB CIRCLE_SOURCES
"*.h"
"*.c"
)
add_executable(circle ${CIRCLE_SOURCES})
if(MSVC)
target_link_libraries(circle wsock32.lib)
set_target_properties(circle PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/.."
)
endif()

View file

@ -20,8 +20,8 @@ CFLAGS = @CFLAGS@ $(MYFLAGS) $(PROFILE)
LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@
SRCFILES := act.comm.c act.informative.c act.item.c act.movement.c act.offensive.c act.other.c act.social.c act.wizard.c aedit.c asciimap.c ban.c boards.c bsd-snprintf.c castle.c cedit.c class.c comm.c config.c constants.c db.c dg_comm.c dg_db_scripts.c dg_event.c dg_handler.c dg_misc.c dg_mobcmd.c dg_objcmd.c dg_olc.c dg_scripts.c dg_triggers.c dg_variables.c dg_wldcmd.c fight.c genmob.c genobj.c genolc.c genqst.c genshp.c genwld.c genzon.c graph.c handler.c hedit.c house.c ibt.c improved-edit.c interpreter.c limits.c lists.c magic.c mail.c medit.c mobact.c modify.c msgedit.c mud_event.c oasis.c oasis_copy.c oasis_delete.c oasis_list.c objsave.c oedit.c players.c prefedit.c protocol.c qedit.c quest.c random.c redit.c sedit.c shop.c spec_assign.c spec_procs.c spell_parser.c spells.c tedit.c utils.c weather.c zedit.c zmalloc.c
OBJFILES := act.comm.o act.informative.o act.item.o act.movement.o act.offensive.o act.other.o act.social.o act.wizard.o aedit.o asciimap.o ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o comm.o config.o constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o dg_handler.o dg_misc.o dg_mobcmd.o dg_objcmd.o dg_olc.o dg_scripts.o dg_triggers.o dg_variables.o dg_wldcmd.o fight.o genmob.o genobj.o genolc.o genqst.o genshp.o genwld.o genzon.o graph.o handler.o hedit.o house.o ibt.o improved-edit.o interpreter.o limits.o lists.o magic.o mail.o medit.o mobact.o modify.o msgedit.o mud_event.o oasis.o oasis_copy.o oasis_delete.o oasis_list.o objsave.o oedit.o players.o prefedit.o protocol.o qedit.o quest.o random.o redit.o sedit.o shop.o spec_assign.o spec_procs.o spell_parser.o spells.o tedit.o utils.o weather.o zedit.o zmalloc.o
SRCFILES := $(shell ls *.c | sort)
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
default: all

56
src/Makefile.macOS Normal file
View file

@ -0,0 +1,56 @@
# tbaMUD Makefile.in - Makefile template used by 'configure'
# Clean-up provided by seqwith.
# C compiler to use
CC = gcc
# Any special flags you want to pass to the compiler
MYFLAGS = -Wall -Wno-char-subscripts -Wno-invalid-source-encoding -DMEMORY_DEBUG
#flags for profiling (see hacker.doc for more information)
PROFILE =
##############################################################################
# Do Not Modify Anything Below This Line (unless you know what you're doing) #
##############################################################################
BINDIR = ../bin
CFLAGS = -g -O0 $(MYFLAGS) $(PROFILE)
LIBS =
SRCFILES := $(shell ls *.c | sort)
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
default: all
all: .accepted
$(MAKE) $(BINDIR)/circle
$(MAKE) utils
.accepted:
@./licheck less
utils: .accepted
(cd util; $(MAKE) all)
circle:
$(MAKE) $(BINDIR)/circle
$(BINDIR)/circle : $(OBJFILES)
$(CC) -o $(BINDIR)/circle $(PROFILE) $(OBJFILES) $(LIBS)
$%.o: %.c
$(CC) $< $(CFLAGS) -c -o $@
clean:
rm -f *.o depend
# Dependencies for the object files (automagically generated with
# gcc -MM)
depend:
$(CC) -MM *.c > depend
-include depend

View file

@ -51,7 +51,7 @@ static void perform_mortal_where(struct char_data *ch, char *arg);
static void print_object_location(int num, struct obj_data *obj, struct char_data *ch, int recur);
/* Subcommands */
/* For show_obj_to_char 'mode'. /-- arbitrary */
/* For show_obj_to_char 'mode'. /-- arbitrary */
#define SHOW_OBJ_LONG 0
#define SHOW_OBJ_SHORT 1
#define SHOW_OBJ_ACTION 2
@ -125,7 +125,7 @@ static void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mod
snprintf(notebuf, sizeof(notebuf), "There is something written on it:\r\n\r\n%s", obj->action_description);
page_string(ch->desc, notebuf, TRUE);
} else
send_to_char(ch, "It's blank.\r\n");
send_to_char(ch, "It's blank.\r\n");
return;
case ITEM_DRINKCON:
@ -225,14 +225,14 @@ static void diag_char_to_char(struct char_data *i, struct char_data *ch)
byte percent;
const char *text;
} diagnosis[] = {
{ 100, "is in excellent condition." },
{ 90, "has a few scratches." },
{ 75, "has some small wounds and bruises." },
{ 50, "has quite a few wounds." },
{ 30, "has some big nasty wounds and scratches." },
{ 15, "looks pretty hurt." },
{ 0, "is in awful condition." },
{ -1, "is bleeding awfully from big wounds." },
{ 100, "is in excellent condition." },
{ 90, "has a few scratches." },
{ 75, "has some small wounds and bruises." },
{ 50, "has quite a few wounds." },
{ 30, "has some big nasty wounds and scratches." },
{ 15, "looks pretty hurt." },
{ 0, "is in awful condition." },
{ -1, "is bleeding awfully from big wounds." },
};
int percent, ar_index;
const char *pers = PERS(i, ch);
@ -240,7 +240,7 @@ static void diag_char_to_char(struct char_data *i, struct char_data *ch)
if (GET_MAX_HIT(i) > 0)
percent = (100 * GET_HIT(i)) / GET_MAX_HIT(i);
else
percent = -1; /* How could MAX_HIT be < 1?? */
percent = -1; /* How could MAX_HIT be < 1?? */
for (ar_index = 0; diagnosis[ar_index].percent >= 0; ar_index++)
if (percent >= diagnosis[ar_index].percent)
@ -269,12 +269,12 @@ static void look_at_char(struct char_data *i, struct char_data *ch)
found = TRUE;
if (found) {
send_to_char(ch, "\r\n"); /* act() does capitalization. */
send_to_char(ch, "\r\n"); /* act() does capitalization. */
act("$n is using:", FALSE, i, 0, ch, TO_VICT);
for (j = 0; j < NUM_WEARS; j++)
if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j))) {
send_to_char(ch, "%s", wear_where[j]);
show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT);
send_to_char(ch, "%s", wear_where[j]);
show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT);
}
}
if (ch != i && (IS_THIEF(ch) || GET_LEVEL(ch) >= LVL_IMMORT)) {
@ -300,7 +300,7 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS)) {
if (IS_NPC(i))
send_to_char(ch, "[%d] ", GET_MOB_VNUM(i));
send_to_char(ch, "[%d] ", GET_MOB_VNUM(i));
if (SCRIPT(i) && TRIGGERS(SCRIPT(i))) {
if (!TRIGGERS(SCRIPT(i))->next)
send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i))));
@ -312,12 +312,12 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (GROUP(i)) {
if (GROUP(i) == GROUP(ch))
send_to_char(ch, "(%s%s%s) ", CBGRN(ch, C_NRM),
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
else
send_to_char(ch, "(%s%s%s) ", CBRED(ch, C_NRM),
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
}
if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == GET_DEFAULT_POS(i)) {
@ -326,9 +326,9 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) {
if (IS_EVIL(i))
send_to_char(ch, "(Red Aura) ");
send_to_char(ch, "(Red Aura) ");
else if (IS_GOOD(i))
send_to_char(ch, "(Blue Aura) ");
send_to_char(ch, "(Blue Aura) ");
}
send_to_char(ch, "%s", i->player.long_descr);
@ -361,24 +361,24 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (GET_POS(i) != POS_FIGHTING) {
if (!SITTING(i))
send_to_char(ch, "%s", positions[(int) GET_POS(i)]);
else {
furniture = SITTING(i);
send_to_char(ch, " is %s upon %s.", (GET_POS(i) == POS_SLEEPING ?
else {
furniture = SITTING(i);
send_to_char(ch, " is %s upon %s.", (GET_POS(i) == POS_SLEEPING ?
"sleeping" : (GET_POS(i) == POS_RESTING ? "resting" : "sitting")),
OBJS(furniture, ch));
}
}
} else {
if (FIGHTING(i)) {
send_to_char(ch, " is here, fighting ");
if (FIGHTING(i) == ch)
send_to_char(ch, "YOU!");
send_to_char(ch, "YOU!");
else {
if (IN_ROOM(i) == IN_ROOM(FIGHTING(i)))
send_to_char(ch, "%s!", PERS(FIGHTING(i), ch));
else
send_to_char(ch, "someone who has already left!");
if (IN_ROOM(i) == IN_ROOM(FIGHTING(i)))
send_to_char(ch, "%s!", PERS(FIGHTING(i), ch));
else
send_to_char(ch, "someone who has already left!");
}
} else /* NIL fighting pointer */
} else /* NIL fighting pointer */
send_to_char(ch, " is here struggling with thin air.");
}
@ -402,13 +402,13 @@ static void list_char_to_char(struct char_data *list, struct char_data *ch)
if (ch != i) {
/* hide npcs whose description starts with a '.' from non-holylighted people - Idea from Elaseth of TBA */
if (!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT) &&
IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.')
IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.')
continue;
send_to_char(ch, "%s", CCYEL(ch, C_NRM));
if (CAN_SEE(ch, i))
list_one_char(i, ch);
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch) &&
AFF_FLAGGED(i, AFF_INFRAVISION))
AFF_FLAGGED(i, AFF_INFRAVISION))
send_to_char(ch, "You see a pair of glowing red eyes looking your way.\r\n");
send_to_char(ch, "%s", CCNRM(ch, C_NRM));
}
@ -425,12 +425,12 @@ static void do_auto_exits(struct char_data *ch)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && !CONFIG_DISP_CLOSED_DOORS)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT))
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT))
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))
send_to_char(ch, "%s(%s)%s ", EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? CCWHT(ch, C_NRM) : CCRED(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN))
send_to_char(ch, "%s%s%s ", CCWHT(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
send_to_char(ch, "%s(%s)%s ", EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? CCWHT(ch, C_NRM) : CCRED(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN))
send_to_char(ch, "%s%s%s ", CCWHT(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else
send_to_char(ch, "\t(%s\t) ", autoexits[door]);
slen++;
@ -443,44 +443,50 @@ ACMD(do_exits)
{
int door, len = 0;
if (AFF_FLAGGED(ch, AFF_BLIND) && GET_LEVEL(ch) < LVL_IMMORT) {
if (AFF_FLAGGED(ch, AFF_BLIND) && GET_LEVEL(ch) < LVL_IMMORT)
{
send_to_char(ch, "You can't see a damned thing, you're blind!\r\n");
return;
}
send_to_char(ch, "Obvious exits:\r\n");
for (door = 0; door < DIR_COUNT; door++) {
for (door = 0; door < DIR_COUNT; door++)
{
if (!EXIT(ch, door) || EXIT(ch, door)->to_room == NOWHERE)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && !CONFIG_DISP_CLOSED_DOORS)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT))
continue;
continue;
len++;
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS) && !EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))
send_to_char(ch, "%-5s - [%5d]%s %s\r\n", dirs[door], GET_ROOM_VNUM(EXIT(ch, door)->to_room),
EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? " [HIDDEN]" : "", world[EXIT(ch, door)->to_room].name);
else if (CONFIG_DISP_CLOSED_DOORS && EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED)) {
/* But we tell them the door is closed */
{
send_to_char(ch, "%-5s -[%5d]%s %s\r\n", dirs[door], GET_ROOM_VNUM(EXIT(ch, door)->to_room),
EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? "[HIDDEN]" : "", world[EXIT(ch, door)->to_room].name);
}
else if (CONFIG_DISP_CLOSED_DOORS && EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))
{
/*But we tell them the door is closed */
send_to_char(ch, "%-5s - The %s is closed%s\r\n", dirs[door],
(EXIT(ch, door)->keyword)? fname(EXIT(ch, door)->keyword) : "opening",
EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? " and hidden." : ".");
}
(EXIT(ch, door)->keyword) ? fname(EXIT(ch, door)->keyword) : "opening",
EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? " and hidden." : ".");
}
else
{
send_to_char(ch, "%-5s - %s\r\n", dirs[door], IS_DARK(EXIT(ch, door)->to_room) &&
!CAN_SEE_IN_DARK(ch) ? "Too dark to tell." : world[EXIT(ch, door)->to_room].name);
!CAN_SEE_IN_DARK(ch) ? "Too dark to tell." : world[EXIT(ch, door)->to_room].name);
}
}
if (!len)
send_to_char(ch, " None.\r\n");
if (!len)
send_to_char(ch, " None.\r\n");
}
void look_at_room(struct char_data *ch, int ignore_brief)
{
trig_data *t;
trig_data * t;
struct room_data *rm = &world[IN_ROOM(ch)];
room_vnum target_room;
@ -489,20 +495,22 @@ void look_at_room(struct char_data *ch, int ignore_brief)
if (!ch->desc)
return;
if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) {
if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)){
send_to_char(ch, "It is pitch black...\r\n");
return;
} else if (AFF_FLAGGED(ch, AFF_BLIND) && GET_LEVEL(ch) < LVL_IMMORT) {
}
else if (AFF_FLAGGED(ch, AFF_BLIND) && GET_LEVEL(ch) < LVL_IMMORT) {
send_to_char(ch, "You see nothing but infinite darkness...\r\n");
return;
}
send_to_char(ch, "%s", CCCYN(ch, C_NRM));
send_to_char(ch, "%s", CCYEL(ch, C_NRM));
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS)) {
char buf[MAX_STRING_LENGTH];
sprintbitarray(ROOM_FLAGS(IN_ROOM(ch)), room_bits, RF_ARRAY_MAX, buf);
send_to_char(ch, "[%5d] ", GET_ROOM_VNUM(IN_ROOM(ch)));
send_to_char(ch, "%s [ %s] [ %s ]", world[IN_ROOM(ch)].name, buf, sector_types[world[IN_ROOM(ch)].sector_type]);
send_to_char(ch, "%s[ %s][ %s ]", world[IN_ROOM(ch)].name, buf, sector_types[world[IN_ROOM(ch)].sector_type]);
if (SCRIPT(rm)) {
send_to_char(ch, "[T");
@ -513,21 +521,23 @@ void look_at_room(struct char_data *ch, int ignore_brief)
}
else
send_to_char(ch, "%s", world[IN_ROOM(ch)].name);
send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if(!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room);
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room);
else
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
}
/* autoexits */
/*autoexits */
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
do_auto_exits(ch);
/* now list characters & objects */
/*now list characters &objects */
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE);
list_char_to_char(world[IN_ROOM(ch)].people, ch);
}
@ -557,35 +567,35 @@ static void look_in_obj(struct char_data *ch, char *arg)
if (!*arg)
send_to_char(ch, "Look in what?\r\n");
else if (!(bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM |
FIND_OBJ_EQUIP, ch, &dummy, &obj))) {
FIND_OBJ_EQUIP, ch, &dummy, &obj))) {
send_to_char(ch, "There doesn't seem to be %s %s here.\r\n", AN(arg), arg);
} else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) &&
(GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) &&
(GET_OBJ_TYPE(obj) != ITEM_CONTAINER))
(GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) &&
(GET_OBJ_TYPE(obj) != ITEM_CONTAINER))
send_to_char(ch, "There's nothing inside that!\r\n");
else {
if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) {
if (OBJVAL_FLAGGED(obj, CONT_CLOSED) && (GET_LEVEL(ch) < LVL_IMMORT || !PRF_FLAGGED(ch, PRF_NOHASSLE)))
send_to_char(ch, "It is closed.\r\n");
send_to_char(ch, "It is closed.\r\n");
else {
send_to_char(ch, "%s", fname(obj->name));
switch (bits) {
case FIND_OBJ_INV:
send_to_char(ch, " (carried): \r\n");
break;
case FIND_OBJ_ROOM:
send_to_char(ch, " (here): \r\n");
break;
case FIND_OBJ_EQUIP:
send_to_char(ch, " (used): \r\n");
break;
}
send_to_char(ch, "%s", fname(obj->name));
switch (bits) {
case FIND_OBJ_INV:
send_to_char(ch, " (carried): \r\n");
break;
case FIND_OBJ_ROOM:
send_to_char(ch, " (here): \r\n");
break;
case FIND_OBJ_EQUIP:
send_to_char(ch, " (used): \r\n");
break;
}
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
}
} else { /* item must be a fountain or drink container */
} else { /* item must be a fountain or drink container */
if ((GET_OBJ_VAL(obj, 1) == 0) && (GET_OBJ_VAL(obj, 0) != -1))
send_to_char(ch, "It is empty.\r\n");
send_to_char(ch, "It is empty.\r\n");
else {
if (GET_OBJ_VAL(obj, 0) < 0)
{
@ -593,14 +603,15 @@ static void look_in_obj(struct char_data *ch, char *arg)
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's full of a %s liquid.\r\n", buf2);
}
else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0))
else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0))
send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */
else {
else
{
char buf2[MAX_STRING_LENGTH];
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2);
}
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2);
}
}
}
}
@ -637,14 +648,14 @@ static void look_at_target(struct char_data *ch, char *arg)
}
bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP |
FIND_CHAR_ROOM, ch, &found_char, &found_obj);
FIND_CHAR_ROOM, ch, &found_char, &found_obj);
/* Is the target a character? */
if (found_char != NULL) {
look_at_char(found_char, ch);
if (ch != found_char) {
if (CAN_SEE(found_char, ch))
act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT);
act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT);
act("$n looks at $N.", TRUE, ch, 0, found_char, TO_NOTVICT);
}
return;
@ -666,16 +677,16 @@ static void look_at_target(struct char_data *ch, char *arg)
for (j = 0; j < NUM_WEARS && !found; j++)
if (GET_EQ(ch, j) && CAN_SEE_OBJ(ch, GET_EQ(ch, j)))
if ((desc = find_exdesc(arg, GET_EQ(ch, j)->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
send_to_char(ch, "%s", desc);
found = TRUE;
}
/* Does the argument match an extra desc in the char's inventory? */
for (obj = ch->carrying; obj && !found; obj = obj->next_content) {
if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
send_to_char(ch, "%s", desc);
found = TRUE;
}
}
@ -683,8 +694,8 @@ static void look_at_target(struct char_data *ch, char *arg)
for (obj = world[IN_ROOM(ch)].contents; obj && !found; obj = obj->next_content)
if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
send_to_char(ch, "%s", desc);
found = TRUE;
}
/* If an object was found back in generic_find */
@ -714,7 +725,7 @@ ACMD(do_look)
send_to_char(ch, "You can't see a damned thing, you're blind!\r\n");
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) {
send_to_char(ch, "It is pitch black...\r\n");
list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */
list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */
} else {
char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
@ -722,12 +733,12 @@ ACMD(do_look)
if (subcmd == SCMD_READ) {
if (!*arg)
send_to_char(ch, "Read what?\r\n");
send_to_char(ch, "Read what?\r\n");
else
look_at_target(ch, strcpy(tempsave, arg));
look_at_target(ch, strcpy(tempsave, arg));
return;
}
if (!*arg) /* "look" alone, without an argument at all */
if (!*arg) /* "look" alone, without an argument at all */
look_at_room(ch, 1);
else if (is_abbrev(arg, "in"))
look_in_obj(ch, arg2);
@ -767,15 +778,15 @@ ACMD(do_examine)
}
/* look_at_target() eats the number. */
look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */
look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */
generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_CHAR_ROOM |
FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object);
FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object);
if (tmp_object) {
if ((GET_OBJ_TYPE(tmp_object) == ITEM_DRINKCON) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) {
(GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) {
send_to_char(ch, "When you look inside, you see:\r\n");
look_in_obj(ch, arg);
}
@ -807,18 +818,18 @@ ACMD(do_score)
send_to_char(ch, "\r\n");
send_to_char(ch, "You have %d(%d) hit, %d(%d) mana and %d(%d) movement points.\r\n",
GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch),
GET_MOVE(ch), GET_MAX_MOVE(ch));
GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch),
GET_MOVE(ch), GET_MAX_MOVE(ch));
send_to_char(ch, "Your armor class is %d/10, and your alignment is %d.\r\n",
compute_armor_class(ch), GET_ALIGNMENT(ch));
compute_armor_class(ch), GET_ALIGNMENT(ch));
send_to_char(ch, "You have %d exp, %d gold coins, and %d questpoints.\r\n",
GET_EXP(ch), GET_GOLD(ch), GET_QUESTPOINTS(ch));
GET_EXP(ch), GET_GOLD(ch), GET_QUESTPOINTS(ch));
if (GET_LEVEL(ch) < LVL_IMMORT)
send_to_char(ch, "You need %d exp to reach your next level.\r\n",
level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch));
level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch));
send_to_char(ch, "You have earned %d quest points.\r\n", GET_QUESTPOINTS(ch));
send_to_char(ch, "You have completed %d quest%s, ",
@ -837,13 +848,13 @@ ACMD(do_score)
}
playing_time = *real_time_passed((time(0) - ch->player.time.logon) +
ch->player.time.played, 0);
ch->player.time.played, 0);
send_to_char(ch, "You have been playing for %d day%s and %d hour%s.\r\n",
playing_time.day, playing_time.day == 1 ? "" : "s",
playing_time.hours, playing_time.hours == 1 ? "" : "s");
send_to_char(ch, "This ranks you as %s %s (level %d).\r\n",
GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch));
GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch));
switch (GET_POS(ch)) {
case POS_DEAD:
@ -974,8 +985,8 @@ ACMD(do_time)
weekday = ((35 * time_info.month) + day) % 7;
send_to_char(ch, "It is %d o'clock %s, on %s.\r\n",
(time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12),
time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]);
(time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12),
time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]);
/* Peter Ajamian supplied the following as a fix for a bug introduced in the
* ordinal display that caused 11, 12, and 13 to be incorrectly displayed as
@ -997,7 +1008,7 @@ ACMD(do_time)
}
}
send_to_char(ch, "The %d%s Day of the %s, Year %d.\r\n",
day, suf, month_name[time_info.month], time_info.year);
day, suf, month_name[time_info.month], time_info.year);
}
ACMD(do_weather)
@ -1012,8 +1023,8 @@ ACMD(do_weather)
if (OUTSIDE(ch))
{
send_to_char(ch, "The sky is %s and %s.\r\n", sky_look[weather_info.sky],
weather_info.change >= 0 ? "you feel a warm wind from south" :
"your foot tells you bad weather is due");
weather_info.change >= 0 ? "you feel a warm wind from south" :
"your foot tells you bad weather is due");
if (GET_LEVEL(ch) >= LVL_GOD)
send_to_char(ch, "Pressure: %d (change: %d), Sky: %d (%s)\r\n",
weather_info.pressure,
@ -1051,7 +1062,7 @@ int search_help(const char *argument, int level)
mid++;
if (strn_cmp(argument, help_table[mid].keywords, minlen) || level < help_table[mid].min_level)
break;
return (mid);
}
else if (chk > 0)
@ -1278,7 +1289,7 @@ ACMD(do_who)
GET_LEVEL(tch), CLASS_ABBR(tch),
GET_NAME(tch), (*GET_TITLE(tch) ? " " : ""), GET_TITLE(tch),
CCNRM(ch, C_SPR));
if (GET_INVIS_LEV(tch))
send_to_char(ch, " (i%d)", GET_INVIS_LEV(tch));
else if (AFF_FLAGGED(tch, AFF_INVISIBLE))
@ -1371,7 +1382,7 @@ ACMD(do_users)
host_search[0] = name_search[0] = '\0';
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
while (*buf) {
char buf1[MAX_INPUT_LENGTH];
@ -1381,49 +1392,49 @@ ACMD(do_users)
switch (mode) {
case 'o':
case 'k':
outlaws = 1;
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
outlaws = 1;
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'p':
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'd':
deadweight = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
deadweight = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'l':
playing = 1;
half_chop(buf1, arg, buf);
sscanf(arg, "%d-%d", &low, &high);
break;
playing = 1;
half_chop(buf1, arg, buf);
sscanf(arg, "%d-%d", &low, &high);
break;
case 'n':
playing = 1;
half_chop(buf1, name_search, buf);
break;
playing = 1;
half_chop(buf1, name_search, buf);
break;
case 'h':
playing = 1;
half_chop(buf1, host_search, buf);
break;
playing = 1;
half_chop(buf1, host_search, buf);
break;
case 'c':
playing = 1;
half_chop(buf1, arg, buf);
showclass = find_class_bitvector(arg);
break;
playing = 1;
half_chop(buf1, arg, buf);
showclass = find_class_bitvector(arg);
break;
default:
send_to_char(ch, "%s", USERS_FORMAT);
return;
} /* end of switch */
send_to_char(ch, "%s", USERS_FORMAT);
return;
} /* end of switch */
} else { /* endif */
} else { /* endif */
send_to_char(ch, "%s", USERS_FORMAT);
return;
}
} /* end while (parser) */
} /* end while (parser) */
send_to_char(ch,
"Num Class Name State Idl Login\t* Site\r\n"
"--- ------- ------------ -------------- ----- -------- ------------------------\r\n");
"Num Class Name State Idl Login\t* Site\r\n"
"--- ------- ------------ -------------- ----- -------- ------------------------\r\n");
one_argument(argument, arg);
@ -1445,7 +1456,7 @@ ACMD(do_users)
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) &&
!PLR_FLAGGED(tch, PLR_THIEF))
!PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
continue;
@ -1453,11 +1464,11 @@ ACMD(do_users)
continue;
if (d->original)
sprintf(classname, "[%2d %s]", GET_LEVEL(d->original),
CLASS_ABBR(d->original));
sprintf(classname, "[%2d %s]", GET_LEVEL(d->original),
CLASS_ABBR(d->original));
else
sprintf(classname, "[%2d %s]", GET_LEVEL(d->character),
CLASS_ABBR(d->character));
sprintf(classname, "[%2d %s]", GET_LEVEL(d->character),
CLASS_ABBR(d->character));
} else
strcpy(classname, " - ");
@ -1470,15 +1481,15 @@ ACMD(do_users)
if (d->character && STATE(d) == CON_PLAYING)
sprintf(idletime, "%5d", d->character->char_specials.timer *
SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN);
SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN);
else
strcpy(idletime, " ");
sprintf(line, "%3d %-7s %-12s %-14s %-3s %-8s ", d->desc_num, classname,
d->original && d->original->player.name ? d->original->player.name :
d->character && d->character->player.name ? d->character->player.name :
"UNDEFINED",
state, idletime, timestr);
d->original && d->original->player.name ? d->original->player.name :
d->character && d->character->player.name ? d->character->player.name :
"UNDEFINED",
state, idletime, timestr);
if (*d->host)
sprintf(line + strlen(line), "[%s]\r\n", d->host);
@ -1568,23 +1579,23 @@ static void perform_mortal_where(struct char_data *ch, char *arg)
send_to_char(ch, "Players in %s\tn.\r\n--------------------\r\n", zone_table[j].name);
for (d = descriptor_list; d; d = d->next) {
if (STATE(d) != CON_PLAYING || d->character == ch)
continue;
continue;
if ((i = (d->original ? d->original : d->character)) == NULL)
continue;
continue;
if (IN_ROOM(i) == NOWHERE || !CAN_SEE(ch, i))
continue;
continue;
if (world[IN_ROOM(ch)].zone != world[IN_ROOM(i)].zone)
continue;
continue;
send_to_char(ch, "%-20s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
}
} else { /* print only FIRST char, not all. */
} else { /* print only FIRST char, not all. */
for (i = character_list; i; i = i->next) {
if (IN_ROOM(i) == NOWHERE || i == ch)
continue;
continue;
if (!CAN_SEE(ch, i) || world[IN_ROOM(i)].zone != world[IN_ROOM(ch)].zone)
continue;
continue;
if (!isname(arg, i->player.name))
continue;
continue;
send_to_char(ch, "%-25s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
return;
}
@ -1593,7 +1604,7 @@ static void perform_mortal_where(struct char_data *ch, char *arg)
}
static void print_object_location(int num, struct obj_data *obj, struct char_data *ch,
int recur)
int recur)
{
if (num > 0)
send_to_char(ch, "O%3d. %-25s%s - ", num, obj->short_description, QNRM);
@ -1658,7 +1669,7 @@ static void perform_immort_where(struct char_data *ch, char *arg)
else
send_to_char(ch, "[TRIGS] ");
}
send_to_char(ch, "%s\r\n", QNRM);
send_to_char(ch, "%s\r\n", QNRM);
}
for (num = 0, k = object_list; k; k = k->next)
if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) {
@ -1727,7 +1738,7 @@ ACMD(do_levels)
for (i = min_lev; i < max_lev; i++) {
nlen = snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d-%-8d : ", (int)i,
level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1);
level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1);
if (len + nlen >= sizeof(buf))
break;
len += nlen;
@ -1751,7 +1762,7 @@ ACMD(do_levels)
if (len < sizeof(buf) && max_lev == LVL_IMMORT)
snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d : Immortality\r\n",
LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT));
LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT));
page_string(ch->desc, buf, TRUE);
}
@ -1939,16 +1950,17 @@ ACMD(do_toggle)
if (!GET_WIMP_LEV(ch))
strcpy(buf2, "OFF"); /* strcpy: OK */
else
sprintf(buf2, "%-3.3d", GET_WIMP_LEV(ch)); /* sprintf: OK */
snprintf(buf2, sizeof(buf2), "%-3.3d", GET_WIMP_LEV(ch)); /* thanks to Ironfist for the fix for the buffer overrun here */
if (GET_LEVEL(ch) == LVL_IMPL) {
if (GET_LEVEL(ch) == LVL_IMPL) {
send_to_char(ch,
" SlowNameserver: %-3s "
" "
" Trackthru Doors: %-3s\r\n",
" "
" Trackthru Doors: %-3s\r\n",
ONOFF(CONFIG_NS_IS_SLOW),
ONOFF(CONFIG_TRACK_T_DOORS));
ONOFF(CONFIG_NS_IS_SLOW),
ONOFF(CONFIG_TRACK_T_DOORS));
}
if (GET_LEVEL(ch) >= LVL_IMMORT) {
@ -2112,7 +2124,7 @@ ACMD(do_toggle)
for (i=0; *arg2 && *(sector_types[i]) != '\n'; i++)
if (is_abbrev(arg2, sector_types[i]))
break;
if (*(sector_types[i]) == '\n')
if (*(sector_types[i]) == '\n')
i=0;
GET_BUILDWALK_SECTOR(ch) = i;
send_to_char(ch, "Default sector type is %s\r\n", sector_types[i]);
@ -2365,9 +2377,9 @@ ACMD(do_whois)
{
CREATE(victim, struct char_data, 1);
clear_char(victim);
new_mobile_data(victim);
CREATE(victim->player_specials, struct player_special_data, 1);
if (load_char(buf, victim) > -1)

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)
{
long object_id = obj_script_id(obj);
if (!drop_otrigger(obj, ch))
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;
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 */
obj = create_money(amount);
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");
act("$n throws some gold into the air where it disappears in a puff of smoke!",
FALSE, ch, 0, 0, TO_ROOM);
obj_to_room(obj, RDR);
act("$p suddenly appears in a puff of orange smoke!", 0, 0, obj, 0, TO_ROOM);
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!",
FALSE, ch, 0, 0, TO_ROOM);
obj_to_room(obj, RDR);
act("$p suddenly appears in a puff of orange smoke!", 0, 0, obj, 0, TO_ROOM);
} else {
char buf[MAX_STRING_LENGTH];
long object_id = obj_script_id(obj);
if (!drop_wtrigger(obj, ch)) {
extract_obj(obj);
if (has_obj_by_uid_in_lookup_table(object_id))
extract_obj(obj);
return;
}
snprintf(buf, sizeof(buf), "$n drops %s.", money_desc(amount));
act(buf, TRUE, ch, 0, 0, TO_ROOM);
snprintf(buf, sizeof(buf), "$n drops %s.", money_desc(amount));
act(buf, TRUE, ch, 0, 0, TO_ROOM);
send_to_char(ch, "You drop some gold.\r\n");
obj_to_room(obj, IN_ROOM(ch));
send_to_char(ch, "You drop some gold.\r\n");
obj_to_room(obj, IN_ROOM(ch));
}
} else {
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];
int value;
long object_id = obj_script_id(obj);
if (!drop_otrigger(obj, ch))
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))
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)) {
snprintf(buf, sizeof(buf), "You can't %s $p, it must be CURSED!", sname);
act(buf, FALSE, ch, obj, 0, TO_CHAR);
@ -768,45 +779,22 @@ void weight_change_object(struct obj_data *obj, int weight)
void name_from_drinkcon(struct obj_data *obj)
{
char *new_name, *cur_name, *next;
const char *liqname;
int liqlen, cpylen;
char *new_name;
if (!obj || (GET_OBJ_TYPE(obj) != ITEM_DRINKCON && GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN))
return;
if (obj->name == obj_proto[GET_OBJ_RNUM(obj)].name)
obj->name = strdup(obj_proto[GET_OBJ_RNUM(obj)].name);
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);
/* SYSERR_DESC: From name_from_drinkcon(), this error comes about if the
* object noted (by keywords and item vnum) does not contain the liquid
* 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);
remove_from_string(obj->name, liqname);
new_name = right_trim_whitespace(obj->name);
free(obj->name);
obj->name = new_name;
}
void name_to_drinkcon(struct obj_data *obj, int type)

View file

@ -461,6 +461,9 @@ int has_key(struct char_data *ch, obj_vnum key)
{
struct obj_data *o;
if (key == NOTHING)
return (0);
for (o = ch->carrying; o; o = o->next_content)
if (GET_OBJ_VNUM(o) == key)
return (1);

View file

@ -546,7 +546,6 @@ ACMD(do_split)
if (rest) {
send_to_char(ch, "%d coin%s %s not splitable, so you keep the money.\r\n",
rest, (rest == 1) ? "" : "s", (rest == 1) ? "was" : "were");
increase_gold(ch, rest);
}
} else {
send_to_char(ch, "How many coins do you wish to split with your group?\r\n");

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->modifier)
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)) {
send_to_char(ch, "sets %s, ", affected_bits[i]);
}

View file

@ -557,7 +557,7 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
}
if (OLC_ACTION(d)->command)
free(OLC_ACTION(d)->command);
OLC_ACTION(d)->command = strdup(arg);
OLC_ACTION(d)->command = strdup(arg);
break;
@ -566,10 +566,10 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
aedit_disp_menu(d);
return;
}
if (OLC_ACTION(d)->sort_as) {
if (OLC_ACTION(d)->sort_as)
free(OLC_ACTION(d)->sort_as);
OLC_ACTION(d)->sort_as = strdup(arg);
}
OLC_ACTION(d)->sort_as = strdup(arg);
break;
case AEDIT_MIN_CHAR_POS:

View file

@ -1596,7 +1596,7 @@ static int process_output(struct descriptor_data *t)
result = write_to_descriptor(t->descriptor, osb);
if (result < 0) { /* Oops, fatal error. Bye! */
close_socket(t);
// close_socket(t); // close_socket is called after return of negative result
return (-1);
} else if (result == 0) /* Socket buffer full. Try later. */
return (0);

367
src/conf.h.macOS Normal file
View file

@ -0,0 +1,367 @@
#ifndef _CONF_H_
#define _CONF_H_
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1
/* Define if you have the vprintf function. */
#define HAVE_VPRINTF 1
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef pid_t */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define to `unsigned' if <sys/types.h> doesn't define. */
/* #undef size_t */
/* Define if you have the ANSI C header files. */
/* #undef STDC_HEADERS */
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define if we're compiling CircleMUD under any type of UNIX system. */
#define CIRCLE_UNIX 1
/* Machine-specific dependencies for running on modern macOS systems 10.13+ (High Sierra)
* Updated by Victor Augusto Borges Dias de Almeida (aka Stoneheart), 26 June 2024.
*
* Tested on:
* - macOS 10.13: High Sierra - September 25, 2017 (Latest: 10.13.6)
* - macOS 10.14: Mojave - September 24, 2018 (Latest: 10.14.6)
* - macOS 10.15: Catalina - October 7, 2019 (Latest: 10.15.7)
* - macOS 11: Big Sur - November 12, 2020 (Latest: 11.7.10)
* - macOS 12: Monterey - October 25, 2021 (Latest: 12.7)
* - macOS 13: Ventura - November 7, 2022 (Latest: 13.7)
* - macOS 14: Sonoma - November 7, 2023 (Latest: 14.3)
*
* This file works on Apple Silicon Chips (M1, M2, M3) without futher configurations. */
#if defined(__APPLE__) && defined(__MACH__)
#define CIRCLE_MAC_OS 1
#endif
/* Define if the system is capable of using crypt() to encrypt. */
#define CIRCLE_CRYPT 1
/* Define if we don't have proper support for the system's crypt(). */
/* #undef HAVE_UNSAFE_CRYPT */
/* Define is the system has struct in_addr. */
#define HAVE_STRUCT_IN_ADDR 1
/* Define to `int' if <sys/socket.h> doesn't define. */
/* #undef socklen_t */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef ssize_t */
/* Define if you have the gettimeofday function. */
#define HAVE_GETTIMEOFDAY 1
/* Define if you have the inet_addr function. */
#define HAVE_INET_ADDR 1
/* Define if you have the inet_aton function. */
#define HAVE_INET_ATON 1
/* Define if you have the select function. */
#define HAVE_SELECT 1
/* Define if you have the snprintf function. */
#define HAVE_SNPRINTF 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1
/* Define if you have the strdup function. */
#define HAVE_STRDUP 1
/* Define if you have the strerror function. */
#define HAVE_STRERROR 1
/* Define if you have the stricmp function. */
/* #undef HAVE_STRICMP */
/* Define if you have the strlcpy function. */
#ifndef CIRCLE_MAC_OS
#define HAVE_STRLCPY 1
#else
#define HAVE_STRLCPY 0
#endif
/* Define if you have the strncasecmp function. */
#define HAVE_STRNCASECMP 1
/* Define if you have the strnicmp function. */
/* #undef HAVE_STRNICMP */
/* Define if you have the strstr function. */
#define HAVE_STRSTR 1
/* Define if you have the vsnprintf function. */
#define HAVE_VSNPRINTF 1
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define if you have the <arpa/telnet.h> header file. */
#define HAVE_ARPA_TELNET_H 1
/* Define if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define if you have the <crypt.h> header file. */
/* #undef HAVE_CRYPT_H */
#ifdef CIRCLE_MAC_OS
#define HAVE_CRYPT_H 1
#endif
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if you have the <mcheck.h> header file. */
/* #undef HAVE_MCHECK_H */
#ifdef CIRCLE_MAC_OS
#define HAVE_MCHECK_H 1
#endif
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the <net/errno.h> header file. */
/* #undef HAVE_NET_ERRNO_H */
/* Define if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <sys/fcntl.h> header file. */
#define HAVE_SYS_FCNTL_H 1
/* Define if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the malloc library (-lmalloc). */
/* #undef HAVE_LIBMALLOC */
/* Check for a prototype to accept. */
/* #undef NEED_ACCEPT_PROTO */
#ifndef CIRCLE_MAC_OS
/* Check for a prototype to atoi. */
#define NEED_ATOI_PROTO
/* Check for a prototype to atol. */
#define NEED_ATOL_PROTO
#endif
/* Check for a prototype to bind. */
/* #undef NEED_BIND_PROTO */
/* Check for a prototype to bzero. */
/* #undef NEED_BZERO_PROTO */
/* Check for a prototype to chdir. */
/* #undef NEED_CHDIR_PROTO */
/* Check for a prototype to close. */
/* #undef NEED_CLOSE_PROTO */
/* Check for a prototype to crypt. */
/* #undef NEED_CRYPT_PROTO */
/* Check for a prototype to fclose. */
/* #undef NEED_FCLOSE_PROTO */
/* Check for a prototype to fcntl. */
/* #undef NEED_FCNTL_PROTO */
/* Check for a prototype to fflush. */
/* #undef NEED_FFLUSH_PROTO */
/* Check for a prototype to fprintf. */
/* #undef NEED_FPRINTF_PROTO */
/* Check for a prototype to fputc. */
/* #undef NEED_FPUTC_PROTO */
/* Check for a prototype to fputs. */
/* #undef NEED_FPUTS_PROTO */
/* Check for a prototype to fread. */
/* #undef NEED_FREAD_PROTO */
/* Check for a prototype to fscanf. */
/* #undef NEED_FSCANF_PROTO */
/* Check for a prototype to fseek. */
/* #undef NEED_FSEEK_PROTO */
/* Check for a prototype to fwrite. */
/* #undef NEED_FWRITE_PROTO */
/* Check for a prototype to getpeername. */
/* #undef NEED_GETPEERNAME_PROTO */
/* Check for a prototype to getpid. */
/* #undef NEED_GETPID_PROTO */
/* Check for a prototype to getrlimit. */
/* #undef NEED_GETRLIMIT_PROTO */
/* Check for a prototype to getsockname. */
/* #undef NEED_GETSOCKNAME_PROTO */
/* Check for a prototype to gettimeofday. */
/* #undef NEED_GETTIMEOFDAY_PROTO */
/* Check for a prototype to htonl. */
/* #undef NEED_HTONL_PROTO */
/* Check for a prototype to htons. */
/* #undef NEED_HTONS_PROTO */
/* Check for a prototype to inet_addr. */
/* #undef NEED_INET_ADDR_PROTO */
/* Check for a prototype to inet_aton. */
/* #undef NEED_INET_ATON_PROTO */
/* Check for a prototype to inet_ntoa. */
/* #undef NEED_INET_NTOA_PROTO */
/* Check for a prototype to listen. */
/* #undef NEED_LISTEN_PROTO */
/* Check for a prototype to ntohl. */
/* #undef NEED_NTOHL_PROTO */
/* Check for a prototype to perror. */
/* #undef NEED_PERROR_PROTO */
/* Check for a prototype to printf. */
/* #undef NEED_PRINTF_PROTO */
/* Check for a prototype to qsort. */
#ifndef CIRCLE_MAC_OS
#define NEED_QSORT_PROTO
#endif
/* Check for a prototype to read. */
/* #undef NEED_READ_PROTO */
/* Check for a prototype to remove. */
/* #undef NEED_REMOVE_PROTO */
/* Check for a prototype to rewind. */
/* #undef NEED_REWIND_PROTO */
/* Check for a prototype to select. */
/* #undef NEED_SELECT_PROTO */
/* Check for a prototype to setitimer. */
/* #undef NEED_SETITIMER_PROTO */
/* Check for a prototype to setrlimit. */
/* #undef NEED_SETRLIMIT_PROTO */
/* Check for a prototype to setsockopt. */
/* #undef NEED_SETSOCKOPT_PROTO */
/* Check for a prototype to snprintf. */
/* #undef NEED_SNPRINTF_PROTO */
/* Check for a prototype to socket. */
/* #undef NEED_SOCKET_PROTO */
/* Check for a prototype to sprintf. */
/* #undef NEED_SPRINTF_PROTO */
/* Check for a prototype to sscanf. */
/* #undef NEED_SSCANF_PROTO */
/* Check for a prototype to strcasecmp. */
/* #undef NEED_STRCASECMP_PROTO */
/* Check for a prototype to strdup. */
/* #undef NEED_STRDUP_PROTO */
/* Check for a prototype to strerror. */
/* #undef NEED_STRERROR_PROTO */
/* Check for a prototype to stricmp. */
#define NEED_STRICMP_PROTO
/* Check for a prototype to strlcpy. */
/* #undef NEED_STRLCPY_PROTO */
/* Check for a prototype to strncasecmp. */
/* #undef NEED_STRNCASECMP_PROTO */
/* Check for a prototype to strnicmp. */
#define NEED_STRNICMP_PROTO
/* Check for a prototype to system. */
#ifndef CIRCLE_MAC_OS
#define NEED_SYSTEM_PROTO
#endif
/* Check for a prototype to time. */
/* #undef NEED_TIME_PROTO */
/* Check for a prototype to unlink. */
/* #undef NEED_UNLINK_PROTO */
/* Check for a prototype to vsnprintf. */
/* #undef NEED_VSNPRINTF_PROTO */
/* Check for a prototype to write. */
/* #undef NEED_WRITE_PROTO */
#endif /* _CONF_H_ */

View file

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

View file

@ -1326,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[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++)
check_bitvector_names(world[room_nr].room_flags[taeller], room_bits_count, flags, "room");
@ -2873,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'. */
/* now only removes trailing ~'s -- Welcor */
point = strchr(tmp, '\0');
for (point-- ; (*point=='\r' || *point=='\n'); point--);
for (point-- ; (*point=='\r' || *point=='\n') && point > tmp; point--);
if (*point=='~') {
*point='\0';
done = 1;
} else {
*(++point) = '\r';
if (*point == '\n' || *point == '\r')
*point = '\r';
else
*(++point) = '\r';
*(++point) = '\n';
*(++point) = '\0';
}

View file

@ -151,7 +151,8 @@ long event_time(struct event *event)
/** Frees all events from event_q. */
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

View file

@ -1091,70 +1091,85 @@ int format_script(struct descriptor_data *d)
char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE];
char *sc;
size_t len = 0, nlen = 0, llen = 0;
int indent = 0, indent_next = FALSE, found_case = FALSE, i, line_num = 0, ret;
int indent = 0, indent_next = FALSE, line_num = 0, ret, i; // Declare i here
int block_stack[READ_SIZE]; // Stack to track block types
int stack_top = -1; // Initialize stack as empty
int switch_indent[READ_SIZE]; // Array to track switch indent levels
int switch_top = -1; // Index for switch_indent array
int case_indent = 0; // Track indent for case blocks
int in_switch = 0; // Flag to indicate if we're inside a switch block
if (!d->str || !*d->str)
return FALSE;
sc = strdup(*d->str); /* we work on a copy, because of strtok() */
sc = strdup(*d->str); // Work on a copy
t = strtok(sc, "\n\r");
*nsc = '\0';
while (t) {
line_num++;
skip_spaces(&t);
if (!strn_cmp(t, "if ", 3) ||
!strn_cmp(t, "switch ", 7)) {
if (!strn_cmp(t, "switch ", 7)) {
indent_next = TRUE;
} else if (!strn_cmp(t, "while ", 6)) {
found_case = TRUE; /* so you can 'break' a loop without complains */
stack_top++;
block_stack[stack_top] = 's'; // 's' for switch
switch_top++;
switch_indent[switch_top] = indent; // Save current indent level for switch
in_switch++; // We're entering a switch block
} else if (!strn_cmp(t, "case", 4) || !strn_cmp(t, "default", 7)) {
if (in_switch > 0) { // If we're inside a switch
indent = switch_indent[switch_top] + 1; // Indent cases one level under switch
indent_next = TRUE; // Indent the next line after case
case_indent = indent; // Save indent for case block
}
} else if (!strn_cmp(t, "if ", 3) || !strn_cmp(t, "while ", 6)) {
indent_next = TRUE;
} else if (!strn_cmp(t, "end", 3) ||
!strn_cmp(t, "done", 4)) {
if (!indent) {
stack_top++;
block_stack[stack_top] = 'l'; // 'l' for loop or conditional
} else if (!strn_cmp(t, "end", 3) || !strn_cmp(t, "done", 4)) {
if (stack_top < 0) {
write_to_output(d, "Unmatched 'end' or 'done' (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
indent--;
indent_next = FALSE;
if (block_stack[stack_top] == 's') {
indent = switch_indent[switch_top]; // Reset to the exact indent level where switch was declared
switch_top--; // Decrease switch stack if ending a switch
case_indent = 0; // Reset case indent since we're leaving the switch
in_switch--; // We're leaving a switch block
} else {
indent--; // For other blocks like while
}
stack_top--;
indent_next = FALSE; // Reset for next line
} else if (!strn_cmp(t, "else", 4)) {
if (!indent) {
if (stack_top < 0 || block_stack[stack_top] != 'l') {
write_to_output(d, "Unmatched 'else' (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
indent--;
indent--; // Reduce indent for else, then increment for next statement
indent_next = TRUE;
} else if (!strn_cmp(t, "case", 4) ||
!strn_cmp(t, "default", 7)) {
if (!indent) {
write_to_output(d, "Case/default outside switch (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
if (!found_case) /* so we don't indent multiple case statements without a break */
indent_next = TRUE;
found_case = TRUE;
} else if (!strn_cmp(t, "break", 5)) {
if (!found_case || !indent ) {
write_to_output(d, "Break not in case (line %d)!\r\n", line_num);
if (stack_top < 0 || (block_stack[stack_top] != 's' && block_stack[stack_top] != 'l')) {
write_to_output(d, "Break not in case or loop (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
found_case = FALSE;
indent--;
indent = case_indent + 1; // Indent break one level deeper than case
indent_next = FALSE; // Ensure no automatic increase for next line after break
}
*line = '\0';
for (nlen = 0, i = 0;i<indent;i++) {
strncat(line, " ", sizeof(line)-1);
for (nlen = 0, i = 0; i < indent; i++) {
strncat(line, " ", sizeof(line) - strlen(line) - 1);
nlen += 2;
}
ret = snprintf(line + nlen, sizeof(line) - nlen, "%s\r\n", t);
llen = (size_t)ret;
if (ret < 0 || llen + nlen + len > d->max_str - 1 ) {
if (ret < 0 || llen + nlen + len > d->max_str - 1) {
write_to_output(d, "String too long, formatting aborted\r\n");
free(sc);
return FALSE;
@ -1169,8 +1184,8 @@ int format_script(struct descriptor_data *d)
t = strtok(NULL, "\n\r");
}
if (indent)
write_to_output(d, "Unmatched if, while or switch ignored.\r\n");
if (stack_top >= 0)
write_to_output(d, "Unmatched block statements ignored.\r\n");
free(*d->str);
*d->str = strdup(nsc);

View file

@ -2486,7 +2486,6 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
char cmd[MAX_INPUT_LENGTH], *p;
struct script_data *sc = 0;
struct cmdlist_element *temp;
unsigned long loops = 0;
void *go = NULL;
void obj_command_interpreter(obj_data *obj, char *argument);
@ -2578,8 +2577,8 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
if (process_if(p + 6, go, sc, trig, type)) {
temp->original = cl;
} else {
cl->loops = 0;
cl = temp;
loops = 0;
}
} else if (!strn_cmp("switch ", p, 7)) {
cl = find_case(trig, cl, go, sc, type, p + 7);
@ -2599,9 +2598,10 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
if (cl->original && process_if(orig_cmd + 6, go, sc, trig,
type)) {
cl = cl->original;
loops++;
cl->loops++;
GET_TRIG_LOOPS(trig)++;
if (loops == 30) {
if (cl->loops == 30) {
cl->loops = 0;
process_wait(go, trig, type, "wait 1", cl);
depth--;
return ret_val;
@ -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));
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) ;
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)
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)
{
int bucket = (int) (uid & (BUCKET_COUNT - 1));
struct lookup_table_t *lt = &lookup_table[bucket];
for (;lt && lt->uid != uid ; lt = lt->next) ;
struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
if (lt)
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;
}
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)
{
int bucket = (int) (uid & (BUCKET_COUNT - 1));
struct lookup_table_t *lt = &lookup_table[bucket];
struct lookup_table_t *lt = get_bucket_head(uid);
if (lt && lt->uid == uid) {
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)
if (lt->next->uid == uid) {
log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->next->c, c);
lt->next->c = c;
return;
}
@ -3054,9 +3069,7 @@ void remove_from_lookup_table(long uid)
if (uid == 0)
return;
for (;lt;lt = lt->next)
if (lt->uid == uid)
flt = lt;
flt = find_element_by_uid_in_lookup_table(uid);
if (flt) {
for (lt = &lookup_table[bucket];lt->next != flt;lt = lt->next)

View file

@ -135,6 +135,7 @@ struct cmdlist_element {
char *cmd; /* one line of a trigger */
struct cmdlist_element *original;
struct cmdlist_element *next;
int loops; /* for counting number of runs in a while loop */
};
struct trig_var_data {
@ -449,6 +450,8 @@ void wld_command_interpreter(room_data *room, char *argument);
// id helpers
extern long char_script_id(char_data *ch);
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)
#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;
char buf[MAX_INPUT_LENGTH];
int ret_val;
long object_id = obj_script_id(obj);
if (!SCRIPT_CHECK(ch, MTRIG_RECEIVE) || AFF_FLAGGED(ch, AFF_CHARM))
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))){
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);
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;
else
return ret_val;
@ -1118,6 +1120,7 @@ int drop_wtrigger(obj_data *obj, char_data *actor)
trig_data *t;
char buf[MAX_INPUT_LENGTH];
int ret_val;
long object_id = obj_script_id(obj);
if (!actor || !SCRIPT_CHECK(&world[IN_ROOM(actor)], WTRIG_DROP))
return 1;
@ -1127,9 +1130,10 @@ int drop_wtrigger(obj_data *obj, char_data *actor)
if (TRIGGER_CHECK(t, WTRIG_DROP) &&
(rand_number(1, 100) <= GET_TRIG_NARG(t))) {
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);
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;
else
return ret_val;

View file

@ -268,7 +268,7 @@ void create_world_index(int znum, const char *type)
while (get_line(oldfile, buf)) {
if (*buf == '$') {
/* The following used to add a blank line, thanks to Brian Taylor for the fix. */
fprintf(newfile, "%s", (!found ? strncat(buf1, "\n$\n", sizeof(buf1)-1) : "$\n"));
fprintf(newfile, "%s", (!found ? strncat(buf1, "\n$\n", sizeof(buf1) - strlen(buf1) - 1) : "$\n"));
break;
} else if (!found) {
sscanf(buf, "%d", &num);

View file

@ -671,12 +671,20 @@ struct char_data *get_char_num(mob_rnum nr)
/* put an object in a room */
void obj_to_room(struct obj_data *object, room_rnum room)
{
if (!object || room == NOWHERE || room > top_of_world)
if (!object || room == NOWHERE || room > top_of_world){
log("SYSERR: Illegal value(s) passed to obj_to_room. (Room #%d/%d, obj %p)",
room, top_of_world, (void *)object);
}
else {
object->next_content = world[room].contents;
world[room].contents = object;
if (world[room].contents == NULL){ // if list is empty
world[room].contents = object; // add object to list
}
else {
struct obj_data *i = world[room].contents; // define a temporary pointer
while (i->next_content != NULL) i = i->next_content; // find the first without a next_content
i->next_content = object; // add object at the end
}
object->next_content = NULL; // mostly for sanity. should do nothing.
IN_ROOM(object) = room;
object->carried_by = NULL;
if (ROOM_FLAGGED(room, ROOM_HOUSE))

View file

@ -177,6 +177,13 @@ static IBT_DATA *read_ibt( char *filename, FILE *fp )
}
break;
case 'F':
if (!str_cmp(word, "Flags")) {
fMatch = TRUE;
fread_flags(fp, ibtData->flags, 4);
}
break;
case 'I':
TXT_KEY("IdNum", id_num, fread_line(fp));
break;

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. */
if (IS_NPC(victim) && !affected_by_spell(victim, spellnum)) {
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)) {
send_to_char(ch, "%s", CONFIG_NOEFFECT);
return;

View file

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

View file

@ -936,7 +936,7 @@ void oedit_parse(struct descriptor_data *d, char *arg)
case OEDIT_PERM:
if ((number = atoi(arg)) == 0)
break;
if (number > 0 && number <= NUM_AFF_FLAGS) {
if (number > 0 && number < NUM_AFF_FLAGS) {
/* Setting AFF_CHARM on objects like this is dangerous. */
if (number != AFF_CHARM) {
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[3] = num8;
} 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);
} else {
log("SYSERR: Invalid affects in pfile (%s), expecting 5 or 8 values", GET_NAME(ch));

View file

@ -13,6 +13,11 @@
#include <sys/types.h>
#include "protocol.h"
#ifdef _MSC_VER
#include "telnet.h"
#define alloca _alloca
#endif
/******************************************************************************
The following section is for Diku/Merc derivatives. Replace as needed.
******************************************************************************/
@ -1763,7 +1768,26 @@ static void PerformSubnegotiation( descriptor_t *apDescriptor, char aCmd, char *
Write(apDescriptor, RequestTTYPE);
}
if ( PrefixString("Mudlet", pClientName) )
if ( PrefixString("MTTS ", pClientName) )
{
pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt = atoi(pClientName+5);
if (pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt & 1)
{
pProtocol->pVariables[eMSDP_ANSI_COLORS]->ValueInt = 1;
}
if (pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt & 4)
{
pProtocol->pVariables[eMSDP_UTF_8]->ValueInt = 1;
}
if (pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt & 8)
{
pProtocol->pVariables[eMSDP_XTERM_256_COLORS]->ValueInt = 1;
pProtocol->b256Support = eYES;
}
}
else if ( PrefixString("Mudlet", pClientName) )
{
/* Mudlet beta 15 and later supports 256 colours, but we can't
* identify it from the mud - everything prior to 1.1 claims

View file

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

View file

@ -1,12 +1,12 @@
/**************************************************************************
* File: spell_parser.c Part of tbaMUD *
* Usage: Top-level magic routines; outside points of entry to magic sys. *
* *
* All rights reserved. See license for complete information. *
* *
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
**************************************************************************/
* File: spell_parser.c Part of tbaMUD *
* Usage: Top-level magic routines; outside points of entry to magic sys. *
* *
* All rights reserved. See license for complete information. *
* *
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
**************************************************************************/
#include "conf.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 */
/* 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 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 void say_spell(struct char_data *ch, int spellnum, struct char_data *tch,
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);
/* Local (File Scope) Variables */
@ -37,112 +40,100 @@ struct syllable {
const char *org;
const char *news;
};
static struct syllable syls[] = {
{" ", " "},
{"ar", "abra"},
{"ate", "i"},
{"cau", "kada"},
{"blind", "nose"},
{"bur", "mosa"},
{"cu", "judi"},
{"de", "oculo"},
{"dis", "mar"},
{"ect", "kamina"},
{"en", "uns"},
{"gro", "cra"},
{"light", "dies"},
{"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 struct syllable syls[] = { { " ", " " }, { "ar", "abra" },
{ "ate", "i" }, { "cau", "kada" }, { "blind", "nose" }, { "bur", "mosa" }, {
"cu", "judi" }, { "de", "oculo" }, { "dis", "mar" },
{ "ect", "kamina" }, { "en", "uns" }, { "gro", "cra" }, { "light", "dies" },
{ "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 *
(GET_LEVEL(ch) - SINFO.min_level[(int) GET_CLASS(ch)])),
SINFO.mana_min);
(GET_LEVEL(ch) - SINFO.min_level[(int) GET_CLASS(ch)])),
SINFO.mana_min);
}
static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch,
struct obj_data *tobj)
{
char lbuf[256], buf[256], buf1[256], buf2[256]; /* FIXME */
const char *format;
static char *obfuscate_spell(const char *unobfuscated) {
static char obfuscated[200];
int maxlen = 200;
struct char_data *i;
int j, ofs = 0;
*buf = '\0';
strlcpy(lbuf, skill_name(spellnum), sizeof(lbuf));
*obfuscated = '\0';
while (lbuf[ofs]) {
while (unobfuscated[ofs]) {
for (j = 0; *(syls[j].org); j++) {
if (!strncmp(syls[j].org, lbuf + ofs, strlen(syls[j].org))) {
strcat(buf, syls[j].news); /* strcat: BAD */
ofs += strlen(syls[j].org);
if (!strncmp(syls[j].org, unobfuscated + ofs, strlen(syls[j].org))) {
if (strlen(syls[j].news) < maxlen) {
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;
}
}
/* i.e., we didn't find a match in syls[] */
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++;
}
}
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 == ch)
format = "$n closes $s eyes and utters the words, '%s'.";
else
format = "$n stares at $N and utters the words, '%s'.";
} else if (tobj != NULL &&
((IN_ROOM(tobj) == IN_ROOM(ch)) || (tobj->carried_by == ch)))
} else if (tobj != NULL
&& ((IN_ROOM(tobj) == IN_ROOM(ch)) || (tobj->carried_by == ch)))
format = "$n stares at $p and utters the words, '%s'.";
else
format = "$n utters the words, '%s'.";
snprintf(buf1, sizeof(buf1), format, skill_name(spellnum));
snprintf(buf2, sizeof(buf2), format, buf);
snprintf(act_buf_original, sizeof(act_buf_original), format, spell);
snprintf(act_buf_obfuscated, sizeof(act_buf_obfuscated), format, obfuscated);
for (i = world[IN_ROOM(ch)].people; i; i = i->next_in_room) {
if (i == ch || i == tch || !i->desc || !AWAKE(i))
continue;
if (GET_CLASS(ch) == GET_CLASS(i))
perform_act(buf1, ch, tobj, tch, i);
perform_act(act_buf_original, ch, tobj, tch, i);
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)) {
snprintf(buf1, sizeof(buf1), "$n stares at you and utters the words, '%s'.",
GET_CLASS(ch) == GET_CLASS(tch) ? skill_name(spellnum) : buf);
act(buf1, FALSE, ch, NULL, tch, TO_VICT);
snprintf(act_buf_original, sizeof(act_buf_original), "$n stares at you and utters the words, '%s'.",
GET_CLASS(ch) == GET_CLASS(tch) ? spell : obfuscated);
act(act_buf_original, FALSE, ch, NULL, tch, TO_VICT);
}
}
/* 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
* 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)
return (spell_info[num].name);
else if (num == -1)
@ -151,8 +142,7 @@ const char *skill_name(int num)
return ("UNDEFINED");
}
int find_skill_num(char *name)
{
int find_skill_num(char *name) {
int skindex, ok;
char *temp, *temp2;
char first[256], first2[256], tempbuf[256];
@ -162,12 +152,12 @@ int find_skill_num(char *name)
return (skindex);
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);
temp2 = any_one_arg(name, first2);
while (*first && *first2 && ok) {
if (!is_abbrev(first2, first))
ok = FALSE;
ok = FALSE;
temp = any_one_arg(temp, first);
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
* ignored here, to make callers simpler. */
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;
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);
return (0);
}
if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_PEACEFUL) &&
(SINFO.violent || IS_SET(SINFO.routines, MAG_DAMAGE))) {
if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_PEACEFUL) && (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");
act("White light from no particular source suddenly fills the room, then vanishes.", FALSE, caster, 0, 0, TO_ROOM);
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 (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))
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))
switch (spellnum) {
case SPELL_CHARM: MANUAL_SPELL(spell_charm); break;
case SPELL_CREATE_WATER: MANUAL_SPELL(spell_create_water); break;
case SPELL_DETECT_POISON: MANUAL_SPELL(spell_detect_poison); break;
case SPELL_ENCHANT_WEAPON: MANUAL_SPELL(spell_enchant_weapon); break;
case SPELL_IDENTIFY: MANUAL_SPELL(spell_identify); break;
case SPELL_LOCATE_OBJECT: MANUAL_SPELL(spell_locate_object); break;
case SPELL_SUMMON: MANUAL_SPELL(spell_summon); break;
case SPELL_WORD_OF_RECALL: MANUAL_SPELL(spell_recall); break;
case SPELL_TELEPORT: MANUAL_SPELL(spell_teleport); break;
case SPELL_CHARM:
MANUAL_SPELL(spell_charm)
;
break;
case SPELL_CREATE_WATER:
MANUAL_SPELL(spell_create_water)
;
break;
case SPELL_DETECT_POISON:
MANUAL_SPELL(spell_detect_poison)
;
break;
case SPELL_ENCHANT_WEAPON:
MANUAL_SPELL(spell_enchant_weapon)
;
break;
case SPELL_IDENTIFY:
MANUAL_SPELL(spell_identify)
;
break;
case SPELL_LOCATE_OBJECT:
MANUAL_SPELL(spell_locate_object)
;
break;
case SPELL_SUMMON:
MANUAL_SPELL(spell_summon)
;
break;
case SPELL_WORD_OF_RECALL:
MANUAL_SPELL(spell_recall)
;
break;
case SPELL_TELEPORT:
MANUAL_SPELL(spell_teleport)
;
break;
}
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
* 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 */
void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
char *argument)
{
void mag_objectmagic(struct char_data *ch, struct obj_data *obj, char *argument) {
char arg[MAX_INPUT_LENGTH];
int i, k;
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);
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)) {
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
* for those spells spells here. */
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)
i++;
while (i-- > 0)
call_magic(ch, NULL, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF);
for (i = 0, tch = world[IN_ROOM(ch)].people; tch;
tch = tch->next_in_room)
i++;
while (i-- > 0)
call_magic(ch, NULL, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF);
} else {
for (tch = world[IN_ROOM(ch)].people; tch; tch = next_tch) {
next_tch = tch->next_in_room;
if (ch != tch)
call_magic(ch, tch, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF);
}
for (tch = world[IN_ROOM(ch)].people; tch; tch = next_tch) {
next_tch = tch->next_in_room;
if (ch != tch)
call_magic(ch, tch, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF);
}
}
}
break;
case ITEM_WAND:
if (k == FIND_CHAR_ROOM) {
if (tch == ch) {
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("You point $p at yourself.", FALSE, ch, obj, 0, TO_CHAR);
act("$n points $p at $mself.", FALSE, ch, obj, 0, TO_ROOM);
} else {
act("You point $p at $N.", FALSE, ch, obj, tch, TO_CHAR);
if (obj->action_description)
act(obj->action_description, FALSE, ch, obj, tch, TO_ROOM);
else
act("$n points $p at $N.", TRUE, ch, obj, tch, TO_ROOM);
act("You point $p at $N.", FALSE, ch, obj, tch, TO_CHAR);
if (obj->action_description)
act(obj->action_description, FALSE, ch, obj, tch, TO_ROOM);
else
act("$n points $p at $N.", TRUE, ch, obj, tch, TO_ROOM);
}
} else if (tobj != NULL) {
act("You point $p at $P.", FALSE, ch, obj, tobj, TO_CHAR);
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
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)) {
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)) {
/* Wands with area spells don't need to be pointed. */
act("You point $p outward.", FALSE, ch, obj, NULL, TO_CHAR);
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)--;
WAIT_STATE(ch, PULSE_VIOLENCE);
if (GET_OBJ_VAL(obj, 0))
call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3),
GET_OBJ_VAL(obj, 0), CAST_WAND);
call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3), GET_OBJ_VAL(obj, 0),
CAST_WAND);
else
call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3),
DEFAULT_WAND_LVL, CAST_WAND);
DEFAULT_WAND_LVL, CAST_WAND);
break;
case ITEM_SCROLL:
if (*arg) {
if (!k) {
act("There is nothing to here to affect with $p.", FALSE,
ch, obj, NULL, TO_CHAR);
return;
act("There is nothing to here to affect with $p.", FALSE, ch, obj, NULL,
TO_CHAR);
return;
}
} else
tch = ch;
@ -394,9 +409,9 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
WAIT_STATE(ch, PULSE_VIOLENCE);
for (i = 1; i <= 3; i++)
if (call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, i),
GET_OBJ_VAL(obj, 0), CAST_SCROLL) <= 0)
break;
if (call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, i), GET_OBJ_VAL(obj, 0),
CAST_SCROLL) <= 0)
break;
if (obj != NULL)
extract_obj(obj);
@ -404,7 +419,7 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
case ITEM_POTION:
tch = ch;
if (!consume_otrigger(obj, ch, OCMD_QUAFF)) /* check trigger */
if (!consume_otrigger(obj, ch, OCMD_QUAFF)) /* check trigger */
return;
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);
for (i = 1; i <= 3; i++)
if (call_magic(ch, ch, NULL, GET_OBJ_VAL(obj, i),
GET_OBJ_VAL(obj, 0), CAST_POTION) <= 0)
break;
if (call_magic(ch, ch, NULL, GET_OBJ_VAL(obj, i), GET_OBJ_VAL(obj, 0),
CAST_POTION) <= 0)
break;
if (obj != NULL)
extract_obj(obj);
break;
default:
log("SYSERR: Unknown object_type %d in mag_objectmagic.",
GET_OBJ_TYPE(obj));
GET_OBJ_TYPE(obj));
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
* for spells cast by NPCs via specprocs. */
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) {
log("SYSERR: cast_spell trying to call spellnum %d/%d.", spellnum,
TOP_SPELL_DEFINE);
TOP_SPELL_DEFINE);
return (0);
}
if (GET_POS(ch) < SINFO.min_position) {
switch (GET_POS(ch)) {
case POS_SLEEPING:
send_to_char(ch, "You dream about great magical powers.\r\n");
break;
case POS_RESTING:
send_to_char(ch, "You cannot concentrate while resting.\r\n");
break;
case POS_SITTING:
send_to_char(ch, "You can't do this sitting!\r\n");
break;
case POS_FIGHTING:
send_to_char(ch, "Impossible! You can't concentrate enough!\r\n");
break;
default:
send_to_char(ch, "You can't do much of anything like this!\r\n");
break;
send_to_char(ch, "You dream about great magical powers.\r\n");
break;
case POS_RESTING:
send_to_char(ch, "You cannot concentrate while resting.\r\n");
break;
case POS_SITTING:
send_to_char(ch, "You can't do this sitting!\r\n");
break;
case POS_FIGHTING:
send_to_char(ch, "Impossible! You can't concentrate enough!\r\n");
break;
default:
send_to_char(ch, "You can't do much of anything like this!\r\n");
break;
}
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
* the spell can be cast, checks for sufficient mana and subtracts it, and
* passes control to cast_spell(). */
ACMD(do_cast)
{
ACMD(do_cast) {
struct char_data *tch = NULL;
struct obj_data *tobj = NULL;
char *s, *t;
@ -507,7 +520,8 @@ ACMD(do_cast)
}
s = strtok(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;
}
t = strtok(NULL, "\0");
@ -546,51 +560,52 @@ ACMD(do_cast)
number = get_number(&t);
if (!target && (IS_SET(SINFO.targets, TAR_CHAR_ROOM))) {
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 ((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 ((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)) {
for (i = 0; !target && i < NUM_WEARS; i++)
if (GET_EQ(ch, i) && isname(t, GET_EQ(ch, i)->name)) {
tobj = GET_EQ(ch, i);
target = TRUE;
}
if (GET_EQ(ch, i) && isname(t, GET_EQ(ch, i)->name)) {
tobj = GET_EQ(ch, i);
target = TRUE;
}
}
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)
target = TRUE;
if ((tobj = get_obj_in_list_vis(ch, t, &number,
world[IN_ROOM(ch)].contents)) != NULL)
target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_WORLD))
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 (FIGHTING(ch) != NULL) {
tch = ch;
target = TRUE;
tch = ch;
target = TRUE;
}
if (!target && IS_SET(SINFO.targets, TAR_FIGHT_VICT))
if (FIGHTING(ch) != NULL) {
tch = FIGHTING(ch);
target = TRUE;
tch = FIGHTING(ch);
target = TRUE;
}
/* if no target specified, and the spell isn't violent, default to self */
if (!target && IS_SET(SINFO.targets, TAR_CHAR_ROOM) &&
!SINFO.violent) {
if (!target && IS_SET(SINFO.targets, TAR_CHAR_ROOM) && !SINFO.violent) {
tch = ch;
target = TRUE;
}
if (!target) {
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;
}
}
@ -617,34 +632,34 @@ ACMD(do_cast)
if (mana > 0)
GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - (mana / 2)));
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 */
if (cast_spell(ch, tch, tobj, spellnum)) {
WAIT_STATE(ch, PULSE_VIOLENCE);
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;
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;
}
if (chclass < 0 || chclass >= NUM_CLASSES) {
log("SYSERR: assigning '%s' to illegal class %d/%d.", skill_name(spell),
chclass, NUM_CLASSES - 1);
chclass, NUM_CLASSES - 1);
bad = 1;
}
if (level < 1 || level > LVL_IMPL) {
log("SYSERR: assigning '%s' to illegal level %d/%d.", skill_name(spell),
level, LVL_IMPL);
level, LVL_IMPL);
bad = 1;
}
@ -652,11 +667,10 @@ void spell_level(int spell, int chclass, int level)
spell_info[spell].min_level[chclass] = level;
}
/* Assign the spells on boot up */
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;
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;
}
void unused_spell(int spl)
{
void unused_spell(int spl) {
int 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
* 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 */
void mag_assign_spells(void)
{
void mag_assign_spells(void) {
int i;
/* Do not change the loop below. */
@ -723,225 +735,183 @@ void mag_assign_spells(void)
/* Do not change the loop above. */
spello(SPELL_ANIMATE_DEAD, "animate dead", 35, 10, 3, POS_STANDING,
TAR_OBJ_ROOM, FALSE, MAG_SUMMONS,
NULL);
TAR_OBJ_ROOM, FALSE, MAG_SUMMONS, NULL);
spello(SPELL_ARMOR, "armor", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS,
"You feel less protected.");
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You feel less protected.");
spello(SPELL_BLESS, "bless", 35, 5, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel less righteous.");
TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel less righteous.");
spello(SPELL_BLINDNESS, "blindness", 35, 25, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_NOT_SELF, FALSE, MAG_AFFECTS,
"You feel a cloak of blindness dissolve.");
TAR_CHAR_ROOM | TAR_NOT_SELF, FALSE, MAG_AFFECTS,
"You feel a cloak of blindness dissolve.");
spello(SPELL_BURNING_HANDS, "burning hands", 30, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_CALL_LIGHTNING, "call lightning", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_CHARM, "charm person", 75, 50, 2, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL,
"You feel more self-confident.");
TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL,
"You feel more self-confident.");
spello(SPELL_CHILL_TOUCH, "chill touch", 30, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_AFFECTS,
"You feel your strength return.");
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_AFFECTS,
"You feel your strength return.");
spello(SPELL_CLONE, "clone", 80, 65, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_SUMMONS,
NULL);
TAR_IGNORE, FALSE, MAG_SUMMONS, NULL);
spello(SPELL_COLOR_SPRAY, "color spray", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_CONTROL_WEATHER, "control weather", 75, 25, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_MANUAL,
NULL);
TAR_IGNORE, FALSE, MAG_MANUAL, NULL);
spello(SPELL_CREATE_FOOD, "create food", 30, 5, 4, POS_STANDING,
TAR_IGNORE, FALSE, MAG_CREATIONS,
NULL);
TAR_IGNORE, FALSE, MAG_CREATIONS, NULL);
spello(SPELL_CREATE_WATER, "create water", 30, 5, 4, POS_STANDING,
TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL,
NULL);
TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL, NULL);
spello(SPELL_CURE_BLIND, "cure blind", 30, 5, 2, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_UNAFFECTS,
NULL);
TAR_CHAR_ROOM, FALSE, MAG_UNAFFECTS, NULL);
spello(SPELL_CURE_CRITIC, "cure critic", 30, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS,
NULL);
TAR_CHAR_ROOM, FALSE, MAG_POINTS, NULL);
spello(SPELL_CURE_LIGHT, "cure light", 30, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS,
NULL);
TAR_CHAR_ROOM, FALSE, MAG_POINTS, NULL);
spello(SPELL_CURSE, "curse", 80, 50, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel more optimistic.");
TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel more optimistic.");
spello(SPELL_DARKNESS, "darkness", 30, 5, 4, POS_STANDING,
TAR_IGNORE, FALSE, MAG_ROOMS,
NULL);
TAR_IGNORE, FALSE, MAG_ROOMS, NULL);
spello(SPELL_DETECT_ALIGN, "detect alignment", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less aware.");
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, "You feel less aware.");
spello(SPELL_DETECT_INVIS, "detect invisibility", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"Your eyes stop tingling.");
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"Your eyes stop tingling.");
spello(SPELL_DETECT_MAGIC, "detect magic", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"The detect magic wears off.");
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"The detect magic wears off.");
spello(SPELL_DETECT_POISON, "detect poison", 15, 5, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL,
"The detect poison wears off.");
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL,
"The detect poison wears off.");
spello(SPELL_DISPEL_EVIL, "dispel evil", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_DISPEL_GOOD, "dispel good", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_EARTHQUAKE, "earthquake", 40, 25, 3, POS_FIGHTING,
TAR_IGNORE, TRUE, MAG_AREAS,
NULL);
TAR_IGNORE, TRUE, MAG_AREAS, NULL);
spello(SPELL_ENCHANT_WEAPON, "enchant weapon", 150, 100, 10, POS_STANDING,
TAR_OBJ_INV, FALSE, MAG_MANUAL,
NULL);
TAR_OBJ_INV, FALSE, MAG_MANUAL, NULL);
spello(SPELL_ENERGY_DRAIN, "energy drain", 40, 25, 1, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_MANUAL,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_MANUAL, NULL);
spello(SPELL_GROUP_ARMOR, "group armor", 50, 30, 2, POS_STANDING,
TAR_IGNORE, FALSE, MAG_GROUPS,
NULL);
TAR_IGNORE, FALSE, MAG_GROUPS, NULL);
spello(SPELL_FIREBALL, "fireball", 40, 30, 2, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_FLY, "fly", 40, 20, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS,
"You drift slowly to the ground.");
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You drift slowly to the ground.");
spello(SPELL_GROUP_HEAL, "group heal", 80, 60, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_GROUPS,
NULL);
TAR_IGNORE, FALSE, MAG_GROUPS, NULL);
spello(SPELL_HARM, "harm", 75, 45, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_HEAL, "heal", 60, 40, 3, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_UNAFFECTS,
NULL);
TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_UNAFFECTS, NULL);
spello(SPELL_INFRAVISION, "infravision", 25, 10, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"Your night vision seems to fade.");
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"Your night vision seems to fade.");
spello(SPELL_INVISIBLE, "invisibility", 35, 25, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel yourself exposed.");
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE,
MAG_AFFECTS | MAG_ALTER_OBJS, "You feel yourself exposed.");
spello(SPELL_LIGHTNING_BOLT, "lightning bolt", 30, 15, 1, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_LOCATE_OBJECT, "locate object", 25, 20, 1, POS_STANDING,
TAR_OBJ_WORLD, FALSE, MAG_MANUAL,
NULL);
TAR_OBJ_WORLD, FALSE, MAG_MANUAL, NULL);
spello(SPELL_MAGIC_MISSILE, "magic missile", 25, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_POISON, "poison", 50, 20, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV, TRUE,
MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel less sick.");
TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV, TRUE,
MAG_AFFECTS | MAG_ALTER_OBJS, "You feel less sick.");
spello(SPELL_PROT_FROM_EVIL, "protection from evil", 40, 10, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less protected.");
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less protected.");
spello(SPELL_REMOVE_CURSE, "remove curse", 45, 25, 5, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE,
MAG_UNAFFECTS | MAG_ALTER_OBJS,
NULL);
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE,
MAG_UNAFFECTS | MAG_ALTER_OBJS, NULL);
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,
NULL);
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE,
MAG_UNAFFECTS | MAG_ALTER_OBJS, NULL);
spello(SPELL_SANCTUARY, "sanctuary", 110, 85, 5, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS,
"The white aura around your body fades.");
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "The white aura around your body fades.");
spello(SPELL_SENSE_LIFE, "sense life", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less aware of your surroundings.");
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less aware of your surroundings.");
spello(SPELL_SHOCKING_GRASP, "shocking grasp", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
spello(SPELL_SLEEP, "sleep", 40, 25, 5, POS_STANDING,
TAR_CHAR_ROOM, TRUE, MAG_AFFECTS,
"You feel less tired.");
TAR_CHAR_ROOM, TRUE, MAG_AFFECTS, "You feel less tired.");
spello(SPELL_STRENGTH, "strength", 35, 30, 1, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS,
"You feel weaker.");
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You feel weaker.");
spello(SPELL_SUMMON, "summon", 75, 50, 3, POS_STANDING,
TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL,
NULL);
TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL, NULL);
spello(SPELL_TELEPORT, "teleport", 75, 50, 3, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_MANUAL,
NULL);
TAR_CHAR_ROOM, FALSE, MAG_MANUAL, NULL);
spello(SPELL_WATERWALK, "waterwalk", 40, 20, 2, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS,
"Your feet seem less buoyant.");
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "Your feet seem less buoyant.");
spello(SPELL_WORD_OF_RECALL, "word of recall", 20, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_MANUAL,
NULL);
TAR_CHAR_ROOM, FALSE, MAG_MANUAL, NULL);
spello(SPELL_IDENTIFY, "identify", 50, 25, 5, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL,
NULL);
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, NULL);
/* NON-castable spells should appear below here. */
spello(SPELL_IDENTIFY, "identify", 0, 0, 0, 0,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL,
NULL);
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, NULL);
/* 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,
TAR_IGNORE, TRUE, 0,
NULL);
TAR_IGNORE, TRUE, 0, NULL);
/* 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

View file

@ -268,7 +268,7 @@
/* Affect bits: used in char_data.char_specials.saved.affected_by */
/* 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_INVISIBLE 2 /**< Char is invisible */
#define AFF_DETECT_ALIGN 3 /**< Char is sensitive to align */
@ -291,8 +291,8 @@
#define AFF_HIDE 20 /**< Char is hidden */
#define AFF_FREE 21 /**< Room for future expansion */
#define AFF_CHARM 22 /**< Char is charmed */
/** Total number of affect flags not including the don't use flag. */
#define NUM_AFF_FLAGS 22
/** Total number of affect flags */
#define NUM_AFF_FLAGS 23
/* Modes of connectedness: used by descriptor_data.state */
#define CON_PLAYING 0 /**< Playing - Nominal state */
@ -1276,7 +1276,7 @@ struct happyhour {
struct recent_player
{
int vnum; /* The ID number for this instance */
char name[MAX_NAME_LENGTH]; /* The char name of the player */
char name[MAX_NAME_LENGTH+1];/* The char name of the player */
bool new_player; /* Is this a new player? */
bool copyover_player; /* Is this a player that was on during the last copyover? */
time_t time; /* login time */

View file

@ -63,6 +63,24 @@
/* Do not change anything below this line. */
#if defined(__APPLE__) && defined(__MACH__)
/* Machine-specific dependencies for running on modern macOS systems 10.13+ (High Sierra)
* Updated by Victor Augusto Borges Dias de Almeida (aka Stoneheart), 26 June 2024.
*
* Tested on:
* - macOS 10.13: High Sierra (Lobo) - September 25, 2017 (Latest: 10.13.6)
* - macOS 10.14: Mojave (Liberty) - September 24, 2018 (Latest: 10.14.6)
* - macOS 10.15: Catalina (Jazz) - October 7, 2019 (Latest: 10.15.7)
* - macOS 11: Big Sur (GoldenGate) - November 12, 2020 (Latest: 11.7.10)
* - macOS 12: Monterey (Star) - October 25, 2021 (Latest: 12.7)
* - macOS 13: Ventura (Rome) - November 7, 2022 (Latest: 13.7)
* - macOS 14: Sonoma (Sunburst) - November 7, 2023 (Latest: 14.3)
*
* This file works on Apple Silicon Chips (M1, M2, M3) without futher configurations.
*/
#define CIRCLE_MAC_OS 1
#endif
/* Set up various machine-specific things based on the values determined from
* configure and conf.h. */
@ -78,7 +96,7 @@
#include <strings.h>
#endif
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) || defined(CIRCLE_MAC_OS))
#include <stdlib.h>
#else /* No standard headers. */
@ -88,9 +106,8 @@
#endif
extern char *malloc(), *calloc(), *realloc();
extern void free ();
extern void abort (), exit ();
extern void free();
extern void abort(), exit();
#endif /* Standard headers. */
@ -150,9 +167,11 @@ extern void abort (), exit ();
#include <sys/errno.h>
#endif
#ifndef CIRCLE_MAC_OS
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
@ -434,9 +453,11 @@ struct in_addr {
char *strerror(int errnum);
#endif
#ifndef CIRCLE_MAC_OS
#ifdef NEED_STRLCPY_PROTO
size_t strlcpy(char *dest, const char *src, size_t copylen);
#endif
#endif
#ifdef NEED_SYSTEM_PROTO
int system(const char *string);

View file

@ -12,7 +12,6 @@
#include "conf.h"
#include "sysdep.h"
#define NOWHERE -1 /* nil reference for room-database */
/* The cardinal directions: used as index to room_data.dir_option[] */
@ -22,14 +21,17 @@
#define WEST 3
#define UP 4
#define DOWN 5
#define NORTHWEST 6
#define NORTHEAST 7
#define SOUTHEAST 8
#define SOUTHWEST 9
#define NUM_OF_DIRS 6
#define NUM_OF_DIRS 10
#define CREATE(result, type, number) do {\
if (!((result) = (type *) calloc ((number), sizeof(type))))\
{ perror("malloc failure"); abort(); } } while(0)
/* Exit info: used in room_data.dir_option.exit_info */
#define EX_ISDOOR (1 << 0) /* Exit is a door */
#define EX_CLOSED (1 << 1) /* The door is closed */
@ -45,7 +47,7 @@ typedef unsigned short int ush_int;
typedef char bool;
typedef char byte;
typedef sh_int room_num;
typedef int room_num;
typedef sh_int obj_num;
@ -133,13 +135,14 @@ struct room_data {
struct room_data *world = NULL; /* array of rooms */
int top_of_world = 0; /* ref to top element of world */
int rec_count = 0;
/* local functions */
char *fread_string(FILE * fl, char *error);
void setup_dir(FILE * fl, int room, int dir);
void index_boot(char *name);
void index_boot(int cnt, char **name);
void discrete_load(FILE * fl);
void parse_room(FILE * fl, int virtual_nr);
void parse_mobile(FILE * mob_f, int nr);
@ -150,7 +153,7 @@ void write_output(void);
char *dir_names[] =
{"North", "East", "South", "West", "Up", "Down"};
{"North", "East", "South", "West", "Up", "Down","North West","North East","South East","South West"};
/*************************************************************************
@ -160,14 +163,12 @@ char *dir_names[] =
/* body of the booting system */
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <world-file-name>\n", argv[0]);
if (argc < 2) {
fprintf(stderr, "Usage: %s <world-file-name(s)>\n", argv[0]);
exit(1);
}
index_boot(argv[1]);
log("Renumbering rooms.");
renum_world();
index_boot(argc,argv);
log("Writing output.");
write_output();
@ -176,6 +177,21 @@ int main(int argc, char **argv)
return (0);
}
/* Since the world is loaded into memory by index
* and not room number, we need to search through
* all rooms and return the correct one. This is
* used to generate door information (ie: the name)
*/
struct room_data* findRoom(int nr)
{
int i;
for (i=0;i<rec_count;i++)
if (world[i].number==nr)
return &world[i];
return NULL;
}
void write_output(void)
{
@ -184,11 +200,22 @@ void write_output(void)
char buf[128];
register int door, found;
for (i = 0; i <= top_of_world; i++) {
for (i=0;i<rec_count;i++) {
//print the record number, but no linefeed.
fprintf(stderr, "Record: %d ",i);
if (world[i].name == NULL) {
//linefeed the prior record since we're skipping this one.
log("");
//the name is blank, which means, most likely, the record is bad as well.
continue;
}
sprintf(buf, "Writing %d.html", world[i].number);
log(buf);
sprintf(buf, "%d.html", world[i].number);
//for some reason, if you use %d with sprintf it rolls over like its 16bit,
//but only if you use the buffer with fopen.
//using %ld and casting to long solves this in case someone really wants
//to use negative room numbers.
sprintf(buf, "%ld.html",(long)world[i].number);
if (!(fl = fopen(buf, "w"))) {
perror("opening output file");
exit(1);
@ -203,18 +230,22 @@ void write_output(void)
found = 0;
for (door = 0; door < NUM_OF_DIRS; door++)
if (world[i].dir_option[door] &&
world[i].dir_option[door]->to_room != NOWHERE) {
found = 1;
fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n",
world[world[i].dir_option[door]->to_room].number,
dir_names[door],
world[world[i].dir_option[door]->to_room].name);
world[i].dir_option[door]->to_room != NOWHERE) {
found = 1;
//this call gets a pointer to the room referenced by the to_room for the door.
//This fixes a lot of issues introduced with the whole 'renumbering rooms' call
//and the binary search that didn't work well.
struct room_data* to_room = findRoom(world[i].dir_option[door]->to_room);
fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n",
to_room->number,
dir_names[door],
to_room->name);
}
if (!found)
fprintf(fl, "None!");
fclose(fl);
}
}
}
/* function to count how many hash-mark delimited records exist in a file */
int count_hash_records(FILE * fl)
@ -231,19 +262,35 @@ int count_hash_records(FILE * fl)
void index_boot(char *name)
void index_boot(int cnt, char **names)
{
FILE *db_file;
int rec_count = 0;
if (!(db_file = fopen(name, "r"))) {
perror("error opening world file");
exit(1);
//throw first entry away as that is the executable.
for (int i=1;i<cnt;i++) {
if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file");
exit(1);
}
//have to loop through files twice.
//once to get total record count
//second time to load them
rec_count += count_hash_records(db_file);
fclose(db_file);
}
rec_count = count_hash_records(db_file);
sprintf(buf,"Total records: %d\n",rec_count);
log(buf);
//now that we know how many records in total
//we can create the memory structure
CREATE(world, struct room_data, rec_count);
rewind(db_file);
discrete_load(db_file);
//now loop through files and load them
for (int i=1;i<cnt;i++) {
if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file");
exit(1);
}
discrete_load(db_file);
}
}
@ -257,6 +304,9 @@ void discrete_load(FILE * fl)
fprintf(stderr, "Format error after room #%d\n", nr);
exit(1);
}
if (*line == 'T') //Toss triggers. THey currently break this util.
continue;
if (*line == '$')
return;
@ -394,22 +444,6 @@ void setup_dir(FILE * fl, int room, int dir)
}
/* resolve all vnums into rnums in the world */
void renum_world(void)
{
register int room, door;
for (room = 0; room <= top_of_world; room++)
for (door = 0; door < NUM_OF_DIRS; door++)
if (world[room].dir_option[door])
if (world[room].dir_option[door]->to_room != NOWHERE)
world[room].dir_option[door]->to_room =
real_room(world[room].dir_option[door]->to_room,
world[room].number);
}
/*************************************************************************
* procedures for resetting, both play-time and boot-time *
*********************************************************************** */
@ -464,32 +498,6 @@ char *fread_string(FILE * fl, char *error)
/* returns the real number of the room with given virtual number */
int real_room(int virtual, int reference)
{
int bot, top, mid;
bot = 0;
top = top_of_world;
/* perform binary search on world-table */
for (;;) {
mid = (bot + top) / 2;
if ((world + mid)->number == virtual)
return (mid);
if (bot >= top) {
fprintf(stderr, "Room %d does not exist in database (referenced in room %d)\n", virtual, reference);
return (-1);
}
if ((world + mid)->number > virtual)
top = mid - 1;
else
bot = mid + 1;
}
}
/* get_line reads the next non-blank line off of the input stream.
* The newline character is removed from the input. Lines which begin
* with '*' are considered to be comments.

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 */
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 */
if (IS_NPC(ch)) col_width = 80 / num_cols;
else col_width = (GET_SCREEN_WIDTH(ch)) / num_cols;
@ -1494,3 +1489,68 @@ char * convert_from_tabs(char * string)
parse_tab(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);
char * convert_from_tabs(char * string);
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 */
void weather_and_time(int mode);