Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ No more stat rolling

No more stat rolling

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Lazerus   (4 posts)  Bio
Date Thu 08 Jun 2006 05:45 PM (UTC)

Amended on Thu 08 Jun 2006 05:46 PM (UTC) by Lazerus

Message
Im fairly new to coding so give me a break on this.

im using swr 1.2 fuss
Putty to conect to my host, and winscp to edit sourcecode files.

Instead of having the stats pulled from a number range, I want to set a number, have the race tables add to this and then display the stats in table like format and then have the user select a stat number and then add a value to it. The value they added would then be subtracted from a 'statpool' and if they went below this it would return a message saying they do not have that many stats to spend.


This is what I have so far, most of it is probably wrong though.

case CON_ROLL_STATS:

ch->perm_str = 13;
ch->perm_int = 13;
ch->perm_wis = 13;
ch->perm_dex = 13;
ch->perm_con = 13;
ch->perm_cha = 13;

ch->perm_str += race_table[ch->race].str_plus;
ch->perm_int += race_table[ch->race].int_plus;
ch->perm_wis += race_table[ch->race].wis_plus;
ch->perm_dex += race_table[ch->race].dex_plus;
ch->perm_con += race_table[ch->race].con_plus;
ch->perm_cha += race_table[ch->race].cha_plus;

ch->perm_str + stradd;
ch->perm_int + intadd;
ch->perm_wis + wisadd;
ch->perm_dex + dexadd;
ch->perm_con + conadd;
ch->perm_cha + chaadd;

sprintf( buf, "\r\n1.STR: %d/27 2.INT: %d/27 3.WIS: %d/27 4.DEX: %d/27 5.CON: %d/27 6.CHA: %d/27\r\n",
ch->perm_str, ch->perm_int, ch->perm_wis, ch->perm_dex, ch->perm_con, ch->perm_cha );

write_to_buffer( d, buf, 0 );
write_to_buffer( d, "\r\nEnter the Number of the Stat you would like to change. ", 0 );
d->connected = CON_STATS_OK;
break;

case CON_STATS_OK:

switch ( argument[0] )
{
case '1':
case 'one':
write_to_buffer( d, "\r\nYou have Chosen Str. How much would you like to add, Str= %d/27, you have %d points left in your stat pool.\r\n",
ch->perm_str, Statpool;


I just started a class in programming about a month ago so I am really new to this.

Thanks in advance for any help I get.


Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #1 on Thu 08 Jun 2006 09:22 PM (UTC)

Amended on Thu 08 Jun 2006 09:25 PM (UTC) by Nick Gammon

Message
I think you are on the right track. You need a one or two more "states" in nanny. Initially you will allocate their base stats and give them a figure in their statpool (which will need to be stored as part of the character structure).

Then (like you are doing) display the current stats *and* the number left in the statpool, and ask which one to modify. If you want two questions, you will need two more states, eg.


Currently: Str: 5 Int: 9 Wis: 10 Dex: 8 Con: 7 cha: 14
You have 13 stats available to allocate.
Which stat to modify? (1 = str, 2 = agi, 3 = wis ... etc.): 3


then (if they answer 3):


Add or subtract how much from wis? (from -5 to +5) ...


You could keep looping until the statpool is zero, and then proceed with the rest of the nanny states.

You would need checks that they don't make a particular stat ridiculous (like -5 for int, or +50 for str).

Personally I think this is a very good idea, as it will reduce the requirement for players to write "stat rollers".

BTW, you can't do this:


case 'one':


The field argument[0] is a single byte, it will never be 'one'.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Lazerus   (4 posts)  Bio
Date Reply #2 on Fri 09 Jun 2006 01:04 AM (UTC)

Amended on Fri 09 Jun 2006 01:06 AM (UTC) by Lazerus

Message
Alright, im going to need a bit more info on the 'states' thing. And how would I accept the input from the user for defining the stradd etc...

Any help would be appreciated.
-Laz-
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #3 on Fri 09 Jun 2006 05:30 AM (UTC)

Amended on Fri 09 Jun 2006 05:31 AM (UTC) by Nick Gammon

Message
In mud.h file is an enum of all the "states" that player can be in:


/*
 * Connected state for a channel.
 */
typedef enum
{
   CON_GET_NAME = -99,
   CON_GET_OLD_PASSWORD, CON_CONFIRM_NEW_NAME,
   CON_GET_NEW_PASSWORD, CON_CONFIRM_NEW_PASSWORD,
   CON_GET_NEW_SEX, CON_GET_NEW_CLASS, CON_READ_MOTD,
   CON_GET_NEW_RACE, CON_GET_EMULATION,
   CON_GET_WANT_RIPANSI, CON_TITLE, CON_PRESS_ENTER,
   CON_WAIT_1, CON_WAIT_2, CON_WAIT_3,
   CON_ACCEPTED, CON_GET_PKILL, CON_READ_IMOTD,

/* Uncomment this if using Samson's Reroll code */
/* CON_ROLL_STATS, */

   CON_COPYOVER_RECOVER, CON_PLAYING = 0,

/* Uncomment this if using Samson's delete code */
/* CON_DELETE, */

/* Uncomment this if using Mudworld's Oasis OLC port */
/* CON_OEDIT,		 CON_MEDIT,			CON_REDIT, */

/* Uncomment this section if using Samson's Shell Code */
/* CON_FORKED, CON_IAFORKED, */

   CON_EDITING
} connection_types;


When a new player connects they start off in CON_GET_NAME state, where any input from them is considered to be their name. There is a switch statement in the nanny routine in comm.c, which switches control to the appropriate handler for the current state.

Eventually they end up in CON_PLAYING state, which is the normal state where they enter commands.

You would need to add new states (eg. CON_MODIFY_STATS, CON_MODIFY_STAT_AMOUNT), and then slot them into the state machine handler. For example, in the handler for CON_GET_NEW_RACE it finishes by switching the state to CON_GET_WANT_RIPANSI.

That might be a good spot to add your new state CON_MODIFY_STATS instead. Then you ask them what stats they want to change, and when they choose one change the state to CON_MODIFY_STAT_AMOUNT. Then keep switching back and forth until they have finished modifying stats. Then you can go back to the normal sequence (eg. CON_GET_WANT_RIPANSI).

If you aren't sure what I am talking about, take a careful look at how the other questions are handled, that should give you plenty of clues about how to add your new stuff.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Lazerus   (4 posts)  Bio
Date Reply #4 on Fri 09 Jun 2006 03:11 PM (UTC)
Message
Ok, I think im starting to get it. I'll add 3 states,
One for selecting the stat to change
One for modifying that stat
One to check the stradd value to make sure it's not rediculous.

Do I have to define stradd, or statpool in order to add them, and if so where do I define them at?

I still dont understand what lets the user set the value, But I'll keep looking at the code and see if I can figure it out.

Thanks for the help nick
-Laz-
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #5 on Fri 09 Jun 2006 09:58 PM (UTC)
Message
You don't really need a state for checking the value. Look at how it handles CON_GET_NEW_CLASS (getting a class) for example. It stays in that state until it gets a valid class.

You would need to keep the things you need to remember in the char_data structure, as they need to be stored for next time through nanny. I would keep the current pool, and what attribute they have selected to modify.

You could stick to a single state if you were prepared to parse a more complicated input, for example:

STR +3
INT -5

That way you don't need to ask 2 questions.

For example (user input in bold):


Currently: Str: 5 Int: 9 Wis: 10 Dex: 8 Con: 7 cha: 14
You have 13 stats available to allocate.
Enter the name of the stat and a modifier (eg. str +3) ...
str +5
Currently: Str: 10 Int: 9 Wis: 10 Dex: 8 Con: 7 cha: 14
You have 8 stats available to allocate.
Enter the name of the stat and a modifier (eg. str +3) ...
int -1
Currently: Str: 10 Int: 8 Wis: 10 Dex: 8 Con: 7 cha: 14
You have 9 stats available to allocate.
Enter the name of the stat and a modifier (eg. str +3) ...
wis +9
** You cannot make wis more than 15!
Currently: Str: 10 Int: 8 Wis: 10 Dex: 8 Con: 7 cha: 14
You have 9 stats available to allocate.
Enter the name of the stat and a modifier (eg. str +3) ...
blah blah
** I do not understand "blah blah"
Currently: Str: 10 Int: 8 Wis: 10 Dex: 8 Con: 7 cha: 14
You have 9 stats available to allocate.
Enter the name of the stat and a modifier (eg. str +3) ...
wis +4
Currently: Str: 10 Int: 8 Wis: 14 Dex: 8 Con: 7 cha: 14
You have 5 stats available to allocate.
Enter the name of the stat and a modifier (eg. str +3) ...
con +5
Currently: Str: 10 Int: 8 Wis: 14 Dex: 8 Con: 12 cha: 14
Stats allocation complete!
Would you like RIP, ANSI or no graphic/color support, (R/A/N)?


In the above example you have a single state (eg. CON_MODIFY_STATS) and in that you check for "wis +4" and do the appropriate checks. You could parse their input with sscanf to break it into a string and a number.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Lazerus   (4 posts)  Bio
Date Reply #6 on Mon 12 Jun 2006 03:47 AM (UTC)
Message
Ok I dont know if this is what you ment or not, But its all I could come up with looking at the class code.

case CON_ROLL_STATS:

ch->perm_str = 13;
ch->perm_int = 13;
ch->perm_wis = 13;
ch->perm_dex = 13;
ch->perm_con = 13;
ch->perm_cha = 13;

ch->perm_str += race_table[ch->race].str_plus;
ch->perm_int += race_table[ch->race].int_plus;
ch->perm_wis += race_table[ch->race].wis_plus;
ch->perm_dex += race_table[ch->race].dex_plus;
ch->perm_con += race_table[ch->race].con_plus;
ch->perm_cha += race_table[ch->race].cha_plus;

ch->perm_str + stradd;
ch->perm_int + intadd;
ch->perm_wis + wisadd;
ch->perm_dex + dexadd;
ch->perm_con + conadd;
ch->perm_cha + chaadd;

sprintf( buf, "\r\n1.STR: %d/27 2.INT: %d/27 3.WIS: %d/27 4.DEX: %d/27 5.CON: %d/27 6.CHA: %d/27\r\n",
ch->perm_str, ch->perm_int, ch->perm_wis, ch->perm_dex, ch->perm_con, ch->perm_cha );

write_to_buffer( d, buf, 0 );
write_to_buffer( d, "\r\nEnter the Number of the Stat you would like to change, and then give a value to modify it by. (Ex: "2 +5" would add 5 to Inteligence.)", 0 );
d->connected = CON_DEFINE_STATADD;
break;

case CON_DEFINE_STATADD:

argument = one_argument( argument, arg );

sprintf( buf, "\r\nCurrently, 1.STR: %d/27 2.INT: %d/27 3.WIS: %d/27 4.DEX: %d/27 5.CON: %d/27 6.CHA: %d/27\r\n",
ch->perm_str, ch->perm_int, ch->perm_wis, ch->perm_dex, ch->perm_con, ch->perm_cha );


if( !str_cmp( arg, "help" ) )
{
do_help( ch, argument );
write_to_buffer( d, "Enter the Number of the stat you would like to change and then give a value to add or subtract to it. (Ex: 1 +5 would add five to Str. 2 -4 would take away four from Int.", 0 );
return;
}

{

statpool=20 - stradd - intadd - wisadd - dexadd - conadd - chaadd;
{
if(!str_cmp(arg, "1 +1") )

write_to_buffer( d, "\r\nYou have Chosen to add 1 to Str.\r\n",
ch->perm_str );
ch->stradd = +1
return;


And then the list would go on, the max you could add to a stat being 7 and the most you could take away being 5.

I doubt this is right, but like I said I just started learning a month ago, so most of the stuff im guessing at.

Thanks for the help Nick.
-Laz
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #7 on Mon 12 Jun 2006 09:40 PM (UTC)
Message
I certainly wouldn't do this:


if(!str_cmp(arg, "1 +1") )


For one thing, if you are doing a straight string comparison, why not make it easier on players and do:


if(!str_cmp(arg, "str +1") )


However the real problem is the number of "if"s you will need. With 6 attributes, and each one can be -5 to +7, you would need 210 (6 x 7 x 5) different "if" statements. Surely you can see that would be messy? Plus, the player might throw you out by entering more spaces (eg. str(2 spaces)+1 ).

You need to break up their input into two things, one being the attribute, the other being the amount it is being changed. As I said before, the function sscanf would help you do that.

Quote:

I just started a class in programming about a month ago ...


I don't want to discourage you, but before you start changing a MUD server, you really need to do a bit of practice on basic programming. Without the fundamentals, even if I showed you the exact way to solve this problem, you will hit problems with the next thing you try to do.

The Smaug server makes extensive use of pointers, and if you don't understand those, you are very likely to make a small mistake, that every time that code is reached, will crash the MUD.

One suggestion is to make a small C program, that simply does what you are trying to do with the stats, but on its own. It displays the 6 stats, and accepts input from user, and lets them modify it. In this small program you can hone your programming skills, and work out neat ways of breaking up the input and applying it, redisplaying the new stats, handling errors, and so on.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


20,997 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.