mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-30 17:07:19 +02:00
Reroll update
This commit is contained in:
parent
4f5ee09ee4
commit
b186c7e87c
9 changed files with 156 additions and 2 deletions
|
|
@ -59,6 +59,7 @@ Changes in v1.1.0-alpha:
|
|||
* PC's and NPC's can now have an age set between 18-65
|
||||
* "audit ac" command for immortals (formerly "acaudit"), allowing for further audit commands in the future
|
||||
* Minor score output change to only show quest status while on a quest, PC/NPC name, sdesc, and current ldesc
|
||||
* Added ability to reroll initial stats if they are not to player's liking, and undo reroll if needed
|
||||
|
||||
Features to be implemented in the next few releases:
|
||||
|
||||
|
|
|
|||
|
|
@ -7962,7 +7962,15 @@ From: justo
|
|||
#2
|
||||
REROLL
|
||||
|
||||
Usage: reroll <player>
|
||||
Usage: reroll
|
||||
reroll undo
|
||||
|
||||
Reroll lets you roll a new set of stats once. Your original stats are saved
|
||||
for 2 hours; during that window you may use 'reroll undo' to restore them.
|
||||
After the review period or after using reroll undo, your stats are permanent
|
||||
and you cannot reroll again.
|
||||
|
||||
Immortals: reroll <player> rerolls that player's stats.
|
||||
|
||||
REROLL gives a player new stats (i.e., Str, Int, Wis, Dex, Con, and Cha)
|
||||
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@ ACMD(do_hide);
|
|||
ACMD(do_listen);
|
||||
ACMD(do_not_here);
|
||||
ACMD(do_change);
|
||||
ACMD(do_reroll);
|
||||
ACMD(do_report);
|
||||
ACMD(do_save);
|
||||
ACMD(do_skills);
|
||||
|
|
|
|||
107
src/act.other.c
107
src/act.other.c
|
|
@ -66,6 +66,14 @@ static void change_trim_trailing_spaces(char *text)
|
|||
}
|
||||
}
|
||||
|
||||
#define REROLL_REVIEW_SECONDS (2 * SECS_PER_REAL_HOUR)
|
||||
|
||||
static void reroll_clear_saved(struct char_data *ch)
|
||||
{
|
||||
GET_REROLL_EXPIRES(ch) = 0;
|
||||
memset(&GET_REROLL_OLD_ABILS(ch), 0, sizeof(struct char_ability_data));
|
||||
}
|
||||
|
||||
ACMD(do_quit)
|
||||
{
|
||||
char first[MAX_INPUT_LENGTH];
|
||||
|
|
@ -275,6 +283,105 @@ ACMD(do_change)
|
|||
send_to_char(ch, "Long description updated.\r\n");
|
||||
}
|
||||
|
||||
ACMD(do_reroll)
|
||||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
struct char_data *vict;
|
||||
time_t now;
|
||||
time_t remaining;
|
||||
bool expired = FALSE;
|
||||
|
||||
one_argument(argument, arg);
|
||||
|
||||
if (IS_NPC(ch)) {
|
||||
send_to_char(ch, "You can't reroll stats.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
now = time(0);
|
||||
if (GET_REROLL_EXPIRES(ch) > 0 && now >= GET_REROLL_EXPIRES(ch)) {
|
||||
reroll_clear_saved(ch);
|
||||
save_char(ch);
|
||||
expired = TRUE;
|
||||
}
|
||||
|
||||
if (*arg && is_abbrev(arg, "undo")) {
|
||||
if (!GET_REROLL_USED(ch)) {
|
||||
send_to_char(ch, "You haven't rerolled yet.\r\n");
|
||||
return;
|
||||
}
|
||||
if (GET_REROLL_EXPIRES(ch) <= 0 || expired) {
|
||||
send_to_char(ch, "You no longer have a reroll pending; your stats are permanent.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ch->real_abils = GET_REROLL_OLD_ABILS(ch);
|
||||
affect_total(ch);
|
||||
reroll_clear_saved(ch);
|
||||
save_char(ch);
|
||||
|
||||
send_to_char(ch, "Your original stats have been restored. You cannot reroll again.\r\n");
|
||||
send_to_char(ch, "Stats: Str %d, Int %d, Wis %d, Dex %d, Con %d, Cha %d\r\n",
|
||||
GET_STR(ch), GET_INT(ch), GET_WIS(ch),
|
||||
GET_DEX(ch), GET_CON(ch), GET_CHA(ch));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*arg && GET_LEVEL(ch) >= LVL_GRGOD) {
|
||||
if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)))
|
||||
send_to_char(ch, "There is no such player.\r\n");
|
||||
else if (IS_NPC(vict))
|
||||
send_to_char(ch, "You can't do that to a mob!\r\n");
|
||||
else {
|
||||
roll_real_abils(vict);
|
||||
affect_total(vict);
|
||||
send_to_char(ch, "Rerolled...\r\n");
|
||||
log("(GC) %s has rerolled %s.", GET_NAME(ch), GET_NAME(vict));
|
||||
send_to_char(ch, "New stats: Str %d, Int %d, Wis %d, Dex %d, Con %d, Cha %d\r\n",
|
||||
GET_STR(vict), GET_INT(vict), GET_WIS(vict),
|
||||
GET_DEX(vict), GET_CON(vict), GET_CHA(vict));
|
||||
save_char(vict);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (*arg) {
|
||||
send_to_char(ch, "Usage: reroll | reroll undo\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GET_REROLL_USED(ch)) {
|
||||
if (GET_REROLL_EXPIRES(ch) > 0 && now < GET_REROLL_EXPIRES(ch)) {
|
||||
remaining = GET_REROLL_EXPIRES(ch) - now;
|
||||
int hours = remaining / SECS_PER_REAL_HOUR;
|
||||
int mins = (remaining % SECS_PER_REAL_HOUR) / SECS_PER_REAL_MIN;
|
||||
|
||||
if (hours > 0)
|
||||
send_to_char(ch, "You have already rerolled. You can 'reroll undo' within %d hour%s %d minute%s.\r\n",
|
||||
hours, hours == 1 ? "" : "s", mins, mins == 1 ? "" : "s");
|
||||
else
|
||||
send_to_char(ch, "You have already rerolled. You can 'reroll undo' within %d minute%s.\r\n",
|
||||
mins, mins == 1 ? "" : "s");
|
||||
} else {
|
||||
send_to_char(ch, "You have already rerolled and cannot reroll again.\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
GET_REROLL_OLD_ABILS(ch) = ch->real_abils;
|
||||
roll_real_abils(ch);
|
||||
affect_total(ch);
|
||||
GET_REROLL_USED(ch) = TRUE;
|
||||
GET_REROLL_EXPIRES(ch) = now + REROLL_REVIEW_SECONDS;
|
||||
save_char(ch);
|
||||
|
||||
send_to_char(ch, "Your stats have been rerolled. You have 2 hours to review them.\r\n");
|
||||
send_to_char(ch, "New stats: Str %d, Int %d, Wis %d, Dex %d, Con %d, Cha %d\r\n",
|
||||
GET_STR(ch), GET_INT(ch), GET_WIS(ch),
|
||||
GET_DEX(ch), GET_CON(ch), GET_CHA(ch));
|
||||
send_to_char(ch, "Use 'reroll undo' to restore your original stats before the timer expires.\r\n");
|
||||
}
|
||||
|
||||
/* Generic function for commands which are normally overridden by special
|
||||
* procedures - i.e., shop commands, mail commands, etc. */
|
||||
ACMD(do_not_here)
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ cpp_extern const struct command_info cmd_info[] = {
|
|||
{ "recent" , "recent" , POS_DEAD , do_recent , LVL_IMMORT, 0 },
|
||||
{ "remove" , "rem" , POS_RESTING , do_remove , 0, 0 },
|
||||
{ "report" , "repo" , POS_RESTING , do_report , 0, 0 },
|
||||
{ "reroll" , "rero" , POS_DEAD , do_wizutil , LVL_GRGOD, SCMD_REROLL },
|
||||
{ "reroll" , "rero" , POS_DEAD , do_reroll , 0, 0 },
|
||||
{ "rescue" , "resc" , POS_FIGHTING, do_rescue , 1, 0 },
|
||||
{ "restore" , "resto" , POS_DEAD , do_restore , LVL_GOD, 0 },
|
||||
{ "return" , "retu" , POS_DEAD , do_return , 0, 0 },
|
||||
|
|
|
|||
|
|
@ -58,5 +58,7 @@
|
|||
#define PFDEF_CURRQUEST NOTHING
|
||||
#define PFDEF_LASTMOTD 0
|
||||
#define PFDEF_LASTNEWS 0
|
||||
#define PFDEF_REROLL_USED 0
|
||||
#define PFDEF_REROLL_EXPIRES 0
|
||||
|
||||
#endif /* _PFDEFAULTS_H_ */
|
||||
|
|
|
|||
|
|
@ -315,6 +315,9 @@ int load_char(const char *name, struct char_data *ch)
|
|||
GET_NUM_QUESTS(ch) = PFDEF_COMPQUESTS;
|
||||
GET_LAST_MOTD(ch) = PFDEF_LASTMOTD;
|
||||
GET_LAST_NEWS(ch) = PFDEF_LASTNEWS;
|
||||
GET_REROLL_USED(ch) = PFDEF_REROLL_USED;
|
||||
GET_REROLL_EXPIRES(ch) = PFDEF_REROLL_EXPIRES;
|
||||
memset(&GET_REROLL_OLD_ABILS(ch), 0, sizeof(struct char_ability_data));
|
||||
if (GET_ACCOUNT(ch)) {
|
||||
free(GET_ACCOUNT(ch));
|
||||
GET_ACCOUNT(ch) = NULL;
|
||||
|
|
@ -454,6 +457,20 @@ int load_char(const char *name, struct char_data *ch)
|
|||
|
||||
case 'R':
|
||||
if (!strcmp(tag, "Room")) GET_LOADROOM(ch) = atoi(line);
|
||||
else if (!strcmp(tag, "RrUs")) GET_REROLL_USED(ch) = atoi(line);
|
||||
else if (!strcmp(tag, "RrTm")) GET_REROLL_EXPIRES(ch) = (time_t)atol(line);
|
||||
else if (!strcmp(tag, "RrAb")) {
|
||||
int rstr, rint, rwis, rdex, rcon, rcha;
|
||||
|
||||
if (sscanf(line, "%d %d %d %d %d %d", &rstr, &rint, &rwis, &rdex, &rcon, &rcha) == 6) {
|
||||
GET_REROLL_OLD_ABILS(ch).str = rstr;
|
||||
GET_REROLL_OLD_ABILS(ch).intel = rint;
|
||||
GET_REROLL_OLD_ABILS(ch).wis = rwis;
|
||||
GET_REROLL_OLD_ABILS(ch).dex = rdex;
|
||||
GET_REROLL_OLD_ABILS(ch).con = rcon;
|
||||
GET_REROLL_OLD_ABILS(ch).cha = rcha;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
|
|
@ -663,6 +680,18 @@ void save_char(struct char_data * ch)
|
|||
fprintf(fl, "Lmot: %d\n", (int)GET_LAST_MOTD(ch));
|
||||
if (GET_LAST_NEWS(ch) != PFDEF_LASTNEWS)
|
||||
fprintf(fl, "Lnew: %d\n", (int)GET_LAST_NEWS(ch));
|
||||
if (GET_REROLL_USED(ch) != PFDEF_REROLL_USED)
|
||||
fprintf(fl, "RrUs: %d\n", (int)GET_REROLL_USED(ch));
|
||||
if (GET_REROLL_EXPIRES(ch) != PFDEF_REROLL_EXPIRES) {
|
||||
fprintf(fl, "RrTm: %ld\n", (long)GET_REROLL_EXPIRES(ch));
|
||||
fprintf(fl, "RrAb: %d %d %d %d %d %d\n",
|
||||
GET_REROLL_OLD_ABILS(ch).str,
|
||||
GET_REROLL_OLD_ABILS(ch).intel,
|
||||
GET_REROLL_OLD_ABILS(ch).wis,
|
||||
GET_REROLL_OLD_ABILS(ch).dex,
|
||||
GET_REROLL_OLD_ABILS(ch).con,
|
||||
GET_REROLL_OLD_ABILS(ch).cha);
|
||||
}
|
||||
|
||||
if (GET_HOST(ch)) fprintf(fl, "Host: %s\n", GET_HOST(ch));
|
||||
if (GET_HEIGHT(ch) != PFDEF_HEIGHT) fprintf(fl, "Hite: %d\n", GET_HEIGHT(ch));
|
||||
|
|
|
|||
|
|
@ -1052,6 +1052,9 @@ struct player_special_data_saved
|
|||
int quest_counter; /**< Count of targets left to get */
|
||||
time_t lastmotd; /**< Last time player read motd */
|
||||
time_t lastnews; /**< Last time player read news */
|
||||
bool reroll_used; /**< Has the PC used their one-time reroll */
|
||||
time_t reroll_expires; /**< When the reroll review period ends */
|
||||
struct char_ability_data reroll_old_abils; /**< Original stats before reroll */
|
||||
time_t next_skill_gain[MAX_SKILLS+1]; /* indexed by skill/spell number */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -678,6 +678,9 @@ do \
|
|||
#define GET_SCAN_RESULTS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->scan_results))
|
||||
#define GET_LAST_MOTD(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.lastmotd))
|
||||
#define GET_LAST_NEWS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.lastnews))
|
||||
#define GET_REROLL_USED(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.reroll_used))
|
||||
#define GET_REROLL_EXPIRES(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.reroll_expires))
|
||||
#define GET_REROLL_OLD_ABILS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.reroll_old_abils))
|
||||
/** Get channel history i for ch. */
|
||||
#define GET_HISTORY(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.comm_hist[i]))
|
||||
/** Return the page length (height) for ch. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue