10 Sep, 2010, Xrakisis wrote in the 1st comment:
Votes: 0
hi.
i have 6 guilds on my mud.
im trying to let players buy protectors and soldiers for their guild forts.
i want to set the max reset to 50,
but not let anymore load than are in the array.
the array only has guards and soldiers for each guild.
if a guard dies or a soldier dies it takes one away from the txt file.

if (pReset->arg1 == 5101)
{
if (fortress[1].guard >= pReset->arg2)
{
return;
}
}


this is in create_mobile and load_mobile
this is the vnum of the guardian guild guard but there keep loading 5 when only allowed one. (there are 5 restets atm)

any help would be appreciated

edit: this is on a Godwars:dystopia 1.4 mud btw
10 Sep, 2010, Xrakisis wrote in the 2nd comment:
Votes: 0
// merc.h
// Fortress
DECLARE_DO_FUN( do_garrison );
DECLARE_DO_FUN( do_hire );

/* Guild */
void save_fortress args( (void) );
void load_fortress args( (void) );

typedef struct fortress
{
int guard;
int soldier;
} FORTRESS;

FORTRESS fortress[12];

// guild.c
void do_garrison(CHAR_DATA *ch, char *argument)
{
char arg1[MAX_INPUT_LENGTH];
char guild[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
int x;


argument = one_argument( argument, arg1 );


sprintf(buf,"Dark Hand Guards: %d\n\r",fortress[0].guard);
send_to_char( buf, ch );
sprintf(buf,"Dark Hand Soldiers: %d\n\r",fortress[0].soldier);
send_to_char( buf, ch );
sprintf(buf,"Guardian Guards: %d\n\r",fortress[1].guard);
send_to_char( buf, ch );
sprintf(buf,"Guardian Soldiers: %d\n\r",fortress[1].soldier);
send_to_char( buf, ch );
sprintf(buf,"Beast Guards: %d\n\r",fortress[2].guard);
send_to_char( buf, ch );
sprintf(buf,"Beast Soldiers: %d\n\r",fortress[2].soldier);
send_to_char( buf, ch );
sprintf(buf,"Damned Guards: %d\n\r",fortress[3].guard);
send_to_char( buf, ch );
sprintf(buf,"Damned Soldiers: %d\n\r",fortress[3].soldier);
send_to_char( buf, ch );
sprintf(buf,"Crusaders Guards: %d\n\r",fortress[4].guard);
send_to_char( buf, ch );
sprintf(buf,"Crusaders Soldiers: %d\n\r",fortress[4].soldier);
send_to_char( buf, ch );
sprintf(buf,"Druid Guards: %d\n\r",fortress[5].guard);
send_to_char( buf, ch );
sprintf(buf,"Druid Soldiers: %d\n\r",fortress[5].soldier);
send_to_char( buf, ch );
return;
}


void do_hire(CHAR_DATA *ch, char *argument)
{
char arg1[MAX_INPUT_LENGTH];
char guild[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
int x;

x = ch->guild;

argument = one_argument( argument, arg1 );

if (arg1[0] == '\0')
{
send_to_char("Soldier 100,000\n\r",ch);
send_to_char("Guard 100,000\n\r",ch);
}

for( x = 1; x < 7;x++)
{
if (!str_cmp(arg1,"soldier"))
{
if (ch->pcgold < 100000 )
{
send_to_char("You don't have the 100,000 gold needed.\n\r",ch);
return;
}

fortress[x].soldier++;
send_to_char("You hire a soldier.\n\r",ch);
ch->pcgold -= 100000;
save_fortress();
return;
}
if (!str_cmp(arg1,"guard"))
{
if (ch->pcgold < 100000 )
{
send_to_char("You don't have the 100,000 gold needed.\n\r",ch);
return;
}

fortress[x].guard++;
send_to_char("You hire a guard.\n\r",ch);
ch->pcgold -= 100000;
save_fortress();
return;
}
}
return;
}
11 Sep, 2010, ATT_Turan wrote in the 3rd comment:
Votes: 0
At first glance, the for loop inside of do_hire() does not do anything. Higher up in the function you set x equal to the character's guild value, but as you begin the for loop you reset x to 1 and never check for it to be equal to anything. That means any time someone uses the hire function, they'll be adding a soldier or guard to the guild whose value is 1 (Guardian). I'm not sure why you have that for loop.

I have two more comments for you that are relating more to the style of your code than its functionality.
1 - If there's only one argument for do_hire() (hire <guard/soldier>), why are you creating an arg1 variable inside of the function and using one_argument on the argument the character input? It doesn't actively hurt anything, but it also doesn't serve any purpose.

2 - It would be a good idea to display an error message after the section where you hire the type of mob the player specified. Right now, if I just type "hire" it will tell me that guards and soldiers are each 100,000, and if I type "hire guard" or "hire soldier" I will hire that kind of mob if I have enough cash, but if I type "hire bob" I'll just get a blank line without knowing what I did wrong.
11 Sep, 2010, Xrakisis wrote in the 4th comment:
Votes: 0
yea, i see… the for loop does nothing… i started the for loop at one though, and thats dark hand, guardian is 2… it works when correct syntax is used, but i dont think the for loop does anything..
11 Sep, 2010, ATT_Turan wrote in the 5th comment:
Votes: 0
Xrakisis said:
thats (sic) dark hand, guardian is 2…


No, according to your do_garrison() function, the second element of your fortress array references Guardian.

Xrakisis said:
void do_garrison(CHAR_DATA *ch, char *argument)
{
sprintf(buf,"Guardian Guards: %d\n\r",fortress[1].guard);
send_to_char( buf, ch );
sprintf(buf,"Guardian Soldiers: %d\n\r",fortress[1].soldier);
send_to_char( buf, ch );
}



Xrakisis said:
it works when correct syntax is used, but i dont think the for loop does anything..


That depends on your definition of "works". The only thing the for loop does is if the player input the wrong syntax ("hire" with neither "soldier" nor "guardian" after it) is make x count from 1 to 7. If the player input a correct syntax, it will add a soldier or guardian to your Guardian guild (fortress[1]).
11 Sep, 2010, Xrakisis wrote in the 6th comment:
Votes: 0
i took the entry out of load_mobiles and have this in reset_room
but the mud wont load with it.. do u see anything wrong with it?
the mud crashes when it hits guardian.are

vnum = fread_number(fp);
if (vnum == 0)
break;


if (vnum == 5101)
{
if (fortress[1].guard < pReset->arg2)
{
break;
}
}

pMob = create_mobile(pMobIndex);
11 Sep, 2010, ATT_Turan wrote in the 7th comment:
Votes: 0
What does this have to do with the code in your last post? What are you trying to do? If you don't give the entire function and describe what you're trying to achieve, it'll be difficult to help you.
12 Sep, 2010, Xrakisis wrote in the 8th comment:
Votes: 0
i have max 50 reset for the guardian guards.
i want it to check, and if the number in the arrray is less than
the max reset than only load the number in the array.
12 Sep, 2010, ATT_Turan wrote in the 9th comment:
Votes: 0
Xrakisis said:
i have max 50 reset for the guardian guards.
i want it to check, and if the number in the arrray is less than
the max reset than only load the number in the array.


Do you mean that you want to use the number in the array (meaning the number of guards they've hired) as the limit to how many guards will spawn, rather than your defined number of 50?

Go ahead and post the entire function and we'll see if we can't figure something out.
12 Sep, 2010, Xrakisis wrote in the 10th comment:
Votes: 0
/* OLC
* Reset one room. Called by reset_area and olc.
*/
void reset_room(ROOM_INDEX_DATA * pRoom)
{
RESET_DATA *pReset;
CHAR_DATA *pMob;
OBJ_DATA *pObj;
CHAR_DATA *LastMob = NULL;
OBJ_DATA *LastObj = NULL;
int iExit;
int level = 0;
bool last;

if (!pRoom)
return;

pMob = NULL;
last = FALSE;
int vnum; // i put this in
FILE *fp; // i put this in 2

for (iExit = 0; iExit < MAX_DIR; iExit++)
{
EXIT_DATA *pExit;

if ((pExit = pRoom->exit[iExit]))
{
pExit->exit_info = pExit->rs_flags;
if ((pExit->to_room != NULL) && ((pExit = pExit->to_room->exit[rev_dir[iExit]])))
{
/* nail the other side */
pExit->exit_info = pExit->rs_flags;
}
}
}

for (pReset = pRoom->reset_first; pReset != NULL; pReset = pReset->next)
{
MOB_INDEX_DATA *pMobIndex;
OBJ_INDEX_DATA *pObjIndex;
OBJ_INDEX_DATA *pObjToIndex;
ROOM_INDEX_DATA *pRoomIndex;

switch (pReset->command)
{
default:
bug("Reset_room: bad command %c.", pReset->command);
break;

case 'M':
if (!(pMobIndex = get_mob_index(pReset->arg1)))
{
bug("Reset_room: 'M': bad vnum %d.", pReset->arg1);
continue;
}

if (pMobIndex->count >= pReset->arg2)
{
last = FALSE;
break;
}

/* vnum = fread_number(fp);
if (vnum == 0)
break;


if (vnum == 5101) // 5101 is the mob vnum of the guardian guard
{
if (fortress[1].guard < pReset->arg2)
{
break;
}
}
*/

pMob = create_mobile(pMobIndex);



/*
* Some more hard coding.
*/
if (room_is_dark(pRoom))
SET_BIT(pMob->affected_by, AFF_INFRARED);

char_to_room(pMob, pRoom);

LastMob = pMob;
level = URANGE(0, pMob->level - 2, LEVEL_HERO);
last = TRUE;
break;

case 'O':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
bug("Reset_room: 'O': bad vnum %d.", pReset->arg1);
continue;
}

if (!(pRoomIndex = get_room_index(pReset->arg3)))
{
bug("Reset_room: 'O': bad vnum %d.", pReset->arg3);
continue;
}

if (count_obj_list(pObjIndex, pRoom->contents) > 0)
break;

pObj = create_object(pObjIndex, number_fuzzy(level));
pObj->cost = 0;
obj_to_room(pObj, pRoom);
break;

case 'P':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
bug("Reset_room: 'P': bad vnum %d.", pReset->arg1);
continue;
}
if (!(pObjToIndex = get_obj_index(pReset->arg3)))
{
bug("Reset_room: 'P': bad vnum %d.", pReset->arg3);
continue;
}

if (!(LastObj = get_obj_type(pObjToIndex)) || count_obj_list(pObjIndex, LastObj->contains) > 0)
break;

pObj = create_object(pObjIndex, number_fuzzy(level));
obj_to_obj(pObj, LastObj);

/*
* Ensure that the container gets reset. OLC 1.1b
*/
if (LastObj->item_type == ITEM_CONTAINER)
{
LastObj->value[1] = LastObj->pIndexData->value[1];
}
else
{
/* THIS SPACE INTENTIONALLY LEFT BLANK */
}
break;

case 'G':
case 'E':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
bug("Reset_room: 'E' or 'G': bad vnum %d.", pReset->arg1);
continue;
}

if (!last)
break;

if (!LastMob)
{
bug("Reset_room: 'E' or 'G': null mob for vnum %d.", pReset->arg1);
last = FALSE;
break;
}

pObj = create_object(pObjIndex, number_fuzzy(level));
obj_to_char(pObj, LastMob);
if (pReset->command == 'E')
equip_char(LastMob, pObj, pReset->arg3);
last = TRUE;
break;

case 'D':
break;

case 'R':
/* OLC 1.1b
if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
{
bug( "Reset_room: 'R': bad vnum %d.", pReset->arg1 );
continue;
}

{
EXIT_DATA *pExit;
int d0;
int d1;

for ( d0 = 0; d0 < pReset->arg2 - 1; d0++ )
{
d1 = number_range( d0, pReset->arg2-1 );
pExit = pRoomIndex->exit[d0];
pRoomIndex->exit[d0] = pRoomIndex->exit[d1];
pRoomIndex->exit[d1] = pExit;
}
}
*/
break;
}
}

return;
}
13 Sep, 2010, ATT_Turan wrote in the 11th comment:
Votes: 0
First off, I don't want to sound mean, but it really seems like you don't very well understand the things you're typing into your code. For example, you create a pointer to a file, but you never open a file with it and then you try to read from a file with it (which would probably be why your code doesn't compile/crashes/whatever it is that's going wrong). Why do you have this? What data are you trying to read?

Have you gone through some online C tutorials that cover material through file management? Grabbed a book to read? Taken a basic programming course at your local school?

All that said and asked, looking through that function, we see that line 59 is where the function checks to see if you have loaded as many mobs of this type as your reset has defined as the limit:

if (pMobIndex->count >= pReset->arg2)


It is therefore that line that we want to modify. Instead of just asking "have we reached the reset's limit for this mob?", we want to ask "is this a Guardian guard? If so, have we reached that guild's limit? Otherwise, have we reached the reset's limit for this mob?"

Notice from studying the reset structure (and looking at line 55) that we already have access to the vnum of the mob that the reset is trying to create: it's pReset->arg1.

Therefore, we will do this (this code could be compacted for sheer efficiency, but I'm going to type it out for you so it matches the format of our question):

if (pReset->arg1 == 5101) // Is this a guardian guard?
{
if (pMobIndex->count >= fortress[1].guard) // Yes it is! Have we already loaded as many guards as they're allowed to have?
{
last = FALSE; // Yes we have! So we won't load more.
break;
}
}
else if (pMobIndex->count >= pReset->arg2) // No it isn't! So have we reached the reset's limit for this mob?
{
last = FALSE; // Yes we have! So we won't load more.
break;
}


Notice the format of the indentations I use inside of blocks formed by if statements and for loops and such - this is a standard practice that helps to make your code more easily readable and tell what code happens when.

You would delete lines 59-63 of the code you posted above, and paste what I wrote in there, and your code will do what you want. Note, however, that this only applies specifically to the guards for your Guardian guild. If you want it to apply to the other guilds, you'd have to write more "else if" blocks to account for each one. This is not a very efficient way to go about this - you'd be better off setting a "am I a guild guard?" flag on mobs, and check for that and then for the appropriate guild's limit, but that would be more complicated a project.
13 Sep, 2010, Xrakisis wrote in the 12th comment:
Votes: 0
Thanks ATT_turan,
its working :)
0.0/12