Bob's Character classes


Adds character classes to the game.

10 months ago
0.16 - 1.1
94.9K

b Space Exploration & Characters Unselectable

4 years ago
(updated 4 years ago)

Is there a means of adding a feature to reclaim a character when it gets disassociated? I got mowed down by a train while not paying attention and lost control of two of my bodies on other planets (of Space Exploration mod). It would be nice if there was a way to either prevent this issue or at least be able to reclaim a body, maybe with an off/on setting so that feature can be disabled on multiplayer servers.

https://i.imgur.com/WB0DvZ9.jpg

4 years ago
(updated 4 years ago)

The Imgur link doesn't seem to be working right now.

But, the disassociation issue is a new one on me. The association is stored in "Player", which is you as the controller. Death should NOT disassociate any existing associated characters, in fact, you should automatically switch to one of your others instead of respawning. It shouldn't matter if they're on the same surface or not. (I had to write in extra scripting to make sure the game didn't crash when switching between surfaces.)

If this isn't how it works for you, it's likely an issue with the way space exploration does things.

The problem with trying to associate with a disassociated character, is figuring out how to let you tell the mod that you want to associate that character to your player controller.

4 years ago

Well, with Space Exploration, it has a thing where when you die, you get a respawn selection prompt, so there's a conflict there. Space Exploration pops up an option to spawn near launch pad (I think it was) or Homeworld.

4 years ago
(updated 4 years ago)

Well, with Space Exploration, it has a thing where when you die, you get a respawn selection prompt, so there's a conflict there. Space Exploration pops up an option to spawn near launch pad (I think it was) or Homeworld.

Sounds like it undoes what my mod does.

My mod would instantly switch to another body while space exploration asks you what you want to do, so when you press any of those buttons, space exploration does it's thing and gives you a new body... without associating the one that you've just left.

That's part of an issue with association, you CAN'T associate an occupied body, so to switch you have to store the current character as a local variable, switch to the new one, then associate the old one. So if Space exploration gives you a new body at the point where my mod just moved you to one of the others, the association is lost.

I'm guessing here, I've not actually tried it, but since I know how my mod works, and what you have to do to not break association, it makes sense that this is what's happening.

4 years ago

I understand it's just an incompatibility between the two due to that conflict. I just wanted to report it anyway on the off chance that either it's an easy fix, or if someone else has the same problem they can read this thread for some info.

4 years ago
(updated 4 years ago)

I understand it's just an incompatibility between the two due to that conflict. I just wanted to report it anyway on the off chance that either it's an easy fix, or if someone else has the same problem they can read this thread for some info.

Lets just say, if it is what I think it is, there's not really anything I can do about it.

Once association is lost, there's no easy way to try and fix it. there's no record of what used to be a linked entity, so, all you can really do is SCAN THE ENTIRE MAP which takes a very long time, and link any unlinked characters that were found, or maybe add an option where you can select a character you're standing next to in some way to link them. Either way it's messy.

As for being disassociated in the first place, there's really nothing I can do about it, due to scripts being completely self contained to their specific mod, and unaccessible to any other. The only way for it to not break is if Space Exploration checks if there's already a character attached to the player when it does it's spawn action, and either calls an event that my mod can look for (And custom events are messy) or just associates it itself.

4 years ago

I appreciate your responses and explanations of the issue. It sucks these two mods don't play nicely together because yours is so perfect for using with Space Exploration. There's no issues with your mod working correctly on its own and with your other mods, so there's really nothing to fix. I'm thinking it would likely take a moderate rewrite to make a Space Exploration compatible version based on what you've said. Thank you for your mod, it still works really well even with the issues that Space Exploration causes.

4 years ago

If the problem is that respawning currently defaults to use the base character that should be fixed soon. If the problem is scripted bonuses, I already raise a custom on_player_respawned_event after the respawn for any scripted modifiers to be applied. If something further is required let me know and I'll see what I can do.

4 years ago

If the problem is that respawning currently defaults to use the base character that should be fixed soon. If the problem is scripted bonuses, I already raise a custom on_player_respawned_event after the respawn for any scripted modifiers to be applied. If something further is required let me know and I'll see what I can do.

Thank you for the attention here.

I think the problem is related to the fact that my mod will set a different character entity on pre_player_died.
If possible, before creating a new character entity, check to see if one is already attached to the player, and if so, Associate it with the player.
(Since you can only associate a character that isn't currently being controlled, this would require something something like... local character = player.character, player.character = new_entity, player.associate_character(character).)

I mean, I could re-write how my mod works to not be dependant on associated characters, but to work properly in multiplayer (Disappear along with their owner when disconnected) they do need to be associated.

4 years ago

I see. I also use on_pre_player_died to circumvent the normal death behaviour, when a character would normally die I detach the character from the player and give them the respawn options. I don't know how on_pre_player_died responds to the death being cancelled by another mod if their code runs first. Assuming both events fire I could check to see if the character seems to have been revived/replaced by seeing if health is above 0, but I don't know if it works like that.

4 years ago

I checked what my mod does... it doesn't really care. It just calls "Next character", which sets a new character, and if an old one exists, associates it.

if an associated character dies, it just gets deleted and disassociated, so... no harm is just associating anything you disconnect, even if it is about to be deleted.

4 years ago

I will update my code to use the associated characters system, it that doesn't resolve the issue initially it should at least be easier to work around any remaining problems. I would probably need to do that later anyway because I am planning a jump-clone style system to avoid the wait from interstellar spaceship travel times, it would be best if that was compatible too.

This is completely off-topic but a few years ago I gave you a list of around 12 specialist class ideas. Did you have any interest in following that up or are you sticking to the 3 classes?

4 years ago
(updated 4 years ago)

I will update my code to use the associated characters system, it that doesn't resolve the issue initially it should at least be easier to work around any remaining problems. I would probably need to do that later anyway because I am planning a jump-clone style system to avoid the wait from interstellar spaceship travel times, it would be best if that was compatible too.

Thanks.

This is completely off-topic but a few years ago I gave you a list of around 12 specialist class ideas. Did you have any interest in following that up or are you sticking to the 3 classes?

I actually looked through that when I was adding more classes. (There's Engineer and Prospector now, Engineer being a combination of Builder and Miner, and Prospector being a combination of Miner and Fighter. They're Tier 2 classes along with Tier 2 Balanced, Miner, Builder and Fighter. Why no Builder and Fighter combination? With the exception of the crafting speed bonus, Every pro on one class was a con on the other, trying to combine them resulted in balanced with +crafting speed.)
I tried to look up the list you gave for writing this comment, but couldn't find it.

It's not that I don't want to add them, it's just that when I was going through the list, trying to actually write it to do what you were suggesting, or making it significantly different to something that already existed wasn't easy.
IIRC, one of them started with a cut down personal roboport and robots. It's a good idea in theory, but consider that you only get minimal equipment on respawn, and can change settings to swap between classes without respawning (It was a request, it's in map settings), when exactly should you change gear? First spawn: Yes. Respawn: Maybe. Swap class: No. Also, you can build classes later on to have multiple bodies (respawning as a T2 class is unlocked by the same technology that lets you build it), and all of those start with no gear.
Having different and unique gear isn't a bad idea, but a class shouldn't be dependant on starting with special gear. Although I did like that class idea, I had to cross it off the list because of this.

3 years ago

Messieurs,
Your mods are allowing us to stay sane during this pandemic. Thanks to you both.
It seems however that the "zombie characters" are still an issue on our modest server.
If any of my characters die, I loose access to all remaining "zombies", and quite annoyingly, their Personal logistics remains turned on. if we could "right click" it to reclaim the clones and "cast" them again, it would really solve most of the issue.

In the end, I find it kind of cool to loose access to the "clones" until we can bring a living character next to it...

So, I am no programmer whatsoever, but as potential workarounds: would it be possible to:
-A "transform" any empy character into a "chest" containing the character and it's stuff #BackInTheBox ?
- Or "kill" ALL the characters if one of them dies? that way, we would have 15 minutes to reclaim all of them and they would not remain there indefinitely as zombies we can't do anything with?
- Or maybe make empty characters "reclaimable" like a dead body, or a vehicule?

Once again, many, many thanks!
Happy to brainstorm if need be,

3 years ago
(updated 3 years ago)

Hi Guys,

I was experiencing the same problem with the two mods and I decided to modify Bob's character class to work around the issue.I added a button to re-associate a character with a player in the character selection panel.

This is not the prettiest code I ever written but considering I never looked at LUA code before last night it's alright I guess. I'm willing to work on it a bit further to make it more robust/in line with the spirit of the mod but I might need some pointers (not having a whole lot of experience with the API).

Would you guys be interested? how do I go at contacting you to share and discuss the workaround?

Cheers

3 years ago

Hi Guys,

I was experiencing the same problem with the two mods and I decided to modify Bob's character class to work around the issue.I added a button to re-associate a character with a player in the character selection panel.

This is not the prettiest code I ever written but considering I never looked at LUA code before last night it's alright I guess. I'm willing to work on it a bit further to make it more robust/in line with the spirit of the mod but I might need some pointers (not having a whole lot of experience with the API).

Would you guys be interested? how do I go at contacting you to share and discuss the workaround?

Cheers

Would you possibly mind sharing the code here or making a compatibility patch mod for this to release to those of us who are still affected by this nuisance?

3 years ago
(updated 3 years ago)

Have any of you gotten disassociated by attempting to switch bodies while in sat-nav view?
Well, we have, but the fix we came up with involves modding both mods.
Basically it has Bob's character selection event tell Earendel's script to exit nav view before having Bob's character switch do its thing.

We register a remote interface to Earendel's "RemoteView.stop(player)" function and add a call to it in Bob's "on_event(on_gui_click)" logic, somewhere before the local player reference is made.

In Earendel's control.lua:
<code>
remote.add_interface("leave_nav", {leave_nav = function(player) RemoteView.stop(player) end})
</code>

In Bob's control.lua:
<code>
script.on_event(defines.events.on_gui_click, function(event)

if remote.interfaces.leave_nav and remote.interfaces.leave_nav.leave_nav then
remote.call("leave_nav","leave_nav",game.players[event.player_index])
end

...
</code>

I don't think this can be achieved with a compatibility mod since there's no way to preempt Bob's "on_event" script with that remote call but maybe I'm wrong.

3 years ago

It turns out Earendel has already made RemoteView.stop(player) a remote interface.
This means all we need is the call to it in Bob's event catch:

<code>

script.on_event(defines.events.on_gui_click, function(event)
if remote.interfaces["space-exploration"] then
remote.call("space-exploration", "remote_view_stop", {player=game.players[event.player_index]})
end
...

</code>

Ultimately this is only a workaround, since Space Exploration isn't aware of Bob's character management.
It also only resolves the SatNav dissociation issue and not death or spaceship launch issues.

3 years ago

I mean, if I were to do this, I wouldn't put it at the top of on_gui_click, because if you do, if you press ANY buttons, it'll boot you out of remote view.
I already have code that tries to boot you out of editor mode when you press a character button (because when you type /editor in the command line, it hides your entity, and just assigning a new entity to your controller exits map view without restoring the old entity, effectively deleting it, booting you out first would restore the old entity under your control to allow it to be associated again), so I'd likely add this in the same place as that.

Before I do, that is 100% accurate right? just these 2 lines. needed somewhere in the code before a character is assigned to your controller:
if remote.interfaces["space-exploration"] then
remote.call("space-exploration", "remote_view_stop", {player=game.players[event.player_index]})

I'm not going to be installing Space Exploration just to test this if I don't have to. I rarely install other people's mods for testing purposes, and if I do it's usually for a more complex thing than a single hook. On top of that, I've really not done much modding at all in the past few months (my to do list does keep growing though.)

3 years ago
(updated 3 years ago)

Thanks for the feedback Bob,

I'm with you on not having it in the top level of the event call.
I had an unfounded worry that putting it after your local player assignment might break something.
After my initial posts I tested it inside the "bob_avatar_list_character_" section and this worked more appropriately.

I tested the following successfully (line 1072, ++ for added logic):

<code>
function switch_character(player_index, new_character)
local player = game.players[player_index]
if player.controller_type == defines.controllers.editor then
player.toggle_map_editor() --safety restores the character entity.
end
++if remote.interfaces["space-exploration"] then
++remote.call("space-exploration", "remote_view_stop", {player=player})
++end
local old_character = player.character
if new_character.surface ~= player.surface then --are we looking at the same surface as the new character?
player.character = nil --we're not, disconnect the player
player.teleport(new_character.position, new_character.surface) --look at the new surface
end
...
</code>

Don't worry about testing. We can define any test code here and I'll run it.

Functional Description:
First we test to make sure the "space-exploration" interface exists. This prevents "bobclasses" from crashing if it tries to call a nonexistent remote function.
The call itself tells space exploration to exit "Remote-view" mode on its own terms. This provides "bobclasses" a "character" object it has an existing association with.

The next issue I will work on is losing association when the "spaceship" changes surfaces with an unattended body.

3 years ago

What you've done there is what I was going to try anyway, so if that works, I'll just use it.

Considering my mod already takes multiple surfaces into account (Tested with the warehouses mod, I think that's what it's called, the one where you go into a building, but inside the building is another surface), I've always just assumed that Space Exploration is doing something strange.

I mean, my mod uses associated characters, the game engine itself keeps track of them for me so that my mod doesn't have to. If Space Exploration is doing something that breaks this, there's not much I can do on my end (Short of a rewrite so that my mod keeps a list internally, but I'd still want to use Association for the multiplayer functionality)

Keep me informed of any progress.

3 years ago

OK, (3 months later)

Space Exploration "clones" a spaceship's tiles and entities and pastes them on a new private surface created just for this spaceship.
Every character entity on the ship, after getting cloned, will have a new "unit_number" value assigned to it.
If the character entity has a player attached then teleport it instead and delete the clone.
(entity is the original item before destruction and clone is the new item to be pasted):

<spaceship-clone.lua, line 413>

      local clone = clone_to.find_entity(entity.name, position)
      if clone and entity.player then
        entity.player.teleport(clone.position, clone_to)
        util.safe_destroy(clone)
      else

This only runs if the character entity has a player attached to it.

To address non player characters this is used:

        for _, playerdata in pairs(global.playerdata) do
          if playerdata.character == entity then
            playerdata.character = clone
          end
        end

It iterates over "global.playerdata", which is managed by SpaceExploration, and seems to be designed to hold all the map's players.
Curiously, in this scope "global.playerdata"'s player objects have no valid data for their character parameter.

What it looks like is supposed to happen seems like:
If the player's character parameter is valid, replace it with the clone.
Perhaps it is scaffolding for future functionality or maybe vestigial.

My current solution is predicated on the character.last_user property always belonging to the player that crated it.

        for index, player in pairs(game.players) do
          if entity.last_user.connected then
            if entity.last_user.index == player.index then
              player.associate_character(clone)
            end
          end
        end

For each player, check that the player is connected, then if the "last_user" property of the entity is the same as the player, associate the clone of that entity with the player.

The net result is that all clones get the opportunity to get re-associated with their players while preserving the original code's changing "unit_number" behavior.

Another option could be to teleport the non player character entities along with the player characters but that might deviate too much from the original functionality depending on what the intentions behind it are.

We've tried a few tests and so far it seems to hold up, hidden edge cases withstanding of course.

I don't know how to approach Earendel about it though.

3 years ago
(updated 3 years ago)

OK, (3 months later)

Space Exploration "clones" a spaceship's tiles and entities and pastes them on a new private surface created just for this spaceship.
Every character entity on the ship, after getting cloned, will have a new "unit_number" value assigned to it.
If the character entity has a player attached then teleport it instead and delete the clone.
(entity is the original item before destruction and clone is the new item to be pasted):

<spaceship-clone.lua, line 413>

      local clone = clone_to.find_entity(entity.name, position)
      if clone and entity.player then
        entity.player.teleport(clone.position, clone_to)
        util.safe_destroy(clone)
      else

This only runs if the character entity has a player attached to it.

To address non player characters this is used:

        for _, playerdata in pairs(global.playerdata) do
          if playerdata.character == entity then
            playerdata.character = clone
          end
        end

It iterates over "global.playerdata", which is managed by SpaceExploration, and seems to be designed to hold all the map's players.
Curiously, in this scope "global.playerdata"'s player objects have no valid data for their character parameter.

What it looks like is supposed to happen seems like:
If the player's character parameter is valid, replace it with the clone.
Perhaps it is scaffolding for future functionality or maybe vestigial.

My current solution is predicated on the character.last_user property always belonging to the player that crated it.

        for index, player in pairs(game.players) do
          if entity.last_user.connected then
            if entity.last_user.index == player.index then
              player.associate_character(clone)
            end
          end
        end

For each player, check that the player is connected, then if the "last_user" property of the entity is the same as the player, associate the clone of that entity with the player.

The net result is that all clones get the opportunity to get re-associated with their players while preserving the original code's changing "unit_number" behavior.

Another option could be to teleport the non player character entities along with the player characters but that might deviate too much from the original functionality depending on what the intentions behind it are.

We've tried a few tests and so far it seems to hold up, hidden edge cases withstanding of course.

I don't know how to approach Earendel about it though.

The ideal solution would be to Teleport all player entities rather than clone them and delete the original.
either way, if that is what it's doing, there's not a lot I can do on my end to fix it. if there is a "on entity created" event, monitoring it is actually fairly costly, but not that bad. If there isn't such an event, then the only way to find entities would be to scan the area for them, and that operation takes so much processing power it tends to freeze the game.
The only safe solutions would be to either just move the original instead of copying it and deleting the original, or to associate it as it is created, depending on the reason for creating it.

Either way, there's nothing "sane" I can really do on my end, even if I can think of a few solutions to the issue, the only sane solution is to associate it as it is created, which means it needs to be done in the same script, which means in space exploration.

New response