Deleting a player should clean up all references to it to prevent segfaults
When you delete a player using the devtools, it will just be removed from the Person::players
vector, but its ID will still be referenced in various places, such as in dialogs.
I've made a quick and dirty attempt at hotfixing this but so far it's not working (I get a segfault when deleting the player):
diff --git a/Source/GameTick.cpp b/Source/GameTick.cpp
index 0b83ced..9d9f318 100644
--- a/Source/GameTick.cpp
+++ b/Source/GameTick.cpp
@@ -1391,6 +1391,45 @@ void Game::ProcessDevInput()
if (Input::isKeyPressed(SDL_SCANCODE_DELETE) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
int closest = findClosestPlayer();
if (closest > 0) {
+ // Reassign player IDs in existing dialogs
+ for (unsigned i = 0; Dialog::dialogs.size(); i++) {
+ // 10 is hardcoded in Dialog
+ const unsigned int numplayers = 10;
+
+ // Module of the type is used to find player ID
+ if ((Dialog::dialogs[i].type % numplayers) >= (unsigned)closest) {
+ Dialog::dialogs[i].type--;
+ }
+
+ for (unsigned j = closest; numplayers - 1; j++) {
+ Dialog::dialogs[i].participantlocation[j + 1] = Dialog::dialogs[i].participantlocation[j];
+ Dialog::dialogs[i].participantyaw[j + 1] = Dialog::dialogs[i].participantyaw[j];
+ }
+ Dialog::dialogs[i].participantlocation[numplayers] = XYZ();
+ Dialog::dialogs[i].participantyaw[numplayers] = 0;
+
+ // Also fix DialogScenes
+ for (unsigned k = 0; Dialog::dialogs[i].scenes.size(); k++) {
+ if (Dialog::dialogs[i].scenes[k].participantfocus == numplayers) {
+ Dialog::dialogs[i].scenes[k].participantfocus = 0;
+ } else if (Dialog::dialogs[i].scenes[k].participantfocus >= closest) {
+ Dialog::dialogs[i].scenes[k].participantfocus++;
+ }
+
+ if (Dialog::dialogs[i].scenes[k].participantaction == numplayers) {
+ Dialog::dialogs[i].scenes[k].participantaction = 0;
+ } else if (Dialog::dialogs[i].scenes[k].participantaction >= closest) {
+ Dialog::dialogs[i].scenes[k].participantaction++;
+ }
+
+ for (unsigned j = closest; numplayers - 1; j++) {
+ Dialog::dialogs[i].scenes[k].participantfacing[j + 1] = Dialog::dialogs[i].scenes[k].participantfacing[j];
+ }
+ Dialog::dialogs[i].scenes[k].participantfacing[numplayers] = XYZ();
+ }
+ }
+
+ // Delete the player
Person::players.erase(Person::players.begin() + closest);
}
}
When we get to fixing this, it should probably be done via a method directly in Person and not a hack in GameTick.