Login
User Name:

Password:



Register
Forgot your password?
Vote for Us!
auth_update crash
Dec 23, 2017, 10:15 pm
By Remcon
check_tumble
Dec 18, 2017, 7:21 pm
By Remcon
parse description bug
Dec 15, 2017, 10:08 pm
By Remcon
Couple bugs
Dec 12, 2017, 5:42 pm
By Remcon
Bug in disarm( )
Nov 12, 2017, 6:54 pm
By GatewaySysop
LoP 1.46
Author: Remcon
Submitted by: Remcon
LOP 1.45
Author: Remcon
Submitted by: Remcon
LOP Heroes Edition
Author: Vladaar
Submitted by: Vladaar
Heroes sound extras
Author: Vladaar
Submitted by: Vladaar
6Dragons 4.3
Author: Vladaar
Submitted by: Vladaar
Users Online
CommonCrawl, Yahoo!, Yandex

Members: 0
Guests: 7
Stats
Files
Topics
Posts
Members
Newest Member
478
3,708
19,242
612
Jacki72H
Today's Birthdays
Evoru (32)
Related Links
» SmaugMuds.org » General » General Discussions » Aurora's Ratings snippet
Forum Rules | Mark all | Recent Posts

Aurora's Ratings snippet
< Newer Topic :: Older Topic >

Pages:<< prev 1 next >>
Post is unread #1 Apr 2, 2006, 4:43 pm   Last edited Apr 2, 2006, 4:45 pm by Harbinger
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

Ok, So I threw in Aurora's Ratings snippet, and compiled it, and all that good stuff. and I followed the directions for making it persist over reboots. But.. it's not. It's not persisting over reboots, shutdowns, or hotboots. it's like instead of saving the file, it's clearing it out... And I'm at a loss. I thought maybe it might be a permissions thing, so I double checked the permissions, and the bootlog, and nothing. No bugs. But when I log a couple morts, to make ratings data, and hotboot, what was there before, isn't there now.

I've also made sure it closes out the playerfiles after it validates that they are an existing character, but if anyone has any ideas, I'd like to hear them. Cuz I'm at a loss.

Currently running: SmaugFUSS 1.7 with up to date bug fixes.

[EDIT]: Or if you know a better ratings system then Aurora's.. You know, feel free to pass that along. :P
       
Post is unread #2 Apr 3, 2006, 11:27 pm
Go to the top of the page
Go to the bottom of the page

Conner
Sorcerer
GroupMembers
Posts870
JoinedMay 8, 2005

You have to change the valid_player function at the bottom of ratings.c to this:
bool valid_player( char *name)
{
   char strsave[MAX_INPUT_LENGTH];
   FILE *fp = NULL;

   sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower(name[0]), capitalize( name ) );
   if ( !( fp = fopen2( strsave, "r" ) ) )
      return TRUE;
   fclose2( fp );
   fp = NULL;

   sprintf( strsave, "%s%s", GOD_DIR, capitalize( name) );
   if ( !( fp = fopen( strsave, "r" ) ) ) /* Uhoh its an imm */
    return TRUE;   
   fclose( fp );
   fp = NULL;
 
   return FALSE;
}

At least that's what I did to fix the same problem.
       
Post is unread #3 Apr 4, 2006, 10:05 am
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

Thanks, Conner, that did the trick, I had changed it so that it was closing them out, but I guess I didn't change it right.
       
Post is unread #4 Apr 5, 2006, 1:00 pm
Go to the top of the page
Go to the bottom of the page

Conner
Sorcerer
GroupMembers
Posts870
JoinedMay 8, 2005

I had the same problem, once Remcon helped me figure out how to make it close the pfiles so I wouldn't get weird bugs from my avatar level players that left them stripped of all gear at logon the ratings kept trying to reset themselves on me at every (hot/re)boot, so I got Dragona to help me try to see what might still be wrong since the scores.dat file was emptying itself like that only after Remcon's changes and we figured we had nothing to lose by trying to see what would happen if we reversed the TRUE/FALSE returns and it seemed to do the trick. :)
       
Post is unread #5 Apr 5, 2006, 1:59 pm   Last edited Apr 5, 2006, 2:04 pm by Remcon
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,868
JoinedJul 26, 2005

odd
stock wise
bool valid_player( char *name)
{
   char strsave[MAX_INPUT_LENGTH];
   FILE *fp = NULL;

   sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower(name[0]), capitalize( name ) );
   if ( ( fp = fopen( strsave, "r" ) ) != NULL ) ;
   else /* pfile gone */
   return FALSE;   

   sprintf( strsave, "%s%s", GOD_DIR, capitalize( name) );
   if ( ( fp = fopen( strsave, "r" ) ) != NULL ) /* Uhoh its an imm */
    return FALSE;   
   else ;
 
   return TRUE;
}

so lets see i think id go with it like this for the same affect
bool valid_player( char *name)
{
   char strsave[MAX_INPUT_LENGTH];
   FILE *fp = NULL;

   /* If its an imm then return false */
   sprintf( strsave, "%s%s", GOD_DIR, capitalize( name) );
   if( ( fp = fopen( strsave, "r" ) ) ) /* Uhoh its an imm */
   {
      fclose( fp );
      fp = NULL;
      return FALSE;
   }
  
   /* if its a player and it exist return true */
   sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower(name[0]), capitalize( name ) );
   if( ( fp = fopen( strsave, "r" ) ) )
   {
      fclose( fp );
      fp = NULL;
      return TRUE;
   }

   /* other wise return FALSE, nothing is open so nothing to close here */
   return FALSE;
}

In Conners case he could use fopen2 and fclose2 instead for each :)
Sometime Samson should fix that snippet not closeing the file.
       
Post is unread #6 Apr 6, 2006, 9:59 pm   Last edited Apr 7, 2006, 6:51 pm by Conner
Go to the top of the page
Go to the bottom of the page

Conner
Sorcerer
GroupMembers
Posts870
JoinedMay 8, 2005

Here's Remcon's cleaned up and tested version of Aurora's Ratings snippet:
/* Ratings Snippet by Aurora (EternalEmpress@LostProphecy.com)
 * Installation:
 * 
 * in mud.h find:
 * struct	pc_data
 * {
 * 
 * At the end of this structure add:
 *     int			score;	/* current player score */
 * 
 * Then find:
 * void	update_aris	args( ( CHAR_DATA *ch) );
 * And add:
 * void	calc_score	args( ( CHAR_DATA *ch) );
 * 
 * Then find:
 * DECLARE_DO_FUN(	do_rank	        );
 * and add:
 * DECLARE_DO_FUN(	do_ratings	        );
 * 
 * 
 * Next In act_comm.c find:
 *     update_aris(ch);     /* update char affects and RIS */
 * And after it add:
 *     calc_score(ch);     /* update char ratings score */
 * 
 * 
 * In tables.c you'll need to hunt out 
 *	if ( !str_cmp( name, "do_rank" ))		return do_rank;	
 * and add:
 * 	if ( !str_cmp( name, "do_ratings" ))		return do_ratings;	
 * Then:
 *     if ( skill == do_rank )		return "do_rank";
 * and add:
 *     if ( skill == do_ratings )		return "do_ratings";
 * 
 * Finally you will need to add this file to your makefile. Add it as:
 * ratings.o in the O_FILES and ratings.c in the C_FILES
 * 
 * Once all changes are made you will require a make clean or quits will crash you.
 * After rebooting use cedit to add ratings: cedit ratings add do_ratings
 * Whenever a player (not imm) typs save they're rating will adjust.
 * 
 * Copyright: This file retains no copyright. I release it into public domain.
 * You can give me credit for it if you want, or not if you dont. 
 */

#include <ctype.h>
#include "mud.h"

typedef struct score_data SCORE_DATA;
struct score_data
{
   char *name;
   int score;
   SCORE_DATA *next;
   SCORE_DATA *prev;
};

SCORE_DATA *first_score;
SCORE_DATA *last_score;
#define MAX_SCORES 10  /* variable for easy adjustment of how many to display */

int score_count; /* keeps track of how many scores are in memory */

/* local functions */
void replace_score args( ( CHAR_DATA *ch) );
bool valid_player args( ( char *name) );
void fix_score_length( void );

/*
 * This is the function that actually tallies a persons score and sets it up
 * to add it to the list, be sure to add it to do_save so that saving will adjust
 * the players scores
 */
void calc_score( CHAR_DATA *ch )
{
   int score = 0;

   if( IS_NPC( ch ) ) /* Mobiles dont have pcdata */
      return;

   if( IS_IMMORTAL( ch ) ) /* Dont want to clutter your table with imms. */
      return;

   /* level formula */
   score += ch->level; /*  adds 1 to 50 */
   score += ch->hitroll; 
   score += ch->damroll;
   score -= ch->armor;  

   /*
    * note this subtracts ac values. This is only a penalty if they have a positive ac,
    * which is considered a bad thing. -300 is the av ac generally... If you subtract 
    * negative 300 from a value thats the equivalent of +300, this one in particular you'll 
    * be needing to adjust to suit your own mud and desires
    */
   score += ch->mod_str / 5; /* (Adds 1 to 5) */
   score += ch->mod_int / 5;
   score += ch->mod_wis / 5;
   score += ch->mod_dex / 5;
   score += ch->mod_con / 5;
   score += ch->mod_cha / 5;
   score += ch->mod_lck / 5;
   score += ch->gold; 

   /* Now that we've calculated the score its time to set it */
   ch->pcdata->score = score;
   replace_score( ch );  /* use the data we just collected */
   return;
}

/* The actual insertion of a new score */
void add_score( CHAR_DATA *ch )
{
   int value = ch->pcdata->score;
   SCORE_DATA *score, *newscore;
   int i;

   if( IS_NPC( ch ) )
      return;

   for( i = 1, score = first_score ; i <= MAX_SCORES ; score = score->next, i++ )
   {
      if( !score ) /* there are empty slots at end of list, add there */
      {
         CREATE( newscore, SCORE_DATA, 1 );
         newscore->name = STRALLOC( ch->name );
         newscore->score = value;
         LINK( newscore, first_score, last_score, next, prev );
         score_count++;
         break;
      }
      /* This section inserts the higher value into the higher slot */
      else if( value > score->score )
      {
         CREATE( newscore, SCORE_DATA, 1 );
         newscore->name = STRALLOC( ch->name );
         newscore->score = value;
         INSERT( newscore, score, first_score, next, prev );
         score_count++;
         break;
      }
   }

   fix_score_length( );
   save_scores( );
   return;
}

/*
 * This is used to determine ensure an existing score is removed before a new one
 * is added, so that you dont have repeats and so if a persons score drops, its actually
 * changed instead of staying forever at its highest point
 */
void replace_score( CHAR_DATA *ch )
{
   SCORE_DATA *score;

   if( IS_NPC( ch ) || IS_IMMORTAL( ch ) )
      return;

   for( score = first_score; score; score = score->next )
      if( !str_cmp( ch->name, score->name ) )
         break;

   if( !score || ( score->name != ch->name ) )
   {
      add_score( ch );
      return;
   }

   UNLINK( score, first_score, last_score, next, prev );
   STRFREE( score->name );
   DISPOSE( score );
   score_count--;

   add_score( ch );
   return;
}

/*
 * This will make sure it stays at only the max you want to display 
 * by checking to see how many total there are and cutting off the last one until
 * there are only the amount you want, default is 10
 */
void fix_score_length( void )
{
   SCORE_DATA *score;
   short x;

   x = score_count;
   while( x > MAX_SCORES )
   {
      score = last_score;
      UNLINK( score, first_score, last_score, next, prev );
      STRFREE( score->name );
      DISPOSE( score );
      score_count--;
      x = score_count;
   }
}

/* the actual command to see whos where */
void do_ratings( CHAR_DATA *ch, char *argument )
{
   SCORE_DATA *score;
   short counter = 0;

   ch_printf( ch, "     The Top %d Players.\n\r", score_count );
   send_to_char( "      Name        Score\n\r", ch );
   send_to_char( "-------------------------------\n\r", ch );
   for( score = first_score; score; score = score->next )
   {
      ++counter;
      ch_printf( ch, "[%2d] %-12s %-32d\n\r", counter, score->name, score->score);
   }
   ch_printf( ch, "-------------------------------\n\r";);
   return;
}

/*
 *  Additions to make persist over reboots.
 * in db.c look for: void	load_corpses	args( ( void ) );   and add:
 * void    load_scores     args( ( void ) );
 *
 * Then find: init_area_weather();
 * and add load_scores();  after it.
 * This will setup the routines to load you scores.dat when the mud opens.
 *
 * To make this section work you will need to place a call to save_scores()
 * just after fix_score_length in add_score, ie:
 * fix_score_length();
 * save_scores();
 */
#define SCORES_FILE SYSTEM_DIR "scores.dat"  /* File to store the scores */

bool valid_player( char *name )
{
   char strsave[MAX_INPUT_LENGTH];
   FILE *fp = NULL;

   /* If its an imm then return false */
   sprintf( strsave, "%s%s", GOD_DIR, capitalize( name ) );
   if( ( fp = fopen( strsave, "r" ) ) ) /* Uhoh its an imm */
   {
      fclose( fp );
      return FALSE;
   }
  
   /* if its a player and it exist return true */
   sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower(name[0]), capitalize( name ) );
   if( ( fp = fopen( strsave, "r" ) ) )
   {
      fclose( fp );
      return TRUE;
   }

   /* other wise return FALSE, nothing is open so nothing to close here */
   return FALSE;
}

void load_scores( void )
{
   FILE *fp;
   SCORE_DATA *score;
   
   score_count = 0;

   if( !( fp = fopen( SCORES_FILE, "r" ) ) )
   {
      bug( "%s: Cannot open %s for reading", __FUNCTION__, SCORES_FILE );
      return;
   }

   for( ; ; )
   {
      char *word;
      
      word = fread_word( fp );
      
      if( !str_cmp( word, "Score" ) )
      {
         CREATE( score, SCORE_DATA, 1 );
         score->score = fread_number( fp );
         score->name = fread_string( fp );
         if( valid_player( score->name ) )
         {
            LINK( score, first_score, last_score, next, prev );
            score_count++;
         }
         else
         {
            STRFREE( score->name );
            DISPOSE( score );
         }
         continue;
      }
         
      if( !str_cmp( word, "End" ) )
      {
         fclose( fp );
         fp = NULL;
         return;
      }
  }
  /* Shouldn't get here but if we do close and return */
  fclose( fp );
  return; 
}

void save_scores( void )
{
   SCORE_DATA *score;
   FILE *fp;

   if( !( fp = fopen( SCORES_FILE, "w" ) ) )
   {
      bug( "%s: Cannot open %s for writing", __FUNCTION__, SCORES_FILE );
      perror( SCORES_FILE );
      return;
   }

   for( score = first_score; score; score = score->next )
      fprintf( fp, "Score %d %s~\n", score->score, score->name );
   fprintf( fp, "End\n\n" );
   fclose( fp );
   fp = NULL;
   return;
}

At Remcon's insistance, we're not to add his name to credit for any of this, it's all to go to Aurora, but above is what he came up with to fix/clean up Aurora's original after we tested it and made sure it all worked as it now stands.
       
Post is unread #7 Apr 7, 2006, 6:04 am
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,868
JoinedJul 26, 2005

heh, when you get a chance Conner can you edit the post above and take out the extra spaces?
As for the not adding my name see no point, Aurora did most of it all I did was modify how some of it worked to get rid of a few problems.
       
Post is unread #8 Apr 7, 2006, 6:52 pm
Go to the top of the page
Go to the bottom of the page

Conner
Sorcerer
GroupMembers
Posts870
JoinedMay 8, 2005

I got rid of the extra blank lines... I don't know why the forum software likes to add them like that though, it's pretty annoying. *grumble*

That didn't stop the original smaug devs from commenting everything they modified throughout the orginal smaug code. ;)
       
Post is unread #9 Apr 8, 2006, 12:32 pm
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

Ive wondered about the extra lines myself, But Thanks for posting the rewrite, Hehe. I changed the way it figures up the scores for mine, I really don't want the scores to end up being in the 100million+ area, so I assigned different score values for different amounts of money. But Conner's right, Take some credit for what you did Remcon. :P
       
Post is unread #10 Apr 8, 2006, 1:05 pm   Last edited Apr 8, 2006, 1:06 pm by Conner
Go to the top of the page
Go to the bottom of the page

Conner
Sorcerer
GroupMembers
Posts870
JoinedMay 8, 2005

Yeah, I changed the way the score is calculated on mine too, who needs players having scores that appear totally unattainable for new players? I also made mine display the top 50 in a two column display. But I also award the top 35 of them glory each month based on their rank, the person in first place gets 35 glory, second place gets 34 glory, 3rd place gets 33, and so on down to 35th place who gets one glory point.
       
Post is unread #11 Apr 9, 2006, 11:54 am
Go to the top of the page
Go to the bottom of the page

Kayle
Off the Edge of the Map
GroupAdministrators
Posts1,195
JoinedMar 21, 2006

That's not a bad idea, Think I'll probably implement a system something like that when mine opens for players.
       
Post is unread #12 Apr 9, 2006, 7:43 pm
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,639
JoinedJan 1, 2002

Conner said:

I got rid of the extra blank lines... I don't know why the forum software likes to add them like that though, it's pretty annoying. *grumble*


As Oblivion releases me for the moment - what extra blank lines were these? The forum software only displays the code as it's entered. So if it had any hidden hard returns, those would have been exposed here.
       
Pages:<< prev 1 next >>