Creating and selecting buttons on runtime

@eugeneloza Yes, it is the TCastleButton.Create. It wants to create a button that already exists.
I tried TCastleButton.Create(FreeAtStop) but the error still shows up.
Nearly all my game code is under TStatePlay, so should I create a separate TState for this procedure (TStateButton or so) and then it gets freed with TCastleButton.Create(FreeAtStop) on next call allright?

I think it would be best if all buttons that are created before, are destroyed before the S := NewButton := TCastleButton.Create to avoid doubles.
So I’m thinking of a stringlist that is made, where all NewButton Names are stored. And then this list is read before creating new buttons. And all button names that are found are buttons that need to be destroyed.
But I don’t know if this is the right way.

Sorry for the delay with answer, but I’m having trouble concentrating last few days. Hmmm… I’m not sure if I can understand what exactly is happening and causing the problem.

But I don’t know if this is the right way.

No, this is not the right way, it’s a workaround. Sometimes workarounds are ok, but in this situation you have to make sure that the buttons are properly handled as it may cause other problems.

Unfortunately without being able to see all the code I can’t tell exactly what can go wrong here (and as of today I’m still not able to grasp a big fraction of code - too dizzy :D). So, let’s try to reason logically:

  1. I see you call RemoveControl(C) but it should be LocationMenu.RemoveControl(C) - otherwise you’ll be removing buttons from TStatePlay and therefore LocationMenu.ControlsCount won’t decrease and you end up in an endless loop.
    1a. But this doesn’t happen. Why?
    1b. If it doesn’t happen, means both calls to this procedure receive empty LocationMenu. Maybe you create it again somewhere? And “that” LocationMenu still has all of its buttons and isn’t changed (maybe only removed from the screen, but not from existence).
  2. I see you assign NewButton.Tag but I don’t see you use it anywhere.
  3. I wonder why do you call Knowledge.Locations.Count - 2 - it should be “-1”. Or is there something special about the last location?
  4. Then I see the piece of code I don’t understand. You assign S := Knowledge.Locations[I] and then you immediately add Knowledge.Locations.Add(S); - this creates duplicates in Knowledge.Locations and will create duplicate buttons even in case button handling is done properly and they aren’t hanging in the memory. It may be a good idea to check if NPC knows the location before adding it to avoid adding it twice. And it doesn’t seem like it’s needed here at all.

Note that if Knowledge.Locations is a TStringList it has property Duplicates TStringList.Duplicates - you can set it to dupIgnore and it’ll handle duplicate entries for you (will not add them). However, note that it’s regularly a better solution to avoid adding duplicates by logic (e.g. “4” still needs fixing).

Ah, yes! Thanks, I changed that now.

No, I only created LocationMenu as TCastleVerticalGroup in the editor, without any buttons.

When I use -1 I get a runtime error on clicking GoToLocation button, saying that the button name (location) already exists. This is indeed the last location in the NPC list (eastcliffs).
I really don’t understand why this is doubled but with -2 it works allright.

Every NPC has some properties. Among them the knowledge of locations:

 Knowledge.Locations := TStringList.Create;
            Knowledge.Locations.Add('westbeach');
            Knowledge.Locations.Add('passagebeach');
            Knowledge.Locations.Add('eastbeach');
            Knowledge.Locations.Add('westcliffs');
            Knowledge.Locations.Add('village');
            Knowledge.Locations.Add('eastcliffs');  

Great!
S := Location.NPC[NPC_Selected].Knowledge.Locations[I];
// Location.NPC[NPC_Selected].Knowledge.Locations.Add(S);
I removed the second one and now the buttons show up fine every time without duplicate errors.
:slight_smile:

Now the button lists show up fine with every NPC assigned buttons and every time I click on GoToLocation they show up without crashing (double name error).
I am very glad this works at last.
Now I noticed the NPC only moves once to the location and does not respond anymore on sending it to another location. But this has probably nothing to do with the buttons. If I don’t get this working I will create a separate topic on it.

Thanks again!