



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
Hi first I would like to thank Remcon for all his fantastic help.
I figured instead of posting on a topic about a loadcrash I may as well make a new topic
Here's the code I'm working with I'll explain the changes I would like to make after the code
This is the section of code I'm looking at the part that adds water to the room
I would like to add a time limit to the amount of time that the water is in the room, showing that water that is not supposed to be there will dry up.
The whole reason I have command is because water mages need water to cast a lot of their spells and this gives them a way to prepare a room before they start casting.
I figured instead of posting on a topic about a loadcrash I may as well make a new topic
Here's the code I'm working with I'll explain the changes I would like to make after the code
void do_flood( CHAR_DATA * ch, char *argument ) { CHAR_DATA * victim; CHAR_DATA * next_vict; int n = 0; if( IS_SET( ch->in_room->room_flags, ROOM_NOFLOOR ) ||( ch->curr_talent[TAL_WATER] < 1 && !IS_NPC( ch ) ) ) { huh( ch ); return; } if( ch->curr_talent[TAL_WATER] > 10 &&ch->in_room->curr_water < 100 ) { act( AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_CHAR ); act( AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_ROOM ); //if( IS_SET( ch->in_room->room_flags, ROOM_INDOORS ) ) ch->in_room->curr_water += TALENT( ch, TAL_WATER ) / 10; } if( !str_cmp( argument, "all" ) ) { for( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if( victim == ch ) continue; magic_damage( victim, ch, TALENT( ch, TAL_WATER ), MAG_WATER, TAL_WATER, FALSE ); } use_magic( ch, TAL_WATER, n * TALENT( ch, TAL_WATER ) ); return; } victim = find_target( ch, argument, TRUE ); if( !victim ) return; magic_damage( victim, ch, ( TALENT( ch, TAL_WATER ) * 2 + ch->in_room->curr_water ) / 3, MAG_WATER, TAL_WATER, FALSE ); }
This is the section of code I'm looking at the part that adds water to the room
void do_flood( CHAR_DATA * ch, char *argument ) { CHAR_DATA * victim; CHAR_DATA * next_vict; int n = 0; if( IS_SET( ch->in_room->room_flags, ROOM_NOFLOOR ) ||( ch->curr_talent[TAL_WATER] < 1 && !IS_NPC( ch ) ) ) { huh( ch ); return; } if( ch->curr_talent[TAL_WATER] > 10 &&ch->in_room->curr_water < 100 ) { act( AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_CHAR ); act( AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_ROOM ); //if( IS_SET( ch->in_room->room_flags, ROOM_INDOORS ) ) ch->in_room->curr_water += TALENT( ch, TAL_WATER ) / 10; }
I would like to add a time limit to the amount of time that the water is in the room, showing that water that is not supposed to be there will dry up.
The whole reason I have command is because water mages need water to cast a lot of their spells and this gives them a way to prepare a room before they start casting.


Magician

GroupMembers
Posts128
JoinedApr 9, 2010
Ok I'm going to continue my brew skill fix questions here.
I fixed the scribe skill per post
Scribe skill fix
I'm trying to do the exact same thing with the brew skill since they are almost identical in code, but it is not working correctly
can anybody tell me what I have done wrong?
The code I have added is
I fixed the scribe skill per post
Scribe skill fix
I'm trying to do the exact same thing with the brew skill since they are almost identical in code, but it is not working correctly
can anybody tell me what I have done wrong?
void do_brew( CHAR_DATA * ch, char *argument ) { OBJ_DATA * potion; OBJ_DATA * fire; int sn; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char buf3[MAX_STRING_LENGTH]; char arg2[MAX_INPUT_LENGTH]; int mana; bool found; argument = one_argument( argument, arg2 ); potion = get_obj_carry( ch, arg2 ); if( IS_NPC( ch ) ) return; if( !skill_available( ch, gsn_brew ) ) { send_to_char( "A skill such as this requires more magical ability than you have.\n\r", ch ); return; } if( argument[0] == '\0' || !str_cmp( argument, "" ) ) { send_to_char( "Brew what?\n\r", ch ); return; } if( ms_find_obj( ch ) ) return; if( ( sn = find_spell( ch, argument, TRUE ) ) < 0 ) { send_to_char( "You have not learned that spell.\n\r", ch ); return; } if( skill_table[sn]->spell_fun == spell_null ) { send_to_char( "That's not a spell!\n\r", ch ); return; } if( SPELL_FLAG( skill_table[sn], SF_NOBREW ) ) { send_to_char( "You cannot brew that spell.\n\r", ch ); return; } mana = IS_NPC( ch ) ? 0 : UMAX( skill_table[sn]->min_mana, 100 / ( 100 - skill_table[sn]->skill_level[get_best_talent( ch, sn )] ) ); mana *= 4; if( !IS_NPC( ch ) && ch->mana < mana ) { send_to_char( "You don't have enough mana.\n\r", ch ); return; } //if( ( potion = get_eq_char( ch, WEAR_HAND ) ) == NULL ) if ( !potion ) { send_to_char("You must have an empty flask to brew a potion.\n\r", ch ); return; } if( potion->pIndexData->vnum != OBJ_VNUM_EMPTY_FLASK ) { send_to_char( "You must be holding an empty flask to brew a potion.\n\r", ch ); return; } if( ( potion->value[1] != -1 ) &&( potion->pIndexData->vnum == OBJ_VNUM_EMPTY_FLASK ) ) { send_to_char( "That's not an empty flask.\n\r", ch ); return; } found = FALSE; for( fire = ch->in_room->first_content; fire; fire = fire->next_content ) { if( fire->item_type == ITEM_FIRE ) { found = TRUE; break; } } if( !found ) { send_to_char( "There must be a fire in the room to brew a potion.\n\r", ch ); return; } if( !process_spell_components( ch, sn ) ) { learn_from_failure( ch, gsn_brew ); ch->mana -= ( mana / 2 ); ch->in_room->area->weather->mana += ( int )mana / 10; return; } if( !can_use_skill( ch, number_percent( ), gsn_brew ) ) { set_char_color( AT_MAGIC, ch ); send_to_char( "You failed.\n\r", ch ); learn_from_failure( ch, gsn_brew ); ch->mana -= ( mana / 2 ); ch->in_room->area->weather->mana += ( int )mana / 10; return; } potion->value[1] = sn; sprintf( buf1, "%s potion", skill_table[sn]->name ); STRFREE( potion->short_descr ); potion->short_descr = STRALLOC( aoran( buf1 ) ); sprintf( buf2, "A strange potion labelled '%s' sizzles in a glass flask.", skill_table[sn]->name ); STRFREE( potion->description ); potion->description = STRALLOC( buf2 ); sprintf( buf3, "flask potion %s", skill_table[sn]->name ); STRFREE( potion->name ); potion->name = STRALLOC( buf3 ); act( AT_MAGIC, "$n brews up $p.", ch, potion, NULL, TO_ROOM ); act( AT_MAGIC, "You brew up $p.", ch, potion, NULL, TO_CHAR ); learn_from_success( ch, gsn_brew ); ch->mana -= mana; ch->in_room->area->weather->mana += ( int )mana / 10; }
The code I have added is
char arg2[MAX_INPUT_LENGTH]; argument = one_argument( argument, arg2 ); potion = get_obj_carry( ch, arg2 ); //if( ( potion = get_eq_char( ch, WEAR_HAND ) ) == NULL ) if ( !potion )



Magician

GroupMembers
Posts239
JoinedJun 13, 2008
My quick and dirty way of going about this would be along the lines of two ways:
First way is via rooms:
Adding a room flag to act as a timer. Call it something you'll remember ROOM_FLOOD_TIMER as an example
Adding a SET_BIT ch->room_flags = numerical value (You could have this value based off your characters skill % or int status or whatever).
Adding an update tick to your game to look at ROOM_FLOOD_TIMER and every game update tick one off. When last tick is reached print out your message 'drains away'
Have your spells check against that room flag.
The above could become messy if the room was prototyped with a timer value on the flag however.
Second way and the way I'd choose to use would be an object. In my opinion objects are much safer to muck with than room flags.
Make object that only immortals can see. This object would be summoned by the spell do_flood. Could do this with vnums or item types. Make an object and have a timer set on it. Summon that object with the do_flood spell. From there that object counts down as soon as its spawns with your timer. Have your spells check against that object. If its there your good to go. If not, they need to recall their water. Basically you'd need a for loop when casting in your code, something like: for ( obj = ch->in_room->first_content; obj; obj = obj_next ) give or take.
As to the idea I'd personally go with ITEM_TYPE vs a static vnum. Hard coding vnums is a bad idea IMO.
Note: I've not looked at the codebase your using. These are only general ideas. I have/had something like that set up for the game I was running and worked fairly well. Your code may not have an obj_update timer or room_update timer. I'd personally suggest whatever one is easier for you. If you have corpses that 'decay into dust' or food that goes sour you could use that as an example for objects with timers.
Hope it helps some. While not offering up code, I do hope it at least sparks some ideas
(I know, likely a useless post)
ayuri
First way is via rooms:
Adding a room flag to act as a timer. Call it something you'll remember ROOM_FLOOD_TIMER as an example
Adding a SET_BIT ch->room_flags = numerical value (You could have this value based off your characters skill % or int status or whatever).
Adding an update tick to your game to look at ROOM_FLOOD_TIMER and every game update tick one off. When last tick is reached print out your message 'drains away'
Have your spells check against that room flag.
The above could become messy if the room was prototyped with a timer value on the flag however.
Second way and the way I'd choose to use would be an object. In my opinion objects are much safer to muck with than room flags.
Make object that only immortals can see. This object would be summoned by the spell do_flood. Could do this with vnums or item types. Make an object and have a timer set on it. Summon that object with the do_flood spell. From there that object counts down as soon as its spawns with your timer. Have your spells check against that object. If its there your good to go. If not, they need to recall their water. Basically you'd need a for loop when casting in your code, something like: for ( obj = ch->in_room->first_content; obj; obj = obj_next ) give or take.
As to the idea I'd personally go with ITEM_TYPE vs a static vnum. Hard coding vnums is a bad idea IMO.
Note: I've not looked at the codebase your using. These are only general ideas. I have/had something like that set up for the game I was running and worked fairly well. Your code may not have an obj_update timer or room_update timer. I'd personally suggest whatever one is easier for you. If you have corpses that 'decay into dust' or food that goes sour you could use that as an example for objects with timers.
Hope it helps some. While not offering up code, I do hope it at least sparks some ideas

(I know, likely a useless post)
ayuri



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
LOl Ayuri no post is ever a useless post to me, you did give me some good information, but maybe me giving more information about my mud might help with suggestions.
My mud is based off of Calarey 3.0 codebase
in the redit menu I have a field called water and you can set a percentage of how much water is in the room (this also changes room descriptions and such so you don't have to manually change the room description)
the flood command raises this field by percentages based on various things like stats and skills and such
honestly I would just be happy if when the area resets the water went away, which it doesn't seem to be doing.
My mud is based off of Calarey 3.0 codebase
in the redit menu I have a field called water and you can set a percentage of how much water is in the room (this also changes room descriptions and such so you don't have to manually change the room description)
the flood command raises this field by percentages based on various things like stats and skills and such
honestly I would just be happy if when the area resets the water went away, which it doesn't seem to be doing.



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
in reset_room in reset.c
find
id personally add in there somewhere to decrease the water some and if it works out good let me know id just go with decreasing it based on how high it currently is etc... range for it seems to be -100 to 100. at least thats the range redit has for setting it.
find
/* * Update vegetation in each room -- Scion */ if( IS_SET( room->room_flags, ROOM_BURNING ) ) { if( room->curr_vegetation > 0 && room->curr_water < 30 ) room->curr_vegetation -= 25; else REMOVE_BIT( room->room_flags, ROOM_BURNING ); } else { if( room->curr_vegetation < room->vegetation ) room->curr_vegetation++; }
id personally add in there somewhere to decrease the water some and if it works out good let me know id just go with decreasing it based on how high it currently is etc... range for it seems to be -100 to 100. at least thats the range redit has for setting it.


Magician

GroupMembers
Posts128
JoinedApr 9, 2010
How is this for decreasing the water I don't get any errors when I compile, but question is will it do what I want
I would also like to put a line in there saying the water seeps into the ground and maybe the fire going out or something
but I'm not quite sure how to do that even after looking at the other code.
/* * Update vegetation in each room -- Scion */ if( IS_SET( room->room_flags, ROOM_BURNING ) ) { if( room->curr_vegetation > 0 && room->curr_water < 30 ) room->curr_vegetation -= 25; else REMOVE_BIT( room->room_flags, ROOM_BURNING ); } else { if( room->curr_vegetation < room->vegetation ) room->curr_vegetation++; } /* * Update water in room if it is more than what was set. */ if( room->curr_water > room->water ) { room->curr_water--; }
I would also like to put a line in there saying the water seeps into the ground and maybe the fire going out or something
but I'm not quite sure how to do that even after looking at the other code.



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
I have also tried this
neither which seems to work
/* * Update vegetation in each room -- Scion */ if( IS_SET( room->room_flags, ROOM_BURNING ) ) { if( room->curr_vegetation > 0 && room->curr_water < 30 ) room->curr_vegetation -= 25; else REMOVE_BIT( room->room_flags, ROOM_BURNING ); } else { if( room->curr_vegetation < room->vegetation ) room->curr_vegetation++; if( room->curr_water > room->water ) room->curr_water--; }
neither which seems to work



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
Ok I would suggest this
find
change it to this
find
if( !room->first_reset ) return; /* * Update vegetation in each room -- Scion */ if( IS_SET( room->room_flags, ROOM_BURNING ) ) { if( room->curr_vegetation > 0 && room->curr_water < 30 ) room->curr_vegetation -= 25; else REMOVE_BIT( room->room_flags, ROOM_BURNING ); } else { if( room->curr_vegetation < room->vegetation ) room->curr_vegetation++; }
change it to this
/* Update vegetation in each room -- Scion */ if( IS_SET( room->room_flags, ROOM_BURNING ) ) { if( room->curr_vegetation > 0 && room->curr_water < 30 ) room->curr_vegetation -= 25; else REMOVE_BIT( room->room_flags, ROOM_BURNING ); } else { if( room->curr_vegetation < room->vegetation ) room->curr_vegetation++; } /* Update water in room if it is more than what was set. */ if( room->curr_water != room->water ) { if( room->first_person ) { if( room->curr_water > room->water ) { act( AT_PLAIN, "The water recedes to its normal level.", room->first_person, NULL, NULL, TO_CHAR ); act( AT_PLAIN, "The water recedes to its normal level", room->first_person, NULL, NULL, TO_ROOM ); } else { act( AT_PLAIN, "The water increases to its normal level.", room->first_person, NULL, NULL, TO_CHAR ); act( AT_PLAIN, "The water increases to its normal level", room->first_person, NULL, NULL, TO_ROOM ); } } room->curr_water = room->water; } if( !room->first_reset ) return;



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
Ah thanks!
that is a better suggestion because if something depletes the water in the room it also takes care of that as well.
that is a better suggestion because if something depletes the water in the room it also takes care of that as well.



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
Ah looking further through code I have found something that Remcon might find useful if he continues to look at the code
that works
further inspection finds that there is also an off_hand
if( !ch->main_hand != OBJ_VNUM_SCROLL_SCRIBING ) { send_to_char( "You must be holding a blank scroll to scribe it.\n\r", ch ); return; }
that works
further inspection finds that there is also an off_hand


Magician

GroupMembers
Posts128
JoinedApr 9, 2010
EDIT: ok What I believed was wrong
It was the holding part
lol I'm not sure what I did wrong but I replaced the whole function with Remcon's and it worked again
ignore the post before, I'm an idiot.
It was the holding part
lol I'm not sure what I did wrong but I replaced the whole function with Remcon's and it worked again
ignore the post before, I'm an idiot.



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
No worries lol, yea id modified scribe and brew in the latest to check those lol. glad they seem to be working




Magician

GroupMembers
Posts128
JoinedApr 9, 2010
Oh one thing I noticed I had changed that you hadn't in the newest src I downloaded
in handler.c
this:
should be this:
the original way doesn't let immortals see mobinvis players
in handler.c
this:
if( IS_NPC( victim ) && xIS_SET( victim->act, ACT_MOBINVIS ) && TALENT( ch, TAL_SEEKING ) < victim->mobinvis ) return FALSE; if( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_HOLYLIGHT ) ) return TRUE;
should be this:
if( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_HOLYLIGHT ) ) return TRUE; if( IS_NPC( victim ) && xIS_SET( victim->act, ACT_MOBINVIS ) && TALENT( ch, TAL_SEEKING ) < victim->mobinvis ) return FALSE;
the original way doesn't let immortals see mobinvis players



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
Ok so I could use some more help in finding a problem
a player can change the weather in an area by typing weather
the problem with this is if they make it as warm as they can by typing weather warmer until they get the message You cannot make it any warmer
and then type weather to check the weather then it crashes the mud
I don't have any idea where to look for this problem
a player can change the weather in an area by typing weather
the problem with this is if they make it as warm as they can by typing weather warmer until they get the message You cannot make it any warmer
and then type weather to check the weather then it crashes the mud
I don't have any idea where to look for this problem



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
well finding the issue isn't to bad. When you type weather it displays messages that have to be 6 and under for most and isn't protected against being to high. problem is they are being allowed to be modified way beyond 6 quickly lol



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
oops sorry if its above 5 it crashes since well the range is 0-5 (total of 6)



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
Ok, fixed the crashing issue and modified the can_see in the download.



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
thank you much mind explaining what you did for learning purposes please?



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
simply tossed in a = URANGE( 0, , 5 ); you cant have the numbers there going over 5. they bad part is, that it was as high as it would go long before it tells you that youve made it as hot as you can, but I assume that there is something that will use high area temps to increase damage etc... so more or less we are just limiting the range of messages it will show when it does the weather message display.



Magician

GroupMembers
Posts128
JoinedApr 9, 2010
I figured we were just limiting the messages that were able to be shown
thanks much
thanks much