Need some opinions on this array

Posted by MattJ820 on Fri 17 Apr 2015 06:39 PM — 22 posts, 82,503 views.

#0
Hello all,

(swfote2.1)

Here's a little backstory on what I'm trying to accomplish for clarity. I changed the wanted system from planets to clans and then edited outlaw and unoutlaw to set players wanted by a clan (The Empire for example). I changed all the defines for WANTED to planets and all char constants to clan names.

I put in an apprehend system (a charm) for bounty hunters to arrest people and now I'm working on a claimbounty function for them so they can collect live bounties against wanted players. Claim bounty will eventually act as a jail function once I add it in addition to giving credits and experience. Right now, I'm working on an if statement to basically allow the function to work if the hunter is claiming the bounty on a planet that is controlled by the clan that is flagged as wanted for the player. GDB doesn't work on my MAC and I still cannot figure out how to use LLDB correctly..so I'm stumped. I'm getting emergency copy overs when I run this function with a player argument which I've been told before means pointer or declaration errors.

I'm trying to get all wanted flags loaded on the victim (The Empire, The New Republic) and pass them into an array. There are only 5 clans loaded so the array is 0,1,2,3,4. Then, i'm trying to get the clan name that owns the planet and check if they are the owner of the wanted bounty. If they are, the function can work...if they're not..the player needs to take the bounty elsewhere.


void do_claimbounty ( CHAR_DATA *ch , char *argument )
{
    CHAR_DATA *victim =NULL;
    CLAN_DATA   *clan =NULL;
    PLANET_DATA *planet =NULL;
    char *wantedby[4];
    char value;
 
    
    if ( IS_NPC (ch) ) return;
 
    
    if ( ch->mount )
    {
        send_to_char( "You can't do that while mounted.\n\r", ch );
        return;
    }
    
    if ( argument[0] == '\0' )
    {
        send_to_char( "Usage claimbounty <target>\n\r", ch );
        return;
    }
    
    if ( ( victim = get_char_room( ch, argument ) ) == NULL )
    {
        send_to_char( "They aren't here.\n\r", ch );
        return;
    }
    
    if ( victim == ch )
    {
        send_to_char( "That's pointless.\n\r", ch );
        return;
    }
    
    if ( IS_NPC(victim) )
    {
        send_to_char( "You cannot claim a bounty on an NPC.\n\r", ch );
        return;
    }
 
    if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) )
    {
        set_char_color( AT_MAGIC, ch );
        send_to_char( "This isn't a good place to do that.\n\r", ch );
        return;
    }
    
    if ( ch->position == POS_FIGHTING )
    {
        send_to_char( "Not while you are fighting.\n\r" , ch );
        return;
    }
    
    if ( ch->position <= POS_SLEEPING )
    {
        send_to_char( "In your dreams or what?\n\r" , ch );
        return;
    }
    
    if (!IS_AFFECTED( victim, AFF_CHARM ) && (ch != victim->master))
    {
        send_to_char( "You will have to apprehend them first.\n\r" , ch );
        return;
    }
 
    wantedby[4] = flag_string(victim->pcdata->wanted_flags, wantedclan_flags);
    for (int i =0; i < 4; i++){
        if (planet->governed_by->name == wantedby)
        {
            value = get_wanted_flag( planet->governed_by->name );
            REMOVE_BIT(victim->pcdata->wanted_flags, 1 << value);
            ch_printf(victim,"&W&RA slight buzz comes over your comlink and you hear, 'Attention all citizens, %s has claimed the wanted bounty on %s for their crimes against %s's planets.Thank you.'\n\r", ch->name, victim->name, clan->name);
            return;
        }
            else
            {
            send_to_char("You need to claim your bounty on a planet controlled by the clan who set the bounty.\n\r", ch);
            return;
            }
      }
    
        return;
}

Amended on Fri 17 Apr 2015 10:01 PM by MattJ820
Australia Forum Administrator #1
For future reference:

Template:codetag
To make your code more readable please use [code] tags as described here.
Australia Forum Administrator #2
Quote:

GDB doesn't work on my MAC


Why not? What Mac is it? What have you tried, to get it installed? Debugging pointer faults without gdb can be tricky.
Australia Forum Administrator #3

    wantedby[4] = flag_string(victim->pcdata->wanted_flags, wantedclan_flags);


That doesn't look right.

flag_string returns a string not an array of strings.

Look at other examples of how flag_string is used.
#4
Nick Gammon said:

Quote:

GDB doesn't work on my MAC


Why not? What Mac is it? What have you tried, to get it installed? Debugging pointer faults without gdb can be tricky.


LLDB replaced GDB for OSX so I've read.
#5
Nick Gammon said:


    wantedby[4] = flag_string(victim->pcdata->wanted_flags, wantedclan_flags);


That doesn't look right.

flag_string returns a string not an array of strings.

Look at other examples of how flag_string is used.


Ya I used flag_string because wanted flags is actually an int and was giving incompatible pointer types. I looked at other pieces returning the actual string (The Empire/Republic etc) instead of 0 or 1 and they use flag_string with wanted clan_flags at the end (used to be planet_flags).

if I take it out, it tells me

bounty.c:277:17: warning: incompatible pointer types assigning to 'char *' from 'char *const *' [-Wincompatible-pointer-types]
wantedby[4] = (victim->pcdata->wanted_flags, wantedclan_flags);

So I should look up something akin to flag_string that returns a string but will go with an array?
#6
Nick Gammon said:

For future reference:

(codetag)


Fixed! That's useful, thank you.
Australia Forum Administrator #7
MattJ820 said:

Nick Gammon said:

Quote:

GDB doesn't work on my MAC


Why not? What Mac is it? What have you tried, to get it installed? Debugging pointer faults without gdb can be tricky.


LLDB replaced GDB for OSX so I've read.


Did you try gdb?
#8
Nick Gammon said:

MattJ820 said:

Nick Gammon said:

Quote:

GDB doesn't work on my MAC


Why not? What Mac is it? What have you tried, to get it installed? Debugging pointer faults without gdb can be tricky.


LLDB replaced GDB for OSX so I've read.


Did you try gdb?


OS X doesn't recognize the command gdb. It only accepts lldb
USA #9
This may be of use http://lldb.llvm.org/lldb-gdb.html
#10
MattJ820 said:

(...)
I'm trying to get all wanted flags loaded on the victim (The Empire, The New Republic) and pass them into an array. There are only 5 clans loaded so the array is 0,1,2,3,4. Then, i'm trying to get the clan name that owns the planet and check if they are the owner of the wanted bounty. If they are, the function can work...if they're not..the player needs to take the bounty elsewhere.


void do_claimbounty ( CHAR_DATA *ch , char *argument )
{
    CHAR_DATA *victim =NULL;
    CLAN_DATA   *clan =NULL;
    PLANET_DATA *planet =NULL;
    char *wantedby[4];

/* ... */
 
    wantedby[4] = flag_string(victim->pcdata->wanted_flags, wantedclan_flags);



You are aware that your wantedby has four members, indices 0, 1, 2, 3. wantedby[4] is out of bounds. Change definition to char *wantedby[5].
Australia Forum Administrator #11
MattJ820 said:

OS X doesn't recognize the command gdb. It only accepts lldb


Well, mine does. I can't remember how it got there, but a quick Google indicates it is on the Developer CD (the thing you can download with XCode and everything on it). In fact the old Macs came with that as a separate CD. If not, I'm sure you can find it on the Apple site.


    wantedby[4] = flag_string(victim->pcdata->wanted_flags, wantedclan_flags);


Closer would be:


char * wantedby;
    wantedby = flag_string(victim->pcdata->wanted_flags, wantedclan_flags);


That's because flag_string returns one string, not four strings.
Amended on Sat 18 Apr 2015 08:35 PM by Nick Gammon
#12
Ok, so here is a different way I've come up with to try and get this function to work.


void do_claimbounty ( CHAR_DATA *ch , char *argument)
{
    CHAR_DATA *victim =NULL;
    CLAN_DATA   *clan =NULL;
    PLANET_DATA *planet =NULL;
    char arg[MAX_INPUT_LENGTH];
    char arg1[MAX_INPUT_LENGTH];
    int value;

    if ( argument[0] == '\0' || arg[0] == '\0' || arg1[0] == '\0')
    {
        send_to_char( "Usage claimbounty <target> <wanted by clan>\n\r", ch );
        return;
    
    if ( IS_NPC (ch) ) return;
    
    
    if ( ch->mount )
    {
        send_to_char( "You can't do that while mounted.\n\r", ch );
        return;
    }
    
    
    if ( victim == ch )
    {
        send_to_char( "That's pointless.\n\r", ch );
        return;
    }
    
    if ( IS_NPC(victim) )
    {
        send_to_char( "You cannot claim a bounty on an NPC.\n\r", ch );
        return;
    }
    
    if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) )
    {
        set_char_color( AT_MAGIC, ch );
        send_to_char( "This isn't a good place to do that.\n\r", ch );
        return;
    }
    
    if ( ch->position == POS_FIGHTING )
    {
        send_to_char( "Not while you are fighting.\n\r" , ch );
        return;
    }
    
    if ( ch->position <= POS_SLEEPING )
    {
        send_to_char( "In your dreams or what?\n\r" , ch );
        return;
    }
    
    if (!IS_AFFECTED( victim, AFF_CHARM ) && (ch != victim->master))
    {
        send_to_char( "You will have to apprehend them first.\n\r" , ch );
        return;
    }
    argument = one_argument( argument, arg );
    argument = one_argument( argument, arg1 );
   
    value = get_wanted_flag( arg1 );
    if ( value < 0 || value < 5)
        send_to_char("That is not a valid clan.\n\r", ch);
    return;
    if ( (value >=0 || value <=5) && !IS_SET( victim->pcdata->wanted_flags, 1 >> value))
        send_to_char("They are not wanted by that clan.\n\r", ch);
    return;
    if ( (value >=0 || value <=5) && IS_SET( victim->pcdata->wanted_flags, 1 >> value) && !str_cmp(wantedclan_flags[value], planet->governed_by->name))
        send_to_char("You must cliam this bounty on a planet controlled by the clan who posted the bounty.\n\r", ch);
        return;
    if ( (value >=0 || value <=5) && IS_SET( victim->pcdata->wanted_flags, 1 >> value) && str_cmp(wantedclan_flags[value], planet->governed_by->name))
        ch_printf(victim,"&W&RA slight buzz comes over your comlink and you hear, 'Attention all citizens, %s has claimed the wanted bounty on %s for their crimes against %s's planets.Thank you.'\n\r", ch->name, victim->name, clan->name);
    REMOVE_BIT(victim->pcdata->wanted_flags, 1 << value);
            return;
   
}


Here's where I'm getting the value numbers



char *  const   wantedclan_flags [] =
{
  "The Empire", "The New Republic", "The Hunters Guild", "Silence Industries", "Marauder Family",
  "Galspan Network", "p6", "p7", "p8", "p9", "p10", "p11",
  "p12", "p13", "p14", "p15", "p16", "p17", "p18", "p19", "p20", "p21", 
  "p22", "p23", "p24", "p25", "p26", "p27", "p28", "p29", "p30", "p31"  
};


int get_wanted_flag( char *flag )
{
    int x;

    for ( x = 0; x < 32; x++ )
      if ( !str_cmp( flag, wantedclan_flags[x] ) ) /* changed to wanted_clan  - Gunner*/
        return x;
    return -1;
}



It compiles fine but I'm getting core dumps. I'm attempting to debug with LLDB and these are the results I'm getting. I do not believe this piece of code has anything to do with my crash...it has shown up in multiple different occasions of me dealing with core dumps. I think LLDB isn't working right.


[1] 30352
Johnson-iMac:src Matt$ Segmentation fault (core dumped)
lldb ../bin/swr 30352
(lldb) target create "../bin/swr"
Current executable set to '../bin/swr' (x86_64).
(lldb) settings set -- target.run-args "30352"
(lldb) list
151 {
152 struct timeval now_time;
153 bool fCopyOver = !TRUE;
154
155 /*
156 * Memory debugging if needed.
157 */
158 #if defined(MALLOC_DEBUG)
159 malloc_debug( 2 );
160 #endif
(lldb) bt
error: invalid process
(lldb) exit
Amended on Mon 20 Apr 2015 12:27 AM by MattJ820
#13
I'm going to keep looking into LLDB while you guys look at this
Australia Forum Administrator #14

clan->name


You don't appear to be initializing this pointer (clan) anywhere. It isn't enough to just paste in variables to make compiler errors go away. "clan" is a pointer, so it has to be set to point to something valid.
#15
It's at the top

CLAN_DATA *clan =NULL;
Amended on Mon 20 Apr 2015 04:22 AM by MattJ820
Australia Forum Administrator #16
If it is NULL, this will give you an access violation:


ch->name, victim->name, clan->name);
#17
hey Nick,

why does LLDB always give me the same info from "list"? I've had several other core dumps dealing with different code and it's always this.

Johnson-iMac:src Matt$ lldb ../bin/swr core.33791
(lldb) target create "../bin/swr"
Current executable set to '../bin/swr' (x86_64).
(lldb) settings set -- target.run-args "core.33791"
(lldb) list
151 {
152 struct timeval now_time;
153 bool fCopyOver = !TRUE;
154
155 /*
156 * Memory debugging if needed.
157 */
158 #if defined(MALLOC_DEBUG)
159 malloc_debug( 2 );
160 #endif
(lldb)
#18
Well I'm getting somewhere...no more core dumps at least. my last chprintf might have been what was causing it and I cleaned that up. I also had a < that should have been an > in the first IF at the bottom.

I'm getting blank returns now, nothing happens but it does accept the input without crashing

Force:1800/1800 Align:-1000
[Hp:500/500] [Mv:1000/1000] (Align:-1000) claimbounty Matt "The Empire"

Force:1800/1800 Align:-1000
[Hp:500/500] [Mv:1000/1000] (Align:-1000)



void do_claimbounty ( CHAR_DATA *ch , char *argument)
{
    CHAR_DATA *victim;
    PLANET_DATA *planet;
    char arg[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    int value;
    
    argument = one_argument( argument, arg );
   

    
        if ( arg[0] == '\0' || arg2[0] == '\0')
        {
        send_to_char( "Usage claimbounty <target> <wanted by clan>\n\r", ch );
        return;
        }
        if ( IS_NPC (ch) ) return;
    
        if ((victim = get_char_room(ch, arg)) == NULL)
        {
        send_to_char("They are not here.\n\r", ch);
        return;
        }
    
        if ( ch->mount )
        {
            send_to_char( "You can't do that while mounted.\n\r", ch );
            return;
        }
        
        
        if ( victim == ch )
        {
            send_to_char( "That's pointless.\n\r", ch );
            return;
        }
        
        if ( IS_NPC(victim) )
        {
            send_to_char( "You cannot claim a bounty on an NPC.\n\r", ch );
            return;
        }
        
        if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) )
        {
            set_char_color( AT_MAGIC, ch );
            send_to_char( "This isn't a good place to do that.\n\r", ch );
            return;
        }
        
        if ( ch->position == POS_FIGHTING )
        {
            send_to_char( "Not while you are fighting.\n\r" , ch );
            return;
        }
        
        if ( ch->position <= POS_SLEEPING )
        {
            send_to_char( "In your dreams or what?\n\r" , ch );
            return;
        }
        
        if (!IS_AFFECTED( victim, AFF_CHARM ) && (ch != victim->master))
        {
            send_to_char( "You will have to apprehend them first.\n\r" , ch );
            return;
        }
    
        argument = one_argument( argument, arg2 );
        value = get_wanted_flag( arg2 );
    
    
        if ( value < 0 || value > 5)
            send_to_char("That is not a valid clan.\n\r", ch);
        return;
        if ( (value >= 0 || value <=5) && !IS_SET( victim->pcdata->wanted_flags, 1 >> value))
            send_to_char("They are not wanted by that clan.\n\r", ch);
        return;
        if ( (value >=0 || value <=5) && IS_SET( victim->pcdata->wanted_flags, 1 >> value) && !str_cmp(wantedclan_flags[value], planet->governed_by->name))
            send_to_char("You must cliam this bounty on a planet controlled by the clan who posted the bounty.\n\r", ch);
        return;
        if ( (value >=0 || value <=5) && IS_SET( victim->pcdata->wanted_flags, 1 >> value) && str_cmp(wantedclan_flags[value], planet->governed_by->name))
            ch_printf(victim,"&W&RA slight buzz comes over your comlink and you hear, 'Attention all citizens, the wanted bounty on %s for their crimes against %s has been claimed!. Thank you.'\n\r", victim->name, planet->governed_by->name);
        REMOVE_BIT(victim->pcdata->wanted_flags, 1 << value);
        return;
        
    }

Australia Forum Administrator #19

 if ( value < 0 || value > 5)
            send_to_char("That is not a valid clan.\n\r", ch);
        return;
        if ( (value >= 0 || value <=5) && !IS_SET( victim->pcdata->wanted_flags, 1 >> value))
            send_to_char("They are not wanted by that clan.\n\r", ch);
        return;


I don't know why you have any code after "return" because it won't be executed. Indenting a few spaces doesn't achieve anything.
Australia Forum Administrator #20
I don't mean this unkindly, but you need to read up on how C works. After an "if" a single statement is executed.
#21
This is what I was missing. planet = ch->in_room->area->planet; it didn't know what planet was. makes sense.