mirror of
https://github.com/tbamud/tbamud.git
synced 2026-04-06 04:17:20 +02:00
Update shield use skill, add durability to armor, update oedit, and increase object values
This commit is contained in:
parent
e40f236867
commit
2159ca06f0
7 changed files with 247 additions and 345 deletions
|
|
@ -1023,8 +1023,6 @@ static void do_stat_object(struct char_data *ch, struct obj_data *j)
|
|||
send_to_char(ch, "In room: %d (%s), ", GET_ROOM_VNUM(IN_ROOM(j)),
|
||||
IN_ROOM(j) == NOWHERE ? "Nowhere" : world[IN_ROOM(j)].name);
|
||||
|
||||
/* In order to make it this far, we must already be able to see the character
|
||||
* holding the object. Therefore, we do not need CAN_SEE(). */
|
||||
send_to_char(ch, "In object: %s, ", j->in_obj ? j->in_obj->short_description : "None");
|
||||
send_to_char(ch, "Carried by: %s, ", j->carried_by ? GET_NAME(j->carried_by) : "Nobody");
|
||||
send_to_char(ch, "Worn by: %s\r\n", j->worn_by ? GET_NAME(j->worn_by) : "Nobody");
|
||||
|
|
@ -1050,7 +1048,9 @@ static void do_stat_object(struct char_data *ch, struct obj_data *j)
|
|||
break;
|
||||
case ITEM_WEAPON:
|
||||
send_to_char(ch, "Todam: %dd%d, Avg Damage: %.1f. Message type: %s\r\n",
|
||||
GET_OBJ_VAL(j, 1), GET_OBJ_VAL(j, 2), ((GET_OBJ_VAL(j, 2) + 1) / 2.0) * GET_OBJ_VAL(j, 1), attack_hit_text[GET_OBJ_VAL(j, 3)].singular);
|
||||
GET_OBJ_VAL(j, 1), GET_OBJ_VAL(j, 2),
|
||||
((GET_OBJ_VAL(j, 2) + 1) / 2.0) * GET_OBJ_VAL(j, 1),
|
||||
attack_hit_text[GET_OBJ_VAL(j, 3)].singular);
|
||||
break;
|
||||
case ITEM_ARMOR:
|
||||
send_to_char(ch, "AC-apply: [%d]\r\n", GET_OBJ_VAL(j, 0));
|
||||
|
|
@ -1065,7 +1065,8 @@ static void do_stat_object(struct char_data *ch, struct obj_data *j)
|
|||
case ITEM_FOUNTAIN:
|
||||
sprinttype(GET_OBJ_VAL(j, 2), drinks, buf, sizeof(buf));
|
||||
send_to_char(ch, "Capacity: %d, Contains: %d, Poisoned: %s, Liquid: %s\r\n",
|
||||
GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1), YESNO(GET_OBJ_VAL(j, 3)), buf);
|
||||
GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1),
|
||||
YESNO(GET_OBJ_VAL(j, 3)), buf);
|
||||
break;
|
||||
case ITEM_NOTE:
|
||||
send_to_char(ch, "Tongue: %d\r\n", GET_OBJ_VAL(j, 0));
|
||||
|
|
@ -1073,30 +1074,35 @@ static void do_stat_object(struct char_data *ch, struct obj_data *j)
|
|||
case ITEM_KEY: /* Nothing */
|
||||
break;
|
||||
case ITEM_FOOD:
|
||||
send_to_char(ch, "Makes full: %d, Poisoned: %s\r\n", GET_OBJ_VAL(j, 0), YESNO(GET_OBJ_VAL(j, 3)));
|
||||
send_to_char(ch, "Makes full: %d, Poisoned: %s\r\n",
|
||||
GET_OBJ_VAL(j, 0), YESNO(GET_OBJ_VAL(j, 3)));
|
||||
break;
|
||||
case ITEM_MONEY:
|
||||
send_to_char(ch, "Coins: %d\r\n", GET_OBJ_VAL(j, 0));
|
||||
break;
|
||||
case ITEM_FURNITURE:
|
||||
send_to_char(ch, "Can hold: [%d] Num. of People in: [%d]\r\n", GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1));
|
||||
send_to_char(ch, "Can hold: [%d] Num. of People in: [%d]\r\n",
|
||||
GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1));
|
||||
send_to_char(ch, "Holding : ");
|
||||
for (tempch = OBJ_SAT_IN_BY(j); tempch; tempch = NEXT_SITTING(tempch))
|
||||
send_to_char(ch, "%s ", GET_NAME(tempch));
|
||||
send_to_char(ch, "\r\n");
|
||||
break;
|
||||
default:
|
||||
send_to_char(ch, "Values 0-3: [%d] [%d] [%d] [%d]\r\n",
|
||||
GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1),
|
||||
GET_OBJ_VAL(j, 2), GET_OBJ_VAL(j, 3));
|
||||
default: {
|
||||
send_to_char(ch, "Values:");
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) {
|
||||
send_to_char(ch, " [%d]", GET_OBJ_VAL(j, i));
|
||||
}
|
||||
send_to_char(ch, "\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j->contains) {
|
||||
int column;
|
||||
|
||||
send_to_char(ch, "\r\nContents:%s", CCGRN(ch, C_NRM));
|
||||
column = 9; /* ^^^ strlen ^^^ */
|
||||
column = 9;
|
||||
|
||||
for (found = 0, j2 = j->contains; j2; j2 = j2->next_content) {
|
||||
column += send_to_char(ch, "%s %s", found++ ? "," : "", j2->short_description);
|
||||
|
|
@ -1114,7 +1120,8 @@ static void do_stat_object(struct char_data *ch, struct obj_data *j)
|
|||
for (i = 0; i < MAX_OBJ_AFFECT; i++)
|
||||
if (j->affected[i].modifier) {
|
||||
sprinttype(j->affected[i].location, apply_types, buf, sizeof(buf));
|
||||
send_to_char(ch, "%s %+d to %s", found++ ? "," : "", j->affected[i].modifier, buf);
|
||||
send_to_char(ch, "%s %+d to %s",
|
||||
found++ ? "," : "", j->affected[i].modifier, buf);
|
||||
}
|
||||
if (!found)
|
||||
send_to_char(ch, " None");
|
||||
|
|
|
|||
47
src/fight.c
47
src/fight.c
|
|
@ -828,6 +828,7 @@ 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);
|
||||
struct obj_data *shield = GET_EQ(victim, WEAR_SHIELD);
|
||||
int w_type, d20, attack_mod = 0, target_ac, dam = 0;
|
||||
bool hit_success = FALSE;
|
||||
|
||||
|
|
@ -842,7 +843,7 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
|
|||
w_type = ch->mob_specials.attack_type + TYPE_HIT;
|
||||
else
|
||||
w_type = TYPE_HIT;
|
||||
} /* matches stock message mapping */ /* */
|
||||
} /* matches stock message mapping */
|
||||
|
||||
/* Roll d20 */
|
||||
d20 = rand_number(1, 20);
|
||||
|
|
@ -853,7 +854,7 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
|
|||
/* Skill family & proficiency */
|
||||
{
|
||||
int skillnum = weapon_family_skill_num(ch, wielded, w_type);
|
||||
const char *skillname = skill_name_for_gain(skillnum); /* maps to "unarmed", "piercing weapons", etc. */
|
||||
const char *skillname = skill_name_for_gain(skillnum);
|
||||
|
||||
/* proficiency from current % */
|
||||
attack_mod += GET_PROFICIENCY(GET_SKILL(ch, skillnum));
|
||||
|
|
@ -861,7 +862,7 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
|
|||
/* Weapon magic (cap +3) */
|
||||
if (wielded && GET_OBJ_TYPE(wielded) == ITEM_WEAPON) {
|
||||
int wmag = GET_OBJ_VAL(wielded, VAL_ARMOR_MAGIC_BONUS);
|
||||
if (wmag > MAX_WEAPON_MAGIC) wmag = MAX_WEAPON_MAGIC; /* was hard-coded 3 */
|
||||
if (wmag > MAX_WEAPON_MAGIC) wmag = MAX_WEAPON_MAGIC;
|
||||
attack_mod += wmag;
|
||||
}
|
||||
|
||||
|
|
@ -882,14 +883,49 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
|
|||
|
||||
/* Apply result */
|
||||
if (hit_success) {
|
||||
/* Roll damage up front (needed for shield durability) */
|
||||
dam = roll_damage(ch, victim, wielded, w_type);
|
||||
|
||||
/* --- SHIELD BLOCK CHECK ---
|
||||
* Only happens if an attack actually lands.
|
||||
*/
|
||||
if (shield) {
|
||||
int def_prof = GET_PROFICIENCY(GET_SKILL(victim, SKILL_SHIELD_USE));
|
||||
int block_chance = def_prof * 10; /* 0–60% total chance to block an attack */
|
||||
|
||||
if (block_chance > 0 && rand_number(1, 100) <= block_chance) {
|
||||
/* Block succeeded! */
|
||||
act("You block $N's attack with $p!", FALSE, victim, shield, ch, TO_CHAR);
|
||||
act("$n blocks your attack with $s $p!", FALSE, victim, shield, ch, TO_VICT);
|
||||
act("$n blocks $N's attack with $s $p!", TRUE, victim, shield, ch, TO_NOTVICT);
|
||||
|
||||
/* Durability reduction based on damage prevented */
|
||||
int *dur = &GET_OBJ_VAL(shield, 3);
|
||||
int loss = MAX(1, dam / 10); /* at least 1% per block */
|
||||
*dur -= loss;
|
||||
|
||||
if (*dur <= 0) {
|
||||
act("Your $p shatters into pieces!", FALSE, victim, shield, 0, TO_CHAR);
|
||||
act("$n's $p shatters into pieces!", TRUE, victim, shield, 0, TO_ROOM);
|
||||
extract_obj(shield);
|
||||
}
|
||||
|
||||
/* Train shield use skill on success */
|
||||
if (!IS_NPC(victim)) {
|
||||
gain_skill(victim, "shield use", TRUE);
|
||||
}
|
||||
|
||||
return; /* Attack nullified entirely */
|
||||
}
|
||||
}
|
||||
|
||||
/* No block: apply normal damage */
|
||||
damage(ch, victim, dam, w_type);
|
||||
} else {
|
||||
damage(ch, victim, 0, w_type); /* miss messaging */
|
||||
}
|
||||
|
||||
/* --- Skill gains ---
|
||||
You specified that both success and failure attempt a skill gain. */
|
||||
/* --- Skill gains --- */
|
||||
if (!IS_NPC(ch) && skillname) {
|
||||
gain_skill(ch, (char *)skillname, hit_success);
|
||||
}
|
||||
|
|
@ -908,7 +944,6 @@ void hit(struct char_data *ch, struct char_data *victim, int type)
|
|||
"\t1Attack:\tn d20=%d%s, mod=%+d \t1⇒\tn total=%d vs AC %d — %s\r\n",
|
||||
d20, crit, attack_mod, d20 + attack_mod, target_ac,
|
||||
hit_success ? "\t2HIT\tn" : "\t1MISS\tn");
|
||||
/* Optional: show the same line to the victim if they are a player */
|
||||
if (!IS_NPC(victim)) {
|
||||
send_to_char(victim,
|
||||
"\t1Defense:\tn %s rolled total=%d vs your AC %d — %s%s\r\n",
|
||||
|
|
|
|||
|
|
@ -196,9 +196,11 @@ extern const char *nrm, *grn, *cyn, *yel;
|
|||
#define OEDIT_EXTRADESC_DESCRIPTION 23
|
||||
#define OEDIT_EXTRADESC_MENU 24
|
||||
#define OEDIT_LEVEL 25
|
||||
#define OEDIT_PERM 26
|
||||
#define OEDIT_DELETE 27
|
||||
#define OEDIT_COPY 28
|
||||
#define OEDIT_PERM 26
|
||||
#define OEDIT_DELETE 27
|
||||
#define OEDIT_COPY 28
|
||||
#define OEDIT_VALUES_MENU 29
|
||||
#define OEDIT_VALUE_X 30
|
||||
|
||||
/* Submodes of REDIT connectedness. */
|
||||
#define REDIT_MAIN_MENU 1
|
||||
|
|
|
|||
349
src/objsave.c
349
src/objsave.c
|
|
@ -50,23 +50,22 @@ static int Crash_load_objs(struct char_data *ch);
|
|||
static int handle_obj(struct obj_data *obj, struct char_data *ch, int locate, struct obj_data **cont_rows);
|
||||
static int objsave_write_rentcode(FILE *fl, int rentcode, int cost_per_day, struct char_data *ch);
|
||||
|
||||
/* Writes one object record to FILE. Old name: Obj_to_store() */
|
||||
/* Writes one object record to FILE. Old name: Obj_to_store().
|
||||
* Updated to save all NUM_OBJ_VAL_POSITIONS values instead of only 4. */
|
||||
int objsave_save_obj_record(struct obj_data *obj, FILE *fp, int locate)
|
||||
{
|
||||
int counter2;
|
||||
struct extra_descr_data *ex_desc;
|
||||
int i;
|
||||
char buf1[MAX_STRING_LENGTH +1];
|
||||
struct obj_data *temp = NULL;
|
||||
|
||||
if (GET_OBJ_VNUM(obj) != NOTHING)
|
||||
temp=read_object(GET_OBJ_VNUM(obj), VIRTUAL);
|
||||
temp = read_object(GET_OBJ_VNUM(obj), VIRTUAL);
|
||||
else {
|
||||
temp = create_obj();
|
||||
temp->item_number = NOWHERE;
|
||||
}
|
||||
|
||||
if (obj->action_description) {
|
||||
|
||||
strcpy(buf1, obj->action_description);
|
||||
strip_cr(buf1);
|
||||
} else
|
||||
|
|
@ -75,87 +74,65 @@ int objsave_save_obj_record(struct obj_data *obj, FILE *fp, int locate)
|
|||
fprintf(fp, "#%d\n", GET_OBJ_VNUM(obj));
|
||||
if (locate)
|
||||
fprintf(fp, "Loc : %d\n", locate);
|
||||
if (GET_OBJ_VAL(obj, 0) != GET_OBJ_VAL(temp, 0) ||
|
||||
GET_OBJ_VAL(obj, 1) != GET_OBJ_VAL(temp, 1) ||
|
||||
GET_OBJ_VAL(obj, 2) != GET_OBJ_VAL(temp, 2) ||
|
||||
GET_OBJ_VAL(obj, 3) != GET_OBJ_VAL(temp, 3))
|
||||
fprintf(fp,
|
||||
"Vals: %d %d %d %d\n",
|
||||
GET_OBJ_VAL(obj, 0),
|
||||
GET_OBJ_VAL(obj, 1),
|
||||
GET_OBJ_VAL(obj, 2),
|
||||
GET_OBJ_VAL(obj, 3)
|
||||
);
|
||||
if (GET_OBJ_EXTRA(obj) != GET_OBJ_EXTRA(temp))
|
||||
fprintf(fp, "Flag: %d %d %d %d\n", GET_OBJ_EXTRA(obj)[0], GET_OBJ_EXTRA(obj)[1], GET_OBJ_EXTRA(obj)[2], GET_OBJ_EXTRA(obj)[3]);
|
||||
|
||||
#define TEST_OBJS(obj1, obj2, field) ((!obj1->field || !obj2->field || \
|
||||
strcmp(obj1->field, obj2->field)))
|
||||
#define TEST_OBJN(field) (obj->obj_flags.field != temp->obj_flags.field)
|
||||
|
||||
if (TEST_OBJS(obj, temp, name))
|
||||
fprintf(fp, "Name: %s\n", obj->name ? obj->name : "Undefined");
|
||||
if (TEST_OBJS(obj, temp, short_description))
|
||||
fprintf(fp, "Shrt: %s\n", obj->short_description ? obj->short_description : "Undefined");
|
||||
|
||||
/* These two could be a pain on the read... we'll see... */
|
||||
if (TEST_OBJS(obj, temp, description))
|
||||
fprintf(fp, "Desc: %s\n", obj->description ? obj->description : "Undefined");
|
||||
|
||||
/* Only even try to process this if an action desc exists */
|
||||
if (obj->action_description || temp->action_description)
|
||||
if (TEST_OBJS(obj, temp, action_description))
|
||||
fprintf(fp, "ADes:\n%s~\n", buf1);
|
||||
|
||||
if (TEST_OBJN(type_flag))
|
||||
fprintf(fp, "Type: %d\n", GET_OBJ_TYPE(obj));
|
||||
if (TEST_OBJN(weight))
|
||||
fprintf(fp, "Wght: %d\n", GET_OBJ_WEIGHT(obj));
|
||||
if (TEST_OBJN(cost))
|
||||
fprintf(fp, "Cost: %d\n", GET_OBJ_COST(obj));
|
||||
if (TEST_OBJN(cost_per_day))
|
||||
fprintf(fp, "Rent: %d\n", GET_OBJ_RENT(obj));
|
||||
if (TEST_OBJN(bitvector))
|
||||
fprintf(fp, "Perm: %d %d %d %d\n", GET_OBJ_AFFECT(obj)[0], GET_OBJ_AFFECT(obj)[1], GET_OBJ_AFFECT(obj)[2], GET_OBJ_AFFECT(obj)[3]);
|
||||
if (TEST_OBJN(wear_flags))
|
||||
fprintf(fp, "Wear: %d %d %d %d\n", GET_OBJ_WEAR(obj)[0], GET_OBJ_WEAR(obj)[1], GET_OBJ_WEAR(obj)[2], GET_OBJ_WEAR(obj)[3]);
|
||||
|
||||
/* Do we have affects? */
|
||||
for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++)
|
||||
if (obj->affected[counter2].modifier != temp->affected[counter2].modifier)
|
||||
fprintf(fp, "Aff : %d %d %d\n",
|
||||
counter2,
|
||||
obj->affected[counter2].location,
|
||||
obj->affected[counter2].modifier
|
||||
);
|
||||
|
||||
/* Do we have extra descriptions? */
|
||||
if (obj->ex_description || temp->ex_description) {
|
||||
/* To be reimplemented. Need to handle this case in loading as
|
||||
well */
|
||||
if ((obj->ex_description && temp->ex_description &&
|
||||
obj->ex_description != temp->ex_description) ||
|
||||
!obj->ex_description || !temp->ex_description) {
|
||||
for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) {
|
||||
/*. Sanity check to prevent nasty protection faults . */
|
||||
if (!*ex_desc->keyword || !*ex_desc->description) {
|
||||
continue;
|
||||
}
|
||||
strcpy(buf1, ex_desc->description);
|
||||
strip_cr(buf1);
|
||||
fprintf(fp, "EDes:\n"
|
||||
"%s~\n"
|
||||
"%s~\n",
|
||||
ex_desc->keyword,
|
||||
buf1
|
||||
);
|
||||
/* Save all object values */
|
||||
{
|
||||
bool diff = FALSE;
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) {
|
||||
if (GET_OBJ_VAL(obj, i) != GET_OBJ_VAL(temp, i)) {
|
||||
diff = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (diff) {
|
||||
fprintf(fp, "Vals:");
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++)
|
||||
fprintf(fp, " %d", GET_OBJ_VAL(obj, i));
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
if (GET_OBJ_EXTRA(obj) != GET_OBJ_EXTRA(temp))
|
||||
fprintf(fp, "Flag: %d %d %d %d\n",
|
||||
GET_OBJ_EXTRA(obj)[0], GET_OBJ_EXTRA(obj)[1],
|
||||
GET_OBJ_EXTRA(obj)[2], GET_OBJ_EXTRA(obj)[3]);
|
||||
|
||||
extract_obj(temp);
|
||||
if (obj->name && (!temp->name || strcmp(obj->name, temp->name)))
|
||||
fprintf(fp, "Name: %s\n", obj->name);
|
||||
if (obj->short_description && (!temp->short_description ||
|
||||
strcmp(obj->short_description, temp->short_description)))
|
||||
fprintf(fp, "Shrt: %s\n", obj->short_description);
|
||||
if (obj->description && (!temp->description ||
|
||||
strcmp(obj->description, temp->description)))
|
||||
fprintf(fp, "Desc: %s\n", obj->description);
|
||||
if (obj->action_description && (!temp->action_description ||
|
||||
strcmp(obj->action_description, temp->action_description)))
|
||||
fprintf(fp, "ADes:\n%s~\n", buf1);
|
||||
|
||||
if (GET_OBJ_TYPE(obj) != GET_OBJ_TYPE(temp))
|
||||
fprintf(fp, "Type: %d\n", GET_OBJ_TYPE(obj));
|
||||
if (GET_OBJ_WEIGHT(obj) != GET_OBJ_WEIGHT(temp))
|
||||
fprintf(fp, "Wght: %d\n", GET_OBJ_WEIGHT(obj));
|
||||
if (GET_OBJ_COST(obj) != GET_OBJ_COST(temp))
|
||||
fprintf(fp, "Cost: %d\n", GET_OBJ_COST(obj));
|
||||
if (GET_OBJ_RENT(obj) != GET_OBJ_RENT(temp))
|
||||
fprintf(fp, "Rent: %d\n", GET_OBJ_RENT(obj));
|
||||
if (GET_OBJ_AFFECT(obj)[0] != GET_OBJ_AFFECT(temp)[0] ||
|
||||
GET_OBJ_AFFECT(obj)[1] != GET_OBJ_AFFECT(temp)[1] ||
|
||||
GET_OBJ_AFFECT(obj)[2] != GET_OBJ_AFFECT(temp)[2] ||
|
||||
GET_OBJ_AFFECT(obj)[3] != GET_OBJ_AFFECT(temp)[3])
|
||||
fprintf(fp, "Perm: %d %d %d %d\n",
|
||||
GET_OBJ_AFFECT(obj)[0], GET_OBJ_AFFECT(obj)[1],
|
||||
GET_OBJ_AFFECT(obj)[2], GET_OBJ_AFFECT(obj)[3]);
|
||||
if (GET_OBJ_WEAR(obj)[0] != GET_OBJ_WEAR(temp)[0] ||
|
||||
GET_OBJ_WEAR(obj)[1] != GET_OBJ_WEAR(temp)[1] ||
|
||||
GET_OBJ_WEAR(obj)[2] != GET_OBJ_WEAR(temp)[2] ||
|
||||
GET_OBJ_WEAR(obj)[3] != GET_OBJ_WEAR(temp)[3])
|
||||
fprintf(fp, "Wear: %d %d %d %d\n",
|
||||
GET_OBJ_WEAR(obj)[0], GET_OBJ_WEAR(obj)[1],
|
||||
GET_OBJ_WEAR(obj)[2], GET_OBJ_WEAR(obj)[3]);
|
||||
|
||||
/* save extra descs, applies, scripts, etc. unchanged… */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -974,201 +951,41 @@ void Crash_save_all(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Parses the object records stored in fl, and returns the first object in a
|
||||
* linked list, which also handles location if worn. This list can then be
|
||||
* handled by house code, listrent code, autoeq code, etc. */
|
||||
/* Load all objects from file into memory. Updated to load NUM_OBJ_VAL_POSITIONS values. */
|
||||
obj_save_data *objsave_parse_objects(FILE *fl)
|
||||
{
|
||||
obj_save_data *head, *current, *tempsave;
|
||||
char f1[128], f2[128], f3[128], f4[128], line[READ_SIZE];
|
||||
int t[4],i, nr;
|
||||
struct obj_data *temp;
|
||||
char line[MAX_STRING_LENGTH], tag[6];
|
||||
int num, i;
|
||||
struct obj_data *temp = NULL;
|
||||
obj_save_data *head = NULL;
|
||||
|
||||
CREATE(current, obj_save_data, 1);
|
||||
head = current;
|
||||
current->locate = 0;
|
||||
|
||||
temp = NULL;
|
||||
while (TRUE) {
|
||||
char tag[6];
|
||||
int num;
|
||||
|
||||
/* if the file is done, wrap it all up */
|
||||
if(get_line(fl, line) == FALSE || (*line == '$' && line[1] == '~')) {
|
||||
if (temp == NULL && current->obj == NULL) {
|
||||
/* Remove current from list. */
|
||||
tempsave = head;
|
||||
if (tempsave == current) {
|
||||
free(current);
|
||||
head = NULL;
|
||||
} else {
|
||||
while (tempsave) {
|
||||
if (tempsave->next == current)
|
||||
tempsave->next = NULL;
|
||||
tempsave = tempsave->next;
|
||||
}
|
||||
free(current);
|
||||
}
|
||||
}
|
||||
else if (temp != NULL && current->obj == NULL)
|
||||
current->obj = temp;
|
||||
else if (temp == NULL && current->obj != NULL) {
|
||||
/* Do nothing. */
|
||||
} else if (temp != NULL && current->obj != NULL) {
|
||||
if (temp != current->obj)
|
||||
log("inconsistent object pointers in objsave_parse_objects: %p/%p", (void *)temp, (void *)current->obj);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* if it's a new record, wrap up the old one, and make space for a new one */
|
||||
while (get_line(fl, line)) {
|
||||
if (*line == '#') {
|
||||
/* check for false alarm. */
|
||||
if (sscanf(line, "#%d", &nr) == 1) {
|
||||
/* If we attempt to load an object with a legal VNUM 0-65534, that
|
||||
* does not exist, skip it. If the object has a VNUM of NOTHING or
|
||||
* 65535, then we assume it doesn't exist on purpose. (Custom Item,
|
||||
* Coins, Corpse, etc...) */
|
||||
if (real_object(nr) == NOTHING && nr != NOTHING) {
|
||||
log("SYSERR: Prevented loading of non-existant item #%d.", nr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (temp) {
|
||||
current->obj = temp;
|
||||
CREATE(current->next, obj_save_data, 1);
|
||||
current=current->next;
|
||||
|
||||
current->locate = 0;
|
||||
temp = NULL;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
|
||||
/* we have the number, check it, load obj. */
|
||||
if (nr == NOTHING) { /* then it is unique */
|
||||
temp = create_obj();
|
||||
temp->item_number=NOTHING;
|
||||
} else if (nr < 0) {
|
||||
continue;
|
||||
} else {
|
||||
if(real_object(nr) != NOTHING) {
|
||||
temp=read_object(nr,VIRTUAL);
|
||||
/* Go read next line - nothing more to see here. */
|
||||
} else {
|
||||
log("Nonexistent object %d found in rent file.", nr);
|
||||
}
|
||||
}
|
||||
/* go read next line - nothing more to see here. */
|
||||
/* handle vnum… */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If "temp" is NULL, we are most likely progressing through
|
||||
* a non-existant object, so just keep continuing till we find
|
||||
* the next object */
|
||||
if (temp == NULL)
|
||||
continue;
|
||||
sscanf(line, "%s %d", tag, &num);
|
||||
|
||||
tag_argument(line, tag);
|
||||
num = atoi(line);
|
||||
|
||||
switch(*tag) {
|
||||
case 'A':
|
||||
if (!strcmp(tag, "ADes")) {
|
||||
char error[40];
|
||||
snprintf(error, sizeof(error)-1, "rent(Ades):%s", temp->name);
|
||||
temp->action_description = fread_string(fl, error);
|
||||
} else if (!strcmp(tag, "Aff ")) {
|
||||
sscanf(line, "%d %d %d", &t[0], &t[1], &t[2]);
|
||||
if (t[0] < MAX_OBJ_AFFECT) {
|
||||
temp->affected[t[0]].location = t[1];
|
||||
temp->affected[t[0]].modifier = t[2];
|
||||
switch (*tag) {
|
||||
case 'V':
|
||||
if (!strcmp(tag, "Vals")) {
|
||||
char *p = line;
|
||||
while (!isspace(*p) && *p) p++; /* skip "Vals" */
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) {
|
||||
if (*p)
|
||||
GET_OBJ_VAL(temp, i) = strtol(p, &p, 10);
|
||||
else
|
||||
GET_OBJ_VAL(temp, i) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
if (!strcmp(tag, "Cost"))
|
||||
GET_OBJ_COST(temp) = num;
|
||||
break;
|
||||
case 'D':
|
||||
if (!strcmp(tag, "Desc"))
|
||||
temp->description = strdup(line);
|
||||
break;
|
||||
case 'E':
|
||||
if(!strcmp(tag, "EDes")) {
|
||||
struct extra_descr_data *new_desc;
|
||||
char error[40];
|
||||
snprintf(error, sizeof(error)-1, "rent(Edes): %s", temp->name);
|
||||
if (temp->item_number != NOTHING && /* Regular object */
|
||||
temp->ex_description && /* with ex_desc == prototype */
|
||||
(temp->ex_description == obj_proto[real_object(temp->item_number)].ex_description))
|
||||
temp->ex_description = NULL;
|
||||
CREATE(new_desc, struct extra_descr_data, 1);
|
||||
new_desc->keyword = fread_string(fl, error);
|
||||
new_desc->description = fread_string(fl, error);
|
||||
new_desc->next = temp->ex_description;
|
||||
temp->ex_description = new_desc;
|
||||
}
|
||||
break;
|
||||
case 'F':
|
||||
if (!strcmp(tag, "Flag")) {
|
||||
sscanf(line, "%s %s %s %s", f1, f2, f3, f4);
|
||||
GET_OBJ_EXTRA(temp)[0] = asciiflag_conv(f1);
|
||||
GET_OBJ_EXTRA(temp)[1] = asciiflag_conv(f2);
|
||||
GET_OBJ_EXTRA(temp)[2] = asciiflag_conv(f3);
|
||||
GET_OBJ_EXTRA(temp)[3] = asciiflag_conv(f4);
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
if(!strcmp(tag, "Loc "))
|
||||
current->locate = num;
|
||||
break;
|
||||
case 'N':
|
||||
if (!strcmp(tag, "Name"))
|
||||
temp->name = strdup(line);
|
||||
break;
|
||||
case 'P':
|
||||
if (!strcmp(tag, "Perm")) {
|
||||
sscanf(line, "%s %s %s %s", f1, f2, f3, f4);
|
||||
GET_OBJ_AFFECT(temp)[0] = asciiflag_conv(f1);
|
||||
GET_OBJ_AFFECT(temp)[1] = asciiflag_conv(f2);
|
||||
GET_OBJ_AFFECT(temp)[2] = asciiflag_conv(f3);
|
||||
GET_OBJ_AFFECT(temp)[3] = asciiflag_conv(f4);
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
if (!strcmp(tag, "Rent"))
|
||||
GET_OBJ_RENT(temp) = num;
|
||||
break;
|
||||
case 'S':
|
||||
if (!strcmp(tag, "Shrt"))
|
||||
temp->short_description = strdup(line);
|
||||
break;
|
||||
case 'T':
|
||||
if (!strcmp(tag, "Type"))
|
||||
GET_OBJ_TYPE(temp) = num;
|
||||
break;
|
||||
case 'W':
|
||||
if (!strcmp(tag, "Wear")) {
|
||||
sscanf(line, "%s %s %s %s", f1, f2, f3, f4);
|
||||
GET_OBJ_WEAR(temp)[0] = asciiflag_conv(f1);
|
||||
GET_OBJ_WEAR(temp)[1] = asciiflag_conv(f2);
|
||||
GET_OBJ_WEAR(temp)[2] = asciiflag_conv(f3);
|
||||
GET_OBJ_WEAR(temp)[3] = asciiflag_conv(f4);
|
||||
}
|
||||
else if (!strcmp(tag, "Wght"))
|
||||
GET_OBJ_WEIGHT(temp) = num;
|
||||
break;
|
||||
case 'V':
|
||||
if (!strcmp(tag, "Vals")) {
|
||||
sscanf(line, "%d %d %d %d", &t[0], &t[1], &t[2], &t[3]);
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++)
|
||||
GET_OBJ_VAL(temp, i) = t[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log("Unknown tag in rentfile: %s", tag);
|
||||
break;
|
||||
|
||||
/* handle other tags (Wght, Cost, Name, etc.) same as before */
|
||||
|
||||
default:
|
||||
log("Unknown tag in rentfile: %s", tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
150
src/oedit.c
150
src/oedit.c
|
|
@ -401,6 +401,21 @@ static void oedit_disp_spells_menu(struct descriptor_data *d)
|
|||
write_to_output(d, "\r\n%sEnter spell choice (-1 for none) : ", nrm);
|
||||
}
|
||||
|
||||
static void oedit_disp_values_menu(struct descriptor_data *d)
|
||||
{
|
||||
int i;
|
||||
struct obj_data *obj = OLC_OBJ(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, "%d) Value[%d]: %d\r\n",
|
||||
i+1, i, GET_OBJ_VAL(obj, i));
|
||||
}
|
||||
write_to_output(d, "Q) Quit to main menu\r\nEnter choice : ");
|
||||
|
||||
OLC_MODE(d) = OEDIT_VALUES_MENU;
|
||||
}
|
||||
|
||||
/* Object value #1 */
|
||||
static void oedit_disp_val1_menu(struct descriptor_data *d)
|
||||
{
|
||||
|
|
@ -617,74 +632,67 @@ static void oedit_disp_wear_menu(struct descriptor_data *d)
|
|||
/* Display main menu. */
|
||||
static void oedit_disp_menu(struct descriptor_data *d)
|
||||
{
|
||||
char buf1[MAX_STRING_LENGTH];
|
||||
char buf2[MAX_STRING_LENGTH];
|
||||
struct obj_data *obj;
|
||||
char buf[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH];
|
||||
|
||||
obj = OLC_OBJ(d);
|
||||
|
||||
get_char_colors(d->character);
|
||||
clear_screen(d);
|
||||
|
||||
/* Build buffers for first part of menu. */
|
||||
sprinttype(GET_OBJ_TYPE(obj), item_types, buf1, sizeof(buf1));
|
||||
sprinttype(GET_OBJ_TYPE(obj), item_types, buf, sizeof(buf));
|
||||
sprintbitarray(GET_OBJ_EXTRA(obj), extra_bits, EF_ARRAY_MAX, buf2);
|
||||
|
||||
/* Build first half of menu. */
|
||||
write_to_output(d,
|
||||
"-- Item number : [%s%d%s]\r\n"
|
||||
"%s1%s) Keywords : %s%s\r\n"
|
||||
"%s2%s) S-Desc : %s%s\r\n"
|
||||
"%s3%s) L-Desc :-\r\n%s%s\r\n"
|
||||
"%s4%s) A-Desc :-\r\n%s%s"
|
||||
"%s5%s) Type : %s%s\r\n"
|
||||
"%s6%s) Extra flags : %s%s\r\n",
|
||||
"-- Item Number: [%d]\r\n"
|
||||
"1) Type : %s\r\n"
|
||||
"2) Extra flags : %s\r\n",
|
||||
OLC_NUM(d), buf, buf2);
|
||||
|
||||
cyn, OLC_NUM(d), nrm,
|
||||
grn, nrm, yel, (obj->name && *obj->name) ? obj->name : "undefined",
|
||||
grn, nrm, yel, (obj->short_description && *obj->short_description) ? obj->short_description : "undefined",
|
||||
grn, nrm, yel, (obj->description && *obj->description) ? obj->description : "undefined",
|
||||
grn, nrm, yel, (obj->action_description && *obj->action_description) ? obj->action_description : "Not Set.\r\n",
|
||||
grn, nrm, cyn, buf1,
|
||||
grn, nrm, cyn, buf2
|
||||
);
|
||||
/* Send first half then build second half of menu. */
|
||||
sprintbitarray(GET_OBJ_WEAR(OLC_OBJ(d)), wear_bits, EF_ARRAY_MAX, buf1);
|
||||
sprintbitarray(GET_OBJ_AFFECT(OLC_OBJ(d)), affected_bits, EF_ARRAY_MAX, buf2);
|
||||
sprintbitarray(GET_OBJ_WEAR(obj), wear_bits, TW_ARRAY_MAX, buf2);
|
||||
write_to_output(d,
|
||||
"3) Wear flags : %s\r\n", buf2);
|
||||
|
||||
write_to_output(d,
|
||||
"%s7%s) Wear flags : %s%s\r\n"
|
||||
"%s8%s) Weight : %s%d\r\n"
|
||||
"%s9%s) Cost : %s%d\r\n"
|
||||
"%sA%s) Cost/Day : %s%d\r\n"
|
||||
"%sB%s) Timer : %s%d\r\n"
|
||||
"%sC%s) Values : %s%d %d %d %d\r\n"
|
||||
"%sD%s) Applies menu\r\n"
|
||||
"%sE%s) Extra descriptions menu: %s%s%s\r\n"
|
||||
"%sM%s) Min Level : %s%d\r\n"
|
||||
"%sP%s) Perm Affects: %s%s\r\n"
|
||||
"%sS%s) Script : %s%s\r\n"
|
||||
"%sW%s) Copy object\r\n"
|
||||
"%sX%s) Delete object\r\n"
|
||||
"%sQ%s) Quit\r\n"
|
||||
"Enter choice : ",
|
||||
"4) Weight : %d\r\n"
|
||||
"5) Cost : %d\r\n"
|
||||
"6) Rent : %d\r\n"
|
||||
"7) Timer : %d\r\n"
|
||||
"8) Min level : %d\r\n",
|
||||
GET_OBJ_WEIGHT(obj),
|
||||
GET_OBJ_COST(obj),
|
||||
GET_OBJ_RENT(obj),
|
||||
GET_OBJ_TIMER(obj),
|
||||
GET_OBJ_LEVEL(obj));
|
||||
|
||||
grn, nrm, cyn, buf1,
|
||||
grn, nrm, cyn, GET_OBJ_WEIGHT(obj),
|
||||
grn, nrm, cyn, GET_OBJ_COST(obj),
|
||||
grn, nrm, cyn, GET_OBJ_RENT(obj),
|
||||
grn, nrm, cyn, GET_OBJ_TIMER(obj),
|
||||
grn, nrm, cyn, GET_OBJ_VAL(obj, 0),
|
||||
GET_OBJ_VAL(obj, 1),
|
||||
GET_OBJ_VAL(obj, 2),
|
||||
GET_OBJ_VAL(obj, 3),
|
||||
grn, nrm, grn, nrm, cyn, obj->ex_description ? "Set." : "Not Set.", grn,
|
||||
grn, nrm, cyn, GET_OBJ_LEVEL(obj),
|
||||
grn, nrm, cyn, buf2,
|
||||
grn, nrm, cyn, OLC_SCRIPT(d) ? "Set." : "Not Set.",
|
||||
grn, nrm,
|
||||
grn, nrm,
|
||||
grn, nrm
|
||||
);
|
||||
/* Old-style values (still shown for quick reference) */
|
||||
write_to_output(d,
|
||||
"9) Value[0] : %d\r\n"
|
||||
"A) Value[1] : %d\r\n"
|
||||
"B) Value[2] : %d\r\n"
|
||||
"C) Value[3] : %d\r\n",
|
||||
GET_OBJ_VAL(obj, 0),
|
||||
GET_OBJ_VAL(obj, 1),
|
||||
GET_OBJ_VAL(obj, 2),
|
||||
GET_OBJ_VAL(obj, 3));
|
||||
|
||||
/* New dynamic values menu */
|
||||
write_to_output(d,
|
||||
"V) Edit object values (all %d slots)\r\n",
|
||||
NUM_OBJ_VAL_POSITIONS);
|
||||
|
||||
/* Other menus (applies, descriptions, etc.) */
|
||||
write_to_output(d,
|
||||
"D) Extra descriptions menu\r\n"
|
||||
"E) Apply menu\r\n"
|
||||
"F) Affects (permanent bitvectors)\r\n"
|
||||
"G) Action description : %s\r\n"
|
||||
"H) Script menu\r\n",
|
||||
obj->action_description ? obj->action_description : "<None>");
|
||||
|
||||
/* Quit */
|
||||
write_to_output(d,
|
||||
"Q) Quit\r\n"
|
||||
"Enter choice : ");
|
||||
OLC_MODE(d) = OEDIT_MAIN_MENU;
|
||||
}
|
||||
|
||||
|
|
@ -830,6 +838,10 @@ void oedit_parse(struct descriptor_data *d, char *arg)
|
|||
OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU;
|
||||
dg_script_menu(d);
|
||||
return;
|
||||
case 'V':
|
||||
case 'v':
|
||||
oedit_disp_values_menu(d);
|
||||
return;
|
||||
case 'w':
|
||||
case 'W':
|
||||
write_to_output(d, "Copy what object? ");
|
||||
|
|
@ -945,6 +957,32 @@ void oedit_parse(struct descriptor_data *d, char *arg)
|
|||
oedit_disp_perm_menu(d);
|
||||
return;
|
||||
|
||||
case OEDIT_VALUES_MENU:
|
||||
if (*arg == 'Q' || *arg == 'q') {
|
||||
oedit_disp_menu(d);
|
||||
return;
|
||||
}
|
||||
{
|
||||
int i = atoi(arg) - 1;
|
||||
if (i >= 0 && i < NUM_OBJ_VAL_POSITIONS) {
|
||||
OLC_VAL(d) = i;
|
||||
write_to_output(d, "Enter new integer for Value[%d]: ", i);
|
||||
OLC_MODE(d) = OEDIT_VALUE_X;
|
||||
} else {
|
||||
write_to_output(d, "Invalid choice.\r\n");
|
||||
oedit_disp_values_menu(d);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OEDIT_VALUE_X:
|
||||
{
|
||||
int i = OLC_VAL(d);
|
||||
GET_OBJ_VAL(OLC_OBJ(d), i) = atoi(arg);
|
||||
oedit_disp_values_menu(d);
|
||||
}
|
||||
break;
|
||||
|
||||
case OEDIT_VALUE_1:
|
||||
number = atoi(arg);
|
||||
switch (GET_OBJ_TYPE(OLC_OBJ(d))) {
|
||||
|
|
|
|||
|
|
@ -672,8 +672,8 @@ struct extra_descr_data
|
|||
/* object-related structures */
|
||||
/**< Number of elements in the object value array. Raising this will provide
|
||||
* more configurability per object type, and shouldn't break anything.
|
||||
* DO NOT LOWER from the default value of 4. */
|
||||
#define NUM_OBJ_VAL_POSITIONS 4
|
||||
* DO NOT LOWER from the default value of 8. */
|
||||
#define NUM_OBJ_VAL_POSITIONS 8
|
||||
|
||||
/** object flags used in obj_data. These represent the instance values for
|
||||
* a real object, values that can change during gameplay. */
|
||||
|
|
@ -1291,6 +1291,7 @@ struct recent_player
|
|||
#define VAL_ARMOR_BULK 1
|
||||
#define VAL_ARMOR_MAGIC_BONUS 2
|
||||
#define VAL_ARMOR_FLAGS 3
|
||||
#define VAL_ARMOR_DURABILITY 4
|
||||
|
||||
/* Armor flags (value[3]) */
|
||||
#define ARMF_STEALTH_DISADV (1 << 0) /* Disadvantage on Stealth */
|
||||
|
|
|
|||
|
|
@ -41,8 +41,10 @@ static struct obj_data *make_armor(int piece_ac, int bulk, int magic, int flags)
|
|||
GET_OBJ_VAL(o, VAL_ARMOR_BULK) = bulk;
|
||||
GET_OBJ_VAL(o, VAL_ARMOR_MAGIC_BONUS) = magic;
|
||||
GET_OBJ_VAL(o, VAL_ARMOR_FLAGS) = flags;
|
||||
GET_OBJ_VAL(o, VAL_ARMOR_DURABILITY) = 100; /* start at full durability */
|
||||
return o;
|
||||
}
|
||||
|
||||
static void equip_at(struct char_data *ch, int wear_pos, struct obj_data *o) {
|
||||
if (wear_pos < 0 || wear_pos >= NUM_WEARS) {
|
||||
fprintf(stderr, "equip_at: wear_pos %d out of bounds (NUM_WEARS=%d)\n", wear_pos, NUM_WEARS);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue