mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-19 10:46:33 +01:00
Update to furniture items
This commit is contained in:
parent
c41e291770
commit
ccf81bc3a4
7 changed files with 199 additions and 56 deletions
|
|
@ -261,6 +261,6 @@ A long, wooden bar takes up most of the south side of the room.~
|
|||
It's a long wooden bar!
|
||||
~
|
||||
6 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
100 8 0 0
|
||||
8 0 0 0
|
||||
200 0 0 0 0
|
||||
$~
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ static void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mod
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
switch (mode) {
|
||||
case SHOW_OBJ_LONG:
|
||||
/* Hide objects starting with . from non-holylighted people. - Elaseth */
|
||||
|
|
@ -121,6 +122,34 @@ static void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mod
|
|||
if (GET_OBJ_MAIN(obj) && *GET_OBJ_MAIN(obj)) {
|
||||
/* Use the pager so multi-line M-Descs display nicely. */
|
||||
page_string(ch->desc, GET_OBJ_MAIN(obj), TRUE);
|
||||
|
||||
/* For furniture, also show items on it after the main description */
|
||||
if (GET_OBJ_TYPE(obj) == ITEM_FURNITURE) {
|
||||
/* Show seat availability */
|
||||
if (GET_OBJ_VAL(obj, 0) > 0) {
|
||||
int current_occupants = GET_OBJ_VAL(obj, 1);
|
||||
int max_occupants = GET_OBJ_VAL(obj, 0);
|
||||
int available_seats = max_occupants - current_occupants;
|
||||
|
||||
if (available_seats > 0) {
|
||||
send_to_char(ch, "\r\n%s(%d seat%s available)%s",
|
||||
CCYEL(ch, C_NRM), available_seats,
|
||||
available_seats == 1 ? "" : "s",
|
||||
CCNRM(ch, C_NRM));
|
||||
} else {
|
||||
send_to_char(ch, "\r\n%s(no seats available)%s",
|
||||
CCRED(ch, C_NRM), CCNRM(ch, C_NRM));
|
||||
}
|
||||
}
|
||||
|
||||
/* Show items on furniture */
|
||||
if (obj->contains) {
|
||||
send_to_char(ch, "\r\nOn %s you see:\r\n", obj->short_description);
|
||||
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
|
||||
} else {
|
||||
send_to_char(ch, "\r\nYou see nothing on %s.", obj->short_description);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +169,33 @@ static void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mod
|
|||
send_to_char(ch, "It looks like a drink container.");
|
||||
break;
|
||||
|
||||
case ITEM_FURNITURE:
|
||||
/* Show seat availability */
|
||||
if (GET_OBJ_VAL(obj, 0) > 0) {
|
||||
int current_occupants = GET_OBJ_VAL(obj, 1);
|
||||
int max_occupants = GET_OBJ_VAL(obj, 0);
|
||||
int available_seats = max_occupants - current_occupants;
|
||||
|
||||
if (available_seats > 0) {
|
||||
send_to_char(ch, "%s(%d seat%s available)%s ",
|
||||
CCYEL(ch, C_NRM), available_seats,
|
||||
available_seats == 1 ? "" : "s",
|
||||
CCNRM(ch, C_NRM));
|
||||
} else {
|
||||
send_to_char(ch, "%s(no seats available)%s ",
|
||||
CCRED(ch, C_NRM), CCNRM(ch, C_NRM));
|
||||
}
|
||||
}
|
||||
|
||||
/* Show items on furniture */
|
||||
if (obj->contains) {
|
||||
send_to_char(ch, "On %s you see:\r\n", obj->short_description);
|
||||
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
|
||||
} else {
|
||||
send_to_char(ch, "You see nothing on %s.", obj->short_description);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Optional: friendlier fallback that names the item. */
|
||||
if (obj->short_description && *obj->short_description)
|
||||
|
|
|
|||
141
src/act.item.c
141
src/act.item.c
|
|
@ -81,12 +81,37 @@ static void perform_put(struct char_data *ch, struct obj_data *obj, struct obj_d
|
|||
}
|
||||
}
|
||||
|
||||
/* Put an item on furniture (like a table, bar, etc.) */
|
||||
static void perform_put_on_furniture(struct char_data *ch, struct obj_data *obj, struct obj_data *furniture)
|
||||
{
|
||||
long object_id = obj_script_id(obj);
|
||||
|
||||
if (!drop_otrigger(obj, ch))
|
||||
return;
|
||||
|
||||
if (!has_obj_by_uid_in_lookup_table(object_id)) /* object might be extracted by drop_otrigger */
|
||||
return;
|
||||
|
||||
if (OBJ_FLAGGED(obj, ITEM_NODROP) && IN_ROOM(furniture) != NOWHERE)
|
||||
act("You can't get $p out of your hand.", FALSE, ch, obj, NULL, TO_CHAR);
|
||||
else {
|
||||
obj_from_char(obj);
|
||||
obj_to_obj(obj, furniture);
|
||||
|
||||
act("$n puts $p on $P.", TRUE, ch, obj, furniture, TO_ROOM);
|
||||
act("You put $p on $P.", FALSE, ch, obj, furniture, TO_CHAR);
|
||||
}
|
||||
}
|
||||
|
||||
/* The following put modes are supported:
|
||||
1) put <object> <container>
|
||||
2) put all.<object> <container>
|
||||
3) put all <container>
|
||||
The <container> must be in inventory, worn/equipped, or on ground. All objects to be put
|
||||
into container must be in inventory. */
|
||||
4) put <object> on <furniture>
|
||||
5) put all.<object> on <furniture>
|
||||
6) put all on <furniture>
|
||||
The <container> or <furniture> must be in inventory, worn/equipped, or on ground.
|
||||
All objects to be put into container or on furniture must be in inventory. */
|
||||
ACMD(do_put)
|
||||
{
|
||||
char arg1[MAX_INPUT_LENGTH];
|
||||
|
|
@ -120,42 +145,74 @@ ACMD(do_put)
|
|||
generic_find(thecont, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP, ch, &tmp_char, &cont);
|
||||
if (!cont)
|
||||
send_to_char(ch, "You don't see %s %s here.\r\n", AN(thecont), thecont);
|
||||
else if (GET_OBJ_TYPE(cont) != ITEM_CONTAINER)
|
||||
act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
else if (OBJVAL_FLAGGED(cont, CONT_CLOSED) && (GET_LEVEL(ch) < LVL_IMMORT || !PRF_FLAGGED(ch, PRF_NOHASSLE)))
|
||||
send_to_char(ch, "You'd better open it first!\r\n");
|
||||
else {
|
||||
if (obj_dotmode == FIND_INDIV) { /* put <obj> <container> */
|
||||
if (!(obj = get_obj_in_list_vis(ch, theobj, NULL, ch->carrying)))
|
||||
send_to_char(ch, "You aren't carrying %s %s.\r\n", AN(theobj), theobj);
|
||||
else if (obj == cont && howmany == 1)
|
||||
send_to_char(ch, "You attempt to fold it into itself, but fail.\r\n");
|
||||
else {
|
||||
while (obj && howmany) {
|
||||
next_obj = obj->next_content;
|
||||
else if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER) {
|
||||
/* Handle container logic */
|
||||
if (OBJVAL_FLAGGED(cont, CONT_CLOSED) && (GET_LEVEL(ch) < LVL_IMMORT || !PRF_FLAGGED(ch, PRF_NOHASSLE)))
|
||||
send_to_char(ch, "You'd better open it first!\r\n");
|
||||
else {
|
||||
if (obj_dotmode == FIND_INDIV) { /* put <obj> <container> */
|
||||
if (!(obj = get_obj_in_list_vis(ch, theobj, NULL, ch->carrying)))
|
||||
send_to_char(ch, "You aren't carrying %s %s.\r\n", AN(theobj), theobj);
|
||||
else if (obj == cont && howmany == 1)
|
||||
send_to_char(ch, "You attempt to fold it into itself, but fail.\r\n");
|
||||
else {
|
||||
while (obj && howmany) {
|
||||
next_obj = obj->next_content;
|
||||
if (obj != cont) {
|
||||
howmany--;
|
||||
perform_put(ch, obj, cont);
|
||||
}
|
||||
obj = get_obj_in_list_vis(ch, theobj, NULL, next_obj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (obj = ch->carrying; obj; obj = next_obj) {
|
||||
next_obj = obj->next_content;
|
||||
if (obj != cont && CAN_SEE_OBJ(ch, obj) &&
|
||||
(obj_dotmode == FIND_ALL || isname(theobj, obj->name))) {
|
||||
found = 1;
|
||||
perform_put(ch, obj, cont);
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
send_to_char(ch, "You don't seem to have %s %s.\r\n",
|
||||
obj_dotmode == FIND_ALL ? "any" : "any",
|
||||
obj_dotmode == FIND_ALL ? "items" : theobj);
|
||||
}
|
||||
}
|
||||
} else if (GET_OBJ_TYPE(cont) == ITEM_FURNITURE) {
|
||||
/* Handle furniture logic - put items ON furniture */
|
||||
if (obj_dotmode == FIND_INDIV) { /* put <obj> on <furniture> */
|
||||
if (!(obj = get_obj_in_list_vis(ch, theobj, NULL, ch->carrying)))
|
||||
send_to_char(ch, "You aren't carrying %s %s.\r\n", AN(theobj), theobj);
|
||||
else if (obj == cont && howmany == 1)
|
||||
send_to_char(ch, "You can't put something on itself.\r\n");
|
||||
else {
|
||||
while (obj && howmany) {
|
||||
next_obj = obj->next_content;
|
||||
if (obj != cont) {
|
||||
howmany--;
|
||||
perform_put(ch, obj, cont);
|
||||
perform_put_on_furniture(ch, obj, cont);
|
||||
}
|
||||
obj = get_obj_in_list_vis(ch, theobj, NULL, next_obj);
|
||||
}
|
||||
}
|
||||
obj = get_obj_in_list_vis(ch, theobj, NULL, next_obj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (obj = ch->carrying; obj; obj = next_obj) {
|
||||
next_obj = obj->next_content;
|
||||
if (obj != cont && CAN_SEE_OBJ(ch, obj) &&
|
||||
(obj_dotmode == FIND_ALL || isname(theobj, obj->name))) {
|
||||
found = 1;
|
||||
perform_put(ch, obj, cont);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (obj_dotmode == FIND_ALL)
|
||||
send_to_char(ch, "You don't seem to have anything to put in it.\r\n");
|
||||
else
|
||||
send_to_char(ch, "You don't seem to have any %ss.\r\n", theobj);
|
||||
}
|
||||
for (obj = ch->carrying; obj; obj = next_obj) {
|
||||
next_obj = obj->next_content;
|
||||
if (obj != cont && CAN_SEE_OBJ(ch, obj) &&
|
||||
(obj_dotmode == FIND_ALL || isname(theobj, obj->name))) {
|
||||
found = 1;
|
||||
perform_put_on_furniture(ch, obj, cont);
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
send_to_char(ch, "You don't seem to have %s %s.\r\n",
|
||||
obj_dotmode == FIND_ALL ? "any" : "any",
|
||||
obj_dotmode == FIND_ALL ? "items" : theobj);
|
||||
}
|
||||
} else {
|
||||
act("$p is not a container or furniture.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -356,8 +413,8 @@ ACMD(do_get)
|
|||
mode = generic_find(arg2, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP, ch, &tmp_char, &cont);
|
||||
if (!cont)
|
||||
send_to_char(ch, "You don't have %s %s.\r\n", AN(arg2), arg2);
|
||||
else if (GET_OBJ_TYPE(cont) != ITEM_CONTAINER)
|
||||
act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
else if (GET_OBJ_TYPE(cont) != ITEM_CONTAINER && GET_OBJ_TYPE(cont) != ITEM_FURNITURE)
|
||||
act("$p is not a container or furniture.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
else
|
||||
get_from_container(ch, cont, arg1, mode, amount);
|
||||
} else {
|
||||
|
|
@ -367,12 +424,12 @@ ACMD(do_get)
|
|||
}
|
||||
for (cont = ch->carrying; cont; cont = cont->next_content)
|
||||
if (CAN_SEE_OBJ(ch, cont) && (cont_dotmode == FIND_ALL || isname(arg2, cont->name))) {
|
||||
if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER) {
|
||||
if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER || GET_OBJ_TYPE(cont) == ITEM_FURNITURE) {
|
||||
found = 1;
|
||||
get_from_container(ch, cont, arg1, FIND_OBJ_INV, amount);
|
||||
} else if (cont_dotmode == FIND_ALLDOT) {
|
||||
found = 1;
|
||||
act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
act("$p is not a container or furniture.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
}
|
||||
}
|
||||
{
|
||||
|
|
@ -385,12 +442,12 @@ ACMD(do_get)
|
|||
|
||||
if (CAN_SEE_OBJ(ch, eq) &&
|
||||
(cont_dotmode == FIND_ALL || isname(arg2, eq->name))) {
|
||||
if (GET_OBJ_TYPE(eq) == ITEM_CONTAINER) {
|
||||
if (GET_OBJ_TYPE(eq) == ITEM_CONTAINER || GET_OBJ_TYPE(eq) == ITEM_FURNITURE) {
|
||||
found = 1;
|
||||
get_from_container(ch, eq, arg1, FIND_OBJ_EQUIP, amount);
|
||||
} else if (cont_dotmode == FIND_ALLDOT) {
|
||||
found = 1;
|
||||
act("$p is not a container.", FALSE, ch, eq, 0, TO_CHAR);
|
||||
act("$p is not a container or furniture.", FALSE, ch, eq, 0, TO_CHAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -398,17 +455,17 @@ ACMD(do_get)
|
|||
for (cont = world[IN_ROOM(ch)].contents; cont; cont = cont->next_content)
|
||||
if (CAN_SEE_OBJ(ch, cont) &&
|
||||
(cont_dotmode == FIND_ALL || isname(arg2, cont->name))) {
|
||||
if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER) {
|
||||
if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER || GET_OBJ_TYPE(cont) == ITEM_FURNITURE) {
|
||||
get_from_container(ch, cont, arg1, FIND_OBJ_ROOM, amount);
|
||||
found = 1;
|
||||
} else if (cont_dotmode == FIND_ALLDOT) {
|
||||
act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
act("$p is not a container or furniture.", FALSE, ch, cont, 0, TO_CHAR);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (cont_dotmode == FIND_ALL)
|
||||
send_to_char(ch, "You can't seem to find any containers.\r\n");
|
||||
send_to_char(ch, "You can't seem to find any containers or furniture.\r\n");
|
||||
else
|
||||
send_to_char(ch, "You can't seem to find any %ss here.\r\n", arg2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -803,6 +803,13 @@ ACMD(do_sit)
|
|||
act("There is no where left to sit upon $p.", TRUE, ch, furniture, 0, TO_CHAR);
|
||||
return;
|
||||
} else {
|
||||
/* Check if furniture allows sitting position */
|
||||
int allowed_positions = GET_OBJ_VAL(furniture, 2); /* VAL_FURN_POSITIONS */
|
||||
if (allowed_positions > 0 && !(allowed_positions & (1 << 1))) { /* Check SIT bit (bit 1) */
|
||||
act("$p doesn't look comfortable for sitting.", TRUE, ch, furniture, 0, TO_CHAR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (OBJ_SAT_IN_BY(furniture) == NULL)
|
||||
OBJ_SAT_IN_BY(furniture) = ch;
|
||||
for (tempch = OBJ_SAT_IN_BY(furniture); tempch != ch ; tempch = NEXT_SITTING(tempch)) {
|
||||
|
|
@ -850,6 +857,14 @@ ACMD(do_rest)
|
|||
GET_POS(ch) = POS_RESTING;
|
||||
break;
|
||||
case POS_SITTING:
|
||||
/* Check if sitting on furniture that allows resting */
|
||||
if (SITTING(ch) && GET_OBJ_TYPE(SITTING(ch)) == ITEM_FURNITURE) {
|
||||
int allowed_positions = GET_OBJ_VAL(SITTING(ch), 2); /* VAL_FURN_POSITIONS */
|
||||
if (allowed_positions > 0 && !(allowed_positions & (1 << 2))) { /* Check REST bit (bit 2) */
|
||||
act("$p doesn't look comfortable for resting.", TRUE, ch, SITTING(ch), 0, TO_CHAR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
send_to_char(ch, "You rest your tired bones.\r\n");
|
||||
act("$n rests.", TRUE, ch, 0, 0, TO_ROOM);
|
||||
GET_POS(ch) = POS_RESTING;
|
||||
|
|
@ -877,6 +892,14 @@ ACMD(do_sleep)
|
|||
case POS_STANDING:
|
||||
case POS_SITTING:
|
||||
case POS_RESTING:
|
||||
/* Check if sitting/resting on furniture that allows sleeping */
|
||||
if (SITTING(ch) && GET_OBJ_TYPE(SITTING(ch)) == ITEM_FURNITURE) {
|
||||
int allowed_positions = GET_OBJ_VAL(SITTING(ch), 2); /* VAL_FURN_POSITIONS */
|
||||
if (allowed_positions > 0 && !(allowed_positions & (1 << 3))) { /* Check SLEEP bit (bit 3) */
|
||||
act("$p doesn't look comfortable for sleeping.", TRUE, ch, SITTING(ch), 0, TO_CHAR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
send_to_char(ch, "You go to sleep.\r\n");
|
||||
act("$n lies down and falls asleep.", TRUE, ch, 0, 0, TO_ROOM);
|
||||
GET_POS(ch) = POS_SLEEPING;
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ const char *furniture_position_bits[] = {
|
|||
"SIT", /* can sit on it */
|
||||
"REST", /* can rest on it */
|
||||
"SLEEP", /* can sleep on it */
|
||||
"KNEEL", /* can kneel at/on it */
|
||||
"\n"
|
||||
};
|
||||
|
||||
|
|
|
|||
21
src/oedit.c
21
src/oedit.c
|
|
@ -102,8 +102,8 @@ static const char *money_val_labels[NUM_OBJ_VAL_POSITIONS] = {
|
|||
|
||||
/* Furniture */
|
||||
static const char *furniture_val_labels[NUM_OBJ_VAL_POSITIONS] = {
|
||||
"capacity", "max_people", "allowed_pos", "furn_flags",
|
||||
"comfy_bonus", "climb_dc", "script_hook", "reserved"
|
||||
"max_seats", "current_occupants", "allowed_pos", "Value[3]",
|
||||
"Value[4]", "Value[5]", "Value[6]", "Value[7]"
|
||||
};
|
||||
|
||||
/* Generic fallback */
|
||||
|
|
@ -525,8 +525,14 @@ static void oedit_disp_values_menu(struct descriptor_data *d)
|
|||
write_to_output(d, "\r\n-- Object Values Menu --\r\n");
|
||||
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) {
|
||||
write_to_output(d, "%2d) %-12s : %d\r\n",
|
||||
i+1, labels[i], GET_OBJ_VAL(obj, i));
|
||||
/* Hide current_occupants field for furniture - it's managed by the game engine */
|
||||
if (GET_OBJ_TYPE(obj) == ITEM_FURNITURE && i == 1) {
|
||||
write_to_output(d, "%2d) %-12s : %d (managed by game engine)\r\n",
|
||||
i+1, labels[i], GET_OBJ_VAL(obj, i));
|
||||
} else {
|
||||
write_to_output(d, "%2d) %-12s : %d\r\n",
|
||||
i+1, labels[i], GET_OBJ_VAL(obj, i));
|
||||
}
|
||||
}
|
||||
|
||||
write_to_output(d, "Q) Quit to main menu\r\nEnter choice : ");
|
||||
|
|
@ -1008,6 +1014,13 @@ void oedit_parse(struct descriptor_data *d, char *arg)
|
|||
} else {
|
||||
int i = atoi(arg) - 1;
|
||||
if (i >= 0 && i < NUM_OBJ_VAL_POSITIONS) {
|
||||
/* Prevent editing current_occupants for furniture - it's managed by the game engine */
|
||||
if (GET_OBJ_TYPE(OLC_OBJ(d)) == ITEM_FURNITURE && i == 1) {
|
||||
write_to_output(d, "The current_occupants field is managed by the game engine and cannot be edited manually.\r\n");
|
||||
oedit_disp_values_menu(d);
|
||||
return;
|
||||
}
|
||||
|
||||
OLC_VAL_SLOT(d) = i;
|
||||
const char **labels = get_val_labels(OLC_OBJ(d));
|
||||
|
||||
|
|
|
|||
|
|
@ -1336,14 +1336,9 @@ struct mob_loadout *loadout_deep_copy(const struct mob_loadout *src);
|
|||
|
||||
/* Furniture defines for object values */
|
||||
/* Furniture object values (obj_flags.value[x]) */
|
||||
#define VAL_FURN_CAPACITY 0 /* how much it can hold / support */
|
||||
#define VAL_FURN_MAX_OCC 1 /* max occupants */
|
||||
#define VAL_FURN_POSITIONS 2 /* allowed positions (bitvector) */
|
||||
#define VAL_FURN_FLAGS 3 /* behavior flags (bitvector) */
|
||||
#define VAL_FURN_COMFORT 4 /* comfort/healing bonus */
|
||||
#define VAL_FURN_ENTRY_DC 5 /* difficulty to climb onto */
|
||||
#define VAL_FURN_SCRIPT 6 /* script hook */
|
||||
#define VAL_FURN_RESERVED 7 /* reserved */
|
||||
#define VAL_FURN_CAPACITY 0 /* maximum number of people who can use furniture */
|
||||
#define VAL_FURN_MAX_OCC 1 /* current number of people using furniture (runtime only, managed by game engine) */
|
||||
#define VAL_FURN_POSITIONS 2 /* allowed positions bitvector: bit 0=STAND(1), bit 1=SIT(2), bit 2=REST(4), bit 3=SLEEP(8) */
|
||||
|
||||
/* Config structs */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue