From 638f3792a5067245ba7b45e665c57f83b582938b Mon Sep 17 00:00:00 2001 From: Zachary Flower Date: Fri, 14 Apr 2017 21:17:32 -0600 Subject: [PATCH] migrate dikumud alfa code in --- Makefile | 13 +- README | 9 +- README.linux | 41 - act.comm.c | 27 +- act.informative.c | 145 +- act.movement.c | 40 +- act.obj1.c | 150 +- act.obj2.c | 35 +- act.offensive.c | 31 +- act.other.c | 10 +- act.social.c | 10 +- act.wizard.c | 62 +- board.c | 12 +- changes.c | 715 ++ comm.c | 2425 ++-- constants.c | 22 +- db.c | 14 +- db.h | 6 +- delplay.c | 2 +- doc/README | 61 +- doc/actions.doc | 132 +- doc/combat.doc | 200 +- doc/comm.doc | 276 +- doc/database.doc | 778 +- doc/dbsup.doc | 1156 +- doc/defs.doc | 754 +- doc/do_mail | 10 +- doc/handler.doc | 158 +- doc/interpreter.doc | 225 +- doc/levels.doc | 122 +- doc/license.doc | 205 +- doc/look.doc | 91 +- doc/macro.doc | 144 +- doc/newstruct.doc | 119 +- doc/running.doc | 188 +- doc/shops.doc | 147 +- doc/skills.doc | 235 +- doc/spell_info.doc | 289 +- doc/spells.doc | 169 +- doc/time.doc | 28 +- doc/values.doc | 610 +- fight.c | 14 +- handler.c | 8 +- handler.h | 3 +- insert_any.c | 2 +- interpreter-quinn.c | 1392 --- interpreter.c | 124 +- lib/README | 112 +- lib/actions | 1204 +- lib/board.messages | 1 + lib/credits | 40 +- lib/help | 42 +- lib/help_table | 2502 ++-- lib/info | 88 +- lib/messages | 814 +- lib/motd | 25 +- lib/news | 68 +- lib/pcobjs.obj | 1 + lib/players | 1 + lib/poses | 326 +- lib/tinyworld.mob | 3255 ++--- lib/tinyworld.obj | 5104 +++++--- lib/tinyworld.shp | 890 +- lib/tinyworld.wld | 27549 ++++++++++++++++++++++++------------------ lib/tinyworld.zon | 1587 ++- lib/wizlist | 49 +- limits.c | 27 +- list.c | 4 +- magic.c | 36 +- mail.c | 706 ++ maildef.h | 70 + mar_fiz_maz.c | 2 +- mobact.c | 4 +- modify.c | 154 +- nightrun | 3 +- opstart | 1 - reception.c | 6 +- repairgo.c | 61 + shop.c | 42 +- sign.c | 6 +- signals.c | 6 +- spec_assign.c | 23 +- spec_procs.c | 275 +- spell_parser.c | 6 +- spells.h | 1 - spells2.c | 8 +- structs.h | 55 +- syslog | 46 - utility.c | 12 +- utils.h | 4 +- weather.c | 4 +- 91 files changed, 31313 insertions(+), 25316 deletions(-) delete mode 100644 README.linux create mode 100644 changes.c delete mode 100644 interpreter-quinn.c create mode 100644 mail.c create mode 100644 maildef.h create mode 100644 repairgo.c delete mode 100644 syslog diff --git a/Makefile b/Makefile index bb8237b..75e717c 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ CC=gcc CFLAGS = -ansi LFLAGS = -lcrypt -HEADERFILES = structs.h utils.h comm.h interpreter.h db.h -dmserver : comm.o act.comm.o act.informative.o act.movement.o act.obj1.o act.obj2.o act.offensive.o act.other.o act.social.o act.wizard.o handler.o db.o interpreter.o utility.o spec_assign.o shop.o limits.o mobact.o fight.o modify.o weather.o spell_parser.o spells1.o spells2.o reception.o constants.o spec_procs.o signals.o board.o mar_fiz_maz.o magic.o +HEADERFILES = structs.h utils.h comm.h interpreter.h db.h maildef.h +dmserver : comm.o act.comm.o act.informative.o act.movement.o act.obj1.o act.obj2.o act.offensive.o act.other.o act.social.o act.wizard.o handler.o db.o interpreter.o utility.o spec_assign.o shop.o limits.o mobact.o fight.o modify.o weather.o spell_parser.o spells1.o spells2.o reception.o constants.o spec_procs.o signals.o board.o mar_fiz_maz.o magic.o mail.o changes.o comm.o : comm.c structs.h utils.h comm.h interpreter.h handler.h db.h $(CC) -c -g $(CFLAGS) comm.c act.comm.o : act.comm.c structs.h utils.h comm.h interpreter.h handler.h \ @@ -87,5 +87,10 @@ signals.o : signals.c utils.h mar_fiz_maz.o : mar_fiz_maz.c structs.h utils.h comm.h interpreter.h \ handler.h db.h spells.h limits.h $(CC) -c $(CFLAGS) mar_fiz_maz.c -dmserver : comm.c act.comm.c act.informative.c act.movement.c act.obj1.c act.obj2.c act.offensive.c act.other.c act.social.c act.wizard.c handler.c db.c interpreter.c utility.c spec_assign.c shop.c limits.c mobact.c fight.c modify.c weather.c spells1.c spells2.c spell_parser.c reception.c constants.c spec_procs.c signals.c board.c mar_fiz_maz.c magic.c - $(CC) -o dmserver $(CFLAGS) comm.o act.comm.o act.informative.o act.movement.o act.obj1.o act.obj2.o act.offensive.o act.other.o act.social.o act.wizard.o handler.o db.o interpreter.o utility.o spec_assign.o shop.o limits.o mobact.o fight.o modify.o weather.o spells1.o spells2.o spell_parser.o reception.o constants.o spec_procs.o signals.o board.o mar_fiz_maz.o magic.o $(LFLAGS) +mail.o : mail.c maildef.h + $(CC) -c $(CFLAGS) mail.c +changes.o : changes.c structs.h utils.h comm.h interpreter.h \ + handler.h db.h spells.h limits.h + $(CC) -c $(CFLAGS) changes.c +dmserver : comm.c act.comm.c act.informative.c act.movement.c act.obj1.c act.obj2.c act.offensive.c act.other.c act.social.c act.wizard.c handler.c db.c interpreter.c utility.c spec_assign.c shop.c limits.c mobact.c fight.c modify.c weather.c spells1.c spells2.c spell_parser.c reception.c constants.c spec_procs.c signals.c board.c mar_fiz_maz.c magic.c mail.c changes.c + $(CC) -o dmserver $(CFLAGS) comm.o act.comm.o act.informative.o act.movement.o act.obj1.o act.obj2.o act.offensive.o act.other.o act.social.o act.wizard.o handler.o db.o interpreter.o utility.o spec_assign.o shop.o limits.o mobact.o fight.o modify.o weather.o spells1.o spells2.o spell_parser.o reception.o constants.o spec_procs.o signals.o board.o mar_fiz_maz.o magic.o mail.o changes.o $(LFLAGS) diff --git a/README b/README index 198f018..94fa6a6 100644 --- a/README +++ b/README @@ -8,10 +8,17 @@ VAX 11/785 - Unix-BSD 4.3 (it was written on one of these babies) Sun 4 - Unix Sun 3 (I think) - Unix +plus lots of others... we've lost track. + +We are, of course, very interested in expanding this list. If you successfully +compile and run the game on a machine not mentioned above, please send us a +word. + See doc/running.doc for some hints on how to run the game - and try 'wizhelp' in the game itself. If you run into trouble whilst compiling or running the game, we'll be happy to try and help you out. Send email to: - quinn@freja.diku.dk + quinn@freja.diku.dk or one of the other people from the 'credits' file. + diff --git a/README.linux b/README.linux deleted file mode 100644 index 0bc31b9..0000000 --- a/README.linux +++ /dev/null @@ -1,41 +0,0 @@ -I had to make modifications to the code mostly in comm.c. Some of the -socket handling stuff did not seem neccessary. One problem was with -gethostbyname() function call. For some reason this allways returned -NULL on my machine. Of course, I may not have tcp/ip set up correctly on -my machine, but looking at the code, the only reason to call this function -was to get the type of the address being returned. Since other OS's use -AF_INET for this I just hardcoded it in. I think this will be ok (read -it works on my machine). - -Some other stuff was that linux uses -struct sockaddr_in -instead of -struct sockaddr -for some of the calls to bind. This caused a few problems but looking at -the structure themselves, they seems fairly interchangeable so I just cast -it to get rid of the warning. - -Lastly there was the strdup() function in utility.c that is about the same -as the strdup written in linux, so I just commented tthe strdup in utility.c -out and took out some of the prototypes. - -There are still some warning with the signals but this code works on ONE -machine... i.e. I am not connected to any network so have no way to test -from another machine. However, I can use telnet to connect to the game -from my own machine. - -Oh... the standard disclaimers apply here.... I am not responsible for any -lost or stolen articles or broken systems or hair pulled out. I am especially -not responsible for any effect this game may have on your grades or your -system. If the game trashes your system, I'll cry for you but that is about -all I can do. - -Just for reference. I am running on SLS 98p5 - -If you have any questions, feel free to email me... However, this does not -mean that I will have an answer.... - -Good Luck -*smile* - - diff --git a/act.comm.c b/act.comm.c index 4a21f77..632957d 100644 --- a/act.comm.c +++ b/act.comm.c @@ -53,6 +53,14 @@ void do_shout(struct char_data *ch, char *argument, int cmd) return; } + if (GET_MOVE(ch) < 10) + { + send_to_char("You are too exhausted.\n\r", ch); + return; + } + + GET_MOVE(ch) -= 10; + for (; *argument == ' '; argument++); if (!(*argument)) @@ -76,6 +84,12 @@ void do_tell(struct char_data *ch, char *argument, int cmd) char name[100], message[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH]; + if (IS_SET(ch->specials.act, PLR_NOTELL)) + { + send_to_char("Your message didn't get through!!\n\r", ch); + return; + } + half_chop(argument,name,message); if(!*name || !*message) @@ -84,7 +98,8 @@ void do_tell(struct char_data *ch, char *argument, int cmd) send_to_char("No-one by that name here..\n\r", ch); else if (ch == vict) send_to_char("You try to tell yourself something.\n\r", ch); - else if (GET_POS(vict) == POSITION_SLEEPING) + else if ((GET_POS(vict) == POSITION_SLEEPING) || + IS_SET(vict->specials.act, PLR_NOTELL)) { act("$E can't hear you.",FALSE,ch,0,vict,TO_CHAR); } @@ -170,7 +185,7 @@ void do_write(struct char_data *ch, char *argument, int cmd) return; if (!*papername) /* nothing was delivered */ - { + { send_to_char( "Write? with what? ON what? what are you trying to do??\n\r", ch); return; @@ -191,7 +206,7 @@ void do_write(struct char_data *ch, char *argument, int cmd) } } else /* there was one arg.let's see what we can find */ - { + { if (!(paper = get_obj_in_list_vis(ch, papername, ch->carrying))) { sprintf(buf, "There is no %s in your inventory.\n\r", papername); @@ -221,13 +236,13 @@ void do_write(struct char_data *ch, char *argument, int cmd) send_to_char("The stuff in your hand is invisible! Yeech!!\n\r", ch); return; } - + if (pen) paper = ch->equipment[HOLD]; else pen = ch->equipment[HOLD]; } - + /* ok.. now let's see what kind of stuff we've found */ if (pen->obj_flags.type_flag != ITEM_PEN) { @@ -242,7 +257,7 @@ void do_write(struct char_data *ch, char *argument, int cmd) else { /* we can write - hooray! */ - + send_to_char("Ok.. go ahead and write.. end the note with a @.\n\r", ch); act("$n begins to jot down a note.", TRUE, ch, 0,0,TO_ROOM); diff --git a/act.informative.c b/act.informative.c index 3e1ad21..bc1655f 100644 --- a/act.informative.c +++ b/act.informative.c @@ -28,7 +28,7 @@ extern char credits[MAX_STRING_LENGTH]; extern char news[MAX_STRING_LENGTH]; extern char info[MAX_STRING_LENGTH]; extern char wizlist[MAX_STRING_LENGTH]; -extern char *dirs[]; +extern char *dirs[]; extern char *where[]; extern char *color_liquid[]; extern char *fullness[]; @@ -107,7 +107,7 @@ void show_obj_to_char(struct obj_data *object, struct char_data *ch, int mode) if ((mode == 0) && object->description) strcpy(buffer,object->description); else if (object->short_description && ((mode == 1) || - (mode == 2) || (mode==3) || (mode == 4))) + (mode == 2) || (mode==3) || (mode == 4))) strcpy(buffer,object->short_description); else if (mode == 5) { if (object->obj_flags.type_flag == ITEM_NOTE) @@ -132,7 +132,7 @@ void show_obj_to_char(struct obj_data *object, struct char_data *ch, int mode) } } - if (mode != 3) { + if (mode != 3) { found = FALSE; if (IS_OBJ_STAT(object,ITEM_INVISIBLE)) { strcat(buffer,"(invisible)"); @@ -160,7 +160,7 @@ void show_obj_to_char(struct obj_data *object, struct char_data *ch, int mode) page_string(ch->desc, buffer, 1); /* - if (((mode == 2) || (mode == 4)) && (GET_ITEM_TYPE(object) == + if (((mode == 2) || (mode == 4)) && (GET_ITEM_TYPE(object) == ITEM_CONTAINER)) { strcpy(buffer,"The "); strcat(buffer,fname(object->name)); @@ -172,18 +172,18 @@ void show_obj_to_char(struct obj_data *object, struct char_data *ch, int mode) */ } -void list_obj_to_char(struct obj_data *list,struct char_data *ch, int mode, +void list_obj_to_char(struct obj_data *list,struct char_data *ch, int mode, bool show) { struct obj_data *i; bool found; found = FALSE; - for ( i = list ; i ; i = i->next_content ) { + for ( i = list ; i ; i = i->next_content ) { if (CAN_SEE_OBJ(ch,i)) { show_obj_to_char(i, ch, mode); found = TRUE; - } - } + } + } if ((! found) && (show)) send_to_char("Nothing\n\r", ch); } @@ -205,7 +205,7 @@ void show_char_to_char(struct char_data *i, struct char_data *ch, int mode) if (!(i->player.long_descr)||(GET_POS(i) != i->specials.default_pos)){ /* A player char or a mobile without long descr, or not in default pos. */ - if (!IS_NPC(i)) { + if (!IS_NPC(i)) { strcpy(buffer,GET_NAME(i)); strcat(buffer," "); strcat(buffer,GET_TITLE(i)); @@ -218,21 +218,21 @@ void show_char_to_char(struct char_data *i, struct char_data *ch, int mode) strcat(buffer," (invisible)"); switch(GET_POS(i)) { - case POSITION_STUNNED : + case POSITION_STUNNED : strcat(buffer," is lying here, stunned."); break; - case POSITION_INCAP : + case POSITION_INCAP : strcat(buffer," is lying here, incapacitated."); break; - case POSITION_MORTALLYW: + case POSITION_MORTALLYW: strcat(buffer," is lying here, mortally wounded."); break; - case POSITION_DEAD : + case POSITION_DEAD : strcat(buffer," is lying here, dead."); break; - case POSITION_STANDING : + case POSITION_STANDING : strcat(buffer," is standing here."); break; - case POSITION_SITTING : + case POSITION_SITTING : strcat(buffer," is sitting here."); break; - case POSITION_RESTING : + case POSITION_RESTING : strcat(buffer," is resting here."); break; - case POSITION_SLEEPING : + case POSITION_SLEEPING : strcat(buffer," is sleeping here."); break; case POSITION_FIGHTING : if (i->specials.fighting) { @@ -278,7 +278,7 @@ void show_char_to_char(struct char_data *i, struct char_data *ch, int mode) send_to_char(buffer, ch); } - + if (IS_AFFECTED(i,AFF_SANCTUARY)) act("$n glows with a bright light!", FALSE, i, 0, ch, TO_VICT); @@ -363,15 +363,15 @@ void show_char_to_char(struct char_data *i, struct char_data *ch, int mode) -void list_char_to_char(struct char_data *list, struct char_data *ch, +void list_char_to_char(struct char_data *list, struct char_data *ch, int mode) { struct char_data *i; for (i = list; i ; i = i->next_in_room) { if ( (ch!=i) && (IS_AFFECTED(ch, AFF_SENSE_LIFE) || (CAN_SEE(ch,i) && !IS_AFFECTED(i, AFF_HIDE))) ) - show_char_to_char(i,ch,0); - } + show_char_to_char(i,ch,0); + } } @@ -387,7 +387,7 @@ void do_look(struct char_data *ch, char *argument, int cmd) struct obj_data *tmp_object, *found_object; struct char_data *tmp_char; char *tmp_desc; - static char *keywords[]= { + static char *keywords[]= { "north", "east", "south", @@ -428,10 +428,10 @@ void do_look(struct char_data *ch, char *argument, int cmd) /* look */ case 0 : case 1 : - case 2 : - case 3 : + case 2 : + case 3 : case 4 : - case 5 : { + case 5 : { if (EXIT(ch, keyword_no)) { @@ -442,7 +442,7 @@ void do_look(struct char_data *ch, char *argument, int cmd) send_to_char("You see nothing special.\n\r", ch); } - if (IS_SET(EXIT(ch, keyword_no)->exit_info, EX_CLOSED) && + if (IS_SET(EXIT(ch, keyword_no)->exit_info, EX_CLOSED) && (EXIT(ch, keyword_no)->keyword)) { sprintf(buffer, "The %s is closed.\n\r", fname(EXIT(ch, keyword_no)->keyword)); @@ -533,7 +533,7 @@ void do_look(struct char_data *ch, char *argument, int cmd) /* Extra description in room?? */ if (!found) { - tmp_desc = find_ex_description(arg2, + tmp_desc = find_ex_description(arg2, world[ch->in_room].ex_description); if (tmp_desc) { page_string(ch->desc, tmp_desc, 0); @@ -550,7 +550,7 @@ void do_look(struct char_data *ch, char *argument, int cmd) for (j = 0; j< MAX_WEAR && !found; j++) { if (ch->equipment[j]) { if (CAN_SEE_OBJ(ch,ch->equipment[j])) { - tmp_desc = find_ex_description(arg2, + tmp_desc = find_ex_description(arg2, ch->equipment[j]->ex_description); if (tmp_desc) { page_string(ch->desc, tmp_desc, 1); @@ -564,11 +564,11 @@ void do_look(struct char_data *ch, char *argument, int cmd) /* In inventory */ if (!found) { - for(tmp_object = ch->carrying; - tmp_object && !found; + for(tmp_object = ch->carrying; + tmp_object && !found; tmp_object = tmp_object->next_content) { if CAN_SEE_OBJ(ch, tmp_object) { - tmp_desc = find_ex_description(arg2, + tmp_desc = find_ex_description(arg2, tmp_object->ex_description); if (tmp_desc) { page_string(ch->desc, tmp_desc, 1); @@ -581,11 +581,11 @@ void do_look(struct char_data *ch, char *argument, int cmd) /* Object In room */ if (!found) { - for(tmp_object = world[ch->in_room].contents; - tmp_object && !found; + for(tmp_object = world[ch->in_room].contents; + tmp_object && !found; tmp_object = tmp_object->next_content) { if CAN_SEE_OBJ(ch, tmp_object) { - tmp_desc = find_ex_description(arg2, + tmp_desc = find_ex_description(arg2, tmp_object->ex_description); if (tmp_desc) { page_string(ch->desc, tmp_desc, 1); @@ -613,7 +613,7 @@ void do_look(struct char_data *ch, char *argument, int cmd) break; - /* look '' */ + /* look '' */ case 8 : { send_to_char(world[ch->in_room].name, ch); @@ -629,7 +629,7 @@ void do_look(struct char_data *ch, char *argument, int cmd) break; /* wrong arg */ - case -1 : + case -1 : send_to_char("Sorry, I didn't understand that!\n\r", ch); break; } @@ -690,7 +690,7 @@ void do_exits(struct char_data *ch, char *argument, int cmd) int door; char buf[MAX_STRING_LENGTH]; char *exits[] = - { + { "North", "East ", "South", @@ -737,8 +737,12 @@ void do_score(struct char_data *ch, char *argument, int cmd) if (GET_COND(ch,DRUNK)>10) send_to_char("You are intoxicated.\n\r", ch); + if (!GET_COND(ch,THIRST)) + send_to_char("You are thirsty.\n\r", ch); + if (!GET_COND(ch,FULL)) + send_to_char("You are hungry.\n\r", ch); - sprintf(buf, + sprintf(buf, "You have %d(%d) hit, %d(%d) mana and %d(%d) movement points.\n\r", GET_HIT(ch),GET_MAX_HIT(ch), GET_MANA(ch),GET_MAX_MANA(ch), @@ -753,8 +757,8 @@ void do_score(struct char_data *ch, char *argument, int cmd) ch->player.time.played, 0); sprintf(buf,"You have been playing for %d days and %d hours.\n\r", playing_time.day, - playing_time.hours); - send_to_char(buf, ch); + playing_time.hours); + send_to_char(buf, ch); sprintf(buf,"This ranks you as %s %s (level %d).\n\r", GET_NAME(ch), @@ -762,19 +766,19 @@ void do_score(struct char_data *ch, char *argument, int cmd) send_to_char(buf,ch); switch(GET_POS(ch)) { - case POSITION_DEAD : + case POSITION_DEAD : send_to_char("You are DEAD!\n\r", ch); break; case POSITION_MORTALLYW : send_to_char("You are mortally wounded!, you should seek help!\n\r", ch); break; - case POSITION_INCAP : + case POSITION_INCAP : send_to_char("You are incapacitated, slowly fading away\n\r", ch); break; - case POSITION_STUNNED : + case POSITION_STUNNED : send_to_char("You are stunned! You can't move\n\r", ch); break; - case POSITION_SLEEPING : + case POSITION_SLEEPING : send_to_char("You are sleeping.\n\r",ch); break; - case POSITION_RESTING : + case POSITION_RESTING : send_to_char("You are resting.\n\r",ch); break; - case POSITION_SITTING : + case POSITION_SITTING : send_to_char("You are sitting.\n\r",ch); break; case POSITION_FIGHTING : if (ch->specials.fighting) @@ -783,7 +787,7 @@ void do_score(struct char_data *ch, char *argument, int cmd) else send_to_char("You are fighting thin air.\n\r", ch); break; - case POSITION_STANDING : + case POSITION_STANDING : send_to_char("You are standing.\n\r",ch); break; default : send_to_char("You are floating.\n\r",ch); break; @@ -850,7 +854,7 @@ void do_weather(struct char_data *ch, char *argument, int cmd) "lit by flashes of lightning"}; if (OUTSIDE(ch)) { - sprintf(buf, + sprintf(buf, "The sky is %s and %s.\n\r", sky_look[weather_info.sky], (weather_info.change >=0 ? "you feel a warm wind from south" : @@ -949,7 +953,7 @@ do_wizhelp(struct char_data *ch, char *argument, int cmd) for (no = 1, i = 0; *command[i] != '\n'; i++) if ((GET_LEVEL(ch) >= cmd_info[i+1].minimum_level) && - (cmd_info[i+1].minimum_level >= 21)) + (cmd_info[i+1].minimum_level >= 21) && (i != 217)) { sprintf(buf + strlen(buf), "%-10s", command[i]); @@ -972,18 +976,19 @@ void do_who(struct char_data *ch, char *argument, int cmd) send_to_char("Players\n\r-------\n\r", ch); for (d = descriptor_list; d; d = d->next) { - if (!d->connected && CAN_SEE(ch, d->character)) + if ((!d->connected) && + (CAN_SEE(ch, d->character) || (GET_LEVEL(ch) >= 23))) { - if(d->original) /* If switched */ - sprintf(buf, "%s %s\n\r", + if(d->original) /* If switched */ + sprintf(buf, "%s %s\n\r", GET_NAME(d->original), d->original->player.title); else - sprintf(buf, "%s %s\n\r", + sprintf(buf, "%s %s\n\r", GET_NAME(d->character), d->character->player.title); - + send_to_char(buf, ch); } } @@ -999,7 +1004,7 @@ void do_users(struct char_data *ch, char *argument, int cmd) struct descriptor_data *d; strcpy(buf, "Connections:\n\r------------\n\r"); - + for (d = descriptor_list; d; d = d->next) { if (d->character && d->character->player.name) @@ -1011,7 +1016,7 @@ void do_users(struct char_data *ch, char *argument, int cmd) } else strcpy(line, "UNDEFINED : "); - if (d->host) + if ((d->host) && *(d->host)) sprintf(line + strlen(line), "[%s]\n\r", d->host); else strcat(line, "[Hostname unknown]\n\r"); @@ -1098,7 +1103,7 @@ void do_where(struct char_data *ch, char *argument, int cmd) else { strcpy(buf, "Players:\n\r--------\n\r"); - + for (d = descriptor_list; d; d = d->next) { if (d->character && (d->connected == CON_PLYNG) && (d->character->in_room != NOWHERE)) { if (d->original) /* If switched */ @@ -1112,7 +1117,7 @@ void do_where(struct char_data *ch, char *argument, int cmd) d->character->player.name, world[d->character->in_room].name, world[d->character->in_room].number); - + send_to_char(buf, ch); } } @@ -1150,7 +1155,7 @@ void do_where(struct char_data *ch, char *argument, int cmd) if (GET_LEVEL(ch) > 20) { for (k = object_list; k; k = k->next) - if (isname(name, k->name) && CAN_SEE_OBJ(ch, k) && + if (isname(name, k->name) && CAN_SEE_OBJ(ch, k) && (k->in_room != NOWHERE)) { sprintf(buf, "%-30s- %s [%d]\n\r", k->short_description, @@ -1171,6 +1176,8 @@ void do_levels(struct char_data *ch, char *argument, int cmd) { int i; char buf[MAX_STRING_LENGTH]; + char arg[MAX_INPUT_LENGTH]; + int class; extern const struct title_type titles[4][25]; @@ -1179,20 +1186,30 @@ void do_levels(struct char_data *ch, char *argument, int cmd) send_to_char("You ain't nothin' but a hound-dog.\n\r", ch); return; } + class = GET_CLASS(ch); + + one_argument(argument,arg); + + if (*arg) { + if (!str_cmp(arg,"magic")) class = 1; + else if (!str_cmp(arg,"cleric")) class = 2; + else if (!str_cmp(arg,"thief")) class = 3; + else if (!str_cmp(arg,"fighter")) class = 4; + } *buf = '\0'; - + for (i = 1; i < 21; i++) { sprintf(buf + strlen(buf), "%7d-%-7d : ", - titles[GET_CLASS(ch) - 1][i].exp, - titles[GET_CLASS(ch) - 1][i + 1].exp); + titles[class - 1][i].exp, + titles[class - 1][i + 1].exp); switch(GET_SEX(ch)) { case SEX_MALE: - strcat(buf, titles[GET_CLASS(ch) - 1][i].title_m); break; + strcat(buf, titles[class - 1][i].title_m); break; case SEX_FEMALE: - strcat(buf, titles[GET_CLASS(ch) - 1][i].title_f); break; + strcat(buf, titles[class - 1][i].title_f); break; default: send_to_char("Oh dear.\n\r", ch); break; } diff --git a/act.movement.c b/act.movement.c index 59fd419..6c89d85 100644 --- a/act.movement.c +++ b/act.movement.c @@ -19,10 +19,10 @@ extern struct room_data *world; extern struct char_data *character_list; -extern struct descriptor_data *descriptor_list; +extern struct descriptor_data *descriptor_list; extern struct index_data *obj_index; extern int rev_dir[]; -extern char *dirs[]; +extern char *dirs[]; extern int movement_loss[]; /* external functs */ @@ -34,9 +34,9 @@ struct obj_data *get_obj_in_list_vis(struct char_data *ch, char *name, int do_simple_move(struct char_data *ch, int cmd, int following) -/* Assumes, +/* Assumes, 1. That there is no master and no followers. - 2. That the direction exists. + 2. That the direction exists. Returns : 1 : If succes. @@ -96,7 +96,7 @@ int do_simple_move(struct char_data *ch, int cmd, int following) char_to_room(ch, world[was_in].dir_option[cmd]->to_room); if (!IS_AFFECTED(ch, AFF_SNEAK)) - act("$n has arrived.", TRUE, ch, 0,0, TO_ROOM); + act("$n has arrived.", TRUE, ch, 0,0, TO_ROOM); do_look(ch, "\0",15); @@ -136,7 +136,7 @@ void do_move(struct char_data *ch, char *argument, int cmd) do_simple_move(ch,cmd,FALSE); else { - if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master) && + if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master) && (ch->in_room == ch->master->in_room)) { send_to_char("The thought of leaving your master makes you weep.\n\r", ch); act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM); @@ -170,7 +170,7 @@ int find_door(struct char_data *ch, char *type, char *dir) { char buf[MAX_STRING_LENGTH]; int door; - char *dirs[] = + char *dirs[] = { "north", "east", @@ -275,7 +275,7 @@ void do_open(struct char_data *ch, char *argument, int cmd) send_to_char("Ok.\n\r", ch); /* now for opening the OTHER side of the door! */ if ((other_room = EXIT(ch, door)->to_room) != NOWHERE) - if (back = world[other_room].dir_option[rev_dir[door]]) + if (back = world[other_room].dir_option[rev_dir[door]]) if (back->to_room == ch->in_room) { REMOVE_BIT(back->exit_info, EX_CLOSED); @@ -290,7 +290,7 @@ void do_open(struct char_data *ch, char *argument, int cmd) send_to_room( "The door is opened from the other side.\n\r", EXIT(ch, door)->to_room); - } + } } } @@ -358,7 +358,7 @@ void do_close(struct char_data *ch, char *argument, int cmd) send_to_room( "The door closes quietly.\n\r", EXIT(ch, door)->to_room); - } + } } } @@ -404,7 +404,7 @@ void do_lock(struct char_data *ch, char *argument, int cmd) else if (obj->obj_flags.value[2] < 0) send_to_char("That thing can't be locked.\n\r", ch); else if (!has_key(ch, obj->obj_flags.value[2])) - send_to_char("You don't seem to have the proper key.\n\r", ch); + send_to_char("You don't seem to have the proper key.\n\r", ch); else if (IS_SET(obj->obj_flags.value[1], CONT_LOCKED)) send_to_char("It is locked already.\n\r", ch); else @@ -470,7 +470,7 @@ void do_unlock(struct char_data *ch, char *argument, int cmd) else if (obj->obj_flags.value[2] < 0) send_to_char("Odd - you can't seem to find a keyhole.\n\r", ch); else if (!has_key(ch, obj->obj_flags.value[2])) - send_to_char("You don't seem to have the proper key.\n\r", ch); + send_to_char("You don't seem to have the proper key.\n\r", ch); else if (!IS_SET(obj->obj_flags.value[1], CONT_LOCKED)) send_to_char("Oh.. it wasn't locked, after all.\n\r", ch); else @@ -656,26 +656,26 @@ void do_stand(struct char_data *ch, char *argument, int cmd) char buffer[MAX_STRING_LENGTH]; switch(GET_POS(ch)) { - case POSITION_STANDING : { + case POSITION_STANDING : { act("You are already standing.",FALSE, ch,0,0,TO_CHAR); } break; - case POSITION_SITTING : { + case POSITION_SITTING : { act("You stand up.", FALSE, ch,0,0,TO_CHAR); act("$n clambers on $s feet.",TRUE, ch, 0, 0, TO_ROOM); GET_POS(ch) = POSITION_STANDING; } break; - case POSITION_RESTING : { + case POSITION_RESTING : { act("You stop resting, and stand up.", FALSE, ch,0,0,TO_CHAR); act("$n stops resting, and clambers on $s feet.", TRUE, ch, 0, 0, TO_ROOM); GET_POS(ch) = POSITION_STANDING; } break; - case POSITION_SLEEPING : { + case POSITION_SLEEPING : { act("You have to wake up first!", FALSE, ch, 0,0,TO_CHAR); } break; - case POSITION_FIGHTING : { + case POSITION_FIGHTING : { act("Do you not consider fighting as standing?",FALSE, ch, 0, 0, TO_CHAR); } break; - default : { + default : { act("You stop floating around, and put your feet on the ground.", FALSE, ch, 0, 0, TO_CHAR); act("$n stops floating around, and puts $s feet on the ground.", @@ -716,7 +716,7 @@ void do_sit(struct char_data *ch, char *argument, int cmd) } break; } } - + void do_rest(struct char_data *ch, char *argument, int cmd) { char buffer[MAX_STRING_LENGTH]; @@ -755,7 +755,7 @@ void do_sleep(struct char_data *ch, char *argument, int cmd) { char buffer[MAX_STRING_LENGTH]; switch(GET_POS(ch)) { - case POSITION_STANDING : + case POSITION_STANDING : case POSITION_SITTING : case POSITION_RESTING : { send_to_char("You go to sleep.\n\r", ch); diff --git a/act.obj1.c b/act.obj1.c index fb27379..9532974 100644 --- a/act.obj1.c +++ b/act.obj1.c @@ -21,14 +21,15 @@ extern struct str_app_type str_app[]; extern struct room_data *world; extern struct descriptor_data *descriptor_list; extern struct room_data *world; - + /* extern functions */ +void log(char *str); struct obj_data *create_money( int amount ); /* procedures related to get */ -void get(struct char_data *ch, struct obj_data *obj_object, +void get(struct char_data *ch, struct obj_data *obj_object, struct obj_data *sub_object) { struct char_data *tmp_char; char buffer[MAX_STRING_LENGTH]; @@ -52,7 +53,7 @@ char buffer[MAX_STRING_LENGTH]; act("You get $p.", 0, ch, obj_object, 0, TO_CHAR); act("$n gets $p.", 1, ch, obj_object, 0, TO_ROOM); } - if((obj_object->obj_flags.type_flag == ITEM_MONEY) && + if((obj_object->obj_flags.type_flag == ITEM_MONEY) && (obj_object->obj_flags.value[0]>=1)) { obj_from_char(obj_object); @@ -107,11 +108,11 @@ void do_get(struct char_data *ch, char *argument, int cmd) switch (type) { /* get */ - case 0:{ - send_to_char("Get what?\n\r", ch); + case 0:{ + send_to_char("Get what?\n\r", ch); } break; /* get all */ - case 1:{ + case 1:{ sub_object = 0; found = FALSE; fail = FALSE; @@ -121,7 +122,7 @@ void do_get(struct char_data *ch, char *argument, int cmd) next_obj = obj_object->next_content; if (CAN_SEE_OBJ(ch,obj_object)) { if ((IS_CARRYING_N(ch) + 1) <= CAN_CARRY_N(ch)) { - if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) <= + if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) <= CAN_CARRY_W(ch)) { if (CAN_WEAR(obj_object,ITEM_TAKE)) { get(ch,obj_object,sub_object); @@ -131,35 +132,31 @@ void do_get(struct char_data *ch, char *argument, int cmd) fail = TRUE; } } else { - sprintf(buffer,"%s : You can't carry that much weight.\n\r", + sprintf(buffer,"%s : You can't carry that much weight.\n\r", fname(obj_object->name)); send_to_char(buffer, ch); fail = TRUE; } } else { - sprintf(buffer,"%s : You can't carry that many items.\n\r", + sprintf(buffer,"%s : You can't carry that many items.\n\r", fname(obj_object->name)); send_to_char(buffer, ch); fail = TRUE; } } } - if (found) { - send_to_char("OK.\n\r", ch); - } else { if (!fail) send_to_char("You see nothing here.\n\r", ch); - } } break; /* get ??? */ case 2:{ sub_object = 0; found = FALSE; fail = FALSE; - obj_object = get_obj_in_list_vis(ch, arg1, + obj_object = get_obj_in_list_vis(ch, arg1, world[ch->in_room].contents); if (obj_object) { if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) { - if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < + if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < CAN_CARRY_W(ch)) { if (CAN_WEAR(obj_object,ITEM_TAKE)) { get(ch,obj_object,sub_object); @@ -169,13 +166,13 @@ void do_get(struct char_data *ch, char *argument, int cmd) fail = TRUE; } } else { - sprintf(buffer,"%s : You can't carry that much weight.\n\r", + sprintf(buffer,"%s : You can't carry that much weight.\n\r", fname(obj_object->name)); send_to_char(buffer, ch); fail = TRUE; } } else { - sprintf(buffer,"%s : You can't carry that many items.\n\r", + sprintf(buffer,"%s : You can't carry that many items.\n\r", fname(obj_object->name)); send_to_char(buffer, ch); fail = TRUE; @@ -187,110 +184,120 @@ void do_get(struct char_data *ch, char *argument, int cmd) } } break; /* get all all */ - case 3:{ + case 3:{ send_to_char("You must be joking?!\n\r", ch); } break; /* get all ??? */ case 4:{ found = FALSE; - fail = FALSE; - sub_object = get_obj_in_list_vis(ch, arg2, + fail = FALSE; + sub_object = get_obj_in_list_vis(ch, arg2, world[ch->in_room].contents); if (!sub_object){ sub_object = get_obj_in_list_vis(ch, arg2, ch->carrying); } if (sub_object) { if (GET_ITEM_TYPE(sub_object) == ITEM_CONTAINER) { - for(obj_object = sub_object->contains; - obj_object; - obj_object = next_obj) { - next_obj = obj_object->next_content; - if (CAN_SEE_OBJ(ch,obj_object)) { - if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) { - if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < - CAN_CARRY_W(ch)) { - if (CAN_WEAR(obj_object,ITEM_TAKE)) { - get(ch,obj_object,sub_object); - found = TRUE; + if (!IS_SET(sub_object->obj_flags.value[1], CONT_CLOSED)) { + for(obj_object = sub_object->contains; + obj_object; + obj_object = next_obj) { + next_obj = obj_object->next_content; + if (CAN_SEE_OBJ(ch,obj_object)) { + if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) { + if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < + CAN_CARRY_W(ch)) { + if (CAN_WEAR(obj_object,ITEM_TAKE)) { + get(ch,obj_object,sub_object); + found = TRUE; + } else { + send_to_char("You can't take that\n\r", ch); + fail = TRUE; + } } else { - send_to_char("You can't take that\n\r", ch); + sprintf(buffer,"%s : You can't carry that much weight.\n\r", + fname(obj_object->name)); + send_to_char(buffer, ch); fail = TRUE; } } else { - sprintf(buffer,"%s : You can't carry that much weight.\n\r", + sprintf(buffer,"%s : You can't carry that many items.\n\r", fname(obj_object->name)); send_to_char(buffer, ch); fail = TRUE; } - } else { - sprintf(buffer,"%s : You can't carry that many items.\n\r", - fname(obj_object->name)); - send_to_char(buffer, ch); - fail = TRUE; } } - } - if (!found && !fail) { - sprintf(buffer,"You do not see anything in the %s.\n\r", + if (!found && !fail) { + sprintf(buffer,"You do not see anything in the %s.\n\r", fname(sub_object->name)); - send_to_char(buffer, ch); - fail = TRUE; + send_to_char(buffer, ch); + fail = TRUE; + } } - } else { + else { /* container closed */ + send_to_char("It's closed.\n\r", ch); + } + }else { sprintf(buffer,"The %s is not a container.\n\r", fname(sub_object->name)); send_to_char(buffer, ch); fail = TRUE; } - } else { + } else { sprintf(buffer,"You do not see or have the %s.\n\r", arg2); send_to_char(buffer, ch); fail = TRUE; } } break; - case 5:{ - send_to_char("You can't take a thing from more than one container.\n\r", + case 5:{ + send_to_char("You can't take a thing from more than one container.\n\r", ch); } break; case 6:{ found = FALSE; fail = FALSE; - sub_object = get_obj_in_list_vis(ch, arg2, + sub_object = get_obj_in_list_vis(ch, arg2, world[ch->in_room].contents); if (!sub_object){ sub_object = get_obj_in_list_vis(ch, arg2, ch->carrying); } if (sub_object) { if (GET_ITEM_TYPE(sub_object) == ITEM_CONTAINER) { - obj_object = get_obj_in_list_vis(ch, arg1, sub_object->contains); - if (obj_object) { - if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) { - if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < - CAN_CARRY_W(ch)) { - if (CAN_WEAR(obj_object,ITEM_TAKE)) { - get(ch,obj_object,sub_object); - found = TRUE; + if (!IS_SET(sub_object->obj_flags.value[1], CONT_CLOSED)) { + obj_object = get_obj_in_list_vis(ch, arg1, sub_object->contains); + if (obj_object) { + if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) { + if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < + CAN_CARRY_W(ch)) { + if (CAN_WEAR(obj_object,ITEM_TAKE)) { + get(ch,obj_object,sub_object); + found = TRUE; + } else { + send_to_char("You can't take that\n\r", ch); + fail = TRUE; + } } else { - send_to_char("You can't take that\n\r", ch); + sprintf(buffer,"%s : You can't carry that much weight.\n\r", + fname(obj_object->name)); + send_to_char(buffer, ch); fail = TRUE; } } else { - sprintf(buffer,"%s : You can't carry that much weight.\n\r", + sprintf(buffer,"%s : You can't carry that many items.\n\r", fname(obj_object->name)); send_to_char(buffer, ch); fail = TRUE; } } else { - sprintf(buffer,"%s : You can't carry that many items.\n\r", - fname(obj_object->name)); + sprintf(buffer,"The %s does not contain the %s.\n\r", + fname(sub_object->name), arg1); send_to_char(buffer, ch); fail = TRUE; } - } else { - sprintf(buffer,"The %s does not contain the %s.\n\r", - fname(sub_object->name), arg1); - send_to_char(buffer, ch); - fail = TRUE; + } + else { + send_to_char("It's closed.\n\r", ch); } } else { sprintf(buffer,"The %s is not a container.\n\r", fname(sub_object->name)); @@ -339,7 +346,7 @@ bool test = FALSE; send_to_char("OK.\n\r",ch); if(amount==0) return; - + act("$n drops some gold.", FALSE, ch, 0, 0, TO_ROOM); tmp_object = create_money(amount); obj_to_room(tmp_object,ch->in_room); @@ -422,7 +429,7 @@ void do_put(struct char_data *ch, char *argument, int cmd) send_to_char("You attempt to fold it into itself, but fail.\n\r", ch); return; } - if (((sub_object->obj_flags.weight) + + if (((sub_object->obj_flags.weight) + (obj_object->obj_flags.weight)) < (sub_object->obj_flags.value[0])) { send_to_char("Ok.\n\r", ch); @@ -439,8 +446,8 @@ void do_put(struct char_data *ch, char *argument, int cmd) obj_to_obj(obj_object, sub_object); /* Dow we need obj_to_room???(sub_object,ch); */ } - - act("$n puts $p in $P",TRUE, ch, obj_object, sub_object, TO_ROOM); + + act("$n puts $p in $s $P",TRUE, ch, obj_object, sub_object, TO_ROOM); } else { send_to_char("It won't fit.\n\r", ch); } @@ -516,6 +523,10 @@ void do_give(struct char_data *ch, char *argument, int cmd) act("$n gives some gold to $N.", 1, ch, 0, vict, TO_NOTVICT); if (IS_NPC(ch) || (GET_LEVEL(ch) < 22)) GET_GOLD(ch)-=amount; + if ((GET_LEVEL(ch) > 20) && (!IS_NPC(ch)) && (!IS_NPC(vict))) { + sprintf(buf,"%s gives %s %d gold coins.",GET_NAME(ch),GET_NAME(vict),amount); + log(buf); + } GET_GOLD(vict)+=amount; return; } @@ -561,4 +572,3 @@ void do_give(struct char_data *ch, char *argument, int cmd) act("$n gives you $p.", 0, ch, obj, vict, TO_VICT); send_to_char("Ok.\n\r", ch); } - diff --git a/act.obj2.c b/act.obj2.c index 4447304..74b40d5 100644 --- a/act.obj2.c +++ b/act.obj2.c @@ -26,10 +26,12 @@ extern char *drinks[]; extern int drink_aff[][3]; /* extern functions */ +void log(char *str); struct obj_data *get_object_in_equip_vis(struct char_data *ch, char *arg, struct obj_data **equipment, int *j); -void log(char *str); +char *strdup(char *source); + @@ -331,30 +333,31 @@ void do_pour(struct char_data *ch, char *argument, int cmd) to_obj->obj_flags.value[2]=from_obj->obj_flags.value[2]; /* Then how much to pour */ - from_obj->obj_flags.value[1]-= (amount= - (to_obj->obj_flags.value[0]-to_obj->obj_flags.value[1])); + /* if to_obj can contail it all give it all */ + amount = to_obj->obj_flags.value[0]-to_obj->obj_flags.value[1]; + if (amount > from_obj->obj_flags.value[1]) + amount = from_obj->obj_flags.value[1]; + + /* take away from from_obj */ + from_obj->obj_flags.value[1]-=amount; + weight_change_object(from_obj, -amount); + + /* give it to to_obj */ + to_obj->obj_flags.value[1]+=amount; + weight_change_object(to_obj, amount); - to_obj->obj_flags.value[1]=to_obj->obj_flags.value[0]; + /* Then the poison boogie */ + to_obj->obj_flags.value[3]= + (to_obj->obj_flags.value[3]||from_obj->obj_flags.value[3]); - if(from_obj->obj_flags.value[1]<0) /* There was to little */ + if(from_obj->obj_flags.value[1]=0) /* from_obj is empty */ { - to_obj->obj_flags.value[1]+=from_obj->obj_flags.value[1]; - amount += from_obj->obj_flags.value[1]; from_obj->obj_flags.value[1]=0; from_obj->obj_flags.value[2]=0; from_obj->obj_flags.value[3]=0; name_from_drinkcon(from_obj); } - /* Then the poison boogie */ - to_obj->obj_flags.value[3]= - (to_obj->obj_flags.value[3]||from_obj->obj_flags.value[3]); - - /* And the weight boogie */ - - weight_change_object(from_obj, -amount); - weight_change_object(to_obj, amount); /* Add weight */ - return; } diff --git a/act.offensive.c b/act.offensive.c index ac4f00b..71588df 100644 --- a/act.offensive.c +++ b/act.offensive.c @@ -18,13 +18,12 @@ /* extern variables */ -extern struct room_data *world; extern struct descriptor_data *descriptor_list; extern struct room_data *world; void raw_kill(struct char_data *ch); - +void stop_follower(struct char_data *ch); void do_hit(struct char_data *ch, char *argument, int cmd) { @@ -175,6 +174,18 @@ void do_order(struct char_data *ch, char *argument, int cmd) if ( (victim->master!=ch) || !IS_AFFECTED(victim, AFF_CHARM) ) act("$n has an indifferent look.", FALSE, victim, 0, 0, TO_ROOM); else { + if (saves_spell(victim,SAVING_SPELL)) { + if (saves_spell(victim,SAVING_SPELL)&& + saves_spell(victim,SAVING_SPELL)&& + saves_spell(victim,SAVING_SPELL)) { + /* make it easyer to use charmn */ + stop_follower(victim); + if (IS_NPC(victim)) + hit(victim,ch); + } else { + act("$n has an indifferent look.", FALSE, victim, 0, 0, TO_ROOM); + } + } send_to_char("Ok.\n\r", ch); command_interpreter(victim, message); } @@ -188,6 +199,18 @@ void do_order(struct char_data *ch, char *argument, int cmd) if (org_room == k->follower->in_room) if (IS_AFFECTED(k->follower, AFF_CHARM)) { found = TRUE; + if (saves_spell(victim,SAVING_SPELL)) { + if (saves_spell(victim,SAVING_SPELL)&& + saves_spell(victim,SAVING_SPELL)&& + saves_spell(victim,SAVING_SPELL)) { + /* make it easyer to use charmn */ + stop_follower(victim); + if (IS_NPC(victim)) + hit(victim,ch); + } else { + act("$n has an indifferent look.", FALSE, victim, 0, 0, TO_ROOM); + } + } command_interpreter(k->follower, message); } } @@ -217,6 +240,7 @@ void do_flee(struct char_data *ch, char *argument, int cmd) if ((die = do_simple_move(ch, attempt, FALSE))== 1) { /* The escape has succeded */ send_to_char("You flee head over heels.\n\r", ch); + return; } else { if (!die) act("$n tries to flee, but is too exhausted!", TRUE, ch, 0, 0, TO_ROOM); return; @@ -233,7 +257,7 @@ void do_flee(struct char_data *ch, char *argument, int cmd) if (CAN_GO(ch, attempt) && !IS_SET(world[EXIT(ch, attempt)->to_room].room_flags, DEATH)) { act("$n panics, and attempts to flee.", TRUE, ch, 0, 0, TO_ROOM); - if ((die = do_simple_move(ch, attempt, FALSE))== 1) { + if ((die = do_simple_move(ch, attempt, FALSE))== 1) { /* The escape has succeded */ loose = GET_MAX_HIT(ch->specials.fighting)-GET_HIT(ch->specials.fighting); loose *= GET_LEVEL(ch->specials.fighting); @@ -411,4 +435,3 @@ void do_kick(struct char_data *ch, char *argument, int cmd) } WAIT_STATE(ch, PULSE_VIOLENCE*3); } - diff --git a/act.other.c b/act.other.c index 2d5033a..7d3e01a 100644 --- a/act.other.c +++ b/act.other.c @@ -27,10 +27,10 @@ extern struct spell_info_type spell_info[]; /* extern procedures */ +void log(char *str); void hit(struct char_data *ch, struct char_data *victim, int type); void do_shout(struct char_data *ch, char *argument, int cmd); -void log(char *str); @@ -162,9 +162,13 @@ void do_steal(struct char_data *ch, char *argument, int cmd) return; } + WAIT_STATE(ch, 10); /* It takes TIME to steal */ + /* 101% is a complete failure */ percent=number(1,101) - dex_app_skill[GET_DEX(ch)].p_pocket; + percent += AWAKE(victim) ? 10 : -50; + if (GET_POS(victim) < POSITION_SLEEPING) percent = -1; /* ALWAYS SUCCESS */ @@ -200,7 +204,7 @@ void do_steal(struct char_data *ch, char *argument, int cmd) percent += GET_OBJ_WEIGHT(obj); /* Make heavy harder */ - if (AWAKE(victim) && (percent > ch->skills[SKILL_STEAL].learned)) { + if (percent > ch->skills[SKILL_STEAL].learned) { ohoh = TRUE; act("Oops..", FALSE, ch,0,0,TO_CHAR); act("$n tried to steal something from you!",FALSE,ch,0,victim,TO_VICT); @@ -217,7 +221,7 @@ void do_steal(struct char_data *ch, char *argument, int cmd) } } } else { /* Steal some coins */ - if (AWAKE(victim) && (percent > ch->skills[SKILL_STEAL].learned)) { + if (percent > ch->skills[SKILL_STEAL].learned) { ohoh = TRUE; act("Oops..", FALSE, ch,0,0,TO_CHAR); act("You discover that $n has $s hands in your wallet.",FALSE,ch,0,victim,TO_VICT); diff --git a/act.social.c b/act.social.c index 10a274b..d2fda98 100644 --- a/act.social.c +++ b/act.social.c @@ -65,8 +65,6 @@ struct pose_type static int list_top = -1; - - char *fread_action(FILE *fl) { char buf[MAX_STRING_LENGTH], *rslt; @@ -324,22 +322,20 @@ void boot_pose_messages(void) fclose(fl); } + do_pose(struct char_data *ch, char *argument, int cmd) { byte to_pose; byte counter; - send_to_char("Sorry Buggy command.\n\r", ch); - return; - if ((GET_LEVEL(ch) < pose_messages[0].level) || IS_NPC(ch)) { send_to_char("You can't do that.\n\r", ch); return; } - for (counter = 0; (pose_messages[counter].level < GET_LEVEL(ch)) && - (pose_messages[counter].level > 0); counter++); + for (counter = 0; (pose_messages[counter].level <= GET_LEVEL(ch)) && + (pose_messages[counter].level >= 0); counter++); counter--; to_pose = number(0, counter); diff --git a/act.wizard.c b/act.wizard.c index d1c1c46..83646b6 100644 --- a/act.wizard.c +++ b/act.wizard.c @@ -53,6 +53,12 @@ do_emote(struct char_data *ch, char *argument, int cmd) if (IS_NPC(ch)) return; + if (IS_SET(ch->specials.act, PLR_NOEMOTE)) + { + send_to_char("You can't show your emotions!!\n\r", ch); + return; + } + for (i = 0; *(argument + i) == ' '; i++); if (!*(argument + i)) @@ -391,9 +397,9 @@ void do_stat(struct char_data *ch, char *argument, int cmd) strcat(buf,"UNDEFINED\n\r"); send_to_char(buf, ch); sprintbit(rm->dir_option[i]->exit_info,exit_bits,buf2); - sprintf(buf, "Exit flag: %s \n\rKey no: %d\n\rTo room (R-Number): %d\n\r", + sprintf(buf, "Exit flag: %s \n\rKey no: %d\n\rTo room (V-Number): %d\n\r", buf2, rm->dir_option[i]->key, - rm->dir_option[i]->to_room); + world[rm->dir_option[i]->to_room].number); send_to_char(buf, ch); } } @@ -824,7 +830,7 @@ void do_shutdow(struct char_data *ch, char *argument, int cmd) void do_shutdown(struct char_data *ch, char *argument, int cmd) { - extern int shutdown, reboot; + extern int diku_shutdown, reboot; char buf[100], arg[MAX_INPUT_LENGTH]; if (IS_NPC(ch)) @@ -837,14 +843,14 @@ void do_shutdown(struct char_data *ch, char *argument, int cmd) sprintf(buf, "Shutdown by %s.", GET_NAME(ch) ); send_to_all(buf); log(buf); - shutdown = 1; + diku_shutdown = 1; } else if (!str_cmp(arg, "reboot")) { sprintf(buf, "Reboot by %s.", GET_NAME(ch)); send_to_all(buf); log(buf); - shutdown = reboot = 1; + diku_shutdown = reboot = 1; } else send_to_char("Go shut down someone your own size.\n\r", ch); @@ -859,6 +865,12 @@ void do_snoop(struct char_data *ch, char *argument, int cmd) if (!ch->desc) return; + if (IS_NPC(ch)) + { + send_to_char("Did you ever try this before?", ch); + return; + } + one_argument(argument, arg); if(!*arg) @@ -1012,7 +1024,7 @@ void do_force(struct char_data *ch, char *argument, int cmd) send_to_char("No-one by that name here..\n\r", ch); else { - if (GET_LEVEL(ch) < GET_LEVEL(vict)) + if ((GET_LEVEL(ch) < GET_LEVEL(vict)) && !IS_NPC(vict)) send_to_char("Oh no you don't!!\n\r", ch); else { sprintf(buf, "$n has forced you to '%s'.", to_force); @@ -1079,6 +1091,10 @@ void do_load(struct char_data *ch, char *argument, int cmd) 0, 0, TO_ROOM); act("$n has created $N!", FALSE, ch, 0, mob, TO_ROOM); send_to_char("Done.\n\r", ch); + sprintf(buf,"%s loads %s at %s.",GET_NAME(ch), + mob->player.short_descr,world[ch->in_room].name); + log(buf); + } else if (is_abbrev(type, "obj")) { @@ -1092,6 +1108,10 @@ void do_load(struct char_data *ch, char *argument, int cmd) act("$n makes a strange magical gesture.", TRUE, ch, 0, 0, TO_ROOM); act("$n has created $p!", FALSE, ch, obj, 0, TO_ROOM); send_to_char("Ok.\n\r", ch); + sprintf(buf,"%s loads %s at %s.",GET_NAME(ch), + obj->short_description,world[ch->in_room].name); + log(buf); + } else send_to_char("That'll have to be either 'char' or 'obj'.\n\r", ch); @@ -1116,9 +1136,11 @@ void do_purge(struct char_data *ch, char *argument, int cmd) if (*name) /* argument supplied. destroy single object or char */ { - if (vict = get_char_room_vis(ch, name)) + if (!(vict = get_char_room_vis(ch, name)) && (GET_LEVEL(ch) >= 23)) + vict = get_char(name); + if (vict) { - if (!IS_NPC(vict) && (GET_LEVEL(ch)<24)) { + if (!IS_NPC(vict) && (GET_LEVEL(ch)<=GET_LEVEL(vict))) { send_to_char("Fuuuuuuuuu!\n\r", ch); return; } @@ -1130,6 +1152,9 @@ void do_purge(struct char_data *ch, char *argument, int cmd) } else { if (vict->desc) { + sprintf(buf,"%s purges %s at %s.",GET_NAME(ch),GET_NAME(vict), + world[ch->in_room].name); + log(buf); close_socket(vict->desc); vict->desc = 0; extract_char(vict); @@ -1368,14 +1393,16 @@ void do_advance(struct char_data *ch, char *argument, int cmd) } send_to_char("You feel generous.\n\r", ch); - act("$n makes some strange gestures.\n\rA strange feeling comes uppon you," - "\n\rLike a giant hand, light comes down from\n\rabove, grabbing your " - "body, that begins\n\rto pulse with coloured lights from inside.\n\rYo" - "ur head seems to be filled with deamons\n\rfrom another plane as your" - " body dissolves\n\rto the elements of time and space itself.\n\rSudde" - "nly a silent explosion of light snaps\n\ryou back to reality. You fee" - "l slightly\n\rdifferent.",FALSE,ch,0,victim,TO_VICT); + act("$n makes some strange gestures.\n\rA strange feeling comes uppon you," + "\n\rLike a giant hand, light comes down from\n\rabove, grabbing your " + "body, that begins\n\rto pulse with coloured lights from inside.\n\rYo" + "ur head seems to be filled with deamons\n\rfrom another plane as your" + " body dissolves\n\rto the elements of time and space itself.\n\rSudde" + "nly a silent explosion of light snaps\n\ryou back to reality. You fee" + "l slightly\n\rdifferent.",FALSE,ch,0,victim,TO_VICT); + sprintf(buf,"%s advances %s to level %d.",GET_NAME(ch),GET_NAME(victim),newlevel); + log(buf); if (GET_LEVEL(victim) == 0) { do_start(victim); @@ -1411,6 +1438,8 @@ void do_reroll(struct char_data *ch, char *argument, int cmd) else { send_to_char("Rerolled...\n\r", ch); roll_abilities(victim); + sprintf(buf,"%s rerolled %s.",GET_NAME(ch),GET_NAME(victim)); + log(buf); } } @@ -1437,6 +1466,9 @@ void do_restore(struct char_data *ch, char *argument, int cmd) GET_HIT(victim) = GET_MAX_HIT(victim); GET_MOVE(victim) = GET_MAX_MOVE(victim); + sprintf(buf,"%s restored %s.",GET_NAME(ch),GET_NAME(victim)); + log(buf); + if (GET_LEVEL(victim) >= 21) { for (i = 0; i < MAX_SKILLS; i++) { victim->skills[i].learned = 100; diff --git a/board.c b/board.c index 42d633f..db9ad63 100644 --- a/board.c +++ b/board.c @@ -7,11 +7,11 @@ #include "comm.h" -#define MAX_MSGS 30 /* Max number of messages. */ +#define MAX_MSGS 50 /* Max number of messages. */ #define SAVE_FILE "board.messages" /* Name of file for saving messages */ #define BOARD_OBJECT xxx /* what are we? */ #define BOARD_ROOM xxx /* where are we? */ -#define MAX_MESSAGE_LENGTH 2048 /* that should be enough */ +#define MAX_MESSAGE_LENGTH 4000 /* that should be enough */ char *msgs[MAX_MSGS]; char *head[MAX_MSGS]; @@ -164,7 +164,7 @@ int board_remove_msg(struct char_data *ch, char *arg) { } void board_save_board() { - FILE *the_file; + FILE *the_file; int ind, len; if (!msg_num) { error_log("No messages to save.\n\r"); @@ -200,7 +200,7 @@ void board_load_board() { return; } fread(&msg_num, sizeof(int), 1, the_file); - + if (msg_num < 1 || msg_num > MAX_MSGS || feof(the_file)) { error_log("Board-message file corrupt or nonexistent.\n\r"); fclose(the_file); @@ -280,7 +280,7 @@ int board_display_msg(struct char_data *ch, char *arg) { } - + void board_fix_long_desc(int num, char *headers[MAX_MSGS]) { struct obj_data *ob; @@ -301,7 +301,7 @@ void board_fix_long_desc(int num, char *headers[MAX_MSGS]) { 4 : Groo got hungry again - bug or sabotage? Well...something like that..;) ****/ - + /**** It is always to contain the first line and ****/ /**** the second line will vary in how many notes ****/ /**** the board has. Then the headers and message ****/ diff --git a/changes.c b/changes.c new file mode 100644 index 0000000..f4981f8 --- /dev/null +++ b/changes.c @@ -0,0 +1,715 @@ +/* ************************************************************************ +* file: changes.c , Implementation of new commands. Part of DIKUMUD * +* Usage : New commands while new datastructures are developed. * +* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * +************************************************************************* */ + +#include +#include +#include + +#include "structs.h" +#include "utils.h" +#include "comm.h" +#include "interpreter.h" +#include "handler.h" +#include "db.h" +#include "spells.h" +#include "limits.h" + +/* external vars */ + +extern struct room_data *world; +extern struct char_data *character_list; +extern struct descriptor_data *descriptor_list; +extern struct title_type titles[4][25]; +extern struct index_data *mob_index; +extern struct index_data *obj_index; +extern struct int_app_type int_app[26]; +extern struct wis_app_type wis_app[26]; +extern bool wizlock; + +/* external functs */ + +void set_title(struct char_data *ch); +int str_cmp(char *arg1, char *arg2); +char *skip_spaces(char *string); +struct time_info_data age(struct char_data *ch); +void sprinttype(int type, char *names[], char *result); +void sprintbit(long vektor, char *names[], char *result); +int mana_limit(struct char_data *ch); +int hit_limit(struct char_data *ch); +int move_limit(struct char_data *ch); +int mana_gain(struct char_data *ch); +int hit_gain(struct char_data *ch); +int move_gain(struct char_data *ch); +void log(char *str); + +/* To be moved to moved to act.wizard.c */ + +void do_noemote(struct char_data *ch, char *argument, int cmd) +{ + struct char_data *vict; + struct obj_data *dummy; + char buf[MAX_INPUT_LENGTH]; + + if (IS_NPC(ch)) + return; + + one_argument(argument, buf); + + if (!*buf) + send_to_char("NOEMOTE who?\n\t", ch); + + else if (!generic_find(argument, FIND_CHAR_WORLD, ch, &vict, &dummy)) + send_to_char("Couldn't find any such creature.\n\r", ch); + else if (IS_NPC(vict)) + send_to_char("Can't do that to a beast.\n\r", ch); + else if (GET_LEVEL(vict) > GET_LEVEL(ch)) + act("$E might object to that.. better not.", 0, ch, 0, vict, TO_CHAR); + else if (IS_SET(vict->specials.act, PLR_NOEMOTE)) + { + send_to_char("You can emote again.\n\r", vict); + send_to_char("NOEMOTE removed.\n\r", ch); + REMOVE_BIT(vict->specials.act, PLR_NOEMOTE); + } + else + { + send_to_char("The gods take away your ability to emote!\n\r", vict); + send_to_char("NOEMOTE set.\n\r", ch); + SET_BIT(vict->specials.act, PLR_NOEMOTE); + } +} + + +void do_notell(struct char_data *ch, char *argument, int cmd) +{ + struct char_data *vict; + struct obj_data *dummy; + char buf[MAX_INPUT_LENGTH]; + + if (IS_NPC(ch)) + return; + + one_argument(argument, buf); + + if (!*buf) + if (IS_SET(ch->specials.act, PLR_NOTELL)) + { + send_to_char("You can now hear tells again.\n\r", ch); + REMOVE_BIT(ch->specials.act, PLR_NOTELL); + } + else + { + send_to_char("From now on, you can't use tell.\n\r", ch); + SET_BIT(ch->specials.act, PLR_NOTELL); + } + else if (!generic_find(argument, FIND_CHAR_WORLD, ch, &vict, &dummy)) + send_to_char("Couldn't find any such creature.\n\r", ch); + else if (IS_NPC(vict)) + send_to_char("Can't do that to a beast.\n\r", ch); + else if (GET_LEVEL(vict) > GET_LEVEL(ch)) + act("$E might object to that.. better not.", 0, ch, 0, vict, TO_CHAR); + else if (IS_SET(vict->specials.act, PLR_NOTELL)) + { + send_to_char("You can use telepatic communication again.\n\r", vict); + send_to_char("NOTELL removed.\n\r", ch); + REMOVE_BIT(vict->specials.act, PLR_NOTELL); + } + else + { + send_to_char("The gods take away your ability to use telepatic communication!\n\r", vict); + send_to_char("NOTELL set.\n\r", ch); + SET_BIT(vict->specials.act, PLR_NOTELL); + } +} + + +void do_freeze(struct char_data *ch, char *argument, int cmd) +{ + struct char_data *vict; + struct obj_data *dummy; + char buf[MAX_INPUT_LENGTH]; + + if (IS_NPC(ch)) + return; + + one_argument(argument, buf); + + if (!*buf) + send_to_char("Freeze who?\n\r", ch); + + else if (!generic_find(argument, FIND_CHAR_WORLD, ch, &vict, &dummy)) + send_to_char("Couldn't find any such creature.\n\r", ch); + else if (IS_NPC(vict)) + send_to_char("Can't do that to a beast.\n\r", ch); + else if (GET_LEVEL(vict) > GET_LEVEL(ch)) + act("$E might object to that.. better not.", 0, ch, 0, vict, TO_CHAR); + else if (IS_SET(vict->specials.act, PLR_FREEZE)) + { + send_to_char("You now can do things again.\n\r", vict); + send_to_char("FREEZE removed.\n\r", ch); + REMOVE_BIT(vict->specials.act, PLR_FREEZE); + } + else + { + send_to_char("The gods take away your ability to ...\n\r", vict); + send_to_char("FREEZE set.\n\r", ch); + SET_BIT(vict->specials.act, PLR_FREEZE); + } +} + + +void do_log(struct char_data *ch, char *argument, int cmd) +{ + struct char_data *vict; + struct obj_data *dummy; + char buf[MAX_INPUT_LENGTH]; + + if (IS_NPC(ch)) + return; + + one_argument(argument, buf); + + if (!*buf) + send_to_char("Log who?\n\r", ch); + + else if (!generic_find(argument, FIND_CHAR_WORLD, ch, &vict, &dummy)) + send_to_char("Couldn't find any such creature.\n\r", ch); + else if (IS_NPC(vict)) + send_to_char("Can't do that to a beast.\n\r", ch); + else if (GET_LEVEL(vict) >= GET_LEVEL(ch)) + act("$E might object to that.. better not.", 0, ch, 0, vict, TO_CHAR); + else if (IS_SET(vict->specials.act, PLR_LOG)) + { + send_to_char("LOG removed.\n\r", ch); + REMOVE_BIT(vict->specials.act, PLR_LOG); + } + else + { + send_to_char("LOG set.\n\r", ch); + SET_BIT(vict->specials.act, PLR_LOG); + } +} + +void do_wizlock(struct char_data *ch, char *argument, int cmd) +{ + char buf[MAX_INPUT_LENGTH]; + + if (wizlock = !wizlock) { + sprintf(buf,"Game has been wizlocked by %s.",GET_NAME(ch)); + log(buf); + send_to_char("Game wizlocked.\n\r", ch); + } else { + sprintf(buf,"Game has been un-wizlocked by %s.",GET_NAME(ch)); + log(buf); + send_to_char("Game un-wizlocked.\n\r", ch); + } +} + + + + +/* This routine is used by 24.level ONLY to set + specific char/npc variables, including skills */ + +void do_set(struct char_data *ch, char *argument, int cmd) +{ + extern char *skill_fields[]; /* in modify.c */ + /* from spell_parser.c */ + char *spells[]= { + "armor","teleport","bless","blindness","burning hands","call lightning", + "charm person","chill touch","clone","colour spray","control weather", + "create food","create water","cure blind","cure critic","cure light", + "curse","detect evil","detect invisibility","detect magic", + "detect poison","dispel evil","earthquake","enchant weapon", + "energy drain","fireball","harm","heal","invisibility", + "lightning bolt","locate object","magic missile","poison", + "protection from evil","remove curse","sanctuary","shocking grasp", + "zzzzz","strength","summon","ventriloquate","word of recall", + "remove poison","sense life", + "sneak","hide","steal","backstab","pick lock", + "kick","bash","rescue","\n" + }; + char *values[] = { + "age","sex","class","level","height","weight","str","stradd", + "int","wis","dex","con","gold","exp","mana","hit","move", + "sessions","alignment","thirst","drunk","full","\n" + }; + struct char_data *vict; + char name[100], buf2[100], buf[100], help[MAX_STRING_LENGTH]; + int skill, field, value, i, qend; + + argument = one_argument(argument, name); + if (!*name) /* no arguments. print an informative text */ + { + send_to_char("Syntax:\n\rset skill '' \n\r", ch); + send_to_char("or:\n\rset value \n\r", ch); + + strcpy(help, "Skill being one of the following:\n\r"); + for (i = 1; *spells[i] != '\n'; i++) + { + sprintf(help + strlen(help), "%18s", spells[i]); + if (!(i % 4)) + { + strcat(help, "\n\r"); + send_to_char(help, ch); + *help = '\0'; + } + } + if (*help) + send_to_char(help, ch); + + strcpy(help, "\n\rField being one of the following:\n\r"); + for (i = 1; *values[i] != '\n'; i++) + { + sprintf(help + strlen(help), "%18s", values[i]); + if (!(i % 4)) + { + strcat(help, "\n\r"); + send_to_char(help, ch); + *help = '\0'; + } + } + if (*help) + send_to_char(help, ch); + send_to_char("\n\r", ch); + return; + } + if (!(vict = get_char_vis(ch, name))) + { + send_to_char("No living thing by that name.\n\r", ch); + return; + } + argument = one_argument(argument, buf); + if (!*buf) + { + send_to_char("'skill' or 'value' expected.\n\r", ch); + return; + } + if (str_cmp(buf,"skill") && str_cmp(buf,"s") && str_cmp(buf,"value") && str_cmp(buf,"v")) + { + send_to_char("'skill' or 'value' expected.\n\r", ch); + return; + } + if (!str_cmp(buf,"skill") || !str_cmp(buf,"s")) + /* This is a skill */ + { + + argument = skip_spaces(argument); + + /* If there is no chars in argument */ + if (!(*argument)) { + send_to_char("Skill name expected.\n\r", ch); + return; + } + + if (*argument != '\'') { + send_to_char("Skill must be enclosed in: ''\n\r",ch); + return; + } + + /* Locate the last quote && lowercase the magic words (if any) */ + + for (qend=1; *(argument+qend) && (*(argument+qend) != '\'') ; qend++) + *(argument+qend) = LOWER(*(argument+qend)); + + if (*(argument+qend) != '\'') { + send_to_char("Skill must be enclosed in: ''\n\r",ch); + return; + } + + if ((skill = old_search_block(argument, 1, qend-1, spells, 0)) < 0) + { + send_to_char("Unrecognized skill.\n\r", ch); + return; + } + skill--; + argument += qend+1; /* skip to next parameter */ + argument = one_argument(argument,buf); + if (!*buf) + { + send_to_char("Learned value expected.\n\r", ch); + return; + } + value = atoi(buf); + if (value < 0) + { + send_to_char("Minimum value for learned is 0.\n\r", ch); + return; + } + if (value > 100) + { + send_to_char("Max value for learned is 100.\n\r", ch); + return; + } + argument = one_argument(argument,buf); + if (!*buf) + { + send_to_char("Learned value expected.\n\r", ch); + return; + } + if (str_cmp(buf,"y") && str_cmp(buf,"n")) + { + send_to_char("Recognice value must be 'y' or 'n'", ch); + return; + } + sprintf(buf2,"%s changes %s's %s to %d,%s.",GET_NAME(ch),GET_NAME(vict), + spells[skill],value,buf); + vict->skills[skill].learned = value; + vict->skills[skill].recognise = (!str_cmp(buf,"y")); + } else { + /* it is another value */ + argument = one_argument(argument,buf); + if (!*buf) + { + send_to_char("Field name expected.\n\r", ch); + return; + } + if ((skill = old_search_block(buf, 0, strlen(buf), values, 1)) < 0) + { + send_to_char("No such field is known. Try 'set' for list.\n\r", ch); + return; + } + skill--; + argument = one_argument(argument,buf); + if (!*buf) + { + send_to_char("Value for field expected.\n\r", ch); + return; + } + sprintf(buf2,"%s sets %s's %s to %s.",GET_NAME(ch),GET_NAME(vict),values[skill],buf); + switch (skill) { + case 0: /* age */ + { + value = atoi(buf); + if ((value < 16) || (value > 79)) + { + send_to_char("Age must be more than 16 years\n\r", ch); + send_to_char("and less than 80 years.\n\r", ch); + return; + } + log(buf2); + /* set age of victim */ + vict->player.time.birth = + time(0) - (long)value*(long)SECS_PER_MUD_YEAR; + }; + break; + case 1: /* sex */ + { + if (str_cmp(buf,"m") && str_cmp(buf,"f") && str_cmp(buf,"n")) + { + send_to_char("Sex must be 'm','f' or 'n'.\n\r", ch); + return; + } + log(buf2); + /* set sex of victim */ + switch(*buf) { + case 'm':vict->player.sex = SEX_MALE; break; + case 'f':vict->player.sex = SEX_FEMALE; break; + case 'n':vict->player.sex = SEX_NEUTRAL;break; + } + } + break; + case 2: /* class */ + { + if (str_cmp(buf,"m") && str_cmp(buf,"c") && + str_cmp(buf,"w") && str_cmp(buf,"t")) + { + send_to_char("Class must be 'm','c','w' or 't'.\n\r", ch); + return; + } + log(buf2); + /* set class of victim */ + switch(*buf) { + case 'm':vict->player.class = CLASS_MAGIC_USER; break; + case 'c':vict->player.class = CLASS_CLERIC; break; + case 'w':vict->player.class = CLASS_WARRIOR; break; + case 't':vict->player.class = CLASS_THIEF; break; + } + } + break; + case 3: /* level */ + { + value = atoi(buf); + if ((value < 0) || (value > 24)) + { + send_to_char("Level must be more than 0\n\r", ch); + send_to_char("and less than 25.\n\r", ch); + return; + } + log(buf2); + /* set level of victim */ + vict->player.level = value; + } + break; + case 4: /* height */ + { + value = atoi(buf); + if ((value < 100) || (value > 250)) + { + send_to_char("Height must be more than 100 cm\n\r", ch); + send_to_char("and less than 251 cm.\n\r", ch); + return; + } + log(buf2); + /* set hieght of victim */ + vict->player.height = value; + } + break; + case 5: /* weight */ + { + value = atoi(buf); + if ((value < 100) || (value > 250)) + { + send_to_char("Weight must be more than 100 pound\n\r", ch); + send_to_char("and less than 250 pound.\n\r", ch); + return; + } + log(buf2); + /* set weight of victim */ + vict->player.weight = value; + } + break; + case 6: /* str */ + { + value = atoi(buf); + if ((value <= 0) || (value > 18)) + { + send_to_char("Strength must be more than 0\n\r", ch); + send_to_char("and less than 19.\n\r", ch); + return; + } + log(buf2); + /* set original strength of victim */ + vict->abilities.str = value; + } + break; + case 7: /* stradd */ + { + value = atoi(buf); + if ((value <= 0) || (value > 100)) + { + send_to_char("Strength addition must be more\n\r", ch); + send_to_char("than 0 and less than 101.\n\r", ch); + } + log(buf2); + /* set original strength addition of victim */ + vict->abilities.str_add = value; + } + break; + case 8: /* int */ + { + value = atoi(buf); + if ((value <= 0) || (value > 18)) + { + send_to_char("Inteligence must be more than 0\n\r", ch); + send_to_char("and less than 19.\n\r", ch); + return; + } + log(buf2); + /* set original INT of victim */ + vict->abilities.intel = value; + } + break; + case 9: /* wis */ + { + value = atoi(buf); + if ((value <= 0) || (value > 18)) + { + send_to_char("Wisdom must be more than 0\n\r", ch); + send_to_char("and less than 19.\n\r", ch); + return; + } + log(buf2); + /* set original WIS of victim */ + vict->abilities.wis = value; + } + break; + case 10: /* dex */ + { + value = atoi(buf); + if ((value <= 0) || (value > 18)) + { + send_to_char("Dexterity must be more than 0\n\r", ch); + send_to_char("and less than 19.\n\r", ch); + return; + } + log(buf2); + /* set original DEX of victim */ + vict->abilities.dex = value; + } + break; + case 11: /* con */ + { + value = atoi(buf); + if ((value <= 0) || (value > 18)) + { + send_to_char("Constitution must be more than 0\n\r", ch); + send_to_char("and less than 19.\n\r", ch); + return; + } + log(buf2); + /* set original CON of victim */ + vict->abilities.con = value; + } + break; + case 12: /* gold */ + { + value = atoi(buf); + log(buf2); + /* set original gold of victim */ + vict->points.gold = value; + } + break; + case 13: /* exp */ + { + value = atoi(buf); + if ((value <= 0) || (value > 7000000)) + { + send_to_char("Experience-points must be more than 0\n\r", ch); + send_to_char("and less than 7000000.\n\r", ch); + return; + } + log(buf2); + /* set original exp of victim */ + vict->points.exp = value; + } + break; + case 14: /* mana */ + { + value = atoi(buf); + if ((value <= -100) || (value > 200)) + { + send_to_char("Mana-points must be more than -100\n\r", ch); + send_to_char("and less than 200.\n\r", ch); + return; + } + log(buf2); + /* set original mana of victim */ + vict->points.mana = value; + } + break; + case 15: /* hit */ + { + value = atoi(buf); + if ((value <= -10) || (value > 30000)) + { + send_to_char("Hit-points must be more than -10\n\r", ch); + send_to_char("and less than 30000.\n\r", ch); + return; + } + log(buf2); + /* set original hit of victim */ + vict->points.hit = value; + } + break; + case 16: /* move */ + { + value = atoi(buf); + if ((value <= -100) || (value > 200)) + { + send_to_char("Move-points must be more than -100\n\r", ch); + send_to_char("and less than 200.\n\r", ch); + return; + } + log(buf2); + /* set original move of victim */ + vict->points.move = value; + } + break; + case 17: /* sessions */ + { + value = atoi(buf); + if ((value < 0) || (value > 100)) + { + send_to_char("Sessions must be more than 0\n\r", ch); + send_to_char("and less than 100.\n\r", ch); + return; + } + log(buf2); + /* set original sessions of victim */ + vict->specials.spells_to_learn = value; + } + break; + case 18: /* alignment */ + { + value = atoi(buf); + if ((value < -1000) || (value > 1000)) + { + send_to_char("Alignment must be more than -1000\n\r", ch); + send_to_char("and less than 1000.\n\r", ch); + return; + } + log(buf2); + /* set original alignment of victim */ + vict->specials.alignment = value; + } + break; + case 19: /* thirst */ + { + value = atoi(buf); + if ((value < -1) || (value > 100)) + { + send_to_char("Thirst must be more than -2\n\r", ch); + send_to_char("and less than 101.\n\r", ch); + return; + } + log(buf2); + /* set original thirst of victim */ + vict->specials.conditions[THIRST] = value; + } + break; + case 20: /* drunk */ + { + value = atoi(buf); + if ((value < -1) || (value > 100)) + { + send_to_char("Drunk must be more than -2\n\r", ch); + send_to_char("and less than 101.\n\r", ch); + return; + } + log(buf2); + /* set original drunk of victim */ + vict->specials.conditions[DRUNK] = value; + } + break; + case 21: /* full */ + { + value = atoi(buf); + if ((value < -1) || (value > 100)) + { + send_to_char("Full must be more than -2\n\r", ch); + send_to_char("and less than 101.\n\r", ch); + return; + } + log(buf2); + /* set original full of victim */ + vict->specials.conditions[FULL] = value; + } + break; + } + } + send_to_char("Ok.\n\r", ch); +} + +void do_wiz(struct char_data *ch, char *argument, int cmd) +{ + static char buf1[MAX_STRING_LENGTH]; + struct descriptor_data *i; + + for (; *argument == ' '; argument++); + + if (!(*argument)) + send_to_char("What do you want to tell all gods and immortals?\n\r", ch); + else + { + send_to_char("Ok.\n\r", ch); + sprintf(buf1, "::$n::%s", argument); + + for (i = descriptor_list; i; i = i->next) + if (i->character != ch && !i->connected && + GET_LEVEL(i->character) > 20) + act(buf1, 0, ch, 0, i->character, TO_VICT); + } +} diff --git a/comm.c b/comm.c index e12df03..2818169 100644 --- a/comm.c +++ b/comm.c @@ -1,1211 +1,1214 @@ -/* ************************************************************************ -* file: comm.c , Communication module. Part of DIKUMUD * -* Usage: Communication, central game loop. * -* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * -* All Rights Reserved * -* Using *any* part of DikuMud without having read license.doc is * -* violating our copyright. -************************************************************************* */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "structs.h" -#include "utils.h" -#include "comm.h" -#include "interpreter.h" -#include "handler.h" -#include "db.h" - -#define DFLT_PORT 4000 /* default port */ -#define MAX_NAME_LENGTH 15 -#define MAX_HOSTNAME 256 -#define OPT_USEC 250000 /* time delay corresponding to 4 passes/sec */ - - - -extern int errno; /* Why isn't this done in errno.h on alfa??? */ - -/* externs */ - -/* extern struct char_data *character_list; */ - -extern struct room_data *world; /* In db.c */ -extern int top_of_world; /* In db.c */ -extern struct time_info_data time_info; /* In db.c */ -extern char help[]; - -/* local globals */ - -struct descriptor_data *descriptor_list, *next_to_process; - -int lawful = 0; /* work like the game regulator */ -int slow_death = 0; /* Shut her down, Martha, she's sucking mud */ -int diku_shutdown = 0; /* clean shutdown */ -int reboot = 0; /* reboot the game after a shutdown */ -int no_specials = 0; /* Suppress ass. of special routines */ - -int maxdesc, avail_descs; -int tics = 0; /* for extern checkpointing */ - -int get_from_q(struct txt_q *queue, char *dest); -/* write_to_q is in comm.h for the macro */ -int run_the_game(int port); -int game_loop(int s); -int init_socket(int port); -int new_connection(int s); -int new_descriptor(int s); -int process_output(struct descriptor_data *t); -int process_input(struct descriptor_data *t); -void close_sockets(int s); -void close_socket(struct descriptor_data *d); -struct timeval timediff(struct timeval *a, struct timeval *b); -void flush_queues(struct descriptor_data *d); -void nonblock(int s); -void parse_name(struct descriptor_data *desc, char *arg); - - -/* extern fcnts */ - -struct char_data *make_char(char *name, struct descriptor_data *desc); -void boot_db(void); -void zone_update(void); -void affect_update( void ); /* In spells.c */ -void point_update( void ); /* In limits.c */ -void free_char(struct char_data *ch); -void log(char *str); -void mobile_activity(void); -void string_add(struct descriptor_data *d, char *str); -void perform_violence(void); -void stop_fighting(struct char_data *ch); -void show_string(struct descriptor_data *d, char *input); -void gr(int s); - -void check_reboot(void); - -/* ********************************************************************* -* main game loop and related stuff * -********************************************************************* */ - - - - -int main(int argc, char **argv) -{ - int port; - char buf[512]; - int pos = 1; - char *dir; - - port = DFLT_PORT; - dir = DFLT_DIR; - - while ((pos < argc) && (*(argv[pos]) == '-')) - { - switch (*(argv[pos] + 1)) - { - case 'l': - lawful = 1; - log("Lawful mode selected."); - break; - case 'd': - if (*(argv[pos] + 2)) - dir = argv[pos] + 2; - else if (++pos < argc) - dir = argv[pos]; - else - { - log("Directory arg expected after option -d."); - exit(0); - } - break; - case 's': - no_specials = 1; - log("Suppressing assignment of special routines."); - break; - default: - sprintf(buf, "Unknown option -% in argument string.", - *(argv[pos] + 1)); - log(buf); - break; - } - pos++; - } - - if (pos < argc) - if (!isdigit(*argv[pos])) - { - fprintf(stderr, "Usage: %s [-l] [-s] [-d pathname] [ port # ]\n", - argv[0]); - exit(0); - } - else if ((port = atoi(argv[pos])) <= 1024) - { - printf("Illegal port #\n"); - exit(0); - } - - sprintf(buf, "Running game on port %d.", port); - log(buf); - - if (chdir(dir) < 0) - { - perror("chdir"); - exit(0); - } - - sprintf(buf, "Using %s as data directory.", dir); - log(buf); - - srandom(time(0)); - run_the_game(port); - return(0); -} - - - - - -#define PROFILE(x) - - -/* Init sockets, run game, and cleanup sockets */ -int run_the_game(int port) -{ - int s; - PROFILE(extern etext();) - - void signal_setup(void); - int load(void); - void coma(); - - PROFILE(monstartup((int) 2, etext);) - - descriptor_list = NULL; - - log("Signal trapping."); - signal_setup(); - - log("Opening mother connection."); - s = init_socket(port); - - if (lawful && load() >= 6) - { - log("System load too high at startup."); - coma(); - } - - boot_db(); - - log("Entering game loop."); - - game_loop(s); - - close_sockets(s); - - PROFILE(monitor(0);) - - if (reboot) - { - log("Rebooting."); - exit(52); /* what's so great about HHGTTG, anyhow? */ - } - - log("Normal termination of game."); -} - - - - - - -/* Accept new connects, relay commands, and call 'heartbeat-functs' */ -int game_loop(int s) -{ - int tmp_room, old_len; - fd_set input_set, output_set, exc_set; - struct timeval last_time, now, timespent, timeout, null_time; - static struct timeval opt_time; - char comm[MAX_INPUT_LENGTH]; - struct descriptor_data *t, *point, *next_point; - int pulse = 0, mask; - - null_time.tv_sec = 0; - null_time.tv_usec = 0; - - opt_time.tv_usec = OPT_USEC; /* Init time values */ - opt_time.tv_sec = 0; - gettimeofday(&last_time, (struct timezone *) 0); - - maxdesc = s; - avail_descs = getdtablesize() - 2; /* !! Change if more needed !! */ - -#ifdef __linux__ - mask = sigprocmask(SIGUSR1) | sigprocmask(SIGUSR2) | sigprocmask(SIGINT) | - sigprocmask(SIGPIPE) | sigprocmask(SIGALRM) | sigprocmask(SIGTERM) | - sigprocmask(SIGURG) | sigprocmask(SIGXCPU) | sigprocmask(SIGHUP); -#else - mask = sigmask(SIGUSR1) | sigmask(SIGUSR2) | sigmask(SIGINT) | - sigmask(SIGPIPE) | sigmask(SIGALRM) | sigmask(SIGTERM) | - sigmask(SIGURG) | sigmask(SIGXCPU) | sigmask(SIGHUP); -#endif - - /* Main loop */ - while (!diku_shutdown) - { - /* Check what's happening out there */ - FD_ZERO(&input_set); - FD_ZERO(&output_set); - FD_ZERO(&exc_set); - FD_SET(s, &input_set); - for (point = descriptor_list; point; point = point->next) - { - FD_SET(point->descriptor, &input_set); - FD_SET(point->descriptor, &exc_set); - FD_SET(point->descriptor, &output_set); - } - - /* check out the time */ - gettimeofday(&now, (struct timezone *) 0); - timespent = timediff(&now, &last_time); - timeout = timediff(&opt_time, ×pent); - last_time.tv_sec = now.tv_sec + timeout.tv_sec; - last_time.tv_usec = now.tv_usec + timeout.tv_usec; - if (last_time.tv_usec >= 1000000) - { - last_time.tv_usec -= 1000000; - last_time.tv_sec++; - } - - sigsetmask(mask); - - if (select(maxdesc + 1, &input_set, &output_set, &exc_set, &null_time) - < 0) - { - perror("Select poll"); - return(-1); - } - - if (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &timeout) < 0) - { - perror("Select sleep"); - exit(1); - } - - sigsetmask(0); - - /* Respond to whatever might be happening */ - - /* New connection? */ - if (FD_ISSET(s, &input_set)) - if (new_descriptor(s) < 0) - perror("New connection"); - - /* kick out the freaky folks */ - for (point = descriptor_list; point; point = next_point) - { - next_point = point->next; - if (FD_ISSET(point->descriptor, &exc_set)) - { - FD_CLR(point->descriptor, &input_set); - FD_CLR(point->descriptor, &output_set); - close_socket(point); - } - } - - for (point = descriptor_list; point; point = next_point) - { - next_point = point->next; - if (FD_ISSET(point->descriptor, &input_set)) - if (process_input(point) < 0) - close_socket(point); - } - - /* process_commands; */ - for (point = descriptor_list; point; point = next_to_process) - { - next_to_process = point->next; - - if ((--(point->wait) <= 0) && get_from_q(&point->input, comm)) - { - if (point->character && point->connected == CON_PLYNG && - point->character->specials.was_in_room != NOWHERE) - { - if (point->character->in_room != NOWHERE) - char_from_room(point->character); - char_to_room(point->character, - point->character->specials.was_in_room); - point->character->specials.was_in_room = NOWHERE; - act("$n has returned.", TRUE, point->character, 0, 0, TO_ROOM); - } - - point->wait = 1; - if (point->character) - point->character->specials.timer = 0; - point->prompt_mode = 1; - - if (point->str) - string_add(point, comm); - else if (!point->connected) - if (point->showstr_point) - show_string(point, comm); - else - command_interpreter(point->character, comm); - else - nanny(point, comm); - } - } - - - for (point = descriptor_list; point; point = next_point) - { - next_point = point->next; - if (FD_ISSET(point->descriptor, &output_set) && point->output.head) - if (process_output(point) < 0) - close_socket(point); - else - point->prompt_mode = 1; - } - - /* give the people some prompts */ - for (point = descriptor_list; point; point = point->next) - if (point->prompt_mode) - { - if (point->str) - write_to_descriptor(point->descriptor, "] "); - else if (!point->connected) - if (point->showstr_point) - write_to_descriptor(point->descriptor, - "*** Press return ***"); - else - write_to_descriptor(point->descriptor, "> "); - point->prompt_mode = 0; - } - - - - /* handle heartbeat stuff */ - /* Note: pulse now changes every 1/4 sec */ - - pulse++; - - if (!(pulse % PULSE_ZONE)) - { - zone_update(); - if (lawful) - gr(s); - } - - - if (!(pulse % PULSE_MOBILE)) - mobile_activity(); - - if (!(pulse % PULSE_VIOLENCE)) - perform_violence(); - - if (!(pulse % (SECS_PER_MUD_HOUR*4))){ - weather_and_time(1); - affect_update(); - point_update(); - if ( time_info.hours == 1 ) - update_time(); - } - - if (pulse >= 2400) { - pulse = 0; - if (lawful) - night_watchman(); - check_reboot(); - } - - tics++; /* tics since last checkpoint signal */ - } -} - - - - - - -/* ****************************************************************** -* general utility stuff (for local use) * -****************************************************************** */ - - - - -int get_from_q(struct txt_q *queue, char *dest) -{ - struct txt_block *tmp; - - /* Q empty? */ - if (!queue->head) - return(0); - - tmp = queue->head; - strcpy(dest, queue->head->text); - queue->head = queue->head->next; - - free(tmp->text); - free(tmp); - - return(1); -} - - - - -void write_to_q(char *txt, struct txt_q *queue) -{ - struct txt_block *new; - - CREATE(new, struct txt_block, 1); - CREATE(new->text, char, strlen(txt) + 1); - - strcpy(new->text, txt); - - /* Q empty? */ - if (!queue->head) - { - new->next = NULL; - queue->head = queue->tail = new; - } - else - { - queue->tail->next = new; - queue->tail = new; - new->next = NULL; - } -} - - - - - - - -struct timeval timediff(struct timeval *a, struct timeval *b) -{ - struct timeval rslt, tmp; - - tmp = *a; - - if ((rslt.tv_usec = tmp.tv_usec - b->tv_usec) < 0) - { - rslt.tv_usec += 1000000; - --(tmp.tv_sec); - } - if ((rslt.tv_sec = tmp.tv_sec - b->tv_sec) < 0) - { - rslt.tv_usec = 0; - rslt.tv_sec =0; - } - return(rslt); -} - - - - - - -/* Empty the queues before closing connection */ -void flush_queues(struct descriptor_data *d) -{ - char dummy[MAX_STRING_LENGTH]; - - while (get_from_q(&d->output, dummy)); - while (get_from_q(&d->input, dummy)); -} - - - - - - -/* ****************************************************************** -* socket handling * -****************************************************************** */ - - - - -int init_socket(int port) -{ - int s; - char *opt; - char hostname[MAX_HOSTNAME+1]; - struct sockaddr_in sa; - struct hostent *hp; -/* struct linger ld; */ -/* linger stuff not supported by Linux.... Taken out bsp 11/22/92 */ - - bzero(&sa, sizeof(struct sockaddr_in)); - gethostname(hostname, MAX_HOSTNAME); -/* hp = gethostbyname(hostname); - if (hp == NULL) - { - perror("gethostbyname"); - exit(1); - } -*/ -/* The gethostbyname function call returns NULL all the time. I have not */ -/* gotten this to work without this, however, the only reason it is called */ -/* is to get the h_addrtype constant. The value AF_INET is used in other */ -/* operating systems so I figure it is reasonable for here.... (bsp) */ -/* sa.sin_family = hp->h_addrtype; */ - sa.sin_family = AF_INET; - sa.sin_port = htons(port); - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) - { - perror("Init-socket"); - exit(1); - } - if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, - (char *) &opt, sizeof (opt)) < 0) - { - perror ("setsockopt REUSEADDR"); - exit (1); - } -/* - ld.l_onoff = 1; - ld.l_linger = 1000; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &ld, sizeof(ld)) < 0) - { - perror("setsockopt LINGER"); - exit(1); - } -*/ -/* linger stuff taken out by bsp */ - if (bind(s,(struct sockaddr *)&sa, sizeof(sa)) < 0) - { - perror("bind"); - close(s); - exit(1); - } - listen(s, 3); - return(s); -} - - - - - -int new_connection(int s) -{ -/* struct sockaddr_in isa;*/ - struct sockaddr isa; - /* struct sockaddr peer; */ - int i; - int t; - char buf[100]; - - i = sizeof(isa); - getsockname(s, &isa, &i); - - - if ((t = accept(s, &isa, &i)) < 0) - { - perror("Accept"); - return(-1); - } - nonblock(t); - - /* - - i = sizeof(peer); - if (!getpeername(t, &peer, &i)) - { - *(peer.sa_data + 49) = '\0'; - sprintf(buf, "New connection from addr %s.\n", peer.sa_data); - log(buf); - } - - */ - - return(t); -} - - - - - -int new_descriptor(int s) -{ - int desc; - struct descriptor_data *newd; - int size; - struct sockaddr_in sock; - struct hostent *from; - char buf[10]; - - if ((desc = new_connection(s)) < 0) - return (-1); - - - if ((maxdesc + 1) >= avail_descs) - { - write_to_descriptor(desc, "Sorry.. The game is full...\n\r"); - close(desc); - return(0); - } - else - if (desc > maxdesc) - maxdesc = desc; - - CREATE(newd, struct descriptor_data, 1); - - /* find info */ - size = sizeof(sock); - if (getpeername(desc, (struct sockaddr *) &sock, &size) < 0) - { - perror("getpeername"); - *newd->host = '\0'; - } - else if (!(from = gethostbyaddr((char*)&sock.sin_addr, - sizeof(sizeof(sock.sin_addr)), AF_INET))) - { - perror("gethostbyaddr"); - *newd->host = '\0'; - } - else - { - strncpy(newd->host, from->h_name, 49); - *(newd->host + 49) = '\0'; - } - - - /* init desc data */ - newd->descriptor = desc; - newd->connected = 1; - newd->wait = 1; - newd->prompt_mode = 0; - *newd->buf = '\0'; - newd->str = 0; - newd->showstr_head = 0; - newd->showstr_point = 0; - *newd->last_input= '\0'; - newd->output.head = NULL; - newd->input.head = NULL; - newd->next = descriptor_list; - newd->character = 0; - newd->original = 0; - newd->snoop.snooping = 0; - newd->snoop.snoop_by = 0; - - /* prepend to list */ - - descriptor_list = newd; - - SEND_TO_Q(GREETINGS, newd); - SEND_TO_Q("By what name do you wish to be known? ", newd); - - return(0); -} - - - - - -int process_output(struct descriptor_data *t) -{ - char i[MAX_STRING_LENGTH + 1]; - - if (!t->prompt_mode && !t->connected) - if (write_to_descriptor(t->descriptor, "\n\r") < 0) - return(-1); - - - /* Cycle thru output queue */ - while (get_from_q(&t->output, i)) - { - if(t->snoop.snoop_by) - { - write_to_q("% ",&t->snoop.snoop_by->desc->output); - write_to_q(i,&t->snoop.snoop_by->desc->output); - } - if (write_to_descriptor(t->descriptor, i)) - return(-1); - } - - if (!t->connected && !(t->character && !IS_NPC(t->character) && - IS_SET(t->character->specials.act, PLR_COMPACT))) - if (write_to_descriptor(t->descriptor, "\n\r") < 0) - return(-1); - - return(1); -} - - -int write_to_descriptor(int desc, char *txt) -{ - int sofar, thisround, total; - - total = strlen(txt); - sofar = 0; - - do - { - thisround = write(desc, txt + sofar, total - sofar); - if (thisround < 0) - { - perror("Write to socket"); - return(-1); - } - sofar += thisround; - } - while (sofar < total); - - return(0); -} - - - - - -int process_input(struct descriptor_data *t) -{ - int sofar, thisround, begin, squelch, i, k, flag; - char tmp[MAX_INPUT_LENGTH+2], buffer[MAX_INPUT_LENGTH + 60]; - - sofar = 0; - flag = 0; - begin = strlen(t->buf); - - /* Read in some stuff */ - do - { - if ((thisround = read(t->descriptor, t->buf + begin + sofar, - MAX_STRING_LENGTH - (begin + sofar) - 1)) > 0) - sofar += thisround; - else - if (thisround < 0) - if(errno != EWOULDBLOCK) - { - perror("Read1 - ERROR"); - return(-1); - } - else - break; - else - { - log("EOF encountered on socket read."); - return(-1); - } - } - while (!ISNEWL(*(t->buf + begin + sofar - 1))); - - *(t->buf + begin + sofar) = 0; - - /* if no newline is contained in input, return without proc'ing */ - for (i = begin; !ISNEWL(*(t->buf + i)); i++) - if (!*(t->buf + i)) - return(0); - - /* input contains 1 or more newlines; process the stuff */ - for (i = 0, k = 0; *(t->buf + i);) - { - if (!ISNEWL(*(t->buf + i)) && !(flag = (k >= (MAX_INPUT_LENGTH - 2)))) - if(*(t->buf + i) == '\b') /* backspace */ - if (k) /* more than one char ? */ - { - if (*(tmp + --k) == '$') - k--; - i++; - } - else - i++; /* no or just one char.. Skip backsp */ - else - if (isascii(*(t->buf + i)) && isprint(*(t->buf + i))) - { - /* trans char, double for '$' (printf) */ - if ((*(tmp + k) = *(t->buf + i)) == '$') - *(tmp + ++k) = '$'; - k++; - i++; - } - else - i++; - else - { - *(tmp + k) = 0; - if(*tmp == '!') - strcpy(tmp,t->last_input); - else - strcpy(t->last_input,tmp); - - write_to_q(tmp, &t->input); - - if(t->snoop.snoop_by) - { - write_to_q("% ",&t->snoop.snoop_by->desc->output); - write_to_q(tmp,&t->snoop.snoop_by->desc->output); - write_to_q("\n\r",&t->snoop.snoop_by->desc->output); - } - - if (flag) - { - sprintf(buffer, - "Line too long. Truncated to:\n\r%s\n\r", tmp); - if (write_to_descriptor(t->descriptor, buffer) < 0) - return(-1); - - /* skip the rest of the line */ - for (; !ISNEWL(*(t->buf + i)); i++); - } - - /* find end of entry */ - for (; ISNEWL(*(t->buf + i)); i++); - - /* squelch the entry from the buffer */ - for (squelch = 0;; squelch++) - if ((*(t->buf + squelch) = - *(t->buf + i + squelch)) == '\0') - break; - k = 0; - i = 0; - } - } - return(1); -} - - - - -void close_sockets(int s) -{ - log("Closing all sockets."); - - while (descriptor_list) - close_socket(descriptor_list); - - close(s); -} - - - - - -void close_socket(struct descriptor_data *d) -{ - struct affected_type *af; - struct descriptor_data *tmp; - char buf[100]; - - close(d->descriptor); - flush_queues(d); - if (d->descriptor == maxdesc) - --maxdesc; - - /* Forget snooping */ - if (d->snoop.snooping) - d->snoop.snooping->desc->snoop.snoop_by = 0; - - if (d->snoop.snoop_by) - { - send_to_char("Your victim is no longer among us.\n\r",d->snoop.snoop_by); - d->snoop.snoop_by->desc->snoop.snooping = 0; - } - - if (d->character) - if (d->connected == CON_PLYNG) - { - save_char(d->character, NOWHERE); - act("$n has lost $s link.", TRUE, d->character, 0, 0, TO_ROOM); - sprintf(buf, "Closing link to: %s.", GET_NAME(d->character)); - log(buf); - d->character->desc = 0; - } - else - { - sprintf(buf, "Losing player: %s.", GET_NAME(d->character)); - log(buf); - - free_char(d->character); - } - else - log("Losing descriptor without char."); - - - if (next_to_process == d) /* to avoid crashing the process loop */ - next_to_process = next_to_process->next; - - if (d == descriptor_list) /* this is the head of the list */ - descriptor_list = descriptor_list->next; - else /* This is somewhere inside the list */ - { - /* Locate the previous element */ - for (tmp = descriptor_list; (tmp->next != d) && tmp; - tmp = tmp->next); - - tmp->next = d->next; - } - if (d->showstr_head) - free(d->showstr_head); - free(d); -} - - - - - -void nonblock(int s) -{ - if (fcntl(s, F_SETFL, O_NDELAY) == -1) - { - perror("Noblock"); - exit(1); - } -} - - - - -#define COMA_SIGN \ -"\n\r\ -DikuMUD is currently inactive due to excessive load on the host machine.\n\r\ -Please try again later.\n\r\n\ -\n\r\ - Sadly,\n\r\ -\n\r\ - the DikuMUD system operators\n\r\n\r" - - -/* sleep while the load is too high */ -void coma(int s) -{ - fd_set input_set; - static struct timeval timeout = - { - 60, - 0 - }; - int conn; - - int workhours(void); - int load(void); - - log("Entering comatose state."); - -#ifdef __linux__ - sigsetmask(sigprocmask(SIGUSR1) | sigprocmask(SIGUSR2) | sigprocmask(SIGINT) | - sigprocmask(SIGPIPE) | sigprocmask(SIGALRM) | sigprocmask(SIGTERM) | - sigprocmask(SIGURG) | sigprocmask(SIGXCPU) | sigprocmask(SIGHUP)); -#else - sigsetmask(sigmask(SIGUSR1) | sigmask(SIGUSR2) | sigmask(SIGINT) | - sigmask(SIGPIPE) | sigmask(SIGALRM) | sigmask(SIGTERM) | - sigmask(SIGURG) | sigmask(SIGXCPU) | sigmask(SIGHUP)); -#endif - - while (descriptor_list) - close_socket(descriptor_list); - - FD_ZERO(&input_set); - do - { - FD_SET(s, &input_set); - if (select(64, &input_set, 0, 0, &timeout) < 0) - { - perror("coma select"); - exit(1); - } - if (FD_ISSET(s, &input_set)) - { - if (load() < 6) - { - log("Leaving coma with visitor."); - sigsetmask(0); - return; - } - if ((conn = new_connection(s)) >= 0) - { - write_to_descriptor(conn, COMA_SIGN); - sleep(2); - close(conn); - } - } - - tics = 1; - if (workhours()) - { - log("Working hours collision during coma. Exit."); - exit(0); - } - } - while (load() >= 6); - - log("Leaving coma."); - sigsetmask(0); -} - - - -/* **************************************************************** -* Public routines for system-to-player-communication * -**************************************************************** */ - - - -void send_to_char(char *messg, struct char_data *ch) -{ - - if (ch->desc && messg) - write_to_q(messg, &ch->desc->output); -} - - - - -void send_to_all(char *messg) -{ - struct descriptor_data *i; - - if (messg) - for (i = descriptor_list; i; i = i->next) - if (!i->connected) - write_to_q(messg, &i->output); -} - - -void send_to_outdoor(char *messg) -{ - struct descriptor_data *i; - - if (messg) - for (i = descriptor_list; i; i = i->next) - if (!i->connected) - if (OUTSIDE(i->character)) - write_to_q(messg, &i->output); -} - - -void send_to_except(char *messg, struct char_data *ch) -{ - struct descriptor_data *i; - - if (messg) - for (i = descriptor_list; i; i = i->next) - if (ch->desc != i && !i->connected) - write_to_q(messg, &i->output); -} - - - -void send_to_room(char *messg, int room) -{ - struct char_data *i; - - if (messg) - for (i = world[room].people; i; i = i->next_in_room) - if (i->desc) - write_to_q(messg, &i->desc->output); -} - - - - -void send_to_room_except(char *messg, int room, struct char_data *ch) -{ - struct char_data *i; - - if (messg) - for (i = world[room].people; i; i = i->next_in_room) - if (i != ch && i->desc) - write_to_q(messg, &i->desc->output); -} - -void send_to_room_except_two - (char *messg, int room, struct char_data *ch1, struct char_data *ch2) -{ - struct char_data *i; - - if (messg) - for (i = world[room].people; i; i = i->next_in_room) - if (i != ch1 && i != ch2 && i->desc) - write_to_q(messg, &i->desc->output); -} - - - -/* higher-level communication */ - - -void act(char *str, int hide_invisible, struct char_data *ch, - struct obj_data *obj, void *vict_obj, int type) -{ - register char *strp, *point, *i; - struct char_data *to; - char buf[MAX_STRING_LENGTH]; - - if (!str) - return; - if (!*str) - return; - - if (type == TO_VICT) - to = (struct char_data *) vict_obj; - else if (type == TO_CHAR) - to = ch; - else - to = world[ch->in_room].people; - - for (; to; to = to->next_in_room) - { - if (to->desc && ((to != ch) || (type == TO_CHAR)) && - (CAN_SEE(to, ch) || !hide_invisible) && AWAKE(to) && - !((type == TO_NOTVICT) && (to == (struct char_data *) vict_obj))) - { - for (strp = str, point = buf;;) - if (*strp == '$') - { - switch (*(++strp)) - { - case 'n': i = PERS(ch, to); break; - case 'N': i = PERS((struct char_data *) vict_obj, to); break; - case 'm': i = HMHR(ch); break; - case 'M': i = HMHR((struct char_data *) vict_obj); break; - case 's': i = HSHR(ch); break; - case 'S': i = HSHR((struct char_data *) vict_obj); break; - case 'e': i = HSSH(ch); break; - case 'E': i = HSSH((struct char_data *) vict_obj); break; - case 'o': i = OBJN(obj, to); break; - case 'O': i = OBJN((struct obj_data *) vict_obj, to); break; - case 'p': i = OBJS(obj, to); break; - case 'P': i = OBJS((struct obj_data *) vict_obj, to); break; - case 'a': i = SANA(obj); break; - case 'A': i = SANA((struct obj_data *) vict_obj); break; - case 'T': i = (char *) vict_obj; break; - case 'F': i = fname((char *) vict_obj); break; - case '$': i = "$"; break; - default: - log("Illegal $-code to act():"); - log(str); - break; - } - while (*point = *(i++)) - ++point; - ++strp; - } - else if (!(*(point++) = *(strp++))) - break; - - *(--point) = '\n'; - *(++point) = '\r'; - *(++point) = '\0'; - - write_to_q(CAP(buf), &to->desc->output); - } - if ((type == TO_VICT) || (type == TO_CHAR)) - return; - } -} +/* ************************************************************************ +* file: comm.c , Communication module. Part of DIKUMUD * +* Usage: Communication, central game loop. * +* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * +* All Rights Reserved * +* Using *any* part of DikuMud without having read license.doc is * +* violating our copyright. +************************************************************************* */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "structs.h" +#include "utils.h" +#include "comm.h" +#include "interpreter.h" +#include "handler.h" +#include "db.h" + +#define DFLT_PORT 4000 /* default port */ +#define MAX_NAME_LENGTH 15 +#define MAX_HOSTNAME 256 +#define OPT_USEC 250000 /* time delay corresponding to 4 passes/sec */ + +#ifndef FNDELAY +#define FNDELAY O_NONBLOCK +#endif + +extern int errno; /* Why isn't this done in errno.h on alfa??? */ + +/* externs */ + +/* extern struct char_data *character_list; */ + +extern struct room_data *world; /* In db.c */ +extern int top_of_world; /* In db.c */ +extern struct time_info_data time_info; /* In db.c */ +extern char help[]; +extern bool wizlock; + +/* local globals */ + +struct descriptor_data *descriptor_list, *next_to_process; + +int lawful = 0; /* work like the game regulator */ +int slow_death = 0; /* Shut her down, Martha, she's sucking mud */ +int diku_shutdown = 0; /* clean shutdown */ +int reboot = 0; /* reboot the game after a shutdown */ +int no_specials = 0; /* Suppress ass. of special routines */ + +int maxdesc, avail_descs; +int tics = 0; /* for extern checkpointing */ + +int get_from_q(struct txt_q *queue, char *dest); +/* write_to_q is in comm.h for the macro */ +int run_the_game(int port); +int game_loop(int s); +int init_socket(int port); +int new_connection(int s); +int new_descriptor(int s); +int process_output(struct descriptor_data *t); +int process_input(struct descriptor_data *t); +void close_sockets(int s); +void close_socket(struct descriptor_data *d); +struct timeval timediff(struct timeval *a, struct timeval *b); +void flush_queues(struct descriptor_data *d); +void nonblock(int s); +void parse_name(struct descriptor_data *desc, char *arg); + + +/* extern fcnts */ + +struct char_data *make_char(char *name, struct descriptor_data *desc); +void boot_db(void); +void zone_update(void); +void affect_update( void ); /* In spells.c */ +void point_update( void ); /* In limits.c */ +void free_char(struct char_data *ch); +void log(char *str); +void mobile_activity(void); +void string_add(struct descriptor_data *d, char *str); +void perform_violence(void); +void stop_fighting(struct char_data *ch); +void show_string(struct descriptor_data *d, char *input); +void gr(int s); + +void check_reboot(void); + +/* ********************************************************************* +* main game loop and related stuff * +********************************************************************* */ + + + + +int main(int argc, char **argv) +{ + int port; + char buf[512]; + int pos = 1; + char *dir; + + port = DFLT_PORT; + dir = DFLT_DIR; + + while ((pos < argc) && (*(argv[pos]) == '-')) + { + switch (*(argv[pos] + 1)) + { + case 'l': + lawful = 1; + log("Lawful mode selected."); + break; + case 'd': + if (*(argv[pos] + 2)) + dir = argv[pos] + 2; + else if (++pos < argc) + dir = argv[pos]; + else + { + log("Directory arg expected after option -d."); + exit(0); + } + break; + case 's': + no_specials = 1; + log("Suppressing assignment of special routines."); + break; + default: + sprintf(buf, "Unknown option -% in argument string.", + *(argv[pos] + 1)); + log(buf); + break; + } + pos++; + } + + if (pos < argc) + if (!isdigit(*argv[pos])) + { + fprintf(stderr, "Usage: %s [-l] [-s] [-d pathname] [ port # ]\n", + argv[0]); + exit(0); + } + else if ((port = atoi(argv[pos])) <= 1024) + { + printf("Illegal port #\n"); + exit(0); + } + + sprintf(buf, "Running game on port %d.", port); + log(buf); + + if (chdir(dir) < 0) + { + perror("chdir"); + exit(0); + } + + sprintf(buf, "Using %s as data directory.", dir); + log(buf); + + srandom(time(0)); + run_the_game(port); + return(0); +} + + + + + +#define PROFILE(x) + + +/* Init sockets, run game, and cleanup sockets */ +int run_the_game(int port) +{ + int s; + PROFILE(extern etext();) + + void signal_setup(void); + int load(void); + void coma(); + + PROFILE(monstartup((int) 2, etext);) + + descriptor_list = NULL; + + log("Signal trapping."); + signal_setup(); + + log("Opening mother connection."); + s = init_socket(port); + + if (lawful && load() >= 6) + { + log("System load too high at startup."); + coma(); + } + + boot_db(); + + log("Entering game loop."); + + game_loop(s); + + close_sockets(s); + + PROFILE(monitor(0);) + + if (reboot) + { + log("Rebooting."); + exit(52); /* what's so great about HHGTTG, anyhow? */ + } + + log("Normal termination of game."); +} + + + + + + +/* Accept new connects, relay commands, and call 'heartbeat-functs' */ +int game_loop(int s) +{ + int tmp_room, old_len; + fd_set input_set, output_set, exc_set; + struct timeval last_time, now, timespent, timeout, null_time; + static struct timeval opt_time; + char comm[MAX_INPUT_LENGTH]; + struct descriptor_data *t, *point, *next_point; + int pulse = 0, mask; + + null_time.tv_sec = 0; + null_time.tv_usec = 0; + + opt_time.tv_usec = OPT_USEC; /* Init time values */ + opt_time.tv_sec = 0; + gettimeofday(&last_time, (struct timeval *) 0); + + maxdesc = s; + avail_descs = getdtablesize() - 2; /* !! Change if more needed !! */ + +#if __linux__ + mask = sigprocmask(SIGUSR1) | sigprocmask(SIGUSR2) | sigprocmask(SIGINT) | + sigprocmask(SIGPIPE) | sigprocmask(SIGALRM) | sigprocmask(SIGTERM) | + sigprocmask(SIGURG) | sigprocmask(SIGXCPU) | sigprocmask(SIGHUP) | + sigprocmask(SIGVTALRM); +#else + mask = sigmask(SIGUSR1) | sigmask(SIGUSR2) | sigmask(SIGINT) | + sigmask(SIGPIPE) | sigmask(SIGALRM) | sigmask(SIGTERM) | + sigmask(SIGURG) | sigmask(SIGXCPU) | sigmask(SIGHUP) | + sigmask(SIGVTALRM); +#endif + + /* Main loop */ + while (!diku_shutdown) + { + /* Check what's happening out there */ + FD_ZERO(&input_set); + FD_ZERO(&output_set); + FD_ZERO(&exc_set); + FD_SET(s, &input_set); + for (point = descriptor_list; point; point = point->next) + { + FD_SET(point->descriptor, &input_set); + FD_SET(point->descriptor, &exc_set); + FD_SET(point->descriptor, &output_set); + } + + /* check out the time */ + gettimeofday(&now, (struct timeval *) 0); + timespent = timediff(&now, &last_time); + timeout = timediff(&opt_time, ×pent); + last_time.tv_sec = now.tv_sec + timeout.tv_sec; + last_time.tv_usec = now.tv_usec + timeout.tv_usec; + if (last_time.tv_usec >= 1000000) + { + last_time.tv_usec -= 1000000; + last_time.tv_sec++; + } + + sigsetmask(mask); + + if (select(maxdesc + 1, &input_set, &output_set, &exc_set, &null_time) + < 0) + { + perror("Select poll"); + return(-1); + } + + if (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &timeout) < 0) + { + perror("Select sleep"); + exit(1); + } + + sigsetmask(0); + + /* Respond to whatever might be happening */ + + /* New connection? */ + if (FD_ISSET(s, &input_set)) + if (new_descriptor(s) < 0) + perror("New connection"); + + /* kick out the freaky folks */ + for (point = descriptor_list; point; point = next_point) + { + next_point = point->next; + if (FD_ISSET(point->descriptor, &exc_set)) + { + FD_CLR(point->descriptor, &input_set); + FD_CLR(point->descriptor, &output_set); + close_socket(point); + } + } + + for (point = descriptor_list; point; point = next_point) + { + next_point = point->next; + if (FD_ISSET(point->descriptor, &input_set)) + if (process_input(point) < 0) + close_socket(point); + } + + /* process_commands; */ + for (point = descriptor_list; point; point = next_to_process) + { + next_to_process = point->next; + + if ((--(point->wait) <= 0) && get_from_q(&point->input, comm)) + { + if (point->character && point->connected == CON_PLYNG && + point->character->specials.was_in_room != NOWHERE) + { + if (point->character->in_room != NOWHERE) + char_from_room(point->character); + char_to_room(point->character, + point->character->specials.was_in_room); + point->character->specials.was_in_room = NOWHERE; + act("$n has returned.", TRUE, point->character, 0, 0, TO_ROOM); + affect_total(point->character); + } + + point->wait = 1; + if (point->character) + point->character->specials.timer = 0; + point->prompt_mode = 1; + + if (point->str) + string_add(point, comm); + else if (!point->connected) + if (point->showstr_point) + show_string(point, comm); + else + command_interpreter(point->character, comm); + else + nanny(point, comm); + } + } + + + for (point = descriptor_list; point; point = next_point) + { + next_point = point->next; + if (FD_ISSET(point->descriptor, &output_set) && point->output.head) + if (process_output(point) < 0) + close_socket(point); + else + point->prompt_mode = 1; + } + + /* give the people some prompts */ + for (point = descriptor_list; point; point = point->next) + if (point->prompt_mode) + { + if (point->str) + write_to_descriptor(point->descriptor, "] "); + else if (!point->connected) + if (point->showstr_point) + write_to_descriptor(point->descriptor, + "*** Press return ***"); + else + write_to_descriptor(point->descriptor, "> "); + point->prompt_mode = 0; + } + + + + /* handle heartbeat stuff */ + /* Note: pulse now changes every 1/4 sec */ + + pulse++; + + if (!(pulse % PULSE_ZONE)) + { + zone_update(); + if (lawful) + gr(s); + } + + + if (!(pulse % PULSE_MOBILE)) + mobile_activity(); + + if (!(pulse % PULSE_VIOLENCE)) + perform_violence(); + + if (!(pulse % (SECS_PER_MUD_HOUR*4))){ + weather_and_time(1); + affect_update(); + point_update(); + if ( time_info.hours == 1 ) + update_time(); + } + + if (pulse >= 2400) { + pulse = 0; + if (lawful) + night_watchman(); + check_reboot(); + } + + tics++; /* tics since last checkpoint signal */ + } +} + + + + + + +/* ****************************************************************** +* general utility stuff (for local use) * +****************************************************************** */ + + + + +int get_from_q(struct txt_q *queue, char *dest) +{ + struct txt_block *tmp; + + /* Q empty? */ + if (!queue->head) + return(0); + + tmp = queue->head; + strcpy(dest, queue->head->text); + queue->head = queue->head->next; + + free(tmp->text); + free(tmp); + + return(1); +} + + + + +void write_to_q(char *txt, struct txt_q *queue) +{ + struct txt_block *new; + + CREATE(new, struct txt_block, 1); + CREATE(new->text, char, strlen(txt) + 1); + + strcpy(new->text, txt); + + /* Q empty? */ + if (!queue->head) + { + new->next = NULL; + queue->head = queue->tail = new; + } + else + { + queue->tail->next = new; + queue->tail = new; + new->next = NULL; + } +} + + + + + + + +struct timeval timediff(struct timeval *a, struct timeval *b) +{ + struct timeval rslt, tmp; + + tmp = *a; + + if ((rslt.tv_usec = tmp.tv_usec - b->tv_usec) < 0) + { + rslt.tv_usec += 1000000; + --(tmp.tv_sec); + } + if ((rslt.tv_sec = tmp.tv_sec - b->tv_sec) < 0) + { + rslt.tv_usec = 0; + rslt.tv_sec =0; + } + return(rslt); +} + + + + + + +/* Empty the queues before closing connection */ +void flush_queues(struct descriptor_data *d) +{ + char dummy[MAX_STRING_LENGTH]; + + while (get_from_q(&d->output, dummy)); + while (get_from_q(&d->input, dummy)); +} + + + + + + +/* ****************************************************************** +* socket handling * +****************************************************************** */ + + + + +int init_socket(int port) +{ + int s; + char *opt; + char hostname[MAX_HOSTNAME+1]; + struct sockaddr_in sa; + struct hostent *hp; + struct linger ld; + + bzero(&sa, sizeof(struct sockaddr_in)); + gethostname(hostname, MAX_HOSTNAME); + hp = gethostbyname(hostname); + if (hp == NULL) + { + perror("gethostbyname"); + exit(1); + } + sa.sin_family = hp->h_addrtype; + sa.sin_port = htons(port); + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + { + perror("Init-socket"); + exit(1); + } + if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, + (char *) &opt, sizeof (opt)) < 0) + { + perror ("setsockopt REUSEADDR"); + exit (1); + } + + ld.l_onoff = 1; + ld.l_linger = 1000; + if (setsockopt(s, SOL_SOCKET, SO_LINGER, &ld, sizeof(ld)) < 0) + { + perror("setsockopt LINGER"); + exit(1); + } + if (bind(s, &sa, sizeof(sa)) < 0) + { + perror("bind"); + close(s); + exit(1); + } + listen(s, 3); + return(s); +} + + + + + +int new_connection(int s) +{ + struct sockaddr_in isa; + /* struct sockaddr peer; */ + int i; + int t; + char buf[100]; + + i = sizeof(isa); + getsockname(s, &isa, &i); + + + if ((t = accept(s, &isa, &i)) < 0) + { + perror("Accept"); + return(-1); + } + nonblock(t); + + /* + + i = sizeof(peer); + if (!getpeername(t, &peer, &i)) + { + *(peer.sa_data + 49) = '\0'; + sprintf(buf, "New connection from addr %s.\n", peer.sa_data); + log(buf); + } + + */ + + return(t); +} + + + + + +int new_descriptor(int s) +{ + int desc; + struct descriptor_data *newd; + int size; + struct sockaddr_in sock; + struct hostent *from; + char buf[10]; + + if ((desc = new_connection(s)) < 0) + return (-1); + + if (wizlock) + { + write_to_descriptor(desc, "The game is wizlocked..."); + close(desc); + return(0); + } + + if ((desc + 1) >= avail_descs) + { + write_to_descriptor(desc, "Sorry.. The game is full...\n\r"); + close(desc); + return(0); + } + else + if (desc > maxdesc) + maxdesc = desc; + + CREATE(newd, struct descriptor_data, 1); + + /* find info */ + size = sizeof(sock); + if (getpeername(desc, (struct sockaddr *) &sock, &size) < 0) + { + perror("getpeername"); + *newd->host = '\0'; + } + else if (!(from = gethostbyaddr((char*)&sock.sin_addr, + sizeof(sock.sin_addr), AF_INET))) + { + strcpy(newd->host, inet_ntoa(sock.sin_addr)); + } + else + { + strncpy(newd->host, from->h_name, 49); + *(newd->host + 49) = '\0'; + } + + + /* init desc data */ + newd->descriptor = desc; + newd->connected = 1; + newd->wait = 1; + newd->prompt_mode = 0; + *newd->buf = '\0'; + newd->str = 0; + newd->showstr_head = 0; + newd->showstr_point = 0; + *newd->last_input= '\0'; + newd->output.head = NULL; + newd->input.head = NULL; + newd->next = descriptor_list; + newd->character = 0; + newd->original = 0; + newd->snoop.snooping = 0; + newd->snoop.snoop_by = 0; + + /* prepend to list */ + + descriptor_list = newd; + + SEND_TO_Q(GREETINGS, newd); + SEND_TO_Q("By what name do you wish to be known? ", newd); + + return(0); +} + + + + + +int process_output(struct descriptor_data *t) +{ + char i[MAX_STRING_LENGTH + 1]; + + if (!t->prompt_mode && !t->connected) + if (write_to_descriptor(t->descriptor, "\n\r") < 0) + return(-1); + + + /* Cycle thru output queue */ + while (get_from_q(&t->output, i)) + { + if(t->snoop.snoop_by) + { + write_to_q("% ",&t->snoop.snoop_by->desc->output); + write_to_q(i,&t->snoop.snoop_by->desc->output); + } + if (write_to_descriptor(t->descriptor, i)) + return(-1); + } + + if (!t->connected && !(t->character && !IS_NPC(t->character) && + IS_SET(t->character->specials.act, PLR_COMPACT))) + if (write_to_descriptor(t->descriptor, "\n\r") < 0) + return(-1); + + return(1); +} + + +int write_to_descriptor(int desc, char *txt) +{ + int sofar, thisround, total; + + total = strlen(txt); + sofar = 0; + + do + { + thisround = write(desc, txt + sofar, total - sofar); + if (thisround < 0) + { + perror("Write to socket"); + return(-1); + } + sofar += thisround; + } + while (sofar < total); + + return(0); +} + + + + + +int process_input(struct descriptor_data *t) +{ + int sofar, thisround, begin, squelch, i, k, flag; + char tmp[MAX_INPUT_LENGTH+2], buffer[MAX_INPUT_LENGTH + 60]; + + sofar = 0; + flag = 0; + begin = strlen(t->buf); + + /* Read in some stuff */ + do + { + if ((thisround = read(t->descriptor, t->buf + begin + sofar, + MAX_STRING_LENGTH - (begin + sofar) - 1)) > 0) + sofar += thisround; + else + if (thisround < 0) + if(errno != EWOULDBLOCK) + { + perror("Read1 - ERROR"); + return(-1); + } + else + break; + else + { + log("EOF encountered on socket read."); + return(-1); + } + } + while (!ISNEWL(*(t->buf + begin + sofar - 1))); + + *(t->buf + begin + sofar) = 0; + + /* if no newline is contained in input, return without proc'ing */ + for (i = begin; !ISNEWL(*(t->buf + i)); i++) + if (!*(t->buf + i)) + return(0); + + /* input contains 1 or more newlines; process the stuff */ + for (i = 0, k = 0; *(t->buf + i);) + { + if (!ISNEWL(*(t->buf + i)) && !(flag = (k >= (MAX_INPUT_LENGTH - 2)))) + if(*(t->buf + i) == '\b') /* backspace */ + if (k) /* more than one char ? */ + { + if (*(tmp + --k) == '$') + k--; + i++; + } + else + i++; /* no or just one char.. Skip backsp */ + else + if (isascii(*(t->buf + i)) && isprint(*(t->buf + i))) + { + /* trans char, double for '$' (printf) */ + if ((*(tmp + k) = *(t->buf + i)) == '$') + *(tmp + ++k) = '$'; + k++; + i++; + } + else + i++; + else + { + *(tmp + k) = 0; + if(*tmp == '!') + strcpy(tmp,t->last_input); + else + strcpy(t->last_input,tmp); + + write_to_q(tmp, &t->input); + + if(t->snoop.snoop_by) + { + write_to_q("% ",&t->snoop.snoop_by->desc->output); + write_to_q(tmp,&t->snoop.snoop_by->desc->output); + write_to_q("\n\r",&t->snoop.snoop_by->desc->output); + } + + if (flag) + { + sprintf(buffer, + "Line too long. Truncated to:\n\r%s\n\r", tmp); + if (write_to_descriptor(t->descriptor, buffer) < 0) + return(-1); + + /* skip the rest of the line */ + for (; !ISNEWL(*(t->buf + i)); i++); + } + + /* find end of entry */ + for (; ISNEWL(*(t->buf + i)); i++); + + /* squelch the entry from the buffer */ + for (squelch = 0;; squelch++) + if ((*(t->buf + squelch) = + *(t->buf + i + squelch)) == '\0') + break; + k = 0; + i = 0; + } + } + return(1); +} + + + + +void close_sockets(int s) +{ + log("Closing all sockets."); + + while (descriptor_list) + close_socket(descriptor_list); + + close(s); +} + + + + + +void close_socket(struct descriptor_data *d) +{ + struct affected_type *af; + struct descriptor_data *tmp; + char buf[100]; + + close(d->descriptor); + flush_queues(d); + if (d->descriptor == maxdesc) + --maxdesc; + + /* Forget snooping */ + if (d->snoop.snooping) + d->snoop.snooping->desc->snoop.snoop_by = 0; + + if (d->snoop.snoop_by) + { + send_to_char("Your victim is no longer among us.\n\r",d->snoop.snoop_by); + d->snoop.snoop_by->desc->snoop.snooping = 0; + } + + if (d->character) + if (d->connected == CON_PLYNG) + { + save_char(d->character, NOWHERE); + act("$n has lost $s link.", TRUE, d->character, 0, 0, TO_ROOM); + sprintf(buf, "Closing link to: %s.", GET_NAME(d->character)); + log(buf); + d->character->desc = 0; + } + else + { + sprintf(buf, "Losing player: %s.", GET_NAME(d->character)); + log(buf); + + free_char(d->character); + } + else + log("Losing descriptor without char."); + + + if (next_to_process == d) /* to avoid crashing the process loop */ + next_to_process = next_to_process->next; + + if (d == descriptor_list) /* this is the head of the list */ + descriptor_list = descriptor_list->next; + else /* This is somewhere inside the list */ + { + /* Locate the previous element */ + for (tmp = descriptor_list; (tmp->next != d) && tmp; + tmp = tmp->next); + + tmp->next = d->next; + } + if (d->showstr_head) + free(d->showstr_head); + free(d); +} + + + + + +void nonblock(int s) +{ + if (fcntl(s, F_SETFL, FNDELAY) == -1) + { + perror("Noblock"); + exit(1); + } +} + + + + +#define COMA_SIGN \ +"\n\r\ +DikuMUD is currently inactive due to excessive load on the host machine.\n\r\ +Please try again later.\n\r\n\ +\n\r\ + Sadly,\n\r\ +\n\r\ + the DikuMUD system operators\n\r\n\r" + + +/* sleep while the load is too high */ +void coma(int s) +{ + fd_set input_set; + static struct timeval timeout = + { + 60, + 0 + }; + int conn; + + int workhours(void); + int load(void); + + log("Entering comatose state."); + +#if __linux__ + sigsetmask(sigprocmask(SIGUSR1) | sigprocmask(SIGUSR2) | sigprocmask(SIGINT) | + sigprocmask(SIGPIPE) | sigprocmask(SIGALRM) | sigprocmask(SIGTERM) | + sigprocmask(SIGURG) | sigprocmask(SIGXCPU) | sigprocmask(SIGHUP) | + sigprocmask(SIGVTALRM)); +#else + sigsetmask(sigmask(SIGUSR1) | sigmask(SIGUSR2) | sigmask(SIGINT) | + sigmask(SIGPIPE) | sigmask(SIGALRM) | sigmask(SIGTERM) | + sigmask(SIGURG) | sigmask(SIGXCPU) | sigmask(SIGHUP) | + sigmask(SIGVTALRM)); +#endif + + while (descriptor_list) + close_socket(descriptor_list); + + FD_ZERO(&input_set); + do + { + FD_SET(s, &input_set); + if (select(64, &input_set, 0, 0, &timeout) < 0) + { + perror("coma select"); + exit(1); + } + if (FD_ISSET(s, &input_set)) + { + if (load() < 6) + { + log("Leaving coma with visitor."); + sigsetmask(0); + return; + } + if ((conn = new_connection(s)) >= 0) + { + write_to_descriptor(conn, COMA_SIGN); + sleep(2); + close(conn); + } + } + + tics = 1; + if (workhours()) + { + log("Working hours collision during coma. Exit."); + exit(0); + } + } + while (load() >= 6); + + log("Leaving coma."); + sigsetmask(0); +} + + + +/* **************************************************************** +* Public routines for system-to-player-communication * +**************************************************************** */ + + + +void send_to_char(char *messg, struct char_data *ch) +{ + + if (ch->desc && messg) + write_to_q(messg, &ch->desc->output); +} + + + + +void send_to_all(char *messg) +{ + struct descriptor_data *i; + + if (messg) + for (i = descriptor_list; i; i = i->next) + if (!i->connected) + write_to_q(messg, &i->output); +} + + +void send_to_outdoor(char *messg) +{ + struct descriptor_data *i; + + if (messg) + for (i = descriptor_list; i; i = i->next) + if (!i->connected) + if (OUTSIDE(i->character)) + write_to_q(messg, &i->output); +} + + +void send_to_except(char *messg, struct char_data *ch) +{ + struct descriptor_data *i; + + if (messg) + for (i = descriptor_list; i; i = i->next) + if (ch->desc != i && !i->connected) + write_to_q(messg, &i->output); +} + + + +void send_to_room(char *messg, int room) +{ + struct char_data *i; + + if (messg) + for (i = world[room].people; i; i = i->next_in_room) + if (i->desc) + write_to_q(messg, &i->desc->output); +} + + + + +void send_to_room_except(char *messg, int room, struct char_data *ch) +{ + struct char_data *i; + + if (messg) + for (i = world[room].people; i; i = i->next_in_room) + if (i != ch && i->desc) + write_to_q(messg, &i->desc->output); +} + +void send_to_room_except_two + (char *messg, int room, struct char_data *ch1, struct char_data *ch2) +{ + struct char_data *i; + + if (messg) + for (i = world[room].people; i; i = i->next_in_room) + if (i != ch1 && i != ch2 && i->desc) + write_to_q(messg, &i->desc->output); +} + + + +/* higher-level communication */ + + +void act(char *str, int hide_invisible, struct char_data *ch, + struct obj_data *obj, void *vict_obj, int type) +{ + register char *strp, *point, *i; + struct char_data *to; + char buf[MAX_STRING_LENGTH]; + + if (!str) + return; + if (!*str) + return; + + if (type == TO_VICT) + to = (struct char_data *) vict_obj; + else if (type == TO_CHAR) + to = ch; + else + to = world[ch->in_room].people; + + for (; to; to = to->next_in_room) + { + if (to->desc && ((to != ch) || (type == TO_CHAR)) && + (CAN_SEE(to, ch) || !hide_invisible) && AWAKE(to) && + !((type == TO_NOTVICT) && (to == (struct char_data *) vict_obj))) + { + for (strp = str, point = buf;;) + if (*strp == '$') + { + switch (*(++strp)) + { + case 'n': i = PERS(ch, to); break; + case 'N': i = PERS((struct char_data *) vict_obj, to); break; + case 'm': i = HMHR(ch); break; + case 'M': i = HMHR((struct char_data *) vict_obj); break; + case 's': i = HSHR(ch); break; + case 'S': i = HSHR((struct char_data *) vict_obj); break; + case 'e': i = HSSH(ch); break; + case 'E': i = HSSH((struct char_data *) vict_obj); break; + case 'o': i = OBJN(obj, to); break; + case 'O': i = OBJN((struct obj_data *) vict_obj, to); break; + case 'p': i = OBJS(obj, to); break; + case 'P': i = OBJS((struct obj_data *) vict_obj, to); break; + case 'a': i = SANA(obj); break; + case 'A': i = SANA((struct obj_data *) vict_obj); break; + case 'T': i = (char *) vict_obj; break; + case 'F': i = fname((char *) vict_obj); break; + case '$': i = "$"; break; + default: + log("Illegal $-code to act():"); + log(str); + break; + } + while (*point = *(i++)) + ++point; + ++strp; + } + else if (!(*(point++) = *(strp++))) + break; + + *(--point) = '\n'; + *(++point) = '\r'; + *(++point) = '\0'; + + write_to_q(CAP(buf), &to->desc->output); + } + if ((type == TO_VICT) || (type == TO_CHAR)) + return; + } +} diff --git a/constants.c b/constants.c index 943e46f..3922ce1 100644 --- a/constants.c +++ b/constants.c @@ -66,15 +66,15 @@ const char *spell_wear_off_msg[] = { }; -const int rev_dir[] = +const int rev_dir[] = { 2, 3, 0, - 1, + 1, 5, 4 -}; +}; const int movement_loss[]= { @@ -88,7 +88,7 @@ const int movement_loss[]= 1 /* Unswimable */ }; -const char *dirs[] = +const char *dirs[] = { "north", "east", @@ -99,7 +99,7 @@ const char *dirs[] = "\n" }; -const char *weekdays[7] = { +const char *weekdays[7] = { "the Day of the Moon", "the Day of the Bull", "the Day of the Deception", @@ -160,8 +160,8 @@ const char *where[] = { " ", " ", " ", - " " -}; + " " +}; const char *drinks[]= { @@ -474,8 +474,8 @@ const char *equipment_types[] = { "Held", "\n" }; - -const char *affected_bits[] = + +const char *affected_bits[] = { "BLIND", "INVISIBLE", "DETECT-EVIL", @@ -566,6 +566,10 @@ const char *player_bits[] = { "NOSHOUT", "COMPACT", "DONTSET", + "NOTELL", + "NOEMOTE", + "", + "FREEZE", "\n" }; diff --git a/db.c b/db.c index 0da388a..7f1f9b0 100644 --- a/db.c +++ b/db.c @@ -57,7 +57,7 @@ int top_of_helpt; /* top of help index table */ struct time_info_data time_info; /* the infomation about the time */ struct weather_data weather_info; /* the infomation about the weather */ - +bool wizlock = FALSE; /* is the game wizlocked */ /* local procedures */ @@ -998,7 +998,6 @@ struct char_data *read_mobile(int nr, int type) mob->points.armor = 10*tmp; fscanf(mob_f, " %dd%d+%d ", &tmp, &tmp2, &tmp3); - mob->points.max_hit = dice(tmp, tmp2)+tmp3; mob->points.hit = mob->points.max_hit; @@ -1868,7 +1867,7 @@ void save_char(struct char_data *ch, sh_int load_room) if (expand = (ch->desc->pos > top_of_p_file)) { - strcpy(mode, "a"); + strcpy(mode, "a+"); top_of_p_file++; } else @@ -1885,8 +1884,13 @@ void save_char(struct char_data *ch, sh_int load_room) exit(1); } - if (!expand) - fseek(fl, ch->desc->pos * sizeof(struct char_file_u), 0); + fflush(fl); + if (expand) + { + fwrite(&st, sizeof(struct char_file_u), 1, fl); + } + + fseek(fl, ch->desc->pos * sizeof(struct char_file_u), 0); fwrite(&st, sizeof(struct char_file_u), 1, fl); diff --git a/db.h b/db.h index c27c832..2d4428a 100644 --- a/db.h +++ b/db.h @@ -79,13 +79,13 @@ struct char_data *read_mobile(int nr, int type); /* structure for the reset commands */ struct reset_com { - char command; /* current command */ + char command; /* current command */ bool if_flag; /* if TRUE: exe only if preceding exe'd */ int arg1; /* */ int arg2; /* Arguments to the command */ int arg3; /* */ - /* + /* * Commands: * * 'M': Read a mobile * * 'O': Read an object * @@ -137,7 +137,7 @@ struct index_data struct reset_q_element { int zone_to_reset; /* ref to zone_data */ - struct reset_q_element *next; + struct reset_q_element *next; }; diff --git a/delplay.c b/delplay.c index f16ae9a..53ebf70 100644 --- a/delplay.c +++ b/delplay.c @@ -66,7 +66,7 @@ void del(char *filename, int name) perror("truncate"); } - + main(int argc, char **argv) { if (argc != 3) diff --git a/doc/README b/doc/README index 44b3ab2..4809721 100644 --- a/doc/README +++ b/doc/README @@ -1,30 +1,31 @@ -This directory contains documentation on various aspects of the game. - -CONTENTS: --------- - -ACTIONS.DOC - Description of the 'social action' system. -COMBAT.DOC - Out of date -COMM.DOC - The game-to-player communications system, most important - the act() procedure. -DATABASE.DOC - The format of the most important data files. -DBSUP.DOC - Detailed information on each field in database.doc -DEFS.DOC - Important document on what rules should be followed - when creating a part of the world, to avoid complete - chaos. -HANDLER.DOC - Descriptions of most of the basic 'database handling' - procedures, found in handler.c -INTERPRETER.DOC - ?? Out of date -LEVELS.DOC - Out of date -LICENSE.DOC - The conditions under which this game is distributed. - NOTE: THIS FILE MUST ALWAYS BE PRESENT. -LOOK.DOC -MACRO.DOC - Descriptions of the macros used in the game code. -NEWSTRUCT.DOC - Out of date -RUNNING.DOC - Directions for running the game. -SHOPS.DOC - Brief doc on how to build shop files in lib/ -SKILLS.DOC - Out of date -SPELL_INFO.DOC - Doc on spells, especially how damage is calculated -SPELLS.DOC - Out of date -TIME.DOC - How time is in DikuMud compared to real world. -VALUES.DOC - The 4 generic values for items, described in detail. +This directory contains documentation on various aspects of the game. + +CONTENTS: +-------- + +ACTIONS.DOC - Description of the 'social action' system. +COMBAT.DOC - Out of date +COMM.DOC - The game-to-player communications system, most important + the act() procedure. +DATABASE.DOC - The format of the most important data files. +DBSUP.DOC - Detailed information on each field in database.doc +DEFS.DOC - Important document on what rules should be followed + when creating a part of the world, to avoid complete + chaos. +HANDLER.DOC - Descriptions of most of the basic 'database handling' + procedures, found in handler.c +INTERPRETER.DOC - ?? Out of date +LEVELS.DOC - Out of date +LICENSE.DOC - The conditions under which this game is distributed. + NOTE: THIS FILE MUST ALWAYS BE PRESENT. +LOOK.DOC +MACRO.DOC - Descriptions of the macros used in the game code. +NEWSTRUCT.DOC - Out of date +RUNNING.DOC - Directions for running the game. +SHOPS.DOC - Brief doc on how to build shop files in lib/ +SKILLS.DOC - Out of date +SPELL_INFO.DOC - Doc on spells, especially how damage is calculated +SPELLS.DOC - Out of date +TIME.DOC - How time is in DikuMud compared to real world. +VALUES.DOC - The 4 generic values for items, described in detail. + \ No newline at end of file diff --git a/doc/actions.doc b/doc/actions.doc index 9cbfbbc..2a50747 100644 --- a/doc/actions.doc +++ b/doc/actions.doc @@ -1,66 +1,66 @@ -/* ************************************************************************ -* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * -************************************************************************* */ - - - --- On the handling facilities for 'social actions'--- - - -A general system exists to handle the 'social' commands, ie. commands that -have no game-related purpose save to convey emotions between players. These -are handled by the procedure - - void do_action(struct char_data *ch, char *argument, int cmd); - -This procedure reacts in accordance with the contents of lib/actions, which -is a text file with information arranged after the following format: - --------------------------------------------- - - - - <---If this field is empty, - <- - | then these fields must be - | skipped, and the action will - | ignore arguments. - <- - - -. -. -. -. -. - - --1 -------------------------------------------------- - -A message must be contained in one line. - -The hide-flag, if nonzero, makes the procedure hide the action from OTHERS, -if they cannot see the character. The action won't be hidden from the VICTIM, -even if he/she cannot see the character (the character's name will, of course, -be replaced with "someone"). - -Where it makes sense to do so, text fields may be left empty. This is done by -putting a '#' in the first column on the line. - This is permissible for the following fields: - -a: messg to others if no arg -b: messg to others if victim found -c: messg to others if vict is char - -NOTE again that if the field _messg to char if victim found_ is empty, then -the following fields must be omitted entirely (not even the '~'), and the -action will ignore any arguments supplied. - -The procedure sends the text strings through act(), and they may contain -control codes (see the documentation for act() in comm.doc. Note that not all -of act()'s control codes may be used. - -In order to improve execution speed, no tests are made on the consistency of -the usage of these codes. Hence, grave disorder may be the result if, say, -the code '$N' occurs in a text field that doesn't naturally refer to a victim; -like _messg to others if no arg_. +/* ************************************************************************ +* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * +************************************************************************* */ + + + --- On the handling facilities for 'social actions'--- + + +A general system exists to handle the 'social' commands, ie. commands that +have no game-related purpose save to convey emotions between players. These +are handled by the procedure + + void do_action(struct char_data *ch, char *argument, int cmd); + +This procedure reacts in accordance with the contents of lib/actions, which +is a text file with information arranged after the following format: + +-------------------------------------------- + + + + <---If this field is empty, + <- + | then these fields must be + | skipped, and the action will + | ignore arguments. + <- + + +. +. +. +. +. + + +-1 +------------------------------------------------- + +A message must be contained in one line. + +The hide-flag, if nonzero, makes the procedure hide the action from OTHERS, +if they cannot see the character. The action won't be hidden from the VICTIM, +even if he/she cannot see the character (the character's name will, of course, +be replaced with "someone"). + +Where it makes sense to do so, text fields may be left empty. This is done by +putting a '#' in the first column on the line. + This is permissible for the following fields: + +a: messg to others if no arg +b: messg to others if victim found +c: messg to others if vict is char + +NOTE again that if the field _messg to char if victim found_ is empty, then +the following fields must be omitted entirely (not even the '~'), and the +action will ignore any arguments supplied. + +The procedure sends the text strings through act(), and they may contain +control codes (see the documentation for act() in comm.doc. Note that not all +of act()'s control codes may be used. + +In order to improve execution speed, no tests are made on the consistency of +the usage of these codes. Hence, grave disorder may be the result if, say, +the code '$N' occurs in a text field that doesn't naturally refer to a victim; +like _messg to others if no arg_. diff --git a/doc/combat.doc b/doc/combat.doc index 5e26ed3..9fa0f70 100644 --- a/doc/combat.doc +++ b/doc/combat.doc @@ -1,100 +1,100 @@ -/* ************************************************************************ -* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * -************************************************************************* */ - -HIT: - -(weapon wielded) - -hit_roll = tohit(weapon)D6 + (str/2) - (weight(weapon)-(str/10)) - /*make hit roll */ -victim | - AC | 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -hit_roll| - needed | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 - -if hit : dam_roll = todam(weapon)D6 + (2Dstr/2) /*damage on victim */ - ------------------------------------------------------------------------- -SPELL: - -check mana && success(spell)>0% - - success_roll = 2*levelDsuccess(spell) /*make success roll */ - - victim_roll = 1D20 /*make saving roll */ - - if ((success_roll > 100) && (victim_roll 100) && (victim_roll0% + + success_roll = 2*levelDsuccess(spell) /*make success roll */ + + victim_roll = 1D20 /*make saving roll */ + + if ((success_roll > 100) && (victim_roll 100) && (victim_roll