Select character on event on_player_changed_force

Place to get help with not working mods / modding interface.
Post Reply
User avatar
yaim904
Long Handed Inserter
Long Handed Inserter
Posts: 86
Joined: Wed Nov 17, 2021 11:26 pm
Contact:

Select character on event on_player_changed_force

Post by yaim904 »

Hello,

I hope you are well,

I need help with the following idea.

I want to add some items to a player's inventory, but I found that, when they change forces, I can't find the instance of the new character associated with the player to add the items.

I hope I have explained myself well.
Solo entiendo español, pero si tu también lo entiendes, escríbeme
:D
Everything i write in English is translated by google.
:D

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

Re: Select character on event on_player_changed_force

Post by Pi-C »

yaim904 wrote:
Tue Jul 26, 2022 11:14 am
I want to add some items to a player's inventory, but I found that, when they change forces, I can't find the instance of the new character associated with the player to add the items.
Are you sure you mean associated characters? If you change forces, player.character will remain the same. You can verify that by running this code from the chat console:

Code: Select all

/c 
check = function() game.print("force.name: "..p.force.name.."\ncharacter.unit_number: "..tostring(p.character.unit_number)) end
p = game.player
p.force = "player"
check()
p.force = "enemy"
check()
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

User avatar
yaim904
Long Handed Inserter
Long Handed Inserter
Posts: 86
Joined: Wed Nov 17, 2021 11:26 pm
Contact:

Re: Select character on event on_player_changed_force

Post by yaim904 »

Thanks for your help.
What you say is not confirmed in the code.
When I try to get the player character in the on_player_changed_force event the value of Player.character does not exist and get_associated_characters() gives me the previous character.
Items are added successfully, but to the old inventory not the new one.
Solo entiendo español, pero si tu también lo entiendes, escríbeme
:D
Everything i write in English is translated by google.
:D

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

Re: Select character on event on_player_changed_force

Post by Pi-C »

yaim904 wrote:
Tue Jul 26, 2022 3:28 pm
Thanks for your help.
What you say is not confirmed in the code.
When I try to get the player character in the on_player_changed_force event the value of Player.character does not exist and get_associated_characters() gives me the previous character.
Items are added successfully, but to the old inventory not the new one.
Sorry, your links are garbled (there's real text instead of a URL), so perhaps I don't understand you correctly.

The following will give a rocket-silo to any player who joins another force:

Code: Select all

script.on_event(defines.on_player_changed_force, function(event)
	local player = game.players[event.player_index]
	if player and player.valid then
		 player.insert("rocket-silo")
	end
end)
If you have a player on force "player", and player.character is not nil, the command

Code: Select all

/c game.player.force = "enemy"

will trigger the event and your character should have a rocket-silo in its inventory.

Now, use

Code: Select all

/c 
c = game.player.character
game.player.character = nil


to enter god mode. If your character's inventory was open, it will be closed now. Open it again to see that you have an empty inventory. Then run

Code: Select all

/c game.player.force = "player"
to trigger the event again. You still have no character, but you'll find that a rocket-silo has been added to your player inventory.

Now try

Code: Select all

/c 
game.player.character = c
game.player.force = "enemy"
to get back your old character and trigger the event again. This time, there should be 2 rocket-silos in your inventory.

In god mod, you don't have a character but you still get an empty inventory. When you switch from god mode to character mode (i.e., when player.character is not nil), the contents of your god-mode inventory will be lost. It's similar with editor mode, but there's an important difference: When you enter /editor, your old character (if you had one) will be stored and you will get an empty inventory. When you leave editor mode again, everything that was in your editor-mode inventory will be lost, but your old character (if you had one) will be restored to you.

I hope that makes sense. :-)
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

User avatar
yaim904
Long Handed Inserter
Long Handed Inserter
Posts: 86
Joined: Wed Nov 17, 2021 11:26 pm
Contact:

Re: Select character on event on_player_changed_force

Post by yaim904 »

This is the test code I have.

Code: Select all

-- Control.lua
local function Test( Event )
GPrefix.Log( "1" )
    local Player = game.players[ Event.player_index ]
    if not Player then return end

    if not Player.character then
GPrefix.Log( "2" )
        Player.insert( { count = 1, name = "rocket-silo" } )
    end

    if Player.character then
GPrefix.Log( "3" )
        local Inventory = Player.character
        local IDInvertory = defines.inventory.character_main
        Inventory = Inventory.get_inventory( IDInvertory )
        Inventory.insert( { count = 1, name = "iron-plate" } )
    end

    local Character = Player.get_associated_characters( )
    Character = #Character > 0 and Character[ 1 ] and nil
    if Character then
GPrefix.Log( "4" )
        local Inventory = Character
        local IDInvertory = defines.inventory.character_main
        Inventory = Inventory.get_inventory( IDInvertory )
        Inventory.insert( { count = 1, name = "copper-plate" } )
    end
end

script.on_event( defines.events.on_player_changed_force, Test )
script.on_event( defines.events.on_player_joined_game, Test )
script.on_event( defines.events.on_cutscene_cancelled, Test )
script.on_event( defines.events.on_player_created, Test )
The answer that throws GProfix.Log is the following

Code: Select all

factorio-current.log

  51.695 Script @__zzYAIM__/mods/__LIBRARIES__/__FUNCTION__.lua:230: 
>>>
[ 1 ] = '1'
<<<
  51.695 Script @__zzYAIM__/mods/__LIBRARIES__/__FUNCTION__.lua:230: 
>>>
[ 1 ] = '3'
<<<
  51.695 Script @__zzYAIM__/mods/__LIBRARIES__/__FUNCTION__.lua:230: 
>>>
[ 1 ] = '1'
<<<
  51.695 Script @__zzYAIM__/mods/__LIBRARIES__/__FUNCTION__.lua:230: 
>>>
[ 1 ] = '3'
<<<
  62.055 Script @__zzYAIM__/mods/__LIBRARIES__/__FUNCTION__.lua:230: 
>>>
[ 1 ] = '1'
<<<
  62.055 Script @__zzYAIM__/mods/__LIBRARIES__/__FUNCTION__.lua:230: 
>>>
[ 1 ] = '2'
<<<
  62.055 Script @__zzYAIM__/mods/__LIBRARIES__/__FUNCTION__.lua:230: 
>>>
[ 1 ] = '4'
<<<
Which results in the following in Team Production mode
Captura de pantalla (87).png
Captura de pantalla (87).png (705 KiB) Viewed 1005 times
Captura de pantalla (88).png
Captura de pantalla (88).png (836.11 KiB) Viewed 1005 times


As you can see, once the equipment is chosen, the objects are not added to the inventory.
How can I correct this??
Solo entiendo español, pero si tu también lo entiendes, escríbeme
:D
Everything i write in English is translated by google.
:D

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

Re: Select character on event on_player_changed_force

Post by Pi-C »

yaim904 wrote:
Tue Jul 26, 2022 10:30 pm
This is the test code I have.

Code: Select all

    local Character = Player.get_associated_characters( )
    Character = #Character > 0 and Character[ 1 ] and nil
That looks wrong. Character will be "false" if the table is empty, or nil if it is not. The second "and" should be "or":

Code: Select all

    Character = #Character > 0 and Character[ 1 ] or nil
Oh, right -- I forgot about the cutscene!

Code: Select all

script.on_event( defines.events.on_cutscene_cancelled, Test )
player.character will be nil while the cutscene is running. You'll have player.cutscene_character instead.

Too tired now to investigate deeper, but I suppose that waiting for the end of the cutscene before trying to add things to the inventory is the way to go. This is what I do in miniMAXIme (scripts/player.lua):

Code: Select all

minime_player.on_player_joined_game = function(event)
  minime.entered_function({event})
  local player = game.players[event.player_index]

  local force = player.force
  if force and force.valid and not global.researched_by[force.name] then
    minime_player.init_force_data(force)
  end


  -- We're still in a cutscene. Wait until it is finished!
  if player.cutscene_character then
    minime.writeDebug("Player has no character yet. Waiting for cutscene to finish!")
    script.on_event(defines.events.on_cutscene_cancelled, function(event)
      minime.entered_event(event)

      minime_player.init_player(event)

      minime.entered_event(event, "leave")
    end)

  -- Cutscene has finished or wasn't played. Initialize player immediately!
  else
    minime.writeDebug("Initializing player %s%s!",
      {player.index, player.name and " ("..player.name..")" or ""})
    minime_player.init_player(event)
    -- We can stop listening to on_cutscene_cancelled now!
    script.on_event(defines.events.on_cutscene_cancelled, nil)
    minime.writeDebug("Unregistered handler for event \"on_cutscene_cancelled\"!")
  end

  minime.entered_function("leave")
end
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

User avatar
yaim904
Long Handed Inserter
Long Handed Inserter
Posts: 86
Joined: Wed Nov 17, 2021 11:26 pm
Contact:

Re: Select character on event on_player_changed_force

Post by yaim904 »

Pi-C wrote:
Tue Jul 26, 2022 11:15 pm
That looks wrong. Character will be "false" if the table is empty, or nil if it is not. The second "and" should be "or":
You are right, this was a mistake.

I still can't find a way to add the items I want to users (automatically) when starting the game or connecting, especially in team production mode.

In sandbox mode and freeplay it's easy, but in the other modes...let's just say not so much.
Solo entiendo español, pero si tu también lo entiendes, escríbeme
:D
Everything i write in English is translated by google.
:D

Post Reply

Return to “Modding help”