diff --git a/doc/FAQ.txt b/doc/FAQ.txt index 3b28a08..aaead4d 100644 --- a/doc/FAQ.txt +++ b/doc/FAQ.txt @@ -700,8 +700,8 @@ trigger variables. 4.15. I want to expand the ability to pk in my MUD, allowing ASSASSINS that'll be able to PK without getting flagged. How can I do this? -With tbaMUD simply enter Cedit (configuration editor) and select Game Play -Options. Then enable Player Killing. +With tbaMUD simply enter Cedit (configuration editor), select Game Play + (G). Select Player Killing Allowed (A) and choose (3) 'Free for all!'. 4.16. Why does it say ``Connection closed by foreign host.'' and not display the ``Byebye!'' message I'm trying to send before cutting diff --git a/src/act.offensive.c b/src/act.offensive.c index cb54edd..ff0401a 100644 --- a/src/act.offensive.c +++ b/src/act.offensive.c @@ -54,7 +54,7 @@ ACMD(do_assist) else if (!CAN_SEE(ch, opponent)) act("You can't see who is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR); /* prevent accidental pkill */ - else if (!CONFIG_PK_ALLOWED && !IS_NPC(opponent)) + else if (!pk_allowed(ch, opponent)) send_to_char(ch, "You cannot kill other players.\r\n"); else { send_to_char(ch, "You join the fight!\r\n"); @@ -82,8 +82,10 @@ ACMD(do_hit) } else if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master == vict)) act("$N is just such a good friend, you simply can't hit $M.", FALSE, ch, 0, vict, TO_CHAR); else { - if (!CONFIG_PK_ALLOWED && !IS_NPC(vict) && !IS_NPC(ch)) - check_killer(ch, vict); + if (!pk_allowed(ch, vict)) { + send_to_char(ch, "Player killing is not allowed.\r\n"); + return; + } if ((GET_POS(ch) == POS_STANDING) && (vict != FIGHTING(ch))) { if (GET_DEX(ch) > GET_DEX(vict) || (GET_DEX(ch) == GET_DEX(vict) && rand_number(1, 2) == 1)) /* if faster */ diff --git a/src/act.other.c b/src/act.other.c index 37cc284..7834921 100644 --- a/src/act.other.c +++ b/src/act.other.c @@ -154,6 +154,7 @@ ACMD(do_steal) send_to_char(ch, "You have no idea how to do that.\r\n"); return; } + if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n"); return; @@ -169,20 +170,26 @@ ACMD(do_steal) return; } + /* Check if player stealing is allowed */ + if (!IS_NPC(vict)) { + if (CONFIG_PT_SETTING == CONFIG_PT_OFF) { + send_to_char(ch, "Stealing from players is not allowed.\r\n"); + return; + } + pcsteal = (CONFIG_PT_SETTING == CONFIG_PT_LIMITED); + } + /* 101% is a complete failure */ percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket; if (GET_POS(vict) < POS_SLEEPING) percent = -1; /* ALWAYS SUCCESS, unless heavy object. */ - if (!CONFIG_PT_ALLOWED && !IS_NPC(vict)) - pcsteal = 1; - if (!AWAKE(vict)) /* Easier to steal from sleeping people. */ percent -= 50; /* No stealing if not allowed. If it is no stealing from Imm's or Shopkeepers. */ - if (GET_LEVEL(vict) >= LVL_IMMORT || pcsteal || GET_MOB_SPEC(vict) == shop_keeper) + if (GET_LEVEL(vict) >= LVL_IMMORT || GET_MOB_SPEC(vict) == shop_keeper) percent = 101; /* Failure */ if (str_cmp(obj_name, "coins") && str_cmp(obj_name, "gold")) { @@ -221,6 +228,12 @@ ACMD(do_steal) if (percent > GET_SKILL(ch, SKILL_STEAL)) { ohoh = TRUE; send_to_char(ch, "Oops..\r\n"); + + /* Player got caught and stealing is limited via cedit */ + if ( (pcsteal) && (!PLR_FLAGGED(ch, PLR_THIEF))) { + SET_BIT_AR(PLR_FLAGS(ch), PLR_THIEF); + } + act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT); act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT); } else { /* Steal the item */ @@ -242,6 +255,10 @@ ACMD(do_steal) } else { /* Steal some coins */ if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) { ohoh = TRUE; + /* Player got caught and stealing is limited via cedit */ + if ( (pcsteal) && (!PLR_FLAGGED(ch, PLR_THIEF))) { + SET_BIT_AR(PLR_FLAGS(ch), PLR_THIEF); + } send_to_char(ch, "Oops..\r\n"); act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, vict, TO_VICT); act("$n tries to steal gold from $N.", TRUE, ch, 0, vict, TO_NOTVICT); diff --git a/src/cedit.c b/src/cedit.c index 82b1016..ca8aa7b 100644 --- a/src/cedit.c +++ b/src/cedit.c @@ -79,8 +79,8 @@ static void cedit_setup(struct descriptor_data *d) /* Copy the current configuration from the config_info to this one and copy * the game play options from the configuration info struct. */ - OLC_CONFIG(d)->play.pk_allowed = CONFIG_PK_ALLOWED; - OLC_CONFIG(d)->play.pt_allowed = CONFIG_PT_ALLOWED; + OLC_CONFIG(d)->play.pk_setting = CONFIG_PK_SETTING; + OLC_CONFIG(d)->play.pt_setting = CONFIG_PT_SETTING; OLC_CONFIG(d)->play.level_can_shout = CONFIG_LEVEL_CAN_SHOUT; OLC_CONFIG(d)->play.holler_move_cost = CONFIG_HOLLER_MOVE_COST; OLC_CONFIG(d)->play.tunnel_size = CONFIG_TUNNEL_SIZE; @@ -183,8 +183,8 @@ static void cedit_save_internally(struct descriptor_data *d) /* see if we need to reassign spec procs on rooms */ int reassign = (CONFIG_DTS_ARE_DUMPS != OLC_CONFIG(d)->play.dts_are_dumps); /* Copy the data back from the descriptor to the config_info structure. */ - CONFIG_PK_ALLOWED = OLC_CONFIG(d)->play.pk_allowed; - CONFIG_PT_ALLOWED = OLC_CONFIG(d)->play.pt_allowed; + CONFIG_PK_SETTING = OLC_CONFIG(d)->play.pk_setting; + CONFIG_PT_SETTING = OLC_CONFIG(d)->play.pt_setting; CONFIG_LEVEL_CAN_SHOUT = OLC_CONFIG(d)->play.level_can_shout; CONFIG_HOLLER_MOVE_COST = OLC_CONFIG(d)->play.holler_move_cost; CONFIG_TUNNEL_SIZE = OLC_CONFIG(d)->play.tunnel_size; @@ -339,9 +339,9 @@ int save_config( IDXTYPE nowhere ) ); fprintf(fl, "* Is player killing allowed on the mud?\n" - "pk_allowed = %d\n\n", CONFIG_PK_ALLOWED); + "pk_setting = %d\n\n", CONFIG_PK_SETTING); fprintf(fl, "* Is player thieving allowed on the mud?\n" - "pt_allowed = %d\n\n", CONFIG_PT_ALLOWED); + "pt_setting = %d\n\n", CONFIG_PT_SETTING); fprintf(fl, "* What is the minimum level a player can shout/gossip/etc?\n" "level_can_shout = %d\n\n", CONFIG_LEVEL_CAN_SHOUT); fprintf(fl, "* How many movement points does shouting cost the player?\n" @@ -608,8 +608,10 @@ static void cedit_disp_menu(struct descriptor_data *d) static void cedit_disp_game_play_options(struct descriptor_data *d) { - int m_opt; + int m_opt, pk_setting, pt_setting; m_opt = OLC_CONFIG(d)->play.map_option; + pk_setting = OLC_CONFIG(d)->play.pk_setting; + pt_setting = OLC_CONFIG(d)->play.pt_setting; get_char_colors(d->character); clear_screen(d); @@ -644,8 +646,8 @@ static void cedit_disp_game_play_options(struct descriptor_data *d) "%s8%s) Scripts on PC's : %s%s\r\n" "%sQ%s) Exit To The Main Menu\r\n" "Enter your choice : ", - grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pk_allowed), - grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pt_allowed), + grn, nrm, cyn, pk_setting == 0 ? "Off" : (pk_setting == 1 ? "Limited" : (pk_setting == 2 ? "Free-for-all" : "Invalid!")), + grn, nrm, cyn, pt_setting == 0 ? "Off" : (pt_setting == 1 ? "Limited" : (pt_setting == 2 ? "Free-for-all" : "Invalid!")), grn, nrm, cyn, OLC_CONFIG(d)->play.level_can_shout, grn, nrm, cyn, OLC_CONFIG(d)->play.holler_move_cost, grn, nrm, cyn, OLC_CONFIG(d)->play.tunnel_size, @@ -883,13 +885,21 @@ void cedit_parse(struct descriptor_data *d, char *arg) switch (*arg) { case 'a': case 'A': - TOGGLE_VAR(OLC_CONFIG(d)->play.pk_allowed); - break; + write_to_output(d, "1) No Player Killing\r\n"); + write_to_output(d, "2) Limited Player Killing\r\n"); + write_to_output(d, "3) Free-for-all!\r\n"); + write_to_output(d, "Enter choice: "); + OLC_MODE(d) = CEDIT_PK_SETTING; + return; case 'b': case 'B': - TOGGLE_VAR(OLC_CONFIG(d)->play.pt_allowed); - break; + write_to_output(d, "1) No Player Thieving\r\n"); + write_to_output(d, "2) Limited Player Thieving\r\n"); + write_to_output(d, "3) Free-for-all!\r\n"); + write_to_output(d, "Enter choice: "); + OLC_MODE(d) = CEDIT_PT_SETTING; + return; case 'c': case 'C': @@ -1708,6 +1718,30 @@ void cedit_parse(struct descriptor_data *d, char *arg) } break; + case CEDIT_PK_SETTING: + if (!*arg || (atoi(arg) < 0) || (atoi(arg) > 3) ) { + write_to_output(d, + "That is an invalid choice!\r\n" + "Select 1, 2 or 3 (0 to cancel) :"); + } else { + if ((atoi(arg) >= 1) && (atoi(arg) <= 3)) + OLC_CONFIG(d)->play.pk_setting = (atoi(arg) - 1); + cedit_disp_game_play_options(d); + } + break; + + case CEDIT_PT_SETTING: + if (!*arg || (atoi(arg) < 0) || (atoi(arg) > 3) ) { + write_to_output(d, + "That is an invalid choice!\r\n" + "Select 1, 2 or 3 (0 to cancel) :"); + } else { + if ((atoi(arg) >= 1) && (atoi(arg) <= 3)) + OLC_CONFIG(d)->play.pt_setting = (atoi(arg) - 1); + cedit_disp_game_play_options(d); + } + break; + default: /* We should never get here, but just in case... */ cleanup_olc(d, CLEANUP_CONFIG); mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: cedit_parse(): Reached default case!"); diff --git a/src/config.c b/src/config.c index aa9a4c5..102dc91 100644 --- a/src/config.c +++ b/src/config.c @@ -39,15 +39,25 @@ /* Can Scripts be attached to players? */ int script_players = NO; -/* pk_allowed sets the tone of the entire game. If pk_allowed is set to NO, - * then players will not be allowed to kill, summon, charm, or sleep other - * players, as well as a variety of other "asshole player" protections. However, - * if you decide you want to have an all-out knock-down drag-out PK Mud, just - * set pk_allowed to YES - and anything goes. */ -int pk_allowed = NO; +/* pk_setting sets the tone of the entire game. + * + * CONFIG_PK_OFF 0 Players are prevented from damaging or fighting other players in code + * CONFIG_PK_LIMITED 1 Players may damage and fight but will be flagged PLR_KILLER + * CONFIG_PK_FREEFORALL 2 No restrictions or flags for player damaging or killing + * + * If pk_setting is set to 0, then players will not be allowed to kill, summon, charm, or sleep other + * players, as well as a variety of other "asshole player" protections. + * However, if you decide you want to have an all-out knock-down drag-out PK Mud, just + * set pk_setting to 2 - and anything goes. */ +int pk_setting = 0; -/* Is playerthieving allowed? */ -int pt_allowed = NO; +/* Is playerthieving allowed? +* +* CONFIG_PT_OFF 0 Players are prevented from stealing from other players in code +* CONFIG_PT_LIMITED 1 Players may steal from other players but will be flagged PLR_THIEF if caught +* CONFIG_PT_FREEFORALL 2 No restrictions or flags for player stealing +*/ +int pt_setting = 0; /* Minimum level a player must be to shout/holler/gossip/auction. */ int level_can_shout = 1; diff --git a/src/config.h b/src/config.h index 1153fac..9e11b2c 100644 --- a/src/config.h +++ b/src/config.h @@ -14,9 +14,9 @@ #define _CONFIG_H_ /* Global variable declarations, all settable by cedit */ -extern int pk_allowed; +extern int pk_setting; extern int script_players; -extern int pt_allowed; +extern int pt_setting; extern int level_can_shout; extern int holler_move_cost; extern int tunnel_size; diff --git a/src/db.c b/src/db.c index fda7ac6..149c0c4 100644 --- a/src/db.c +++ b/src/db.c @@ -3838,8 +3838,8 @@ static void load_default_config( void ) /* This function is called only once, at boot-time. We assume config_info is * empty. -Welcor */ /* Game play options. */ - CONFIG_PK_ALLOWED = pk_allowed; - CONFIG_PT_ALLOWED = pt_allowed; + CONFIG_PK_SETTING = pk_setting; + CONFIG_PT_SETTING = pt_setting; CONFIG_LEVEL_CAN_SHOUT = level_can_shout; CONFIG_HOLLER_MOVE_COST = holler_move_cost; CONFIG_TUNNEL_SIZE = tunnel_size; @@ -4113,12 +4113,12 @@ void load_config( void ) break; case 'p': - if (!str_cmp(tag, "pk_allowed")) - CONFIG_PK_ALLOWED = num; + if (!str_cmp(tag, "pk_setting")) + CONFIG_PK_SETTING = num; else if (!str_cmp(tag, "protocol_negotiation")) CONFIG_PROTOCOL_NEGOTIATION = num; - else if (!str_cmp(tag, "pt_allowed")) - CONFIG_PT_ALLOWED = num; + else if (!str_cmp(tag, "pt_setting")) + CONFIG_PT_SETTING = num; break; case 'r': diff --git a/src/fight.c b/src/fight.c index e823eb9..3dfa9dd 100644 --- a/src/fight.c +++ b/src/fight.c @@ -110,10 +110,13 @@ void update_pos(struct char_data *victim) void check_killer(struct char_data *ch, struct char_data *vict) { - if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF)) - return; - if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict) + if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF)) { return; + } + + if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict){ + return; + } SET_BIT_AR(PLR_FLAGS(ch), PLR_KILLER); send_to_char(ch, "If you want to be a PLAYER KILLER, so be it...\r\n"); @@ -122,6 +125,22 @@ void check_killer(struct char_data *ch, struct char_data *vict) GET_NAME(ch), GET_NAME(vict), world[IN_ROOM(vict)].name); } +bool pk_allowed(struct char_data *ch, struct char_data *victim) +{ + /* NPCs are never restricted */ + if (IS_NPC(ch) || IS_NPC(victim)) + return true; + + if (CONFIG_PK_SETTING == CONFIG_PK_OFF) + return false; + + if (CONFIG_PK_SETTING == CONFIG_PK_LIMITED) + check_killer(ch, victim); + + return true; +} + + /* start one char fighting another (yes, it is horrible, I know... ) */ void set_fighting(struct char_data *ch, struct char_data *vict) { @@ -133,6 +152,12 @@ void set_fighting(struct char_data *ch, struct char_data *vict) return; } + + if (!pk_allowed(ch, vict)) { + send_to_char(ch, "Player killing is not permitted.\r\n"); + return; + } + ch->next_fighting = combat_list; combat_list = ch; @@ -142,8 +167,6 @@ void set_fighting(struct char_data *ch, struct char_data *vict) FIGHTING(ch) = vict; GET_POS(ch) = POS_FIGHTING; - if (!CONFIG_PK_ALLOWED) - check_killer(ch, vict); } /* remove a char from the list of fighting chars */ @@ -603,6 +626,12 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty return (-1); /* -je, 7/7/92 */ } + /* Check for PK if this is not a PK MUD */ + if (!pk_allowed(ch, victim)) { + send_to_char(ch, "Player killing is not permitted.\r\n"); + return (0); + } + /* peaceful rooms */ if (ch->nr != real_mobile(DG_CASTER_PROXY) && ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { @@ -650,13 +679,6 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2) dam /= 2; - /* Check for PK if this is not a PK MUD */ - if (!CONFIG_PK_ALLOWED) { - check_killer(ch, victim); - if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim)) - dam = 0; - } - /* Set the maximum damage per round and subtract the hit points */ dam = MAX(MIN(dam, 100), 0); GET_HIT(victim) -= dam; diff --git a/src/fight.h b/src/fight.h index e24bc16..612e1a3 100644 --- a/src/fight.h +++ b/src/fight.h @@ -34,6 +34,7 @@ void set_fighting(struct char_data *ch, struct char_data *victim); int skill_message(int dam, struct char_data *ch, struct char_data *vict, int attacktype); void stop_fighting(struct char_data *ch); +bool pk_allowed(struct char_data *ch, struct char_data *victim); /* Global variables */ diff --git a/src/magic.c b/src/magic.c index 5882589..16156d8 100644 --- a/src/magic.c +++ b/src/magic.c @@ -473,7 +473,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim, break; case SPELL_SLEEP: - if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(victim)) + if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(ch) && !IS_NPC(victim)) return; if (MOB_FLAGGED(victim, MOB_NOSLEEP)) return; @@ -650,7 +650,7 @@ void mag_areas(int level, struct char_data *ch, int spellnum, int savetype) continue; if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT) continue; - if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(tch)) + if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(ch) && !IS_NPC(tch)) continue; if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM)) continue; diff --git a/src/oasis.h b/src/oasis.h index 8268a89..c69d4bd 100644 --- a/src/oasis.h +++ b/src/oasis.h @@ -380,6 +380,8 @@ extern const char *nrm, *grn, *cyn, *yel; #define CEDIT_MAP_SIZE 55 #define CEDIT_MINIMAP_SIZE 56 #define CEDIT_DEBUG_MODE 57 +#define CEDIT_PK_SETTING 58 +#define CEDIT_PT_SETTING 59 /* Hedit Submodes of connectedness. */ #define HEDIT_CONFIRM_SAVESTRING 0 diff --git a/src/spells.c b/src/spells.c index d9785b7..20f8452 100644 --- a/src/spells.c +++ b/src/spells.c @@ -120,7 +120,7 @@ ASPELL(spell_summon) return; } - if (!CONFIG_PK_ALLOWED) { + if (CONFIG_PK_SETTING == CONFIG_PK_OFF) { if (MOB_FLAGGED(victim, MOB_AGGRESSIVE)) { act("As the words escape your lips and $N travels\r\n" "through time and space towards you, you realize that $E is\r\n" @@ -265,7 +265,7 @@ ASPELL(spell_charm) else if (AFF_FLAGGED(victim, AFF_CHARM) || level < GET_LEVEL(victim)) send_to_char(ch, "You fail.\r\n"); /* player charming another player - no legal reason for this */ - else if (!CONFIG_PK_ALLOWED && !IS_NPC(victim)) + else if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(victim)) send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n"); else if (circle_follow(victim, ch)) send_to_char(ch, "Sorry, following in circles is not allowed.\r\n"); diff --git a/src/structs.h b/src/structs.h index 8dd7089..736236d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1291,8 +1291,8 @@ struct recent_player * variables. */ struct game_data { - int pk_allowed; /**< Is player killing allowed? */ - int pt_allowed; /**< Is player thieving allowed? */ + int pk_setting; /**< Is player killing allowed? */ + int pt_setting; /**< Is player thieving allowed? */ int level_can_shout; /**< Level player must be to shout. */ int holler_move_cost; /**< Cost to holler in move points. */ int tunnel_size; /**< Number of people allowed in a tunnel.*/ diff --git a/src/utils.h b/src/utils.h index d02cd2b..34bd9ef 100644 --- a/src/utils.h +++ b/src/utils.h @@ -939,9 +939,15 @@ do \ #define CONFIG_CONFFILE config_info.CONFFILE /** Player killing allowed or not? */ -#define CONFIG_PK_ALLOWED config_info.play.pk_allowed +#define CONFIG_PK_SETTING config_info.play.pk_setting +#define CONFIG_PK_OFF 0 /* Players are prevented from damaging or fighting other players in code */ +#define CONFIG_PK_LIMITED 1 /* Players may damage and fight but will be flagged PLR_KILLER */ +#define CONFIG_PK_FREEFORALL 2 /* No restrictions or flags for player damaging or killing */ /** Player thieving allowed or not? */ -#define CONFIG_PT_ALLOWED config_info.play.pt_allowed +#define CONFIG_PT_SETTING config_info.play.pt_setting +#define CONFIG_PT_OFF 0 /* Players are prevented from stealing from other players in code */ +#define CONFIG_PT_LIMITED 1 /* Players may steal from other players but will be flagged PLR_THIEF if caught */ +#define CONFIG_PT_FREEFORALL 2 /* No restrictions or flags for player stealing */ /** What level to use the shout command? */ #define CONFIG_LEVEL_CAN_SHOUT config_info.play.level_can_shout /** How many move points does holler cost? */