29 Nov, 2012, khyldes wrote in the 1st comment:
Votes: 0
I'm trying to display any skills/spells that are on Cooldown with the following code:

void do_cooldowns( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
int i = 0;

push_call("do_cooldowns(%p,%p)",ch,argument);


send_to_char("\r\n-=-=-=Cooldowns=-=-=-\r\n",ch);

for (i = 0; i <= MAX_SKILL; i++)
{

if (ch->cooldowns[i] > 0)
{
sprintf(buf, "%-20s: %2ld \r\n", skill_table[i].name, ch->cooldowns[i]);

send_to_char(buf, ch);
return;
}
}

pop_call();
return;

}


Seems to only be half working. If more then one thing is on cooldown it will only show one of them. Also, if nothing is on cooldown it crashes the mud. Any help would be great.

Thanks,

Khyldes
29 Nov, 2012, Igabod wrote in the 2nd comment:
Votes: 0
I'm not the greatest coder in the world but line 14 to 19 would be where the problem is I think. If you need more details than that then you will need to wait for a better coder to answer.
29 Nov, 2012, Igabod wrote in the 3rd comment:
Votes: 0
as for the 2nd problem, you don't have an if statement telling it what to do when there aren't any cooldowns.
30 Nov, 2012, khyldes wrote in the 4th comment:
Votes: 0
Igabod said:
as for the 2nd problem, you don't have an if statement telling it what to do when there aren't any cooldowns.


Yeah I tried doing something like this:

void do_cooldowns( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
int i = 0;

push_call("do_cooldowns(%p,%p)",ch,argument);


send_to_char("\r\n-=-=-=Cooldowns=-=-=-\r\n",ch);

for (i = 0; i <= MAX_SKILL; i++)
{

if (ch->cooldowns[i] >= 0)
{
sprintf(buf, "%-20s: %2ld \r\n", skill_table[i].name, ch->cooldowns[i]);

send_to_char(buf, ch);

return;
}
else
{
send_to_char("\r\nNothing\r\n", ch);

return;
}
}

pop_call();
return;

}


But then no matter what it would only display "Nothing" even when things were on cooldown, so I pulled it out trying to see if I could at least get the cooldown to display.
30 Nov, 2012, Igabod wrote in the 5th comment:
Votes: 0
well unfortunately I'm not skilled enough nor have I done any coding in a couple years so I can't help ya any further. But from my perspective the else statement is fine, the error would be in the lines above that. But I don't know what the exact cause of the problem is. Hopefully somebody better at coding than me will see this soon and point it out.
30 Nov, 2012, Runter wrote in the 6th comment:
Votes: 0
You don't want to return when you print each detail. That would be why you're only seeing the first one.

You also don't want the else statement where you have it to display nothing. You need to keep a boolean variable that's set to true at the start, then set it to false if you find a cooldown. Then at the end of the logic if the variable is true print "Nothing."
30 Nov, 2012, roh-bane wrote in the 7th comment:
Votes: 0
1) Get rid of the return after you send the cooldown to the character, it'll stop after the first cooldown with it there.

2) How is ch->cooldowns declared?
30 Nov, 2012, Runter wrote in the 8th comment:
Votes: 0
void do_cooldowns( CHAR_DATA *ch, char *argument ) {
char buf[MAX_STRING_LENGTH];
int i = 0;
int none_found = 1;

push_call("do_cooldowns(%p,%p)",ch,argument);
send_to_char("\r\n-=-=-=Cooldowns=-=-=-\r\n",ch);

for (i = 0; i <= MAX_SKILL; i++) {
if (ch->cooldowns[i] > 0) {
sprintf(buf, "%-20s: %2ld \r\n", skill_table[i].name, ch->cooldowns[i]);

send_to_char(buf, ch);
none_found = 0;
}
}

if (none_found)
send_to_char("\r\nNothing\r\n", ch);

pop_call();
}
30 Nov, 2012, Tyche wrote in the 9th comment:
Votes: 0
You are always returning from the function on the first element of cooldowns[] no matter what.
Try something like:
void do_cooldowns( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
int i = 0;
int found = 0; /* Set if any cooldown found. */
push_call("do_cooldowns(%p,%p)",ch,argument);
send_to_char("\r\n-=-=-=Cooldowns=-=-=-\r\n",ch);
for (i = 0; i <= MAX_SKILL; i++) {
if (ch->cooldowns[i] >= 0) {
found = 1;
sprintf(buf, "%-20s: %2ld \r\n", skill_table[i].name, ch->cooldowns[i]);
send_to_char(buf, ch);
}
}
if (!found) send_to_char("\r\nNothing\r\n", ch); /* no cooldowns found */
pop_call();
return;
}


Ed: Ninja'd
30 Nov, 2012, khyldes wrote in the 10th comment:
Votes: 0
Thanks for the help guys, I really appreciate it!

Okay so I tried it how Runter showed and it crashed, so then I switched it to how Tyche had it and it spit out a list of every skill/spell in the game with a timer of 0 next to it like this:

Quote
-1 slot: 0
acid blast: 0
acid breath: 0
acupunch: 0
ambush: 0
anatomy: 0


and then crashed when it got to the end of the list.
30 Nov, 2012, KaVir wrote in the 11th comment:
Votes: 0
for (i = 0; i <= MAX_SKILL; i++)

If you're using MAX_SKILL to define the size of the skill array, then the above should be "i < MAX_SKILL" not "<=".
30 Nov, 2012, Davion wrote in the 12th comment:
Votes: 0
khyldes said:
Thanks for the help guys, I really appreciate it!

Okay so I tried it how Runter showed and it crashed, so then I switched it to how Tyche had it and it spit out a list of every skill/spell in the game with a timer of 0 next to it like this:

Quote
-1 slot: 0
acid blast: 0
acid breath: 0
acupunch: 0
ambush: 0
anatomy: 0


and then crashed when it got to the end of the list.



Code is quite literal, my friend :). If it's showing every skill in the game that's 0, it's probably because your condition to show, includes 0.

Your current code

if (ch->cooldowns[i] >= 0)


This includes 0. You'll want just want to remove the equal.

if (ch->cooldowns[i] > 0)
01 Dec, 2012, Igabod wrote in the 13th comment:
Votes: 0
See, this is why I continue to visit these forums even though I haven't done any coding in a few years. You guys not only show a person where they went wrong, but you also educate them as to WHY they were wrong. I may not be putting any of this education to use at the moment, but I suspect it is sinking in enough to help me along in the future when I get back into it again.

Thanks for the education guys.
02 Dec, 2012, khyldes wrote in the 14th comment:
Votes: 0
Okay so it took me a day to get back to this and thanks to everyones help it's working.

This is the final code for the output:

void do_cooldown( CHAR_DATA *ch, char *argument )
{
char buf1[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
char colc[10], colC[10], colW[10], colw[10], colG[10], colR[10];
int i = 0;
int found = 0;

push_call("do_cooldown(%p,%p)",ch,argument);

strcpy(colc, "{068}");
strcpy(colC, "{168}");
strcpy(colW, "{178}");
strcpy(colw, "{078}");
strcpy(colG, "{128}");
strcpy(colR, "{118}");

sprintf(buf1, "\r\n%sAbilities on Cooldown\r\n\r\n", colW);
send_to_char_color(buf1, ch);

for (i = 0; i < MAX_SKILL; i++)
{
if (ch->cooldowns[i] > 0)
{
if (ch->cooldowns[i] >= 60)
{
if (ch->cooldowns[i] % 60 == 0)
{
found = 1;
sprintf(buf2, "%s%-20s %s%2ld:00\r\n", colC, skill_table[i].name, colw, (ch->cooldowns[i] / 60));
}
else
{
found = 1;
sprintf(buf2, "%s%-20s %s%2ld:%ld\r\n", colC, skill_table[i].name, colw, (ch->cooldowns[i] / 60), (ch->cooldowns[i] %60));
}
}

if (ch->cooldowns[i] >= 30 && ch->cooldowns[i] < 60)
{
found = 1;
sprintf(buf2, "%s%-20s %s00:%2ld\r\n", colC, skill_table[i].name, colw, ch->cooldowns[i]);
}
else if (ch->cooldowns[i] <= 29)
{
found = 1;
sprintf(buf2, "%s%-20s %s00:%2ld\r\n", colC, skill_table[i].name, colR, ch->cooldowns[i]);
}

send_to_char_color(buf2, ch);
}
}

if (!found)
send_to_char_color("{138}Nothing!\r\n", ch);

pop_call();
return;
}


My only issue now is that the cooldown state doesn't save when a player logs off. Soon as they log back in the cooldowns are reset, obviously this can be abused. Any ideas?
02 Dec, 2012, Rarva.Riendf wrote in the 15th comment:
Votes: 0
Just for your information, as soon as you enter your if (ch->cooldowns> 0) it means found = 1, so you should only do it once.

Quote
My only issue now is that the cooldown state doesn't save when a player logs off. Soon as they log back in the cooldowns are reset, obviously this can be abused. Any ideas?

Yep, save them. You added something in CHAR_DATA, now you need to go in the save_char function and save what you added, and go in the load_char function and load it. (and better do it somwhere you can restore char if you screw something in the process). The best system (imho) is to have the load function works before the save function. (you can edit char files manually and add the field the way you would want to write them, and test the function that should work with or without its presence in the char file). Because this way you can put it in production without modifying all the char at once to add the missing field.
02 Dec, 2012, khyldes wrote in the 16th comment:
Votes: 0
Okay so I fixed the 'found =1' part, thanks for the tip.

Im kind of confused what I'm supposed to add to which function, so I'll just show what I have now.

In my CHAR_DATA I added the this line:

long				  cooldowns[MAX_SKILL];


For saving players this is the code:

void fwrite_char( CHAR_DATA *ch, FILE *fp )
{
AFFECT_DATA *paf;
CRIME_DATA *pcr;
bool IS_DESC;
int sn;
sh_int cnt;
int i = 0;

push_call("fwrite_char(%p,%p)",ch,fp);

IS_DESC = is_desc_valid( ch );

fprintf(fp, "#PLAYER\n");

fprintf(fp, "Version %d\n", PLAYER_VERSION);
fprintf(fp, "Login %s~\n", ch->pcdata->host);

fprintf(fp, "S_Descr %s~\n", ch->short_descr);
fprintf(fp, "L_Descr %s~\n", ch->long_descr);
fprintf(fp, "E_Descr %s~\n", fixer(ch->description));

if (ch->pcdata->first_record)
{
for (pcr = ch->pcdata->first_record ; pcr ; pcr = pcr->next)
{
fprintf(fp, "Crime_Data\n");
fprintf(fp, "%s~\n", fixer(pcr->crime_record));
fprintf(fp, "%s~\n", pcr->arrester);
fprintf(fp, "%d\n", pcr->date);
fprintf(fp, "%d\n", pcr->level);
fprintf(fp, "%d\n", pcr->jailtime);
fprintf(fp, "%d\n", pcr->released);
fprintf(fp, "%s~\n", pcr->releaser);
}
}
fprintf(fp, "Level %d\n", ch->level);
fprintf(fp, "Sex %d\n", ch->sex);
fprintf(fp, "ActualSex %d\n", ch->pcdata->actual_sex);
fprintf(fp, "Class %d\n", ch->class);
fprintf(fp, "Race %d\n", ch->race);

if (get_room_index(ch->pcdata->was_in_room) && IS_SET(ch->in_room->room_flags, ROOM_NO_SAVE))
{
fprintf(fp, "Room %u\n", ch->pcdata->was_in_room);
}
else
{
fprintf(fp, "Room %u\n", ch->in_room->vnum);
}

if (ch->pcdata->corpse)
{
fprintf(fp, "C_Room %u\n", ch->pcdata->corpse_room);
}

fprintf(fp, "LastRoom %d\n", ch->pcdata->last_real_room);
fprintf(fp, "Language %d\n", ch->pcdata->language);
fprintf(fp, "Speak %d\n", ch->pcdata->speak);
fprintf(fp, "Played %d\n", ch->pcdata->played);
fprintf(fp, "K_Played %d\n", ch->pcdata->killer_played);
fprintf(fp, "O_Played %d\n", ch->pcdata->outcast_played);

fprintf(fp, "HpMaMv %d %d %d %d %d %d\n", ch->hit, ch->max_hit, ch->mana, ch->max_mana, ch->move, ch->max_move);
fprintf(fp, "Actuals %d %d %d\n", ch->pcdata->actual_max_hit, ch->pcdata->actual_max_mana, ch->pcdata->actual_max_move);
fprintf(fp, "Gold %d\n", ch->gold);
fprintf(fp, "Account %d\n", ch->pcdata->account);
fprintf(fp, "Exp %d\n", ch->pcdata->exp);
fprintf(fp, "Act %lld\n", ch->act);
fprintf(fp, "Affects1 %lld\n", ch->affected_by);
fprintf(fp, "Affects2 %lld\n", ch->affected2_by);
fprintf(fp, "Practice %d\n", ch->pcdata->practice);
fprintf(fp, "Align %d\n", ch->alignment);
fprintf(fp, "Channel %d\n", ch->pcdata->channel);
fprintf(fp, "Morph %d\n", ch->pcdata->morph_points);
fprintf(fp, "Trivia %d\n", ch->pcdata->trivia_points);

fprintf(fp, "Wimpy %d\n", ch->pcdata->wimpy );

if (ch->pcdata->clan && ch->pcdata->clan_name[0] != '\0')
{
fprintf(fp, "ClanName %s~\n", ch->pcdata->clan_name );
}
if (ch->pcdata->clan_pledge[0] != '\0')
{
fprintf(fp, "ClanPled %s~\n", ch->pcdata->clan_pledge );
}
if (ch->pcdata->clan_position != 0)
{
fprintf(fp, "ClanPosi %d\n", ch->pcdata->clan_position);
}
if (ch->pcdata->last_connect != mud->current_time)
{
fprintf(fp, "LastTime %d\n", (int) mud->current_time );

}
else
{
fprintf(fp, "LastTime %d\n", ch->pcdata->last_time );
}

fprintf(fp, "LastImprove %d\n", ch->pcdata->last_improve);
fprintf(fp, "Playtime %d\n", (int) mud->current_time - ch->pcdata->last_connect);
fprintf(fp, "Jailtime %d\n", ch->pcdata->jailtime );
fprintf(fp, "Jaildate %d\n", ch->pcdata->jaildate );
fprintf(fp, "MailAddy %s~\n", ch->pcdata->mail_address );
fprintf(fp, "HtmlAddy %s~\n", ch->pcdata->html_address );
fprintf(fp, "Password %lld\n", ch->pcdata->password );
fprintf(fp, "Bamfin %s~\n", ch->pcdata->bamfin );
fprintf(fp, "Bamfout %s~\n", ch->pcdata->bamfout );
fprintf(fp, "Title %s~\n", ch->pcdata->title );
fprintf(fp, "Prefix %d\n", ch->pcdata->honorific );
fprintf(fp, "AttrPerm %d %d %d %d %d\n", ch->pcdata->perm_str, ch->pcdata->perm_int, ch->pcdata->perm_wis, ch->pcdata->perm_dex, ch->pcdata->perm_con);
fprintf(fp, "AttrMod %d %d %d %d %d\n", ch->pcdata->mod_str, ch->pcdata->mod_int, ch->pcdata->mod_wis, ch->pcdata->mod_dex, ch->pcdata->mod_con );
fprintf(fp, "DrFuThAi %d %d %d %d\n", ch->pcdata->condition[0], ch->pcdata->condition[1], ch->pcdata->condition[2], ch->pcdata->condition[3]);

for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
fprintf(fp, "Mclass %d %d\n", cnt, ch->pcdata->mclass[cnt] );
}

for (sn = 0 ; sn < MAX_SKILL ; sn++)
{
if (skill_table[sn].name != NULL && ch->pcdata->learned[sn] > 0)
{
if (multi(ch, sn) != -1)
{
fprintf(fp, "Skill %d '%s'\n", ch->pcdata->learned[sn], skill_table[sn].name );
}
}
}

for (sn = 0 ; sn < MAX_AREA ; sn++)
{
if (ch->pcdata->quest[sn])
{
fprintf(fp, "Qstb %d %3d ", MAX_QUEST_BYTES, sn);

for (cnt = 0 ; cnt < MAX_QUEST_BYTES ; cnt++)
{
fprintf(fp, "%d ", ch->pcdata->quest[sn][cnt]);
}
fprintf(fp, "\n");
}
}

fprintf(fp, "Speed %d\n", ch->speed);
fprintf(fp, "Reinc %d\n", ch->pcdata->reincarnation);
fprintf(fp, "Prev_hrs %d\n", ch->pcdata->previous_hours);
fprintf(fp, "Tact_v %d\n", ch->pcdata->tactical_size_v);
fprintf(fp, "Tact_f %d\n", ch->pcdata->tactical_flags);
fprintf(fp, "Tact_c %d\n", ch->pcdata->tactical_size_c);
fprintf(fp, "Tact_i %s~\n", ch->pcdata->tactical_index);

if (IS_IMMORTAL(ch))
{
if (ch->pcdata->a_range_lo && ch->pcdata->a_range_hi)
{
fprintf(fp, "A_Range %d %d\n", ch->pcdata->a_range_lo, ch->pcdata->a_range_hi);
}
}

fprintf(fp, "Pvnum %d\n", ch->pcdata->pvnum);
fprintf(fp, "Size_v %d\n", ch->pcdata->screensize_v );
fprintf(fp, "Size_h %d\n", ch->pcdata->screensize_h );
fprintf(fp, "Vt100_F %d\n", ch->pcdata->vt100_flags );
fprintf(fp, "Portsize %d\n", ch->pcdata->port_size );
fprintf(fp, "Prompt %s~\n", ch->pcdata->prompt_layout);
fprintf(fp, "Spam %d\n", ch->pcdata->spam );
fprintf(fp, "Clock %d\n", ch->pcdata->clock);
fprintf(fp, "Recall %d\n", ch->pcdata->recall);
fprintf(fp, "Death %d\n", ch->pcdata->death_room);
fprintf(fp, "Whichgod %d\n", ch->pcdata->god);
fprintf(fp, "Blocking %s~\n", ch->pcdata->block_list);
fprintf(fp, "AutoComm %s~\n", ch->pcdata->auto_command);
fprintf(fp, "AutoMode %d\n", ch->pcdata->auto_flags);

for (cnt = 0 ; cnt < 6 ; cnt++)
{
fprintf(fp, "History %d %d\n", cnt, ch->pcdata->history[cnt]);
}

fprintf(fp, "LastNote %d\n", ch->pcdata->last_note );

for (cnt = 0 ; cnt < MAX_TOPIC ; cnt++)
{
fprintf(fp, "Topic %d %d\n", cnt, ch->pcdata->topic_stamp[cnt]);
}

for (cnt = 0 ; cnt < COLOR_MAX ; cnt++)
{
fprintf(fp, "Color %2d %2d\n", cnt, ch->pcdata->color[cnt]);
}

for (cnt = 0 ; cnt < APPEAR_MAX ; cnt++)
{
fprintf(fp, "Appear %2d %2d\n", cnt, ch->pcdata->appearance[cnt]);
}

for (cnt = 0 ; cnt < MAX_ALIAS ; cnt++)
{
if (ch->pcdata->alias[cnt][0]!='\0')
{
fprintf(fp, "Alias %s~%s~\n", ch->pcdata->alias_c[cnt], ch->pcdata->alias[cnt]);
}
}



/*
castle stuff
*/
if (ch->pcdata->castle != NULL)
{
fprintf(fp, "Cstl_ent %d\n",ch->pcdata->castle->entrance);
fprintf(fp, "Cstl_dor %d\n",ch->pcdata->castle->door_room);
fprintf(fp, "Cstl_dir %d\n",ch->pcdata->castle->door_dir);
fprintf(fp, "Cstl_has %d\n",ch->pcdata->castle->has_backdoor);
fprintf(fp, "Cstl_cst %d\n",ch->pcdata->castle->cost);
fprintf(fp, "Cstl_nrm %d\n",ch->pcdata->castle->num_rooms);
fprintf(fp, "Cstl_nmo %d\n",ch->pcdata->castle->num_mobiles);
fprintf(fp, "Cstl_nob %d\n",ch->pcdata->castle->num_objects);
}

for (paf = ch->first_affect ; paf != NULL ; paf = paf->next)
{
if (paf->type < 0 || paf->type >= MAX_SKILL)
{
log_printf("save_char_obj: bad affect type: %d", paf->type);
continue;
}
fprintf(fp, "AffectData '%s' %d %d %d %d %lld\n", skill_table[paf->type].name, paf->duration, paf->modifier, paf->location, paf->bittype, paf->bitvector);
}

fprintf(fp, "Critical %d\n", ch->critical_hit_by );

if (ch->poison != NULL)
{
fwrite_poison_data( ch->poison, fp );
}

fprintf(fp, "PK_ATTACKS %d\n", MAX_PK_ATTACKS );

for (cnt = 0 ; cnt < MAX_PK_ATTACKS ; cnt++)
{
fprintf(fp, "%d %d %s~\n", ch->pcdata->last_pk_attack_time[cnt], ch->pcdata->last_pk_attack_pvnum[cnt], ch->pcdata->last_pk_attack_name[cnt]);
}

fprintf(fp, "End\n\n" );
pop_call();
return;
}


What do I need to modify here to allow cooldowns to save?

For loading player files, the only reference I could find was:

void load_players( void )
{
char letter;
FILE *fpList;
PVNUM_DATA *player;
int vnum;

push_call("load_players(void)");

log_printf("Loading %s…", PLAYER_LIST);

close_reserve();

if ((fpList = my_fopen(PLAYER_LIST, "r", FALSE)) == NULL)
{
perror( PLAYER_LIST );
exit( 1 );
}

for ( ; ; )
{
letter = fread_letter( fpList );

if (letter != 'P')
{
if (letter != '$')
{
log_printf("***WARNING*** load_players: bad format");
}
fread_to_eol(fpList);
break;
}
vnum = fread_number( fpList );

ALLOCMEM(player, PVNUM_DATA, 1);
player->date = fread_number( fpList );
player->flags = fread_number( fpList );
player->name = fread_string( fpList );

pvnum_index[vnum] = player;
}

if (fpList)
{
my_fclose( fpList );
}

open_reserve();

pop_call();
return;
}


I'm not really sure what to modify here as well. There is only 1 pfile in the game atm, my own, so I can just manually edit in the fields as necessary.
02 Dec, 2012, Rarva.Riendf wrote in the 17th comment:
Votes: 0
This code show you how a table is saved
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
fprintf(fp, "Mclass %d %d\n", cnt, ch->pcdata->mclass[cnt] );
}



And the method you look for to read those value is probably fread_char

You have all the syntax needed in those example.
03 Dec, 2012, triskaledia wrote in the 18th comment:
Votes: 0
I'm not sure which code base you're using, but on ROM you also have to define the variable (cooldowns in this case) in more than one place within the save.c to get it to save properly.
fwrite_char saves gold out and fread_char does something with gold under 'case G:'.
Again, not sure which code base you're using, so you might not have to define your variable within fread_char.

fwrite_char()
if (ch->gold > 0)
fprintf (fp, "Gold %ld\n", ch->gold);
else
fprintf (fp, "Gold %d\n", 0);


fread_char()
case 'G':
KEY ("Gold", ch->gold, fread_number (fp));
27 Dec, 2012, Scandum wrote in the 19th comment:
Votes: 0
You could try:

for (sn = 0 ; sn < MAX_SKILL ; sn++)
{
if (ch->cooldown[sn] > 0)
{
fprintf(fp, "Cooldown %d %d\n", sn, ch->cooldown[sn]);
}
}


Then in fread_char() you could define:

case 'C':
AKEY("Cooldown", ch->cooldown, fread_number(fp));
27 Dec, 2012, Rarva.Riendf wrote in the 20th comment:
Votes: 0
Wont work, you wrote multiple value from a table so you need to read multiple values.
0.0/27