Dealing with characters and corpses

Place to get help with not working mods / modding interface.
Post Reply
Pi-C
Smart Inserter
Smart Inserter
Posts: 1645
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Dealing with characters and corpses

Post by Pi-C »

I've lately developed a morbid interest in corpses (especially corpses of characters) and want to know as much as possible about them. :twisted: But there are some limitations that make it impossible to get the data I need:

Usually, a character will be connected to a player. When a player is killed,
  • on_pre_player_ died,
  • on_player_ died,
  • on_entity_ died, and
  • on_post_entity_ died
will be raised in this order. The event data of on_player_died contains the player index, and this can be used to get player.character and player.character.unit_number. When on_player_died has run, the player is removed from the character. When on_entity_died triggers for the player's character, one can still access entity.unit_number, but entity.player is nil. I deal with this by storing event.player_index and player.character.unit_number in on_player_died, and adding the other data in on_entity_died. Splitting it up like this is not nice, but it works.

But characters are not necessarily connected to a player. They could be completely independent entities (these are not relevant in my case, just mentioning them for the sake of completeness), and they may also be associated with a player. I want to get character.associated_player, but there is no way to do that:
  • on_player_died won't be triggered when an associated character dies.
  • In on_entity_died, both entity.player and entity.associated_player are nil.
  • From on_post_entity_died, one could get corpse.character_corpse_player_index, but there is no equivalent for associated players.
One way to cope with that would be to keep track of which characters get associated with a player. However, as there is no event for that there is no reliable way to be notified when that happens. (I could add a remote function that other mods call when they associate a character with a player, but other modders would have to know about it.) Another way would be to go over game.players and store the results of player.get_associated_characters() in regular intervals (on_nth_tick). That's also not reliable because a character may be associated with a player and killed before the association has been stored. (The alternative is to minimize the intervals by acting in on_tick instead, but I don't want to do that for obvious reasons.)

In my opinion, it would be best if the problem was solved in vanilla. I've several ideas:
  • Add corpse.character_corpse_associated_player_index (on_post_entity_died). This seems to be the easiest way.
  • Raise on_entity_died before on_player_died. Hopefully, this would preserve entity.player and entity.associated_player, but it could have unintended effects.
  • Add a new event on_pre_entity_died, which would be raised before on_player_died.
  • Add new events on_player_associated_character and on_player_disassociated_character.
I don't want to make a modding interface request for all of these, though, because each of these suggestions would solve my problem. What do you think I should ask for?
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Pi-C
Smart Inserter
Smart Inserter
Posts: 1645
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Dealing with characters and corpses

Post by Pi-C »

Pi-C wrote:
Thu Jan 20, 2022 12:17 am
When on_entity_died triggers for the player's character, one can still access entity.unit_number, but entity.player is nil. …

But characters are not necessarily connected to a player. They could be completely independent entities (these are not relevant in my case, just mentioning them for the sake of completeness), and they may also be associated with a player. I want to get character.associated_player, but there is no way to do that:
  • In on_entity_died, both entity.player and entity.associated_player are nil.
Found the solution myself now: If a character has been killed, on_entity_died won't have entity.player, but if there was an associated character, entity.associated_player won't be nil. So why didn't it work as expected? Quite simple: There was another mod active which would disassociate player and character in on_entity_died. Unfortunately, that mod was loading before mine, so it would remove the association before I had a chance to get the associated player … :oops:
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Post Reply

Return to “Modding help”