mirror of
https://github.com/tbamud/tbamud.git
synced 2026-04-02 02:17:19 +02:00
Forage command update
This commit is contained in:
parent
715e778b29
commit
0267a4c091
10 changed files with 280 additions and 0 deletions
|
|
@ -159,6 +159,7 @@ ACMD(do_remove);
|
|||
ACMD(do_wear);
|
||||
ACMD(do_wield);
|
||||
ACMD(do_skin);
|
||||
ACMD(do_forage);
|
||||
|
||||
/*****************************************************************************
|
||||
* Begin Functions and defines for act.movement.c
|
||||
|
|
|
|||
|
|
@ -2039,3 +2039,58 @@ ACMD(do_skin)
|
|||
|
||||
extract_obj(corpse);
|
||||
}
|
||||
|
||||
ACMD(do_forage)
|
||||
{
|
||||
room_rnum room;
|
||||
struct forage_entry *entry, *best = NULL;
|
||||
struct obj_data *obj;
|
||||
int total;
|
||||
int best_dc = -1;
|
||||
int prof_bonus, cost;
|
||||
int delay_seconds;
|
||||
|
||||
room = IN_ROOM(ch);
|
||||
if (room == NOWHERE) {
|
||||
send_to_char(ch, "You can't do that here.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
prof_bonus = GET_PROFICIENCY(GET_SKILL(ch, SKILL_SURVIVAL));
|
||||
cost = MAX(1, 10 - prof_bonus);
|
||||
|
||||
if (!IS_NPC(ch) && GET_MOVE(ch) < cost) {
|
||||
send_to_char(ch, "You are too exhausted to forage.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
delay_seconds = rand_number(8, 12);
|
||||
WAIT_STATE(ch, delay_seconds * PASSES_PER_SEC);
|
||||
|
||||
if (!IS_NPC(ch))
|
||||
GET_MOVE(ch) = MAX(0, GET_MOVE(ch) - cost);
|
||||
|
||||
total = roll_skill_check(ch, SKILL_SURVIVAL, 0, NULL);
|
||||
|
||||
for (entry = world[room].forage; entry; entry = entry->next) {
|
||||
if (total >= entry->dc && entry->dc > best_dc) {
|
||||
best = entry;
|
||||
best_dc = entry->dc;
|
||||
}
|
||||
}
|
||||
|
||||
if (best) {
|
||||
obj = read_object(best->obj_vnum, VIRTUAL);
|
||||
if (obj) {
|
||||
obj_to_char(obj, ch);
|
||||
act("You take some time to look around, and end up finding $p.", FALSE, ch, obj, 0, TO_CHAR);
|
||||
act("$n takes some time to look around, and ends up finding $p.", FALSE, ch, obj, 0, TO_ROOM);
|
||||
gain_skill(ch, "survival", TRUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
send_to_char(ch, "You take some time to look around, but don't find anything.\r\n");
|
||||
act("$n takes some time to look around, but doesn't find anything.", FALSE, ch, 0, 0, TO_ROOM);
|
||||
gain_skill(ch, "survival", FALSE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ void grant_class_skills(struct char_data *ch, bool reset)
|
|||
SET_SKILL(ch, SKILL_SURVIVAL, 5);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Some initializations for characters, including initial skills */
|
||||
|
|
|
|||
58
src/db.c
58
src/db.c
|
|
@ -1352,6 +1352,7 @@ void parse_room(FILE *fl, int virtual_nr)
|
|||
world[room_nr].dir_option[i] = NULL;
|
||||
|
||||
world[room_nr].ex_description = NULL;
|
||||
world[room_nr].forage = NULL;
|
||||
|
||||
snprintf(buf, sizeof(buf), "SYSERR: Format error in room #%d (expecting D/E/S)", virtual_nr);
|
||||
|
||||
|
|
@ -1373,6 +1374,38 @@ void parse_room(FILE *fl, int virtual_nr)
|
|||
new_descr->next = world[room_nr].ex_description;
|
||||
world[room_nr].ex_description = new_descr;
|
||||
break;
|
||||
case 'F':
|
||||
for (;;) {
|
||||
obj_vnum ovnum;
|
||||
int dc;
|
||||
|
||||
if (!get_line(fl, line)) {
|
||||
log("SYSERR: Unexpected EOF while reading 'F' block in room #%d.", virtual_nr);
|
||||
break;
|
||||
}
|
||||
if (sscanf(line, "%d %d", &ovnum, &dc) != 2) {
|
||||
log("SYSERR: Bad 'F' line in room #%d: '%s' (need <obj_vnum> <dc>).", virtual_nr, line);
|
||||
continue;
|
||||
}
|
||||
if (ovnum == 0 && dc == 0)
|
||||
break;
|
||||
|
||||
struct forage_entry *e;
|
||||
struct forage_entry *tail;
|
||||
CREATE(e, struct forage_entry, 1);
|
||||
e->obj_vnum = ovnum;
|
||||
e->dc = dc;
|
||||
e->next = NULL;
|
||||
if (!world[room_nr].forage) {
|
||||
world[room_nr].forage = e;
|
||||
} else {
|
||||
tail = world[room_nr].forage;
|
||||
while (tail->next)
|
||||
tail = tail->next;
|
||||
tail->next = e;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'S': /* end of room */
|
||||
/* DG triggers -- script is defined after the end of the room */
|
||||
letter = fread_letter(fl);
|
||||
|
|
@ -4453,3 +4486,28 @@ struct skin_yield_entry *copy_skin_yields(struct skin_yield_entry *src)
|
|||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
void free_forage_list(struct forage_entry *list)
|
||||
{
|
||||
struct forage_entry *e, *next;
|
||||
for (e = list; e; e = next) {
|
||||
next = e->next;
|
||||
free(e);
|
||||
}
|
||||
}
|
||||
|
||||
struct forage_entry *copy_forage_list(struct forage_entry *src)
|
||||
{
|
||||
struct forage_entry *head = NULL, *tail = NULL, *e;
|
||||
|
||||
for (; src; src = src->next) {
|
||||
CREATE(e, struct forage_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
|
|
@ -260,6 +260,8 @@ 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);
|
||||
void free_forage_list(struct forage_entry *list);
|
||||
struct forage_entry *copy_forage_list(struct forage_entry *src);
|
||||
|
||||
zone_rnum real_zone(zone_vnum vnum);
|
||||
room_rnum real_room(room_vnum vnum);
|
||||
|
|
|
|||
13
src/genwld.c
13
src/genwld.c
|
|
@ -373,6 +373,13 @@ int save_rooms(zone_rnum rzone)
|
|||
"%s~\n", xdesc->keyword, buf);
|
||||
}
|
||||
}
|
||||
if (room->forage) {
|
||||
struct forage_entry *entry;
|
||||
fprintf(sf, "F\n");
|
||||
for (entry = room->forage; entry; entry = entry->next)
|
||||
fprintf(sf, "%d %d\n", entry->obj_vnum, entry->dc);
|
||||
fprintf(sf, "0 0\n");
|
||||
}
|
||||
fprintf(sf, "S\n");
|
||||
script_save_to_disk(sf, room, WLD_TRIGGER);
|
||||
}
|
||||
|
|
@ -439,6 +446,9 @@ int copy_room_strings(struct room_data *dest, struct room_data *source)
|
|||
if (source->ex_description)
|
||||
copy_ex_descriptions(&dest->ex_description, source->ex_description);
|
||||
|
||||
if (source->forage)
|
||||
dest->forage = copy_forage_list(source->forage);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -453,6 +463,9 @@ int free_room_strings(struct room_data *room)
|
|||
free(room->description);
|
||||
if (room->ex_description)
|
||||
free_ex_descriptions(room->ex_description);
|
||||
if (room->forage)
|
||||
free_forage_list(room->forage);
|
||||
room->forage = NULL;
|
||||
|
||||
/* Free exits. */
|
||||
for (i = 0; i < DIR_COUNT; i++) {
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
{ "forage" , "for" , POS_STANDING, do_forage , 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 },
|
||||
|
|
|
|||
|
|
@ -227,6 +227,9 @@ extern const char *nrm, *grn, *cyn, *yel;
|
|||
#define REDIT_EXTRADESC_DESCRIPTION 16
|
||||
#define REDIT_DELETE 17
|
||||
#define REDIT_COPY 18
|
||||
#define REDIT_FORAGE_MENU 19
|
||||
#define REDIT_FORAGE_ADD 20
|
||||
#define REDIT_FORAGE_DELETE 21
|
||||
|
||||
/* Submodes of ZEDIT connectedness. */
|
||||
#define ZEDIT_MAIN_MENU 0
|
||||
|
|
|
|||
136
src/redit.c
136
src/redit.c
|
|
@ -29,6 +29,7 @@ static void redit_disp_exit_menu(struct descriptor_data *d);
|
|||
static void redit_disp_exit_flag_menu(struct descriptor_data *d);
|
||||
static void redit_disp_flag_menu(struct descriptor_data *d);
|
||||
static void redit_disp_sector_menu(struct descriptor_data *d);
|
||||
static void redit_disp_forage_menu(struct descriptor_data *d);
|
||||
static void redit_disp_menu(struct descriptor_data *d);
|
||||
|
||||
/* Utils and exported functions. */
|
||||
|
|
@ -161,6 +162,7 @@ static void redit_setup_new(struct descriptor_data *d)
|
|||
OLC_ROOM(d)->number = NOWHERE;
|
||||
OLC_ITEM_TYPE(d) = WLD_TRIGGER;
|
||||
OLC_ROOM(d)->proto_script = OLC_SCRIPT(d) = NULL;
|
||||
OLC_ROOM(d)->forage = NULL;
|
||||
|
||||
OLC_VAL(d) = 0;
|
||||
}
|
||||
|
|
@ -221,6 +223,8 @@ void redit_setup_existing(struct descriptor_data *d, int real_num)
|
|||
}
|
||||
}
|
||||
|
||||
room->forage = copy_forage_list(world[real_num].forage);
|
||||
|
||||
/* Attach copy of room to player's descriptor. */
|
||||
OLC_ROOM(d) = room;
|
||||
OLC_VAL(d) = 0;
|
||||
|
|
@ -412,16 +416,57 @@ static void redit_disp_sector_menu(struct descriptor_data *d)
|
|||
OLC_MODE(d) = REDIT_SECTOR;
|
||||
}
|
||||
|
||||
static int redit_forage_count(struct forage_entry *list)
|
||||
{
|
||||
int count = 0;
|
||||
for (; list; list = list->next)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
static void redit_disp_forage_menu(struct descriptor_data *d)
|
||||
{
|
||||
struct forage_entry *entry;
|
||||
int i = 0;
|
||||
|
||||
get_char_colors(d->character);
|
||||
clear_screen(d);
|
||||
write_to_output(d, "Forage table:\r\n");
|
||||
|
||||
for (entry = OLC_ROOM(d)->forage; entry; entry = entry->next) {
|
||||
obj_rnum rnum = real_object(entry->obj_vnum);
|
||||
const char *sdesc = (rnum != NOTHING) ? obj_proto[rnum].short_description : "Unknown object";
|
||||
write_to_output(d, "%s%2d%s) [%s%d%s] DC %s%d%s - %s%s%s\r\n",
|
||||
grn, ++i, nrm,
|
||||
cyn, entry->obj_vnum, nrm,
|
||||
yel, entry->dc, nrm,
|
||||
yel, sdesc, nrm);
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
write_to_output(d, " None.\r\n");
|
||||
|
||||
write_to_output(d,
|
||||
"\r\n%sA%s) Add item\r\n"
|
||||
"%sD%s) Delete item\r\n"
|
||||
"%sQ%s) Quit\r\n"
|
||||
"Enter choice : ",
|
||||
grn, nrm, grn, nrm, grn, nrm);
|
||||
OLC_MODE(d) = REDIT_FORAGE_MENU;
|
||||
}
|
||||
|
||||
/* The main menu. */
|
||||
static void redit_disp_menu(struct descriptor_data *d)
|
||||
{
|
||||
char buf1[MAX_STRING_LENGTH];
|
||||
char buf2[MAX_STRING_LENGTH];
|
||||
struct room_data *room;
|
||||
int forage_count;
|
||||
|
||||
get_char_colors(d->character);
|
||||
clear_screen(d);
|
||||
room = OLC_ROOM(d);
|
||||
forage_count = redit_forage_count(room->forage);
|
||||
|
||||
sprintbitarray(room->room_flags, room_bits, RF_ARRAY_MAX, buf1);
|
||||
sprinttype(room->sector_type, sector_types, buf2, sizeof(buf2));
|
||||
|
|
@ -493,6 +538,7 @@ static void redit_disp_menu(struct descriptor_data *d)
|
|||
"%s9%s) Exit up : %s%d\r\n"
|
||||
"%sA%s) Exit down : %s%d\r\n"
|
||||
"%sF%s) Extra descriptions menu\r\n"
|
||||
"%sG%s) Forage table: %s%d%s entries\r\n"
|
||||
"%sS%s) Script : %s%s\r\n"
|
||||
"%sW%s) Copy Room\r\n"
|
||||
"%sX%s) Delete Room\r\n"
|
||||
|
|
@ -505,6 +551,7 @@ static void redit_disp_menu(struct descriptor_data *d)
|
|||
room->dir_option[DOWN] && room->dir_option[DOWN]->to_room != NOWHERE ?
|
||||
world[room->dir_option[DOWN]->to_room].number : -1,
|
||||
grn, nrm,
|
||||
grn, nrm, cyn, forage_count, nrm,
|
||||
grn, nrm, cyn, OLC_SCRIPT(d) ? "Set." : "Not Set.",
|
||||
grn, nrm,
|
||||
grn, nrm,
|
||||
|
|
@ -655,6 +702,10 @@ void redit_parse(struct descriptor_data *d, char *arg)
|
|||
OLC_DESC(d) = OLC_ROOM(d)->ex_description;
|
||||
redit_disp_extradesc_menu(d);
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
redit_disp_forage_menu(d);
|
||||
break;
|
||||
case 'w':
|
||||
case 'W':
|
||||
write_to_output(d, "Copy what room? ");
|
||||
|
|
@ -727,6 +778,91 @@ void redit_parse(struct descriptor_data *d, char *arg)
|
|||
OLC_ROOM(d)->sector_type = number;
|
||||
break;
|
||||
|
||||
case REDIT_FORAGE_MENU:
|
||||
switch (LOWER(*arg)) {
|
||||
case 'a':
|
||||
write_to_output(d, "Enter object vnum and DC: ");
|
||||
OLC_MODE(d) = REDIT_FORAGE_ADD;
|
||||
return;
|
||||
case 'd':
|
||||
if (!OLC_ROOM(d)->forage) {
|
||||
write_to_output(d, "No forage entries to delete.\r\n");
|
||||
redit_disp_forage_menu(d);
|
||||
} else {
|
||||
write_to_output(d, "Delete which entry (number)? ");
|
||||
OLC_MODE(d) = REDIT_FORAGE_DELETE;
|
||||
}
|
||||
return;
|
||||
case 'q':
|
||||
redit_disp_menu(d);
|
||||
return;
|
||||
default:
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
|
||||
case REDIT_FORAGE_ADD: {
|
||||
int vnum, dc;
|
||||
struct forage_entry *entry;
|
||||
|
||||
if (sscanf(arg, "%d %d", &vnum, &dc) != 2) {
|
||||
write_to_output(d, "Usage: <vnum> <dc>\r\n");
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
if (vnum <= 0 || dc <= 0) {
|
||||
write_to_output(d, "Both vnum and DC must be positive.\r\n");
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
if (real_object(vnum) == NOTHING) {
|
||||
write_to_output(d, "That object vnum doesn't exist.\r\n");
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
|
||||
CREATE(entry, struct forage_entry, 1);
|
||||
entry->obj_vnum = vnum;
|
||||
entry->dc = dc;
|
||||
entry->next = OLC_ROOM(d)->forage;
|
||||
OLC_ROOM(d)->forage = entry;
|
||||
OLC_VAL(d) = 1;
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
|
||||
case REDIT_FORAGE_DELETE: {
|
||||
struct forage_entry *entry = OLC_ROOM(d)->forage;
|
||||
struct forage_entry *prev = NULL;
|
||||
int count = 0;
|
||||
|
||||
number = atoi(arg);
|
||||
if (number <= 0) {
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
|
||||
while (entry && ++count < number) {
|
||||
prev = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
write_to_output(d, "Invalid entry number.\r\n");
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
prev->next = entry->next;
|
||||
else
|
||||
OLC_ROOM(d)->forage = entry->next;
|
||||
free(entry);
|
||||
OLC_VAL(d) = 1;
|
||||
redit_disp_forage_menu(d);
|
||||
return;
|
||||
}
|
||||
|
||||
case REDIT_EXIT_MENU:
|
||||
switch (*arg) {
|
||||
case '0':
|
||||
|
|
|
|||
|
|
@ -816,6 +816,8 @@ struct room_direction_data
|
|||
room_rnum to_room; /**< Where direction leads, or NOWHERE if not defined */
|
||||
};
|
||||
|
||||
struct forage_entry;
|
||||
|
||||
/** The Room Structure. */
|
||||
struct room_data
|
||||
{
|
||||
|
|
@ -834,6 +836,7 @@ struct room_data
|
|||
struct obj_data *contents; /**< List of items in room */
|
||||
struct char_data *people; /**< List of NPCs / PCs in room */
|
||||
|
||||
struct forage_entry *forage; /**< Forage table entries for this room */
|
||||
struct list_data * events;
|
||||
};
|
||||
|
||||
|
|
@ -1350,6 +1353,13 @@ struct skin_yield_entry {
|
|||
struct skin_yield_entry *next;
|
||||
};
|
||||
|
||||
/* Forage table entries attached to rooms */
|
||||
struct forage_entry {
|
||||
obj_vnum obj_vnum; /* object to create on success */
|
||||
int dc; /* DC required */
|
||||
struct forage_entry *next;
|
||||
};
|
||||
|
||||
/* Config structs */
|
||||
|
||||
/** The game configuration structure used for configurating the game play
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue