diff --git a/common/living.c b/common/living.c index 3928030..884c4b1 100644 --- a/common/living.c +++ b/common/living.c @@ -936,6 +936,7 @@ void fix_object(object *op) { free_string(op->slaying); op->slaying=NULL; } + if (!QUERY_FLAG(op,FLAG_WIZ)) { CLEAR_FLAG(op, FLAG_XRAYS); CLEAR_FLAG(op, FLAG_MAKE_INVIS); @@ -973,6 +974,16 @@ void fix_object(object *op) { potion_resist[i]=0; } + + /* initialize slaying to whatever is defined in the arch + * this would really only make a difference for archetypes that + * have an intrisic slaying type, such as a player race. classes + * must be handled with FORCE objects instead. + */ + if (op->arch->clone.slaying != NULL) { + op->slaying = add_refcount(op->arch->clone.slaying); + } + wc=op->arch->clone.stats.wc; op->stats.dam=op->arch->clone.stats.dam; @@ -1173,8 +1184,9 @@ void fix_object(object *op) { if (tmp->slaying!=NULL) { if (op->slaying != NULL) - free_string(op->slaying); - add_refcount(op->slaying = tmp->slaying); + op->slaying = join_strings(op->slaying, tmp->slaying, ","); + else + add_refcount(op->slaying = tmp->slaying); } if (tmp->stats.ac) @@ -1224,8 +1236,9 @@ void fix_object(object *op) { weapon_speed=0; if (tmp->slaying!=NULL) { if (op->slaying != NULL) - free_string(op->slaying); - add_refcount(op->slaying = tmp->slaying); + op->slaying = join_strings(op->slaying, tmp->slaying, ","); + else + add_refcount(op->slaying = tmp->slaying); } /* If there is desire that two handed weapons should do * extra strength damage, this is where the code should @@ -1264,6 +1277,12 @@ void fix_object(object *op) { ac-=(tmp->stats.ac+tmp->magic); if (ARMOUR_SPEED(tmp) && ARMOUR_SPEED(tmp)/10.0slaying!=NULL) { + if (op->slaying != NULL) + op->slaying = join_strings(op->slaying, tmp->slaying, ","); + else + add_refcount(op->slaying = tmp->slaying); + } break; } /* switch tmp->type */ } /* item is equipped */ diff --git a/common/shstr.c b/common/shstr.c index 4e8bf60..72687f1 100644 --- a/common/shstr.c +++ b/common/shstr.c @@ -192,6 +192,59 @@ sstring add_string(const char *str) { } } +/** + * This will join str2 to the end of str. It follows the same rules as add_string + * and free_string. + * + * @param target_str + * string to be appended to. + * @param source_str + * string to append with. + * @param separator + * separator to place between the joined strings. + * @return + * pointer to string to target_str+separator+source_str. + */ +sstring join_strings(sstring target_str, sstring source_str, const char *separator) { + size_t target_len, source_len, separator_len; + char *buf; + sstring ss; + + if (target_str != NULL) + target_len = strlen(target_str); + else + target_len = 0; + if (source_str != NULL) + source_len = strlen(source_str); + else + source_len = 0; + if (separator != NULL) + separator_len = strlen(separator); + else + separator_len = 0; + + /* create our buffer */ + buf = malloc( (target_len + source_len + separator_len + 1) * sizeof(char) ); + if (buf == NULL) + fatal(OUT_OF_MEMORY); + + /* copy our strings to buffer */ + buf[0] = '\0'; + buf = strcat(buf, target_str); + buf = strcat(buf, separator); + buf = strcat(buf, source_str); + + /* create shared string from buffer */ + ss = add_string(buf); + + /* free our buffer and our shared string references */ + free(buf); + free_string(target_str); + free_string(source_str); + + return ss; +} + /** * This will increase the refcount of the string str. * @param str diff --git a/include/libproto.h b/include/libproto.h index 3c2419c..72cdac3 100644 --- a/include/libproto.h +++ b/include/libproto.h @@ -318,6 +318,7 @@ extern region *get_region_struct(void); /* shstr.c */ extern void init_hash_table(void); extern sstring add_string(const char *str); +extern sstring join_strings(sstring target_str, sstring source_str, const char *separator); extern sstring add_refcount(sstring str); extern int query_refcount(sstring str); extern sstring find_string(const char *str); diff --git a/server/apply.c b/server/apply.c index 888aff8..f58c9dc 100644 --- a/server/apply.c +++ b/server/apply.c @@ -1827,6 +1827,13 @@ void apply_changes_to_player(object *pl, object *change) { if (change->randomitems != NULL) give_initial_items(pl, change->randomitems); + /* modify the player's slaying field */ + if (change->slaying != NULL) { + if (pl->slaying == NULL) + pl->slaying = add_refcount(change->slaying); + else + pl->slaying = join_strings(pl->slaying, change->slaying, ","); + } /* set up the face, for some races. */