Cap skill levels, fix imm combat, remove plr_killer and plr_thief flags

This commit is contained in:
kinther 2025-12-28 15:11:37 -08:00
parent 8eb30084b0
commit 1efb08dafd
22 changed files with 366 additions and 351 deletions

View file

@ -46,16 +46,31 @@ Features in Miranthas MUD Alpha release:
Features to be implemented in the next few releases:
* Race/species selection
* Subclass selection
* Race/species selection and stat ranges (elves have higher dex, dwarves have higher str, etc)
* Subclass selection to personalize character further
* Prioritized stats during character generation
* Combat is slowed down so it isn't over in < 15 seconds (unless you're far outmatched)
* Mounts added to help with long trips
* Wagons added to help with caravans
* Plantlife introduced
* Updated lockpicking skill
* Trap as a skill - one focused on city and one focused on desert
* Poisons and antidotes
* New alcohol and drugs/stimulants
* Skimmers/ships to traverse difficult terrain
* New elemental classes
* Introduction of gathering mana/magic for sorceror class
* Highly modified magic system
* Components for some magical spells
* Reading/writing limited to specific castes of society
* Haggling and bartering system
* New calendar and moon cycles
* Heat based on time of day increases/decreases, changing hunger/thirst levels
* Sandstorms
* Shaded rooms
* Sandstorms limiting visibility
* Shaded rooms providing bonuses to regeneration
* Criminal system for cities and jails
* Basic Psionics
* Basic crafting system
* Continued skill and spell improvements
* Apartment rentals for storing your loot
* Enhanced quest system
* Dialogue trees with NPC's

View file

@ -1 +1,7 @@
#1
Test~
0 q 1
~
* No Script
~
$~

View file

@ -1,4 +1,5 @@
0.trg
1.trg
2.trg
$

View file

@ -1589,8 +1589,6 @@ ACMD(do_who)
continue;
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) && !PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (questwho && !PRF_FLAGGED(tch, PRF_QUEST))
continue;
if (localwho && world[IN_ROOM(ch)].zone != world[IN_ROOM(tch)].zone)
@ -1635,8 +1633,6 @@ ACMD(do_who)
continue;
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) && !PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (questwho && !PRF_FLAGGED(tch, PRF_QUEST))
continue;
if (localwho && world[IN_ROOM(ch)].zone != world[IN_ROOM(tch)].zone)
@ -1709,10 +1705,6 @@ ACMD(do_who)
send_to_char(ch, " (noshout)");
if (PRF_FLAGGED(tch, PRF_QUEST))
send_to_char(ch, " (quest)");
if (PLR_FLAGGED(tch, PLR_THIEF))
send_to_char(ch, " (THIEF)");
if (PLR_FLAGGED(tch, PLR_KILLER))
send_to_char(ch, " (KILLER)");
send_to_char(ch, "\r\n");
}
}
@ -1820,9 +1812,6 @@ ACMD(do_users)
continue;
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) &&
!PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
continue;
if (GET_INVIS_LEV(tch) > GET_LEVEL(ch))

View file

@ -54,8 +54,6 @@ 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))
send_to_char(ch, "You cannot kill other players.\r\n");
else {
send_to_char(ch, "You join the fight!\r\n");
act("$N assists you!", 0, helpee, 0, ch, TO_CHAR);
@ -82,9 +80,6 @@ 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 ((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 */
hit(ch, vict, TYPE_UNDEFINED); /* first */
@ -150,7 +145,7 @@ ACMD(do_backstab)
return;
}
/* Only piercing weapons allowed */
if (GET_OBJ_VAL(weap, 3) != TYPE_PIERCE - TYPE_HIT) {
if (GET_OBJ_VAL(weap, 2) != TYPE_PIERCE - TYPE_HIT) {
send_to_char(ch, "Only piercing weapons can be used for backstabbing.\r\n");
return;
}
@ -187,14 +182,14 @@ ACMD(do_backstab)
/* Keeping this logic really simple so it can be adjusted later if need be */
if (crit_success) {
/* Simple crit = 2x damage */
int base = dice(GET_OBJ_VAL(weap, 1), GET_OBJ_VAL(weap, 2));
int base = dice(GET_OBJ_VAL(weap, 0), GET_OBJ_VAL(weap, 1));
int dmg = base + GET_ABILITY_MOD(GET_DEX(ch));
if (dmg < 1) dmg = 1;
dmg *= 2;
damage(ch, vict, dmg, SKILL_BACKSTAB);
} else {
/* Hit but not crit = 1.5x damage */
int base = dice(GET_OBJ_VAL(weap, 1), GET_OBJ_VAL(weap, 2));
int base = dice(GET_OBJ_VAL(weap, 0), GET_OBJ_VAL(weap, 1));
int dmg = base + GET_ABILITY_MOD(GET_DEX(ch));
if (dmg < 1) dmg = 1;
dmg *= 1.5;

View file

@ -3302,16 +3302,8 @@ ACMD(do_wizutil)
GET_DEX(vict), GET_CON(vict), GET_CHA(vict));
break;
case SCMD_PARDON:
if (!PLR_FLAGGED(vict, PLR_THIEF) && !PLR_FLAGGED(vict, PLR_KILLER)) {
send_to_char(ch, "Your victim is not flagged.\r\n");
return;
}
REMOVE_BIT_AR(PLR_FLAGS(vict), PLR_THIEF);
REMOVE_BIT_AR(PLR_FLAGS(vict), PLR_KILLER);
send_to_char(ch, "Pardoned.\r\n");
send_to_char(vict, "You have been pardoned by the Gods!\r\n");
mudlog(BRF, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s pardoned by %s", GET_NAME(vict), GET_NAME(ch));
break;
send_to_char(ch, "Criminal flags are currently disabled.\r\n");
return;
case SCMD_MUTE:
result = PLR_TOG_CHK(vict, PLR_NOSHOUT);
mudlog(BRF, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) Mute %s for %s by %s.",
@ -3783,7 +3775,7 @@ static struct set_struct {
{ "int", LVL_BUILDER, BOTH, NUMBER },
{ "invis", LVL_GOD, PC, NUMBER },
{ "invstart", LVL_BUILDER, PC, BINARY },
{ "killer", LVL_GOD, PC, BINARY },
{ "unused0", LVL_GOD, PC, BINARY },
{ "level", LVL_GRGOD, BOTH, NUMBER }, /* 25 */
{ "loadroom", LVL_BUILDER, PC, MISC },
{ "mana", LVL_BUILDER, BOTH, NUMBER },
@ -3808,7 +3800,7 @@ static struct set_struct {
{ "siteok", LVL_GOD, PC, BINARY },
{ "skill", LVL_GOD, BOTH, NUMBER },
{ "str", LVL_BUILDER, BOTH, NUMBER },
{ "thief", LVL_GOD, PC, BINARY },
{ "unused1", LVL_GOD, PC, BINARY },
{ "thirst", LVL_BUILDER, BOTH, MISC }, /* 50 */
{ "variable", LVL_GRGOD, PC, MISC },
{ "weight", LVL_BUILDER, BOTH, NUMBER },
@ -4024,9 +4016,9 @@ static int perform_set(struct char_data *ch, struct char_data *vict, int mode, c
case 21: /* invistart */
SET_OR_REMOVE(PLR_FLAGS(vict), PLR_INVSTART);
break;
case 22: /* killer */
SET_OR_REMOVE(PLR_FLAGS(vict), PLR_KILLER);
break;
case 22: /* unused0 (removed killer flag) */
send_to_char(ch, "That flag is no longer in use.\r\n");
return (0);
case 23: /* level */
if ((!IS_NPC(vict) && value > GET_LEVEL(ch)) || value > LVL_IMPL) {
send_to_char(ch, "You can't do that.\r\n");
@ -4273,9 +4265,9 @@ static int perform_set(struct char_data *ch, struct char_data *vict, int mode, c
vict->real_abils.str = value;
affect_total(vict);
break;
case 47: /* thief */
SET_OR_REMOVE(PLR_FLAGS(vict), PLR_THIEF);
break;
case 47: /* unused1 (removed thief flag) */
send_to_char(ch, "That flag is no longer in use.\r\n");
return (0);
case 48: /* thirst */
if (!str_cmp(val_arg, "off")) {
GET_COND(vict, THIRST) = -1;

View file

@ -79,7 +79,6 @@ 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.level_can_shout = CONFIG_LEVEL_CAN_SHOUT;
OLC_CONFIG(d)->play.tunnel_size = CONFIG_TUNNEL_SIZE;
@ -177,7 +176,6 @@ 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_LEVEL_CAN_SHOUT = OLC_CONFIG(d)->play.level_can_shout;
CONFIG_TUNNEL_SIZE = OLC_CONFIG(d)->play.tunnel_size;
@ -326,8 +324,6 @@ int save_config( IDXTYPE nowhere )
"* [ Game Play Options ]\n"
);
fprintf(fl, "* Is player killing allowed on the mud?\n"
"pk_allowed = %d\n\n", CONFIG_PK_ALLOWED);
fprintf(fl, "* Is player thieving allowed on the mud?\n"
"pt_allowed = %d\n\n", CONFIG_PT_ALLOWED);
fprintf(fl, "* What is the minimum level a player can shout/gossip/etc?\n"
@ -591,7 +587,6 @@ static void cedit_disp_game_play_options(struct descriptor_data *d)
write_to_output(d, "\r\n\r\n"
"%sA%s) Player Killing Allowed : %s%s\r\n"
"%sB%s) Player Thieving Allowed : %s%s\r\n"
"%sC%s) Minimum Level To Shout : %s%d\r\n"
"%sE%s) Tunnel Size : %s%d\r\n"
@ -617,7 +612,6 @@ 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, OLC_CONFIG(d)->play.level_can_shout,
grn, nrm, cyn, OLC_CONFIG(d)->play.tunnel_size,
@ -844,11 +838,6 @@ void cedit_parse(struct descriptor_data *d, char *arg)
case CEDIT_GAME_OPTIONS_MENU:
switch (*arg) {
case 'a':
case 'A':
TOGGLE_VAR(OLC_CONFIG(d)->play.pk_allowed);
break;
case 'b':
case 'B':
TOGGLE_VAR(OLC_CONFIG(d)->play.pt_allowed);

View file

@ -234,6 +234,231 @@ void roll_real_abils(struct char_data *ch)
ch->aff_abils = ch->real_abils;
}
/* Per-class skill caps */
#define DEFAULT_CLASS_SKILL_MAX 90
static int class_skill_maxes[NUM_CLASSES][MAX_SKILLS + 1];
static bool class_skill_caps_ready = FALSE;
static int clamp_skill_max(int max)
{
if (max < 0)
return 0;
if (max > 100)
return 100;
return max;
}
static void apply_class_skill(int chclass, struct char_data *ch, int skill, int start, int max)
{
if (ch)
SET_SKILL(ch, skill, start);
if (chclass >= 0 && chclass < NUM_CLASSES && skill >= 0 && skill <= MAX_SKILLS)
class_skill_maxes[chclass][skill] = clamp_skill_max(max);
}
static void apply_class_skills(int chclass, struct char_data *ch)
{
switch (chclass) {
case CLASS_SORCEROR:
apply_class_skill(chclass, ch, SPELL_MAGIC_MISSILE, 5, 90);
apply_class_skill(chclass, ch, SPELL_DETECT_INVIS, 5, 90);
apply_class_skill(chclass, ch, SPELL_DETECT_MAGIC, 5, 90);
apply_class_skill(chclass, ch, SPELL_CHILL_TOUCH, 5, 90);
apply_class_skill(chclass, ch, SPELL_INFRAVISION, 5, 90);
apply_class_skill(chclass, ch, SPELL_INVISIBLE, 5, 90);
apply_class_skill(chclass, ch, SPELL_ARMOR, 5, 90);
apply_class_skill(chclass, ch, SPELL_BURNING_HANDS, 5, 90);
apply_class_skill(chclass, ch, SPELL_LOCATE_OBJECT, 5, 90);
apply_class_skill(chclass, ch, SPELL_STRENGTH, 5, 90);
apply_class_skill(chclass, ch, SPELL_SHOCKING_GRASP, 5, 90);
apply_class_skill(chclass, ch, SPELL_SLEEP, 5, 90);
apply_class_skill(chclass, ch, SPELL_LIGHTNING_BOLT, 5, 90);
apply_class_skill(chclass, ch, SPELL_BLINDNESS, 5, 90);
apply_class_skill(chclass, ch, SPELL_DETECT_POISON, 5, 90);
apply_class_skill(chclass, ch, SPELL_COLOR_SPRAY, 5, 90);
apply_class_skill(chclass, ch, SPELL_ENERGY_DRAIN, 5, 90);
apply_class_skill(chclass, ch, SPELL_CURSE, 5, 90);
apply_class_skill(chclass, ch, SPELL_POISON, 5, 90);
apply_class_skill(chclass, ch, SPELL_FIREBALL, 5, 90);
apply_class_skill(chclass, ch, SPELL_CHARM, 5, 90);
apply_class_skill(chclass, ch, SPELL_IDENTIFY, 5, 90);
apply_class_skill(chclass, ch, SPELL_FLY, 5, 90);
apply_class_skill(chclass, ch, SPELL_ENCHANT_WEAPON, 5, 90);
apply_class_skill(chclass, ch, SPELL_CLONE, 5, 90);
apply_class_skill(chclass, ch, SKILL_UNARMED, 5, 90);
apply_class_skill(chclass, ch, SKILL_ARCANA, 5, 90);
apply_class_skill(chclass, ch, SKILL_HISTORY, 5, 90);
apply_class_skill(chclass, ch, SKILL_INSIGHT, 5, 90);
break;
case CLASS_CLERIC:
apply_class_skill(chclass, ch, SPELL_CURE_LIGHT, 5, 90);
apply_class_skill(chclass, ch, SPELL_ARMOR, 5, 90);
apply_class_skill(chclass, ch, SPELL_CREATE_FOOD, 5, 90);
apply_class_skill(chclass, ch, SPELL_CREATE_WATER, 5, 90);
apply_class_skill(chclass, ch, SPELL_DETECT_POISON, 5, 90);
apply_class_skill(chclass, ch, SPELL_DETECT_ALIGN, 5, 90);
apply_class_skill(chclass, ch, SPELL_CURE_BLIND, 5, 90);
apply_class_skill(chclass, ch, SPELL_BLESS, 5, 90);
apply_class_skill(chclass, ch, SPELL_DETECT_INVIS, 5, 90);
apply_class_skill(chclass, ch, SPELL_BLINDNESS, 5, 90);
apply_class_skill(chclass, ch, SPELL_INFRAVISION, 5, 90);
apply_class_skill(chclass, ch, SPELL_PROT_FROM_EVIL, 5, 90);
apply_class_skill(chclass, ch, SPELL_POISON, 5, 90);
apply_class_skill(chclass, ch, SPELL_GROUP_ARMOR, 5, 90);
apply_class_skill(chclass, ch, SPELL_CURE_CRITIC, 5, 90);
apply_class_skill(chclass, ch, SPELL_SUMMON, 5, 90);
apply_class_skill(chclass, ch, SPELL_REMOVE_POISON, 5, 90);
apply_class_skill(chclass, ch, SPELL_IDENTIFY, 5, 90);
apply_class_skill(chclass, ch, SPELL_WORD_OF_RECALL, 5, 90);
apply_class_skill(chclass, ch, SPELL_DARKNESS, 5, 90);
apply_class_skill(chclass, ch, SPELL_EARTHQUAKE, 5, 90);
apply_class_skill(chclass, ch, SPELL_DISPEL_EVIL, 5, 90);
apply_class_skill(chclass, ch, SPELL_DISPEL_GOOD, 5, 90);
apply_class_skill(chclass, ch, SPELL_SANCTUARY, 5, 90);
apply_class_skill(chclass, ch, SPELL_CALL_LIGHTNING, 5, 90);
apply_class_skill(chclass, ch, SPELL_HEAL, 5, 90);
apply_class_skill(chclass, ch, SPELL_CONTROL_WEATHER, 5, 90);
apply_class_skill(chclass, ch, SPELL_SENSE_LIFE, 5, 90);
apply_class_skill(chclass, ch, SPELL_HARM, 5, 90);
apply_class_skill(chclass, ch, SPELL_GROUP_HEAL, 5, 90);
apply_class_skill(chclass, ch, SPELL_REMOVE_CURSE, 5, 90);
apply_class_skill(chclass, ch, SKILL_SHIELD_USE, 5, 90);
apply_class_skill(chclass, ch, SKILL_ACROBATICS, 5, 90);
apply_class_skill(chclass, ch, SKILL_ARCANA, 5, 90);
apply_class_skill(chclass, ch, SKILL_RELIGION, 5, 90);
break;
case CLASS_ROGUE:
apply_class_skill(chclass, ch, SKILL_STEALTH, 5, 90);
apply_class_skill(chclass, ch, SKILL_TRACK, 5, 90);
apply_class_skill(chclass, ch, SKILL_BACKSTAB, 5, 90);
apply_class_skill(chclass, ch, SKILL_PICK_LOCK, 5, 90);
apply_class_skill(chclass, ch, SKILL_SLEIGHT_OF_HAND, 5, 90);
apply_class_skill(chclass, ch, SKILL_UNARMED, 5, 90);
apply_class_skill(chclass, ch, SKILL_SHIELD_USE, 5, 90);
apply_class_skill(chclass, ch, SKILL_PIERCING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERCEPTION, 5, 90);
apply_class_skill(chclass, ch, SKILL_ACROBATICS, 5, 90);
apply_class_skill(chclass, ch, SKILL_DECEPTION, 5, 90);
apply_class_skill(chclass, ch, SKILL_INVESTIGATION, 5, 90);
break;
case CLASS_FIGHTER:
apply_class_skill(chclass, ch, SKILL_KICK, 5, 90);
apply_class_skill(chclass, ch, SKILL_RESCUE, 5, 90);
apply_class_skill(chclass, ch, SKILL_BANDAGE, 5, 90);
apply_class_skill(chclass, ch, SKILL_BASH, 5, 90);
apply_class_skill(chclass, ch, SKILL_UNARMED, 5, 90);
apply_class_skill(chclass, ch, SKILL_SLASHING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_PIERCING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_BLUDGEONING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_SHIELD_USE, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERCEPTION, 5, 90);
apply_class_skill(chclass, ch, SKILL_ATHLETICS, 5, 90);
apply_class_skill(chclass, ch, SKILL_INTIMIDATION, 5, 90);
apply_class_skill(chclass, ch, SKILL_SURVIVAL, 5, 90);
break;
case CLASS_BARBARIAN:
apply_class_skill(chclass, ch, SKILL_KICK, 5, 90);
apply_class_skill(chclass, ch, SKILL_RESCUE, 5, 90);
apply_class_skill(chclass, ch, SKILL_BANDAGE, 5, 90);
apply_class_skill(chclass, ch, SKILL_WHIRLWIND, 5, 90);
apply_class_skill(chclass, ch, SKILL_UNARMED, 5, 90);
apply_class_skill(chclass, ch, SKILL_PIERCING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_BLUDGEONING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERCEPTION, 5, 90);
apply_class_skill(chclass, ch, SKILL_ATHLETICS, 5, 90);
apply_class_skill(chclass, ch, SKILL_INTIMIDATION, 5, 90);
break;
case CLASS_RANGER:
apply_class_skill(chclass, ch, SKILL_BANDAGE, 5, 90);
apply_class_skill(chclass, ch, SKILL_TRACK, 5, 90);
apply_class_skill(chclass, ch, SKILL_BASH, 5, 90);
apply_class_skill(chclass, ch, SKILL_SLEIGHT_OF_HAND, 5, 90);
apply_class_skill(chclass, ch, SKILL_UNARMED, 5, 90);
apply_class_skill(chclass, ch, SKILL_SLASHING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_PIERCING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_SHIELD_USE, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERCEPTION, 5, 90);
apply_class_skill(chclass, ch, SKILL_NATURE, 5, 90);
apply_class_skill(chclass, ch, SKILL_ANIMAL_HANDLING, 5, 90);
apply_class_skill(chclass, ch, SKILL_SURVIVAL, 5, 90);
apply_class_skill(chclass, ch, SKILL_ATHLETICS, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERSUASION, 5, 90);
apply_class_skill(chclass, ch, SKILL_STEALTH, 5, 90);
break;
case CLASS_BARD:
apply_class_skill(chclass, ch, SPELL_ARMOR, 5, 90);
apply_class_skill(chclass, ch, SPELL_IDENTIFY, 5, 90);
apply_class_skill(chclass, ch, SKILL_BANDAGE, 5, 90);
apply_class_skill(chclass, ch, SKILL_TRACK, 5, 90);
apply_class_skill(chclass, ch, SKILL_PICK_LOCK, 5, 90);
apply_class_skill(chclass, ch, SKILL_SLEIGHT_OF_HAND, 5, 90);
apply_class_skill(chclass, ch, SKILL_UNARMED, 5, 90);
apply_class_skill(chclass, ch, SKILL_PIERCING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_SHIELD_USE, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERCEPTION, 5, 90);
apply_class_skill(chclass, ch, SKILL_ACROBATICS, 5, 90);
apply_class_skill(chclass, ch, SKILL_HISTORY, 5, 90);
apply_class_skill(chclass, ch, SKILL_INVESTIGATION, 5, 90);
apply_class_skill(chclass, ch, SKILL_SURVIVAL, 5, 90);
apply_class_skill(chclass, ch, SKILL_STEALTH, 5, 90);
break;
case CLASS_DRUID:
apply_class_skill(chclass, ch, SPELL_DETECT_INVIS, 5, 90);
apply_class_skill(chclass, ch, SPELL_DETECT_MAGIC, 5, 90);
apply_class_skill(chclass, ch, SPELL_LOCATE_OBJECT, 5, 90);
apply_class_skill(chclass, ch, SKILL_BANDAGE, 5, 90);
apply_class_skill(chclass, ch, SKILL_TRACK, 5, 90);
apply_class_skill(chclass, ch, SKILL_UNARMED, 5, 90);
apply_class_skill(chclass, ch, SKILL_PIERCING_WEAPONS, 5, 90);
apply_class_skill(chclass, ch, SKILL_SHIELD_USE, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERCEPTION, 5, 90);
apply_class_skill(chclass, ch, SKILL_ACROBATICS, 5, 90);
apply_class_skill(chclass, ch, SKILL_ARCANA, 5, 90);
apply_class_skill(chclass, ch, SKILL_HISTORY, 5, 90);
apply_class_skill(chclass, ch, SKILL_INSIGHT, 5, 90);
apply_class_skill(chclass, ch, SKILL_INVESTIGATION, 5, 90);
apply_class_skill(chclass, ch, SKILL_PERSUASION, 5, 90);
apply_class_skill(chclass, ch, SKILL_RELIGION, 5, 90);
apply_class_skill(chclass, ch, SKILL_SURVIVAL, 5, 90);
break;
}
}
void init_class_skill_caps(void)
{
int chclass, skill;
for (chclass = 0; chclass < NUM_CLASSES; chclass++) {
for (skill = 0; skill <= MAX_SKILLS; skill++)
class_skill_maxes[chclass][skill] = DEFAULT_CLASS_SKILL_MAX;
}
for (chclass = 0; chclass < NUM_CLASSES; chclass++)
apply_class_skills(chclass, NULL);
class_skill_caps_ready = TRUE;
}
int class_skill_max(int chclass, int skillnum)
{
if (!class_skill_caps_ready)
return DEFAULT_CLASS_SKILL_MAX;
if (chclass < 0 || chclass >= NUM_CLASSES)
return DEFAULT_CLASS_SKILL_MAX;
if (skillnum < 0 || skillnum > MAX_SKILLS)
return DEFAULT_CLASS_SKILL_MAX;
return class_skill_maxes[chclass][skillnum];
}
void grant_class_skills(struct char_data *ch, bool reset)
{
int i;
@ -248,179 +473,7 @@ void grant_class_skills(struct char_data *ch, bool reset)
if (GET_CLASS(ch) < CLASS_SORCEROR || GET_CLASS(ch) >= NUM_CLASSES)
return;
switch (GET_CLASS(ch)) {
case CLASS_SORCEROR:
SET_SKILL(ch, SPELL_MAGIC_MISSILE, 5);
SET_SKILL(ch, SPELL_DETECT_INVIS, 5);
SET_SKILL(ch, SPELL_DETECT_MAGIC, 5);
SET_SKILL(ch, SPELL_CHILL_TOUCH, 5);
SET_SKILL(ch, SPELL_INFRAVISION, 5);
SET_SKILL(ch, SPELL_INVISIBLE, 5);
SET_SKILL(ch, SPELL_ARMOR, 5);
SET_SKILL(ch, SPELL_BURNING_HANDS, 5);
SET_SKILL(ch, SPELL_LOCATE_OBJECT, 5);
SET_SKILL(ch, SPELL_STRENGTH, 5);
SET_SKILL(ch, SPELL_SHOCKING_GRASP, 5);
SET_SKILL(ch, SPELL_SLEEP, 5);
SET_SKILL(ch, SPELL_LIGHTNING_BOLT, 5);
SET_SKILL(ch, SPELL_BLINDNESS, 5);
SET_SKILL(ch, SPELL_DETECT_POISON, 5);
SET_SKILL(ch, SPELL_COLOR_SPRAY, 5);
SET_SKILL(ch, SPELL_ENERGY_DRAIN, 5);
SET_SKILL(ch, SPELL_CURSE, 5);
SET_SKILL(ch, SPELL_POISON, 5);
SET_SKILL(ch, SPELL_FIREBALL, 5);
SET_SKILL(ch, SPELL_CHARM, 5);
SET_SKILL(ch, SPELL_IDENTIFY, 5);
SET_SKILL(ch, SPELL_FLY, 5);
SET_SKILL(ch, SPELL_ENCHANT_WEAPON, 5);
SET_SKILL(ch, SPELL_CLONE, 5);
SET_SKILL(ch, SKILL_UNARMED, 5);
SET_SKILL(ch, SKILL_ARCANA, 5);
SET_SKILL(ch, SKILL_HISTORY, 5);
SET_SKILL(ch, SKILL_INSIGHT, 5);
break;
case CLASS_CLERIC:
SET_SKILL(ch, SPELL_CURE_LIGHT, 5);
SET_SKILL(ch, SPELL_ARMOR, 5);
SET_SKILL(ch, SPELL_CREATE_FOOD, 5);
SET_SKILL(ch, SPELL_CREATE_WATER, 5);
SET_SKILL(ch, SPELL_DETECT_POISON, 5);
SET_SKILL(ch, SPELL_DETECT_ALIGN, 5);
SET_SKILL(ch, SPELL_CURE_BLIND, 5);
SET_SKILL(ch, SPELL_BLESS, 5);
SET_SKILL(ch, SPELL_DETECT_INVIS, 5);
SET_SKILL(ch, SPELL_BLINDNESS, 5);
SET_SKILL(ch, SPELL_INFRAVISION, 5);
SET_SKILL(ch, SPELL_PROT_FROM_EVIL, 5);
SET_SKILL(ch, SPELL_POISON, 5);
SET_SKILL(ch, SPELL_GROUP_ARMOR, 5);
SET_SKILL(ch, SPELL_CURE_CRITIC, 5);
SET_SKILL(ch, SPELL_SUMMON, 5);
SET_SKILL(ch, SPELL_REMOVE_POISON, 5);
SET_SKILL(ch, SPELL_IDENTIFY, 5);
SET_SKILL(ch, SPELL_WORD_OF_RECALL, 5);
SET_SKILL(ch, SPELL_DARKNESS, 5);
SET_SKILL(ch, SPELL_EARTHQUAKE, 5);
SET_SKILL(ch, SPELL_DISPEL_EVIL, 5);
SET_SKILL(ch, SPELL_DISPEL_GOOD, 5);
SET_SKILL(ch, SPELL_SANCTUARY, 5);
SET_SKILL(ch, SPELL_CALL_LIGHTNING, 5);
SET_SKILL(ch, SPELL_HEAL, 5);
SET_SKILL(ch, SPELL_CONTROL_WEATHER, 5);
SET_SKILL(ch, SPELL_SENSE_LIFE, 5);
SET_SKILL(ch, SPELL_HARM, 5);
SET_SKILL(ch, SPELL_GROUP_HEAL, 5);
SET_SKILL(ch, SPELL_REMOVE_CURSE, 5);
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
SET_SKILL(ch, SKILL_ACROBATICS, 5);
SET_SKILL(ch, SKILL_ARCANA, 5);
SET_SKILL(ch, SKILL_RELIGION, 5);
break;
case CLASS_ROGUE:
SET_SKILL(ch, SKILL_STEALTH, 5);
SET_SKILL(ch, SKILL_TRACK, 5);
SET_SKILL(ch, SKILL_BACKSTAB, 5);
SET_SKILL(ch, SKILL_PICK_LOCK, 5);
SET_SKILL(ch, SKILL_SLEIGHT_OF_HAND, 5);
SET_SKILL(ch, SKILL_UNARMED, 5);
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
SET_SKILL(ch, SKILL_PERCEPTION, 5);
SET_SKILL(ch, SKILL_ACROBATICS, 5);
SET_SKILL(ch, SKILL_DECEPTION, 5);
SET_SKILL(ch, SKILL_INVESTIGATION, 5);
break;
case CLASS_FIGHTER:
SET_SKILL(ch, SKILL_KICK, 5);
SET_SKILL(ch, SKILL_RESCUE, 5);
SET_SKILL(ch, SKILL_BANDAGE, 5);
SET_SKILL(ch, SKILL_BASH, 5);
SET_SKILL(ch, SKILL_UNARMED, 5);
SET_SKILL(ch, SKILL_SLASHING_WEAPONS, 5);
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
SET_SKILL(ch, SKILL_BLUDGEONING_WEAPONS, 5);
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
SET_SKILL(ch, SKILL_PERCEPTION, 5);
SET_SKILL(ch, SKILL_ATHLETICS, 5);
SET_SKILL(ch, SKILL_INTIMIDATION, 5);
SET_SKILL(ch, SKILL_SURVIVAL, 5);
break;
case CLASS_BARBARIAN:
SET_SKILL(ch, SKILL_KICK, 5);
SET_SKILL(ch, SKILL_RESCUE, 5);
SET_SKILL(ch, SKILL_BANDAGE, 5);
SET_SKILL(ch, SKILL_WHIRLWIND, 5);
SET_SKILL(ch, SKILL_UNARMED, 5);
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
SET_SKILL(ch, SKILL_BLUDGEONING_WEAPONS, 5);
SET_SKILL(ch, SKILL_PERCEPTION, 5);
SET_SKILL(ch, SKILL_ATHLETICS, 5);
SET_SKILL(ch, SKILL_INTIMIDATION, 5);
break;
case CLASS_RANGER:
SET_SKILL(ch, SKILL_BANDAGE, 5);
SET_SKILL(ch, SKILL_TRACK, 5);
SET_SKILL(ch, SKILL_BASH, 5);
SET_SKILL(ch, SKILL_SLEIGHT_OF_HAND, 5);
SET_SKILL(ch, SKILL_UNARMED, 5);
SET_SKILL(ch, SKILL_SLASHING_WEAPONS, 5);
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
SET_SKILL(ch, SKILL_PERCEPTION, 5);
SET_SKILL(ch, SKILL_NATURE, 5);
SET_SKILL(ch, SKILL_ANIMAL_HANDLING, 5);
SET_SKILL(ch, SKILL_SURVIVAL, 5);
SET_SKILL(ch, SKILL_ATHLETICS, 5);
SET_SKILL(ch, SKILL_PERSUASION, 5);
SET_SKILL(ch, SKILL_STEALTH, 5);
break;
case CLASS_BARD:
SET_SKILL(ch, SPELL_ARMOR, 5);
SET_SKILL(ch, SPELL_IDENTIFY, 5);
SET_SKILL(ch, SKILL_BANDAGE, 5);
SET_SKILL(ch, SKILL_TRACK, 5);
SET_SKILL(ch, SKILL_PICK_LOCK, 5);
SET_SKILL(ch, SKILL_SLEIGHT_OF_HAND, 5);
SET_SKILL(ch, SKILL_UNARMED, 5);
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
SET_SKILL(ch, SKILL_PERCEPTION, 5);
SET_SKILL(ch, SKILL_ACROBATICS, 5);
SET_SKILL(ch, SKILL_HISTORY, 5);
SET_SKILL(ch, SKILL_INVESTIGATION, 5);
SET_SKILL(ch, SKILL_SURVIVAL, 5);
SET_SKILL(ch, SKILL_STEALTH, 5);
break;
case CLASS_DRUID:
SET_SKILL(ch, SPELL_DETECT_INVIS, 5);
SET_SKILL(ch, SPELL_DETECT_MAGIC, 5);
SET_SKILL(ch, SPELL_LOCATE_OBJECT, 5);
SET_SKILL(ch, SKILL_BANDAGE, 5);
SET_SKILL(ch, SKILL_TRACK, 5);
SET_SKILL(ch, SKILL_UNARMED, 5);
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
SET_SKILL(ch, SKILL_PERCEPTION, 5);
SET_SKILL(ch, SKILL_ACROBATICS, 5);
SET_SKILL(ch, SKILL_ARCANA, 5);
SET_SKILL(ch, SKILL_HISTORY, 5);
SET_SKILL(ch, SKILL_INSIGHT, 5);
SET_SKILL(ch, SKILL_INVESTIGATION, 5);
SET_SKILL(ch, SKILL_PERSUASION, 5);
SET_SKILL(ch, SKILL_RELIGION, 5);
SET_SKILL(ch, SKILL_SURVIVAL, 5);
break;
}
apply_class_skills(GET_CLASS(ch), ch);
}
/* Some initializations for characters, including initial skills */

View file

@ -23,6 +23,8 @@ int parse_class(char arg);
void roll_real_abils(struct char_data *ch);
bool has_save_proficiency(int class_num, int ability);
void grant_class_skills(struct char_data *ch, bool reset);
void init_class_skill_caps(void);
int class_skill_max(int chclass, int skillnum);
/* Global variables */

View file

@ -39,13 +39,6 @@
/* 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;
/* Is playerthieving allowed? */
int pt_allowed = NO;

View file

@ -14,7 +14,6 @@
#define _CONFIG_H_
/* Global variable declarations, all settable by cedit */
extern int pk_allowed;
extern int script_players;
extern int pt_allowed;
extern int level_can_shout;

View file

@ -189,8 +189,8 @@ const char *position_types[] = {
* @pre Must be in the same order as the defines.
* Must end array with a single newline. */
const char *player_bits[] = {
"KILLER",
"THIEF",
"UNUSED0",
"UNUSED1",
"FROZEN",
"DONTSET",
"WRITING",

View file

@ -30,6 +30,7 @@
#include "genolc.h"
#include "genobj.h" /* for free_object_strings */
#include "config.h" /* for the default config values. */
#include "class.h"
#include "fight.h"
#include "modify.h"
#include "shop.h"
@ -748,6 +749,7 @@ void boot_db(void)
log("Assigning spell and skill levels.");
init_spell_levels();
init_class_skill_caps();
log("Sorting command list and spells.");
sort_commands();
@ -4128,7 +4130,6 @@ 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_LEVEL_CAN_SHOUT = level_can_shout;
CONFIG_TUNNEL_SIZE = tunnel_size;
@ -4388,9 +4389,7 @@ void load_config( void )
break;
case 'p':
if (!str_cmp(tag, "pk_allowed"))
CONFIG_PK_ALLOWED = num;
else if (!str_cmp(tag, "protocol_negotiation"))
if (!str_cmp(tag, "protocol_negotiation"))
CONFIG_PROTOCOL_NEGOTIATION = num;
else if (!str_cmp(tag, "pt_allowed"))
CONFIG_PT_ALLOWED = num;

View file

@ -801,30 +801,6 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
}
}
}
else if (!str_cmp(field, "is_killer")) {
if (subfield && *subfield) {
if (!str_cmp("on", subfield))
SET_BIT_AR(PLR_FLAGS(c), PLR_KILLER);
else if (!str_cmp("off", subfield))
REMOVE_BIT_AR(PLR_FLAGS(c), PLR_KILLER);
}
if (PLR_FLAGGED(c, PLR_KILLER))
strcpy(str, "1");
else
strcpy(str, "0");
}
else if (!str_cmp(field, "is_thief")) {
if (subfield && *subfield) {
if (!str_cmp("on", subfield))
SET_BIT_AR(PLR_FLAGS(c), PLR_THIEF);
else if (!str_cmp("off", subfield))
REMOVE_BIT_AR(PLR_FLAGS(c), PLR_THIEF);
}
if (PLR_FLAGGED(c, PLR_THIEF))
strcpy(str, "1");
else
strcpy(str, "0");
}
break;
case 'l':
if (!str_cmp(field, "level")) {

View file

@ -72,8 +72,8 @@ static int roll_damage(struct char_data *ch, struct char_data *victim,
int dam = 0;
if (wielded && GET_OBJ_TYPE(wielded) == ITEM_WEAPON) {
int ndice = GET_OBJ_VAL(wielded, 1); /* #dice */
int sdice = GET_OBJ_VAL(wielded, 2); /* sides */
int ndice = GET_OBJ_VAL(wielded, 0); /* #dice */
int sdice = GET_OBJ_VAL(wielded, 1); /* sides */
dam = dice(ndice, sdice);
dam += GET_ABILITY_MOD(GET_STR(ch)); /* STR adds to weapon damage */
} else {
@ -92,7 +92,7 @@ static int weapon_family_skill_num(struct char_data *ch, struct obj_data *wielde
if (!wielded || GET_OBJ_TYPE(wielded) != ITEM_WEAPON)
return SKILL_UNARMED;
/* NOTE: w_type here is TYPE_HIT + GET_OBJ_VAL(wielded, 3) or mob attack type + TYPE_HIT.
/* NOTE: w_type here is TYPE_HIT + GET_OBJ_VAL(wielded, 2) or mob attack type + TYPE_HIT.
Adjust the cases below to match your game's TYPE_* values. */
switch (w_type) {
/* --- Piercing family --- */
@ -176,20 +176,6 @@ void update_pos(struct char_data *victim)
GET_POS(victim) = POS_STUNNED;
}
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)
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");
mudlog(BRF, MAX(LVL_IMMORT, MAX(GET_INVIS_LEV(ch), GET_INVIS_LEV(vict))),
TRUE, "PC Killer bit set on %s for initiating attack on %s at %s.",
GET_NAME(ch), GET_NAME(vict), world[IN_ROOM(vict)].name);
}
/* start one char fighting another (yes, it is horrible, I know... ) */
void set_fighting(struct char_data *ch, struct char_data *vict)
{
@ -210,8 +196,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 */
@ -363,8 +347,6 @@ struct char_data *i;
void die(struct char_data * ch, struct char_data * killer)
{
if (!IS_NPC(ch)) {
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_KILLER);
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_THIEF);
}
raw_kill(ch, killer);
}
@ -634,6 +616,7 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
char local_buf[256];
struct char_data *tmp_char;
struct obj_data *corpse_obj;
int prev_hit = 0;
if (GET_POS(victim) <= POS_DEAD) {
/* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */
@ -659,8 +642,8 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
return (0);
}
/* You can't damage an immortal! */
if (!IS_NPC(victim) && ((GET_LEVEL(victim) >= LVL_IMMORT) && PRF_FLAGGED(victim, PRF_NOHASSLE)))
/* Immortals cannot be damaged. */
if (!IS_NPC(victim) && GET_REAL_LEVEL(victim) >= LVL_IMMORT)
dam = 0;
dam = damage_mtrigger(ch, victim, dam, attacktype);
@ -694,14 +677,9 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
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);
prev_hit = GET_HIT(victim);
GET_HIT(victim) -= dam;
update_pos(victim);
@ -826,16 +804,30 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
void hit(struct char_data *ch, struct char_data *victim, int type)
{
struct obj_data *wielded = GET_EQ(ch, WEAR_WIELD);
bool wielded_weapon = (wielded && GET_OBJ_TYPE(wielded) == ITEM_WEAPON);
struct obj_data *shield = GET_EQ(victim, WEAR_SHIELD);
int w_type, d20, attack_mod = 0, target_ac, dam = 0;
bool hit_success = FALSE;
bool attacker_immortal, victim_immortal;
bool attacker_is_player, victim_is_player;
int unarmed_die_size = 0;
int unarmed_prof_bonus = 0;
int unarmed_str_mod = 0;
/* Basic sanity */
if (!ch || !victim) return;
attacker_is_player = (ch->desc != NULL);
victim_is_player = (victim->desc != NULL);
attacker_immortal = (attacker_is_player &&
(GET_REAL_LEVEL(ch) >= LVL_IMMORT || PRF_FLAGGED(ch, PRF_NOHASSLE)));
victim_immortal = (victim_is_player &&
(GET_REAL_LEVEL(victim) >= LVL_IMMORT || PRF_FLAGGED(victim, PRF_NOHASSLE)));
/* Determine attack message type exactly like stock code */
if (wielded && GET_OBJ_TYPE(wielded) == ITEM_WEAPON)
w_type = GET_OBJ_VAL(wielded, 3) + TYPE_HIT;
if (wielded_weapon)
w_type = GET_OBJ_VAL(wielded, 2) + TYPE_HIT;
else {
if (IS_NPC(ch) && ch->mob_specials.attack_type != 0)
w_type = ch->mob_specials.attack_type + TYPE_HIT;
@ -843,6 +835,39 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
w_type = TYPE_HIT;
} /* matches stock message mapping */
if (victim_immortal) {
damage(ch, victim, 0, w_type);
return;
}
if (attacker_immortal) {
if (wielded_weapon) {
int ndice = GET_OBJ_VAL(wielded, 0);
int sdice = GET_OBJ_VAL(wielded, 1);
dam = (ndice * sdice) + GET_ABILITY_MOD(GET_STR(ch));
} else {
int prof_bonus = (!IS_NPC(ch)) ? GET_PROFICIENCY(GET_SKILL(ch, SKILL_UNARMED)) : 0;
int str_mod = GET_ABILITY_MOD(GET_STR(ch));
int die_size;
switch (prof_bonus) {
case 0: die_size = 4; break; /* untrained */
case 1: die_size = 6; break; /* trained */
case 2: die_size = 8; break; /* expert */
default: die_size = 10; break; /* master or above */
}
if (IS_NPC(ch) && prof_bonus <= 0) {
prof_bonus = MIN(6, (GET_LEVEL(ch) / 4));
}
dam = die_size + str_mod + prof_bonus;
}
damage(ch, victim, dam, w_type);
return;
}
/* Roll d20 */
d20 = rand_number(1, 20);
@ -859,7 +884,7 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
attack_mod += GET_PROFICIENCY(GET_SKILL(ch, skillnum));
/* --- UNARMED ATTACK HANDLING --- */
if (!wielded) {
if (!wielded_weapon) {
int prof_bonus = (!IS_NPC(ch)) ? GET_PROFICIENCY(GET_SKILL(ch, SKILL_UNARMED)) : 0;
int str_mod = GET_ABILITY_MOD(GET_STR(ch));
int die_size;
@ -871,6 +896,7 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
case 2: die_size = 8; break; /* expert */
default: die_size = 10; break; /* master or above */
}
unarmed_die_size = die_size;
/* NPC fallback scaling */
if (IS_NPC(ch) && prof_bonus <= 0) {
@ -879,9 +905,11 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
/* base damage roll for unarmed attacks */
dam = dice(1, die_size) + str_mod + prof_bonus;
unarmed_prof_bonus = prof_bonus;
unarmed_str_mod = str_mod;
/* mark attack type for damage() messaging */
w_type = SKILL_UNARMED + TYPE_HIT;
w_type = TYPE_HIT;
}
/* Weapon magic (cap +3) */
@ -901,8 +929,9 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
/* Ascending AC target */
target_ac = compute_armor_class_asc(victim);
/* Nat 1/20, then normal resolution */
if (d20 == 1) hit_success = FALSE;
/* Nat 1/20, then normal resolution (immortals always hit). */
if (attacker_immortal) hit_success = TRUE;
else if (d20 == 1) hit_success = FALSE;
else if (d20 == 20) hit_success = TRUE;
else hit_success = ((d20 + attack_mod) >= target_ac);
@ -912,13 +941,22 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
* If we are unarmed, dam was already rolled above.
* If wielding a weapon, roll normally.
*/
if (wielded)
if (wielded_weapon)
dam = roll_damage(ch, victim, wielded, w_type);
if (attacker_immortal) {
if (wielded_weapon) {
int ndice = GET_OBJ_VAL(wielded, 0);
int sdice = GET_OBJ_VAL(wielded, 1);
dam = (ndice * sdice) + GET_ABILITY_MOD(GET_STR(ch));
} else if (unarmed_die_size > 0) {
dam = unarmed_die_size + unarmed_str_mod + unarmed_prof_bonus;
}
}
/* --- SHIELD BLOCK CHECK ---
* Only happens if an attack actually lands.
*/
if (shield) {
if (shield && !attacker_immortal) {
int def_prof = (!IS_NPC(victim)) ? GET_PROFICIENCY(GET_SKILL(victim, SKILL_SHIELD_USE)) : 0;
int block_chance = def_prof * 10; /* 060% total chance to block an attack */

View file

@ -22,7 +22,6 @@ struct attack_hit_type {
/* Functions available in fight.c */
void appear(struct char_data *ch);
void check_killer(struct char_data *ch, struct char_data *vict);
int compute_armor_class(struct char_data *ch);
int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype);
void death_cry(struct char_data *ch);

View file

@ -209,12 +209,13 @@ void run_autowiz(void)
/* Requires: find_skill_num(), GET_WIS(), wis_app[], GET_SKILL(), SET_SKILL(), rand_number()
* Cooldown: 1 hour - 5 * WIS bonus minutes (floored at 0)
* Rolls: failure -> 1..20, success -> 1..100
* Cap: 90% (change MIN(90, ...) if you want a different cap)
* Cap: per-class max (see class.c)
*/
void gain_skill(struct char_data *ch, char *skill, bool success)
{
int skill_num, base, roll, increase;
int wisb, cd_seconds;
int cap;
time_t now;
if (IS_NPC(ch))
@ -233,8 +234,11 @@ void gain_skill(struct char_data *ch, char *skill, bool success)
}
base = GET_SKILL(ch, skill_num);
cap = class_skill_max(GET_CLASS(ch), skill_num);
if (cap <= 0)
return;
/* If already capped, bail early (and dont start cooldown) */
if (base >= 90)
if (base >= cap)
return;
/* Wisdom bonus from wis_app[] (constants.c). Higher = better learning & shorter cooldown. */
@ -246,7 +250,7 @@ void gain_skill(struct char_data *ch, char *skill, bool success)
/* Old 1..400 with (400 - wisb*4) ⇒ scaled: (100 - wisb) */
if (roll >= (100 - wisb)) {
increase = base + 1;
SET_SKILL(ch, skill_num, MIN(90, increase));
SET_SKILL(ch, skill_num, MIN(cap, increase));
/* Cooldown only when an increase actually happens */
cd_seconds = 3600 - (wisb * 5 * 60); /* 1 hour - 5 * WIS minutes */
@ -259,7 +263,7 @@ void gain_skill(struct char_data *ch, char *skill, bool success)
/* Old 1..100 with (100 - wisb) ⇒ scaled: (20 - wisb) */
if (roll >= (20 - wisb)) {
increase = base + 1;
SET_SKILL(ch, skill_num, MIN(90, increase));
SET_SKILL(ch, skill_num, MIN(cap, increase));
/* Cooldown only when an increase actually happens */
cd_seconds = 3600 - (wisb * 5 * 60); /* 1 hour - 5 * WIS minutes */

View file

@ -189,6 +189,7 @@ int mag_damage(int level, struct char_data *ch, struct char_data *victim,
int spellnum, int savetype)
{
int dam = 0;
int save_dc;
if (victim == NULL || ch == NULL)
return (0);
@ -279,8 +280,12 @@ int mag_damage(int level, struct char_data *ch, struct char_data *victim,
} /* switch(spellnum) */
save_dc = compute_save_dc(ch, level, spellnum);
if (!IS_NPC(ch) && GET_REAL_LEVEL(ch) >= LVL_IMMORT)
save_dc = 1000;
/* divide damage by two if victim makes his saving throw */
if (mag_savingthrow(victim, savetype, compute_save_dc(ch, level, spellnum)))
if (mag_savingthrow(victim, savetype, save_dc))
dam /= 2;
/* and finally, inflict the damage */
@ -307,6 +312,8 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
return;
save_dc = compute_save_dc(ch, level, spellnum);
if (!IS_NPC(ch) && GET_REAL_LEVEL(ch) >= LVL_IMMORT)
save_dc = 1000;
for (i = 0; i < MAX_SPELL_AFFECTS; i++) {
new_affect(&(af[i]));
@ -470,8 +477,6 @@ 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))
return;
if (MOB_FLAGGED(victim, MOB_NOSLEEP))
return;
if (mag_savingthrow(victim, ABIL_WIS, save_dc))
@ -645,8 +650,6 @@ 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))
continue;
if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM))
continue;
if (!IS_NPC(tch) && spell_info[spellnum].violent && GROUP(tch) && GROUP(ch) && GROUP(ch) == GROUP(tch))

View file

@ -488,18 +488,6 @@ SPECIAL(cityguard)
for (tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room) {
if (!CAN_SEE(ch, tch))
continue;
if (!IS_NPC(tch) && PLR_FLAGGED(tch, PLR_KILLER)) {
act("$n screams 'HEY!!! You're one of those PLAYER KILLERS!!!!!!'", FALSE, ch, 0, 0, TO_ROOM);
hit(ch, tch, TYPE_UNDEFINED);
return (TRUE);
}
if (!IS_NPC(tch) && PLR_FLAGGED(tch, PLR_THIEF)) {
act("$n screams 'HEY!!! You're one of those PLAYER THIEVES!!!!!!'", FALSE, ch, 0, 0, TO_ROOM);
hit(ch, tch, TYPE_UNDEFINED);
return (TRUE);
}
if (FIGHTING(tch) && GET_ALIGNMENT(tch) < max_evil && (IS_NPC(tch) || IS_NPC(FIGHTING(tch)))) {
max_evil = GET_ALIGNMENT(tch);
evil = tch;

View file

@ -124,28 +124,6 @@ ASPELL(spell_summon)
return;
}
if (!CONFIG_PK_ALLOWED) {
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"
"aggressive and might harm you, so you wisely send $M back.",
FALSE, ch, 0, victim, TO_CHAR);
return;
}
if (!IS_NPC(victim) && !PRF_FLAGGED(victim, PRF_SUMMONABLE) &&
!PLR_FLAGGED(victim, PLR_KILLER)) {
send_to_char(victim, "%s just tried to summon you to: %s.\r\n"
"This failed because you have summon protection on.\r\n"
"Type NOSUMMON to allow other players to summon you.\r\n",
GET_NAME(ch), world[IN_ROOM(ch)].name);
send_to_char(ch, "You failed because %s has summon protection on.\r\n", GET_NAME(victim));
mudlog(BRF, MAX(LVL_IMMORT, MAX(GET_INVIS_LEV(ch), GET_INVIS_LEV(victim))), TRUE,
"%s failed summoning %s to %s.", GET_NAME(ch), GET_NAME(victim), world[IN_ROOM(ch)].name);
return;
}
}
if (MOB_FLAGGED(victim, MOB_NOSUMMON) ||
(IS_NPC(victim) && mag_savingthrow(victim, SAVING_CHA, save_dc))) {
send_to_char(ch, "%s", SUMMON_FAIL);
@ -272,8 +250,6 @@ 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))
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");
else if (mag_savingthrow(victim, SAVING_WIS, save_dc))

View file

@ -193,8 +193,8 @@
#define NUM_POSITIONS 9
/* Player flags: used by char_data.char_specials.act */
#define PLR_KILLER 0 /**< Player is a player-killer */
#define PLR_THIEF 1 /**< Player is a player-thief */
#define PLR_UNUSED0 0 /**< Reserved (unused) */
#define PLR_UNUSED1 1 /**< Reserved (unused) */
#define PLR_FROZEN 2 /**< Player is frozen */
#define PLR_DONTSET 3 /**< Don't EVER set (ISNPC bit, set by mud) */
#define PLR_WRITING 4 /**< Player writing (board/mail/olc) */
@ -1387,7 +1387,6 @@ struct forage_entry {
* variables. */
struct game_data
{
int pk_allowed; /**< Is player killing allowed? */
int pt_allowed; /**< Is player thieving allowed? */
int level_can_shout; /**< Level player must be to shout. */
int tunnel_size; /**< Number of people allowed in a tunnel.*/

View file

@ -1021,7 +1021,6 @@ do \
#define CONFIG_CONFFILE config_info.CONFFILE
/** Player killing allowed or not? */
#define CONFIG_PK_ALLOWED config_info.play.pk_allowed
/** Player thieving allowed or not? */
#define CONFIG_PT_ALLOWED config_info.play.pt_allowed
/** What level to use the shout command? */