17 Dec, 2006, cbunting wrote in the 1st comment:
Votes: 0
Hello All,
I've redone some code and idea multiple times and I've been close to achieving what I want but I just can't get it 100% right.

A mud I used to play has sublevels and this is where I had gotten the idea. However, I've been trying to do this without having to use a remort system or multiclassing.

General breakdown of levels:

Mortal Level 1 - 50 (Also show on Mortal Who)
Hero Level 51, Sublevel (001) - Sublevel (999) if wanted to go that high.

So basicly, once the player reaches level 51, they go on leveling but instead of raising the actual levels, they just advance in sublevels instead. But I thought this would be rather simple but I seem to be missing something.

In pc_data in merc.h, I have int sublevel;

In save.c, I put the sublevel code in fread_char and fwrite_char.

Now in update.c, gain_exp I have this

void gain_exp( CHAR_DATA *ch, int gain )
{
if ( IS_NPC(ch) || ch->level >= LEVEL_IMMORTAL )
return;

ch->exp = UMAX( exp_per_level(ch,ch->pcdata->exp_lvl), ch->exp + gain );
while ( ch->level < LEVEL_IMMORTAL && ch->exp >=
exp_per_level(ch,ch->pcdata->exp_lvl) * (ch->level+1))
{
send_to_char( "{MYou raise a level!!{x ", ch );

if (ch->level < LEVEL_HERO)
ch->level += 1;

if (ch->level == LEVEL_HERO)
ch->level += 0;
ch->pcdata->sublevel += 1;

advance_level( ch );
save_char_obj(ch);
}

return;
}


The thing is, is that once the char reaches level hero, I don't want to add to the level anymore, I want to add to the sublevel instead. I eventually plan on adding in a lord level with will have additional sublevels but so far, the code above seems to work but instead of the char gaining level 51 with +1 sublevel, you'll see it show Level 51 and the sublevel jumps to 304 or something instead of starting at one.

Any ideas?

Thanks for your time,
Chris
17 Dec, 2006, gazzy123 wrote in the 2nd comment:
Votes: 0
I think this line is he problem:

while ( ch->level < LEVEL_IMMORTAL && ch->exp >= exp_per_level(ch,ch->pcdata->exp_lvl) * (ch->level+1))


exp_per_level uses ch->level+1 but that doesn't change casue it wont increase the level so the exp needed is always the same and it increase sublevel by 1 (like every exp-point you gain) so if you get 100 exp froma mob then it should increase the sublevel to 100.

so you need to make acheck and see if ch->level == LEVEL_HERO then you want to use
exp_per_level(ch,ch->pcdata->exp_lvl) * (ch->pcdata->sublevel+1)

with sublevel (and level) dont know how you want it.

hope this helps out and that you understand me I'm not that good at explaining.. but I think thats the problem.

perhaps exp_per_level(ch,ch->pcdata->exp_lvl) * (ch->level+(ch->pcdata->sublevel+1)) is something to use.
18 Dec, 2006, cbunting wrote in the 3rd comment:
Votes: 0
Hello,
Thanks for the reply. However, I'm not wanting to change how exp is given. This is why I wanted to use sublevels. This way, the players level will stay at Level 51 while they advance in sublevels 1 - 999 or whatever. It makes it easier because builders can create hero mobs ranging in levels from Acutal level 51 - 60. So basicly, you can add an additional 100 areas for heros and they would only need to maintain the levels, as mentioned above which is 51 - 60..

As mentioned, I didn't want to change the exp gain.. That is fine for me as I already used bonuses in fight.c to figure out the exp gain for each level so it's fairly consistant.

What is happening with the above code is this.

I advance a char to level 50.. I kill mobs and gain a level. So I become Level 51, Sublevel 1.. Thats exactly what I want. But then, when I try to gain another level, the mud crashes where I would normally see the, you raise another level. So once the char has reached level 51, the mud crashes because it's not changing anything or adding the += 1 to the sublevel. Instead, after I restart the mud and log back in with the test char, I'll be at level 51, Sublevel 305.. It's jumping 304 levels instead of just 1.

Sorry if this is confusing. I've tried this a million different ways in the last 2 days.

Chris
18 Dec, 2006, Davion wrote in the 4th comment:
Votes: 0
You're scoping is lacking here. If you change this ->

if (ch->level == LEVEL_HERO)
ch->level += 0;
ch->pcdata->sublevel += 1;


to
if(ch->level == LEVEL_HERO)
ch->pcdata->sublevel++;


You should get your desired effect.
18 Dec, 2006, cbunting wrote in the 5th comment:
Votes: 0
That also didn't work either. Here is all the code that I am using.

Everything this round seems to be working except for the gain_exp function. If anyone can help figure this out. I will release all of this.

merc.h pc_data structure.

int level;
+ int sublevel;


save.c fwrite_char

fprintf( fp, "Level        %d\n",	ch->level		);
+ fprintf( fp, "Sublevel %d\n", ch->sublevel );


save.c fread_char

Under case S

KEY( "Security",    ch->pcdata->security,	fread_number( fp ) );	/* OLC */
+ KEY( "Sublevel", ch->sublevel, fread_number( fp ) );


update.c

void gain_exp( CHAR_DATA *ch, int gain )
{
if ( IS_NPC(ch) || ch->level >= LEVEL_IMMORTAL )
return;

ch->exp = UMAX( exp_per_level(ch,ch->pcdata->exp_lvl), ch->exp + gain );
while ( ch->level < LEVEL_IMMORTAL && ch->exp >=
exp_per_level(ch,ch->pcdata->exp_lvl) * (ch->level+1))
{
send_to_char( "{MYou raise a level!!{x ", ch );

if (ch->level < LEVEL_HERO)
ch->level += 1;
return;

if (ch->level == LEVEL_HERO)
ch->sublevel ++;
return;

advance_level( ch );
save_char_obj(ch);
}

return;
}


act_wiz.c do_advance

void do_advance( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg1[MAX_INPUT_LENGTH];
bool sublevel = FALSE;
CHAR_DATA *victim;
int level;
int iLevel;

argument = one_argument( argument, arg1 );

if( arg1[0] == '\0' || argument[0] == '\0' )
{
send_to_char( "Syntax: advance <char> <level>\n\r", ch );
return;
}

if ( ( victim = get_char_world( ch, arg1 ) ) == NULL )
{
send_to_char( "That player is not here.\n\r", ch);
return;
}

if ( IS_NPC(victim) )
{
send_to_char( "Not on NPC's.\n\r", ch );
return;
}

if( victim->sublevel )
{
argument = one_argument( argument, arg1 );
if( argument[0] == '\0' || !is_number( argument )
|| ( str_cmp( arg1, "level" ) && str_cmp( arg1, "sublevel" ) ) )
{
send_to_char( "For chars that are heros/lords, please specify level or sublevel.\n\r", ch );
return;
}
if( !str_cmp( arg1, "sublevel" ) )
sublevel = TRUE;
}

if( !is_number( argument ) )
{
send_to_char( "Usage: advance <character> [sublevel|level] <level>\n\r", ch );
return;
}

level = atoi( argument );

if( level <= 0 || level > LEVEL_HERO )
{
sprintf( buf, "Advance within range 1 to %d.\n\r", LEVEL_HERO );
send_to_char(buf,ch);
return;
}
if( victim->sublevel && ( level > victim->level
|| ( sublevel && level <= victim->sublevel ) ) )
{
send_to_char(
"For hero or lords, you may only demote them to a\n\r"
"lower level, or promote them sublevels.\n\r", ch );
return;
}

/*
* Lower level:
* Reset to level 1.
* Then raise again.
* Currently, an imp can lower another imp.
* – Swiftest
*/
if( !sublevel && level <= victim->level )
{
int temp_prac;
int temp_train;

send_to_char( "Lowering a player's level!\n\r", ch );
send_to_char( "**** OOOOHHHHHHHHHH NNNNOOOO ****\n\r", victim );
temp_prac = victim->practice;
temp_train = victim->train;
victim->level = 1;
victim->sublevel = 0;
victim->exp = exp_per_level(victim,victim->pcdata->exp_lvl);
victim->max_hit = 20;
victim->max_mana = 100;
victim->max_move = 100;
victim->hit = victim->max_hit;
victim->mana = victim->max_mana;
victim->move = victim->max_move;
advance_level( victim );
victim->practice = temp_prac;
victim->train = temp_train;
}
else
{
send_to_char( "Raising a player's level!\n\r", ch );
send_to_char( "**** OOOOHHHHHHHHHH YYYYEEEESSS ****\n\r", victim );
}

if( victim->sublevel > 0 )
{
for( iLevel = victim->sublevel; iLevel < level; iLevel++ )
{
victim->sublevel += 1;
advance_level( victim );
}
}
else
{
for( iLevel = victim->level; iLevel < level; iLevel++ )
{
victim->level += 1;
advance_level( victim );
}
}
sprintf(buf,"You are now level %d.\n\r",victim->level);
send_to_char(buf,victim);
victim->exp = exp_per_level(victim,victim->pcdata->exp_lvl)
* UMAX( 1, victim->level );
victim->trust = 0;
save_char_obj(victim);
return;
}
18 Dec, 2006, Tyche wrote in the 6th comment:
Votes: 0
cbunting said:
void gain_exp( CHAR_DATA *ch, int gain )
{
if ( IS_NPC(ch) || ch->level >= LEVEL_IMMORTAL )
return;

ch->exp = UMAX( exp_per_level(ch,ch->pcdata->exp_lvl), ch->exp + gain );
while ( ch->level < LEVEL_IMMORTAL && ch->exp >=
exp_per_level(ch,ch->pcdata->exp_lvl) * (ch->level+1))
{
send_to_char( "{MYou raise a level!!{x ", ch );

if (ch->level < LEVEL_HERO)
ch->level += 1;
return;

if (ch->level == LEVEL_HERO)
ch->sublevel ++;
return;

advance_level( ch );
save_char_obj(ch);
}

return;
}


Oh for Christ sake. How many years did you play with ROM, Envy and Merc, again!?
Hint: Learn to use blocks. C ain't flipping Python.
18 Dec, 2006, cbunting wrote in the 7th comment:
Votes: 0
Hello all,

The is an except of what I'm trying to accomplish..
Quote
Characters start as newbies at level 1, and continue up the ranks by gaining experience points, and levelling, or reaching the next level. The first tier comprises levels 1-50, and is called the 'low mortal' tier. The second tier starts at level 51, and is called the 'hero' tier. At this point, the player stops gaining regular levels, but gains sublevels. Because of this, a hero 500 character could be level 51, but sublevel 500. After 'hero' sublevel 500, the player has the option of morphing to a 'lord', which is level 125. After sublevel 500 of Lord, the player can become a Legend, which is level 250.


Now, unnamed mud talks about tiers. I figured I could achive the same thing by simply using the following:

pc_data…
int level;
int sublevel;

Thats what I was trying to get working above but would then move on to:

int level;
int levelhero;
int levellord;

level = 1 - 50
levelhero - 51, Sublevel (001) - (999)
levellord - 125, Sublevel (001) - (999)

Would this be the right way to go about doing something like this? I've looked at the multi-tier code that I have for Rot but the thing is, I don't want to have remorting. If I need to use tiers, I'd like to have tier 1 for levels 1 - 50, tier 2 for levels 51(001) - (999) and so one. But even most of the code for tier systems have the players starting back at level one. This is what I don't want. I want to start them on a sublevel upon reaching a new tier.

I just don't want to have level 2000 mobiles.. I'd rather have level 60 mobiles that even level 51(600) Hero's can still gain exp from.

Any ideas on this?

Thanks in advance,
Chris
18 Dec, 2006, cbunting wrote in the 8th comment:
Votes: 0
Quote
Oh for Christ sake. How many years did you play with ROM, Envy and Merc, again!?
Hint: Learn to use blocks. C ain't flipping Python.


Well, I've been doing it long enough to try and give ideas to people when they are having problems. If you knew how to do it, then why didn't you give some idea on what I am doing wrong?

I asked for help because I'm not 100% sure if I am going about this the right way.

Thanks for your reply about using blocks and reading a book…

Care to tell me what is wrong with this version then cause it ain't workin either?

void gain_exp( CHAR_DATA *ch, int gain )
{
char Info[MAX_INPUT_LENGTH];
int i;

if( IS_NPC( ch ) || ch->level >= LEVEL_HERO )
return;

ch->exp -= UMIN( get_tnl( ch ) * 2, gain );
while( ch->level < LEVEL_HERO && ch->exp <= 0 )
{
ch->exp += get_tnl( ch );

if( ch->sublevel )
{
ch->sublevel++;
if( ch->sublevel > ch->level )
{
ch->sublevel = 0;
ch->level++;
else
{
ch->level++;
if( ch->level == 51 )
do_help( ch, "GRATS_HERO" );
}
advance_level( ch, FALSE );
}

while( ch->level == LEVEL_HERO && ch->exp <= 0 )
{
ch->exp += get_tnl( ch );
if( ch->sublevel < 1000 )
ch->sublevel++;

if( ch->exp > 0 )
advance_level( ch, FALSE );
else
advance_level( ch, TRUE );
}

return;
}
18 Dec, 2006, Tyche wrote in the 9th comment:
Votes: 0
cbunting said:
Thanks for your reply about using blocks and reading a book…


I said nothing whatsoever about reading a damn book.
Of course if you think it would help…

cbunting said:
Care to tell me what is wrong with this version then cause it ain't workin either?
-snip-


I can tell at brief glance that it will not compile correctly at all.
Hint: Blocks again.

And why the hell should I bend over to help someone that cannot code the trivial in C, yet throws around code theft allegations without even a shred of evidence?

Screw you.
18 Dec, 2006, Conner wrote in the 10th comment:
Votes: 0
cbunting said:
if( ch->sublevel )
{
ch->sublevel++;
if( ch->sublevel > ch->level )
{
ch->sublevel = 0;
ch->level++;
else
{
ch->level++;
if( ch->level == 51 )
do_help( ch, "GRATS_HERO" );
}

You're not closing your second brace: there should be a } right beore your else.
18 Dec, 2006, Davion wrote in the 11th comment:
Votes: 0
More specifically, you're not closing -both-

You have

if( ch->sublevel )
{
ch->sublevel++;
if( ch->sublevel > ch->level )
{
ch->sublevel = 0;
ch->level++;
else
{
ch->level++;
if( ch->level == 51 )
do_help( ch, "GRATS_HERO" );
}

You want:

if( ch->sublevel )
{
ch->sublevel++;
if( ch->sublevel > ch->level )
{
ch->sublevel = 0;
ch->level++;
}
}
else
{
ch->level++;
if( ch->level == 51 )
do_help( ch, "GRATS_HERO" );
}


For every { you need a }. When you don't use that with an if/else/for/while/do…etc, it's scope only spans the very next statement.
19 Dec, 2006, cbunting wrote in the 12th comment:
Votes: 0
Hello All,

As far as the code, I've been trying to get this going for the last 3 days. I've tried to do it numberous ways so I'm sorry if these test bits of code were not properly formatted. I mean, No one aparently has tried to do anything with sublevels that is mentioned online because I've searched every search engine, mud forum and anything else I can think of.

The problem hasn't been so much as how to code it. It's been more along the lines of how to actually do it. I've tried using tiers, mortal levels = tier 1, hero, tier 2 and so one. I've also removed all references to LEVEL_HERO where it would affect the overall level of the mud in areas such as gain_exp. But for some reason, things get out of whack when they become Hero, sublevel one… The mud crashes when it should hit level 51, seublevel 2 but there is no cor sile or anything. When I logg back in, the char is hero sublevel 300 or some so the crashes come from the overflow in write_to_descriptor. But I still can't figure out why the levels would affect that.

In regards to Tyhche..
Quote
yet throws around code theft allegations without even a shred of evidence?


The Diku codebase that offered OLC is and has been downloadable online long before Locke released OLC in the Isles…
19 Dec, 2006, Guest wrote in the 13th comment:
Votes: 0
I can't tell for sure what the intent of the code was due to the bad formatting, but this version is how I interpret it - no idea if it will work as you want though.

void gain_exp( CHAR_DATA *ch, int gain )
{
char Info[MAX_INPUT_LENGTH];
int i;

if( IS_NPC( ch ) || ch->level >= LEVEL_HERO )
return;

ch->exp -= UMIN( get_tnl( ch ) * 2, gain );
while( ch->level < LEVEL_HERO && ch->exp <= 0 )
{
ch->exp += get_tnl( ch );

if( ch->sublevel )
{
ch->sublevel++;
if( ch->sublevel > ch->level )
{
ch->sublevel = 0;
ch->level++;
}
else
{
ch->level++;
if( ch->level == 51 )
do_help( ch, "GRATS_HERO" );
}
advance_level( ch, FALSE );
}
}

while( ch->level == LEVEL_HERO && ch->exp <= 0 )
{
ch->exp += get_tnl( ch );
if( ch->sublevel < 1000 )
ch->sublevel++;

if( ch->exp > 0 )
advance_level( ch, FALSE );
else
advance_level( ch, TRUE );
}
return;
}


As far as the OLC crap, this really wasn't the place to drag that in at random and I fail to see how attacking each other over it is helping anyone.
0.0/13