28 Jun, 2012, Koumintang wrote in the 1st comment:
Votes: 0
Ok, here's what I got. I'm trying to make a call command to call a public ship to a landing pad.. right now i am in testing phases and i know this code is incomplete as far as checking room flags…

Here is the code.

void do_call( CHAR_DATA *ch, char * argument)
{
SHIP_DATA *ship;

for ( ship = first_ship; ship; ship = ship->next )
{
if ( !str_cmp( ship->owner , "Public" ) && !IS_SET(ship->flags, SHIP_SIMULATOR ) )
{
if (ship->class > CAPITAL_SHIP)
continue;
if (ship->type == MOB_SHIP)
continue;
transship(ship, ch->in_room->vnum);
}
}
}


Now what it is doing is calling all the public ships into the room, I want it to call a random public ship to the room, or call them in order each time the command is issued. I'm not sure if there is a function that will pull one from the list alone. any help will be apprieciated.
28 Jun, 2012, Kline wrote in the 2nd comment:
Votes: 0
Does transship return a value at all, letting you know it worked? Your problem is you are looping your entire ship list with no break in the loop before it reaches the end of the list. You need to either check a boolean based on transship, so that after the first invocation the loop exits, or keep a counter (again probably based on transship returning true/false) if you want it to pull the first X number of ships. If you want it to pull ships in sequential order of your list, you need to break the loop after the first successfull call of transship and ensure your loop (or transship function) does not attempt to call ships already in the room with you.
28 Jun, 2012, plamzi wrote in the 3rd comment:
Votes: 0
Try something like this:

void do_call( CHAR_DATA *ch, char * argument) {

SHIP_DATA *ship, *rndm;
int count;

for ( ship = first_ship; ship; ship = ship->next ) {
if ( !str_cmp( ship->owner , "Public" ) && !IS_SET(ship->flags, SHIP_SIMULATOR ) ) {
if (ship->class > CAPITAL_SHIP) continue;
if (ship->type == MOB_SHIP) continue;
if (number_range(0, count) == 0)
rndm = ship;
count++;
}
}

transship(rndm, ch->in_room->vnum);
}


Where number_range() is the name of your utility function returning a random number in the range between the first and second argument.

You probably have code like that in mob activity functions, or any special procedures that take a random target.
28 Jun, 2012, Koumintang wrote in the 4th comment:
Votes: 0
ok this is causing transship to crash the mud… not sure why, transship works for other functions that call upon it. not really sure why
28 Jun, 2012, Koumintang wrote in the 5th comment:
Votes: 0
ok got it to work with this code:

void do_call( CHAR_DATA *ch, char * argument)
{
SHIP_DATA *ship, *rental;

for ( ship = first_ship; ship; ship = ship->next )
{
if ( !str_cmp( ship->owner , "Public" ) && !IS_SET(ship->flags, SHIP_SIMULATOR ) )
{
if (ship->class > CAPITAL_SHIP)
continue;
if (ship->type == MOB_SHIP)
continue;
if(ship->lastdoc == ch->in_room->vnum)
continue;
if( is_rental(ch,ship) )
rental = ship;
}
}
if (rental == NULL )
{
send_to_char( "All the public ships are already here.\n\r", ch);
return;
}
transship(rental, ch->in_room->vnum);
send_to_char( "A shuttle lands infront of you and its doors swing open.\n\r", ch);
}


The problem i have now, is that when i run out of eligable ships the code crashes the mud when it tries to transfer the ship.

I thought this like of code would have stopped it:
if (rental == NULL )
{
send_to_char( "All the public ships are already here.\n\r", ch);
return;
}


But it did not. I also tried if (!rental) and if (!ship) both failed… but (!ship) didn't allow any ships to transfer. Any suggestions?
28 Jun, 2012, plamzi wrote in the 6th comment:
Votes: 0
Try to initialize rental to NULL when you declare it. If you still crash, it may be because of something in "transship".

My earlier example was showing how to get a random entity with one list iteration. If it crashes your game, it's not because of the basic logic.
28 Jun, 2012, Koumintang wrote in the 7th comment:
Votes: 0
when it calls up transship, it crashes on this line:

origShipyard = ship->shipyard;


It is crashing here because there is no ship for it to set origShipyard.

So in the code I need it to stop the function voiddo_call before it gets to the call for transship.

I tried to set rental to NULL like this:
SHIP_DATA *ship, *rental = NULL;

and it still crashed the mud.
28 Jun, 2012, Koumintang wrote in the 8th comment:
Votes: 0
Oops i was playing with the code and forgot to put if (rental == NULL) back in… But when i did, it works perfectly… THANK YOU SO VERY MUCH You have all been a big help… Hopefully I don't need anymore help with this one peice of code.
29 Jun, 2012, plamzi wrote in the 9th comment:
Votes: 0
Good luck.

As far as good practices go, you should check if ship is null inside transship. That's because it's clearly a function that can be called from multiple places, and people may or may not remember to check for null before calling it. Basically, always check the parent object right before accessing its members.
29 Jun, 2012, Koumintang wrote in the 10th comment:
Votes: 0
Thank you for the great advice, and the excellent help… I have now finished the code completely and have installed it into my mud. I have also created a snippet for the code for everyone to use if the want this command. I made this snippet because I could not find one anywhere else and I think some newer coders may want this command.
0.0/10