mirror of
https://github.com/tbamud/tbamud.git
synced 2026-04-03 19:07:19 +02:00
Skinning update
This commit is contained in:
parent
4ea7abca56
commit
1278c31e89
15 changed files with 464 additions and 22 deletions
|
|
@ -12,6 +12,7 @@ call his stature bulky, as he has quite a bit of muscle.
|
|||
B
|
||||
|
||||
|
||||
|
||||
~
|
||||
6218 0 0 0 0 0 0 0 0 E
|
||||
1 3d20+40
|
||||
|
|
@ -30,17 +31,17 @@ Skill 145 5
|
|||
Skill 146 5
|
||||
Skill 147 5
|
||||
E
|
||||
L 3 118 1
|
||||
L 5 131 1
|
||||
L 6 110 1
|
||||
L 7 108 1
|
||||
L 8 115 1
|
||||
L 9 124 1
|
||||
L 10 107 1
|
||||
L 11 111 1
|
||||
L 15 117 1
|
||||
L 16 117 1
|
||||
L 17 127 1
|
||||
L 16 117 1
|
||||
L 15 117 1
|
||||
L 11 111 1
|
||||
L 10 107 1
|
||||
L 9 124 1
|
||||
L 8 115 1
|
||||
L 7 108 1
|
||||
L 6 110 1
|
||||
L 5 131 1
|
||||
L 3 118 1
|
||||
#101
|
||||
Sally~
|
||||
slim lanky human soldier guard~
|
||||
|
|
@ -56,6 +57,7 @@ her nose.
|
|||
B
|
||||
|
||||
|
||||
|
||||
~
|
||||
6218 0 0 0 0 0 0 0 0 E
|
||||
1 3d20+40
|
||||
|
|
@ -71,17 +73,17 @@ Skill 145 5
|
|||
Skill 146 5
|
||||
Skill 147 5
|
||||
E
|
||||
L 17 127 1
|
||||
L 16 117 1
|
||||
L 15 117 1
|
||||
L 11 111 1
|
||||
L 10 107 1
|
||||
L 9 124 1
|
||||
L 8 115 1
|
||||
L 7 108 1
|
||||
L 6 110 1
|
||||
L 5 131 1
|
||||
L 3 118 1
|
||||
L 5 131 1
|
||||
L 6 110 1
|
||||
L 7 108 1
|
||||
L 8 115 1
|
||||
L 9 124 1
|
||||
L 10 107 1
|
||||
L 11 111 1
|
||||
L 15 117 1
|
||||
L 16 117 1
|
||||
L 17 127 1
|
||||
#102
|
||||
Baldy~
|
||||
barkeep stocky bald~
|
||||
|
|
@ -97,13 +99,14 @@ others.
|
|||
B
|
||||
|
||||
|
||||
|
||||
~
|
||||
10 0 0 0 0 0 0 0 0 E
|
||||
1 3d12+60
|
||||
8 8 1
|
||||
E
|
||||
L 14 113 1
|
||||
L 9 112 1
|
||||
L 14 113 1
|
||||
#103
|
||||
Lanky~
|
||||
woman lanky scarred~
|
||||
|
|
@ -120,6 +123,7 @@ appear slightly bloodshot.
|
|||
B
|
||||
|
||||
|
||||
|
||||
~
|
||||
10 0 0 0 0 0 0 0 0 E
|
||||
1 3d8+60
|
||||
|
|
@ -135,4 +139,22 @@ Skill 143 5
|
|||
Skill 144 5
|
||||
Skill 147 5
|
||||
E
|
||||
#104
|
||||
Rat~
|
||||
rat small furry~
|
||||
a small, furry rat~
|
||||
Keeping low to the ground, a small, furry rat wanders around here.
|
||||
~
|
||||
This small rat is covered in thick fur. The fur itself appears matted and
|
||||
has grime coating it. Two beady black eyes look around, constantly shifting.
|
||||
Its tail is four, perhaps five inches long and grey in color. Both hindlings
|
||||
appear thick and ready to propel the animal if it feels threatened.
|
||||
~
|
||||
B
|
||||
It's a rat.
|
||||
~
|
||||
8 0 0 0 0 0 0 0 0 E
|
||||
1 0d0+10
|
||||
8 8 2
|
||||
E
|
||||
$
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ ACMD(do_put);
|
|||
ACMD(do_remove);
|
||||
ACMD(do_wear);
|
||||
ACMD(do_wield);
|
||||
ACMD(do_skin);
|
||||
|
||||
/*****************************************************************************
|
||||
* Begin Functions and defines for act.movement.c
|
||||
|
|
|
|||
121
src/act.item.c
121
src/act.item.c
|
|
@ -1927,3 +1927,124 @@ ACMD(do_raise_lower_hood)
|
|||
send_to_char(ch, "You lower your hood.\r\n");
|
||||
act("$n lowers $s hood.", FALSE, ch, 0, 0, TO_ROOM);
|
||||
}
|
||||
|
||||
static void dump_obj_contents_to_room(struct obj_data *container, room_rnum room)
|
||||
{
|
||||
struct obj_data *obj, *next_obj;
|
||||
|
||||
if (!container || room == NOWHERE)
|
||||
return;
|
||||
|
||||
for (obj = container->contains; obj; obj = next_obj) {
|
||||
next_obj = obj->next_content;
|
||||
obj_from_obj(obj);
|
||||
obj_to_room(obj, room);
|
||||
}
|
||||
}
|
||||
|
||||
static int is_corpse_obj(struct obj_data *obj)
|
||||
{
|
||||
if (!obj)
|
||||
return 0;
|
||||
return (GET_OBJ_TYPE(obj) == ITEM_CONTAINER && GET_OBJ_VAL(obj, 3) == 1);
|
||||
}
|
||||
|
||||
ACMD(do_skin)
|
||||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
struct obj_data *corpse = NULL;
|
||||
struct skin_yield_entry *y;
|
||||
room_rnum room;
|
||||
mob_vnum mvnum;
|
||||
mob_rnum mrnum;
|
||||
int d20, total, successes = 0;
|
||||
int number = 1;
|
||||
|
||||
one_argument(argument, arg);
|
||||
|
||||
if (!*arg) {
|
||||
send_to_char(ch, "Skin what?\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prefer room first, then inventory. */
|
||||
number = 1;
|
||||
corpse = get_obj_in_list_vis(ch, arg, &number, world[IN_ROOM(ch)].contents);
|
||||
|
||||
if (!corpse) {
|
||||
number = 1;
|
||||
corpse = get_obj_in_list_vis(ch, arg, &number, ch->carrying);
|
||||
}
|
||||
|
||||
if (!corpse) {
|
||||
send_to_char(ch, "You don't see that here.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_corpse_obj(corpse)) {
|
||||
send_to_char(ch, "You can't skin that.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
room = IN_ROOM(ch);
|
||||
if (room == NOWHERE) {
|
||||
send_to_char(ch, "You can't do that here.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mvnum = corpse->corpse_mob_vnum;
|
||||
if (mvnum <= 0) {
|
||||
send_to_char(ch, "You aren't able to cut anything useful from the corpse.\r\n");
|
||||
dump_obj_contents_to_room(corpse, room);
|
||||
extract_obj(corpse);
|
||||
return;
|
||||
}
|
||||
|
||||
mrnum = real_mobile(mvnum);
|
||||
if (mrnum < 0 || !mob_index[mrnum].skin_yields) {
|
||||
send_to_char(ch, "You aren't able to cut anything useful from the corpse.\r\n");
|
||||
dump_obj_contents_to_room(corpse, room);
|
||||
extract_obj(corpse);
|
||||
return;
|
||||
}
|
||||
|
||||
d20 = dice(1, 20);
|
||||
|
||||
if (d20 == 1) {
|
||||
send_to_char(ch, "You aren't able to cut anything useful from the corpse.\r\n");
|
||||
dump_obj_contents_to_room(corpse, room);
|
||||
extract_obj(corpse);
|
||||
return;
|
||||
}
|
||||
|
||||
total = roll_survival_check(ch, 0, &d20);
|
||||
|
||||
if (d20 == 1) {
|
||||
send_to_char(ch, "You aren't able to cut anything useful from the corpse.\r\n");
|
||||
dump_obj_contents_to_room(corpse, room);
|
||||
extract_obj(corpse);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Evaluate configured yields (if any). */
|
||||
for (y = mob_index[mrnum].skin_yields; y; y = y->next) {
|
||||
if (total >= y->dc) {
|
||||
struct obj_data *o = read_object(y->obj_vnum, VIRTUAL);
|
||||
if (o) {
|
||||
obj_to_room(o, room);
|
||||
successes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (successes == 0) {
|
||||
send_to_char(ch, "You aren't able to cut anything useful from the corpse.\r\n");
|
||||
} else {
|
||||
act("You skin $p, cutting away anything useful.", FALSE, ch, corpse, 0, TO_CHAR);
|
||||
act("$n skins $p, cutting away anything useful.", FALSE, ch, corpse, 0, TO_ROOM);
|
||||
}
|
||||
|
||||
dump_obj_contents_to_room(corpse, room);
|
||||
|
||||
extract_obj(corpse);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -486,6 +486,8 @@ const char *extra_bits[] = {
|
|||
"ANTI_DRUID",
|
||||
"NO_SELL",
|
||||
"QUEST_ITEM",
|
||||
"HOOD_UP",
|
||||
"SKINNED",
|
||||
"\n"
|
||||
};
|
||||
|
||||
|
|
|
|||
91
src/db.c
91
src/db.c
|
|
@ -1765,6 +1765,7 @@ void parse_mobile(FILE *mob_f, int nr)
|
|||
mob_index[i].vnum = nr;
|
||||
mob_index[i].number = 0;
|
||||
mob_index[i].func = NULL;
|
||||
mob_index[i].skin_yields = NULL;
|
||||
|
||||
clear_char(mob_proto + i);
|
||||
|
||||
|
|
@ -1926,6 +1927,39 @@ void parse_mobile(FILE *mob_f, int nr)
|
|||
/* look ahead to see if there is another 'L' */
|
||||
letter = fread_letter(mob_f);
|
||||
}
|
||||
ungetc(letter, mob_f);
|
||||
|
||||
/* ---- Skinning yields (Y block): allow before triggers ---- */
|
||||
letter = fread_letter(mob_f);
|
||||
while (letter == 'Y') {
|
||||
obj_vnum ovnum;
|
||||
int dc;
|
||||
|
||||
for (;;) {
|
||||
if (!get_line(mob_f, line)) {
|
||||
log("SYSERR: Unexpected EOF while reading 'Y' block in mob #%d.", nr);
|
||||
break;
|
||||
}
|
||||
if (sscanf(line, "%d %d", &ovnum, &dc) != 2) {
|
||||
log("SYSERR: Bad 'Y' line in mob #%d: '%s' (need <obj_vnum> <dc>).", nr, line);
|
||||
continue;
|
||||
}
|
||||
if (ovnum == 0 && dc == 0)
|
||||
break;
|
||||
|
||||
/* add entry to mob_index[i].skin_yields */
|
||||
struct skin_yield_entry *e;
|
||||
CREATE(e, struct skin_yield_entry, 1);
|
||||
e->mob_vnum = mob_index[i].vnum;
|
||||
e->obj_vnum = ovnum;
|
||||
e->dc = dc;
|
||||
e->next = mob_index[i].skin_yields;
|
||||
mob_index[i].skin_yields = e;
|
||||
}
|
||||
|
||||
/* look ahead for another Y block (rare but harmless to support) */
|
||||
letter = fread_letter(mob_f);
|
||||
}
|
||||
ungetc(letter, mob_f);
|
||||
|
||||
/* ---- DG triggers: script info follows mob S/E section ---- */
|
||||
|
|
@ -1936,6 +1970,38 @@ void parse_mobile(FILE *mob_f, int nr)
|
|||
}
|
||||
ungetc(letter, mob_f);
|
||||
|
||||
/* ---- Skinning yields (Y block): allow after triggers ---- */
|
||||
letter = fread_letter(mob_f);
|
||||
while (letter == 'Y') {
|
||||
obj_vnum ovnum;
|
||||
int dc;
|
||||
|
||||
for (;;) {
|
||||
if (!get_line(mob_f, line)) {
|
||||
log("SYSERR: Unexpected EOF while reading 'Y' block in mob #%d.", nr);
|
||||
break;
|
||||
}
|
||||
if (sscanf(line, "%d %d", &ovnum, &dc) != 2) {
|
||||
log("SYSERR: Bad 'Y' line in mob #%d: '%s' (need <obj_vnum> <dc>).", nr, line);
|
||||
continue;
|
||||
}
|
||||
if (ovnum == 0 && dc == 0)
|
||||
break;
|
||||
|
||||
struct skin_yield_entry *e;
|
||||
CREATE(e, struct skin_yield_entry, 1);
|
||||
e->mob_vnum = mob_index[i].vnum;
|
||||
e->obj_vnum = ovnum;
|
||||
e->dc = dc;
|
||||
e->next = mob_index[i].skin_yields;
|
||||
mob_index[i].skin_yields = e;
|
||||
}
|
||||
|
||||
/* look ahead for another Y block (optional) */
|
||||
letter = fread_letter(mob_f);
|
||||
}
|
||||
ungetc(letter, mob_f);
|
||||
|
||||
/* ---- And allow loadout lines AFTER triggers, too ---- */
|
||||
letter = fread_letter(mob_f);
|
||||
while (letter == 'L') {
|
||||
|
|
@ -4348,3 +4414,28 @@ void load_config( void )
|
|||
|
||||
fclose(fl);
|
||||
}
|
||||
|
||||
void free_skin_yields(struct skin_yield_entry *list)
|
||||
{
|
||||
struct skin_yield_entry *e, *next;
|
||||
for (e = list; e; e = next) {
|
||||
next = e->next;
|
||||
free(e);
|
||||
}
|
||||
}
|
||||
|
||||
struct skin_yield_entry *copy_skin_yields(struct skin_yield_entry *src)
|
||||
{
|
||||
struct skin_yield_entry *head = NULL, *tail = NULL, *e;
|
||||
|
||||
for (; src; src = src->next) {
|
||||
CREATE(e, struct skin_yield_entry, 1);
|
||||
*e = *src;
|
||||
e->next = NULL;
|
||||
|
||||
if (!head) head = e;
|
||||
else tail->next = e;
|
||||
tail = e;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
|
|
|||
2
src/db.h
2
src/db.h
|
|
@ -258,6 +258,8 @@ void free_player_index(void);
|
|||
void load_help(FILE *fl, char *name);
|
||||
void new_mobile_data(struct char_data *ch);
|
||||
void equip_mob_from_loadout(struct char_data *mob);
|
||||
void free_skin_yields(struct skin_yield_entry *list);
|
||||
struct skin_yield_entry *copy_skin_yields(struct skin_yield_entry *src);
|
||||
|
||||
zone_rnum real_zone(zone_vnum vnum);
|
||||
room_rnum real_room(room_vnum vnum);
|
||||
|
|
|
|||
|
|
@ -238,6 +238,8 @@ static void make_corpse(struct char_data *ch)
|
|||
|
||||
corpse = create_obj();
|
||||
|
||||
corpse->corpse_mob_vnum = IS_NPC(ch) ? GET_MOB_VNUM(ch) : 0;
|
||||
|
||||
corpse->item_number = NOTHING;
|
||||
IN_ROOM(corpse) = NOWHERE;
|
||||
corpse->name = strdup("corpse");
|
||||
|
|
|
|||
13
src/genmob.c
13
src/genmob.c
|
|
@ -479,6 +479,19 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
|
|||
/* --- DG Scripts --- */
|
||||
script_save_to_disk(fd, mob, MOB_TRIGGER);
|
||||
|
||||
/* --- Skinning yields --- */
|
||||
{
|
||||
mob_rnum rmob = real_mobile(mvnum);
|
||||
struct skin_yield_entry *sy;
|
||||
|
||||
if (rmob != NOBODY && mob_index[rmob].skin_yields) {
|
||||
fprintf(fd, "Y\n");
|
||||
for (sy = mob_index[rmob].skin_yields; sy; sy = sy->next)
|
||||
fprintf(fd, "%d %d\n", sy->obj_vnum, sy->dc);
|
||||
fprintf(fd, "0 0\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_GENOLC_MOBPROG
|
||||
if (write_mobile_mobprog(mvnum, mob, fd) < 0)
|
||||
log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum);
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ cpp_extern const struct command_info cmd_info[] = {
|
|||
{ "set" , "set" , POS_DEAD , do_set , LVL_IMMORT, 0 },
|
||||
{ "shout" , "sho" , POS_RESTING , do_gen_comm , 0, SCMD_SHOUT },
|
||||
{ "skills" , "sk" , POS_SLEEPING, do_skills , 0, 0 },
|
||||
{ "skin" , "skin" , POS_STANDING, do_skin, 0, 0 },
|
||||
{ "show" , "show" , POS_DEAD , do_show , LVL_IMMORT, 0 },
|
||||
{ "shutdow" , "shutdow" , POS_DEAD , do_shutdown , LVL_IMPL, 0 },
|
||||
{ "shutdown" , "shutdown", POS_DEAD , do_shutdown , LVL_IMPL, SCMD_SHUTDOWN },
|
||||
|
|
|
|||
126
src/medit.c
126
src/medit.c
|
|
@ -115,6 +115,7 @@ ACMD(do_oasis_medit)
|
|||
}
|
||||
|
||||
CREATE(d->olc, struct oasis_olc_data, 1);
|
||||
d->olc->skin_yields = NULL;
|
||||
|
||||
/* Find the zone. */
|
||||
OLC_ZNUM(d) = save ? real_zone(number) : real_zone_by_thing(number);
|
||||
|
|
@ -221,6 +222,9 @@ void medit_setup_existing(struct descriptor_data *d, int rmob_num)
|
|||
*/
|
||||
SCRIPT(mob) = NULL;
|
||||
OLC_MOB(d)->proto_script = NULL;
|
||||
|
||||
/* Copy skinning yields from the prototype index into OLC working storage. */
|
||||
d->olc->skin_yields = copy_skin_yields(mob_index[rmob_num].skin_yields);
|
||||
}
|
||||
|
||||
/* Ideally, this function should be in db.c, but I'll put it here for portability. */
|
||||
|
|
@ -448,6 +452,7 @@ static void medit_disp_menu(struct descriptor_data *d)
|
|||
"%s8%s) Default : %s%s\r\n"
|
||||
"%s9%s) Attack : %s%s\r\n"
|
||||
"%sD%s) Class : %s%s\r\n"
|
||||
"%sK%s) Skinning Menu...\r\n"
|
||||
"%s0%s) Stats Menu...\r\n"
|
||||
"%s-%s) Skills Menu...\r\n"
|
||||
"%sA%s) NPC Flags : %s%s\r\n"
|
||||
|
|
@ -463,6 +468,7 @@ static void medit_disp_menu(struct descriptor_data *d)
|
|||
grn, nrm, yel, position_types[(int)GET_DEFAULT_POS(mob)],
|
||||
grn, nrm, yel, attack_hit_text[(int)GET_ATTACK(mob)].singular,
|
||||
grn, nrm, yel, classname,
|
||||
grn, nrm,
|
||||
grn, nrm,
|
||||
grn, nrm,
|
||||
grn, nrm, cyn, flags,
|
||||
|
|
@ -618,6 +624,27 @@ static void medit_disp_skill_menu(struct descriptor_data *d)
|
|||
OLC_MODE(d) = MEDIT_SKILL_MENU;
|
||||
}
|
||||
|
||||
static void medit_disp_skin_menu(struct descriptor_data *d)
|
||||
{
|
||||
struct skin_yield_entry *e;
|
||||
int n = 1;
|
||||
|
||||
write_to_output(d, "\r\n-- Skinning Yields --\r\n");
|
||||
|
||||
if (!d->olc->skin_yields) {
|
||||
write_to_output(d, " <none>\r\n");
|
||||
} else {
|
||||
for (e = d->olc->skin_yields; e; e = e->next)
|
||||
write_to_output(d, "%2d) obj %d dc %d\r\n", n++, e->obj_vnum, e->dc);
|
||||
}
|
||||
|
||||
write_to_output(d,
|
||||
"\r\nA) Add yield\r\n"
|
||||
"D) Delete yield\r\n"
|
||||
"Q) Quit to main menu\r\n"
|
||||
"Enter choice: ");
|
||||
}
|
||||
|
||||
void medit_parse(struct descriptor_data *d, char *arg)
|
||||
{
|
||||
int i = -1, j;
|
||||
|
|
@ -640,6 +667,14 @@ void medit_parse(struct descriptor_data *d, char *arg)
|
|||
switch (*arg) {
|
||||
case 'y':
|
||||
case 'Y':
|
||||
/* Commit skinning yields from OLC working copy into the prototype index. */
|
||||
{
|
||||
mob_rnum rmob = real_mobile(OLC_NUM(d));
|
||||
if (rmob != NOBODY) {
|
||||
free_skin_yields(mob_index[rmob].skin_yields);
|
||||
mob_index[rmob].skin_yields = copy_skin_yields(d->olc->skin_yields);
|
||||
}
|
||||
}
|
||||
/* Save the mob in memory and to disk. */
|
||||
medit_save_internally(d);
|
||||
mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits mob %d", GET_NAME(d->character), OLC_NUM(d));
|
||||
|
|
@ -752,6 +787,11 @@ void medit_parse(struct descriptor_data *d, char *arg)
|
|||
string_write(d, &OLC_MOB(d)->player.background, MAX_MOB_DESC, 0, oldtext);
|
||||
OLC_VAL(d) = 1;
|
||||
return;
|
||||
case 'k':
|
||||
case 'K':
|
||||
medit_disp_skin_menu(d);
|
||||
OLC_MODE(d) = MEDIT_SKIN_MENU;
|
||||
return;
|
||||
case 'w':
|
||||
case 'W':
|
||||
write_to_output(d, "Copy what mob? ");
|
||||
|
|
@ -781,6 +821,92 @@ void medit_parse(struct descriptor_data *d, char *arg)
|
|||
write_to_output(d, "Oops...\r\n");
|
||||
return;
|
||||
|
||||
case MEDIT_SKIN_MENU:
|
||||
switch (UPPER(*arg)) {
|
||||
case 'A':
|
||||
write_to_output(d, "Enter object vnum: ");
|
||||
OLC_MODE(d) = MEDIT_SKIN_ADD_VNUM;
|
||||
return;
|
||||
|
||||
case 'D':
|
||||
write_to_output(d, "Delete which entry number? ");
|
||||
OLC_MODE(d) = MEDIT_SKIN_DELETE;
|
||||
return;
|
||||
|
||||
case 'Q':
|
||||
medit_disp_menu(d);
|
||||
OLC_MODE(d) = MEDIT_MAIN_MENU;
|
||||
return;
|
||||
|
||||
default:
|
||||
medit_disp_skin_menu(d);
|
||||
return;
|
||||
}
|
||||
/* not reached */
|
||||
|
||||
case MEDIT_SKIN_ADD_VNUM: {
|
||||
obj_vnum ovnum = (obj_vnum)atoi(arg);
|
||||
|
||||
if (ovnum <= 0) {
|
||||
write_to_output(d, "Invalid object vnum. Enter object vnum: ");
|
||||
return;
|
||||
}
|
||||
|
||||
OLC_VAL(d) = (int)ovnum; /* stash temporarily (note: OLC_VAL is also your dirty flag) */
|
||||
write_to_output(d, "Enter DC required: ");
|
||||
OLC_MODE(d) = MEDIT_SKIN_ADD_DC;
|
||||
return;
|
||||
}
|
||||
|
||||
case MEDIT_SKIN_ADD_DC: {
|
||||
int dc = atoi(arg);
|
||||
struct skin_yield_entry *e;
|
||||
|
||||
CREATE(e, struct skin_yield_entry, 1);
|
||||
e->mob_vnum = OLC_NUM(d); /* mob vnum being edited */
|
||||
e->obj_vnum = (obj_vnum)OLC_VAL(d); /* vnum captured in prior step */
|
||||
e->dc = MAX(0, dc);
|
||||
e->next = d->olc->skin_yields;
|
||||
d->olc->skin_yields = e;
|
||||
|
||||
/* Mark the mob as changed */
|
||||
OLC_VAL(d) = TRUE;
|
||||
|
||||
medit_disp_skin_menu(d);
|
||||
OLC_MODE(d) = MEDIT_SKIN_MENU;
|
||||
return;
|
||||
}
|
||||
|
||||
case MEDIT_SKIN_DELETE: {
|
||||
int target = atoi(arg);
|
||||
struct skin_yield_entry *e, *prev = NULL;
|
||||
int n = 1;
|
||||
|
||||
if (target < 1) {
|
||||
medit_disp_skin_menu(d);
|
||||
OLC_MODE(d) = MEDIT_SKIN_MENU;
|
||||
return;
|
||||
}
|
||||
|
||||
for (e = d->olc->skin_yields; e; prev = e, e = e->next, n++) {
|
||||
if (n == target) {
|
||||
if (prev)
|
||||
prev->next = e->next;
|
||||
else
|
||||
d->olc->skin_yields = e->next;
|
||||
free(e);
|
||||
|
||||
/* Mark the mob as changed */
|
||||
OLC_VAL(d) = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
medit_disp_skin_menu(d);
|
||||
OLC_MODE(d) = MEDIT_SKIN_MENU;
|
||||
return;
|
||||
}
|
||||
|
||||
case MEDIT_STATS_MENU:
|
||||
i=0;
|
||||
switch(*arg) {
|
||||
|
|
|
|||
|
|
@ -213,6 +213,12 @@ void cleanup_olc(struct descriptor_data *d, byte cleanup_type)
|
|||
STATE(d) = CON_PLAYING;
|
||||
}
|
||||
|
||||
/* Free Skinning Yield working list (medit). */
|
||||
if (d->olc->skin_yields) {
|
||||
free_skin_yields(d->olc->skin_yields);
|
||||
d->olc->skin_yields = NULL;
|
||||
}
|
||||
|
||||
free(d->olc);
|
||||
d->olc = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#define _OASIS_H_
|
||||
|
||||
#include "utils.h" /* for ACMD macro */
|
||||
#include "structs.h"
|
||||
|
||||
#define _OASISOLC 0x206 /* 2.0.6 */
|
||||
|
||||
|
|
@ -110,6 +111,7 @@ struct oasis_olc_data {
|
|||
int item_type;
|
||||
struct trig_proto_list *script; /* for assigning triggers in [r|o|m]edit*/
|
||||
struct help_index_element*help; /* Hedit uses this */
|
||||
struct skin_yield_entry *skin_yields;
|
||||
};
|
||||
|
||||
/* Exported globals. */
|
||||
|
|
@ -294,6 +296,12 @@ extern const char *nrm, *grn, *cyn, *yel;
|
|||
#define MEDIT_SAVE_CHA 37
|
||||
#define MEDIT_SKILL_VALUE 38
|
||||
|
||||
/* Skinning yield editor */
|
||||
#define MEDIT_SKIN_MENU 39
|
||||
#define MEDIT_SKIN_ADD_VNUM 40
|
||||
#define MEDIT_SKIN_ADD_DC 41
|
||||
#define MEDIT_SKIN_DELETE 42
|
||||
|
||||
/* Submodes of SEDIT connectedness. */
|
||||
#define SEDIT_MAIN_MENU 0
|
||||
#define SEDIT_CONFIRM_SAVESTRING 1
|
||||
|
|
|
|||
|
|
@ -445,8 +445,9 @@
|
|||
#define ITEM_NOSELL 20 /**< Shopkeepers won't touch it */
|
||||
#define ITEM_QUEST 21 /**< Item is a quest item */
|
||||
#define ITEM_HOOD_UP 22 /**< WORN item hood is currently up */
|
||||
#define ITEM_SKINNED 23 /* Item/corpse can be skinned */
|
||||
/** Total number of item flags */
|
||||
#define NUM_ITEM_FLAGS 23
|
||||
#define NUM_ITEM_FLAGS 24
|
||||
|
||||
/* Modifier constants used with obj affects ('A' fields) */
|
||||
#define APPLY_NONE 0 /**< No effect */
|
||||
|
|
@ -753,6 +754,8 @@ struct obj_data
|
|||
struct char_data *sitting_here; /**< For furniture, who is sitting in it */
|
||||
|
||||
struct list_data *events; /**< Used for object events */
|
||||
|
||||
mob_vnum corpse_mob_vnum;
|
||||
};
|
||||
|
||||
/** Instance info for an object that gets saved to disk.
|
||||
|
|
@ -1262,6 +1265,7 @@ struct index_data
|
|||
|
||||
char *farg; /**< String argument for special function. */
|
||||
struct trig_data *proto; /**< Points to the trigger prototype. */
|
||||
struct skin_yield_entry *skin_yields;
|
||||
};
|
||||
|
||||
/** Master linked list for the mob/object prototype trigger lists. */
|
||||
|
|
@ -1338,6 +1342,14 @@ struct mob_loadout *loadout_deep_copy(const struct mob_loadout *src);
|
|||
#define VAL_FOOD_HOURS_PER_BITE 2
|
||||
#define VAL_FOOD_POISONED 3
|
||||
|
||||
/* For skinning/survival skill usage */
|
||||
struct skin_yield_entry {
|
||||
mob_vnum mob_vnum; /* redundant but useful for debugging */
|
||||
obj_vnum obj_vnum; /* object to create on success */
|
||||
int dc; /* DC required */
|
||||
struct skin_yield_entry *next;
|
||||
};
|
||||
|
||||
/* Config structs */
|
||||
|
||||
/** The game configuration structure used for configurating the game play
|
||||
|
|
|
|||
34
src/utils.c
34
src/utils.c
|
|
@ -1707,6 +1707,40 @@ int roll_d20(void) { return rand_number(1, 20); }
|
|||
int roll_d20_adv(void) { int a=roll_d20(), b=roll_d20(); return (a>b)?a:b; }
|
||||
int roll_d20_disadv(void) { int a=roll_d20(), b=roll_d20(); return (a<b)?a:b; }
|
||||
|
||||
int roll_survival_check(struct char_data *ch, int mode, int *out_d20)
|
||||
{
|
||||
int d20, total;
|
||||
|
||||
if (!ch) {
|
||||
if (out_d20) *out_d20 = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode > 0)
|
||||
d20 = roll_d20_adv();
|
||||
else if (mode < 0)
|
||||
d20 = roll_d20_disadv();
|
||||
else
|
||||
d20 = roll_d20();
|
||||
|
||||
if (out_d20)
|
||||
*out_d20 = d20;
|
||||
|
||||
/* Base: d20 + WIS mod */
|
||||
total = d20 + GET_ABILITY_MOD(GET_WIS(ch));
|
||||
|
||||
/*
|
||||
* Proficiency: Fighters/Rangers/Druids are proficient in Survival.
|
||||
* This uses your existing proficiency bonus helper.
|
||||
*/
|
||||
if (GET_CLASS(ch) == CLASS_FIGHTER ||
|
||||
GET_CLASS(ch) == CLASS_RANGER ||
|
||||
GET_CLASS(ch) == CLASS_DRUID)
|
||||
total += get_total_proficiency_bonus(ch);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/* Percent style (for legacy percent-based skill checks) */
|
||||
bool percent_success(int chance_pct) {
|
||||
if (chance_pct <= 0) return FALSE;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ const char *const *obj_value_labels(int item_type);
|
|||
const char *get_char_sdesc(const struct char_data *ch);
|
||||
int obj_is_storage(const struct obj_data *obj);
|
||||
int obj_storage_is_closed(const struct obj_data *obj);
|
||||
int roll_survival_check(struct char_data *ch, int mode, int *out_d20);
|
||||
|
||||
/* 5e system helpers */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue