Jump to content

Help with Event Handler for MP


Recommended Posts

Guys,

 

I've written a simple script to spawn new units from a group of units. It works fine in SP, but does not in MP.

From what I can figure, it's a problem with the Event Handler.

Does the Event Handler work differently for MP?

 

Here is the code I am using. It uses the Player Enter Unit event.

 

EventHandlerControlUnit = {}
function EventHandlerControlUnit:onEvent(Event)
    
    if ( Event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT and Event.initiator:getPlayerName() ~= nil ) then
        
        EventGroup = Event.initiator:getGroup():getName()
        EventGroupType = Event.initiator:getTypeName()
        EventGroupID = Event.initiator:getGroup():getID()
        EventPlayerName = Event.initiator:getPlayerName()
        trigger.action.outText("Control Detected "..EventGroupType.." "..EventGroup, 15)
        
        
        if ( EventGroupType == "Tigr_233036" ) then             
            trigger.action.outText("Get out of my truck!", 15)
        end
        
        NasamSpawn(EventGroup)
        
    end      
end
world.addEventHandler(EventHandlerControlUnit)

 

Any ideas?

 

Thanks, 

DM

[PC] ASUS X570E - Ryzen 9  5950X - RX 6900 XT - 32GB 3600Mhz

Hornet, A-4E-C, Huey, Ka-50, Mi-8, F-15E, F-14

Join us on Death Dealers PvE server.

Link to comment
Share on other sites

8 minutes ago, Wizxrd said:

Have you tried setting player slots to Client for MP and slots to Player for SP? It does say here https://wiki.hoggitworld.com/view/DCS_event_player_enter_unit that it should trigger for player/client slots so not sure… Your code does look okay though for handling the event though.

 

To be honest, I'm not sure how to do that in this instance. These units have been spawned via coalition.addGroup while the mission is running.

I read that some of the event triggers do not work properly in MP, so I took the time to modify the script and use the MOOSE event handlers. Now it subscribes to the event for a particular type of unit, at the unit level.

 

It works fine in SP, but doesn't work in MP. I know the code is good because it works fine in SP.

 

    coalition.addGroup(Cargo_Country, Group.Category.GROUND, Herc_Cargo_Spawn)
    
--// Subscribe to Event //--
    if Cargo_Type_name == "Tigr_233036" then
        
        U = 1
        TigrUnitName = Herc_Cargo_Spawn.units[U].name
        TigrUnit = UNIT:FindByName(TigrUnitName)
        TigrUnit:HandleEvent(EVENTS.PlayerEnterUnit)
        
        function TigrUnit:OnEventPlayerEnterUnit(EventData)
    
            EventGroup = EventData.IniGroup
            EventGroupID = EventGroup:GetID()
            SetupConstructionMenu(EventGroupID, EventGroup)
                  
        end
    end
    

Thanks for you help.

DM

 

 

[PC] ASUS X570E - Ryzen 9  5950X - RX 6900 XT - 32GB 3600Mhz

Hornet, A-4E-C, Huey, Ka-50, Mi-8, F-15E, F-14

Join us on Death Dealers PvE server.

Link to comment
Share on other sites

4 hours ago, Death Merchant said:

Guys,

 

I've written a simple script to spawn new units from a group of units. It works fine in SP, but does not in MP.

 

 

Can you perhaps give a bit more context? Does it always fail, or only fail when a client (i.e. not the player also serving as host) triggers? I have observed some wierd behaviour when the initiator of a player event does return nil. Note that since S_EVENT_PLAYER_ENTER_UNIT should always reference a unit, you could log if either initiator is nil or getPlayerName returns nil to get some more diagnostics to work on.

 

Link to comment
Share on other sites

9 minutes ago, cfrag said:

 

Can you perhaps give a bit more context? Does it always fail, or only fail when a client (i.e. not the player also serving as host) triggers? I have observed some wierd behaviour when the initiator of a player event does return nil. Note that since S_EVENT_PLAYER_ENTER_UNIT should always reference a unit, you could log if either initiator is nil or getPlayerName returns nil to get some more diagnostics to work on.

 

cfrag,

 

I'll explain the best that I can. I'm new to all of this.

 

I am working on adding some functionality to a mission. The following works fine when I run the mission on my  local machine in SP mode.

 

We are using the Hercules mod to spawn units via coalition.addGroup.

When it spawns a Tigr, it uses the code from the above message to add menu items to the F10 menu.

 

The purpose is to be able to unload or drop crates/units from the Herc.

When you have 1-Tigr and 4-Hummers in a 300 meter radius, you enter the Tigr via CA/ralt-J.

From the F10 menu you choose 'Constuct Nasam Site' and the 4 Hummers are destroyed and a Nasam Site is spawned.

The Herc units and Nasam Sites are persistent from mission to mission.

 

I'm adding this functionality to the Snowfox Escalation Mission.

 

Everything works great in SP on my local machine.

 

I am hosting a dedicated server on a second machine here in my home. The mission has been running great for weeks. The mission is persistent, the Herc spawned units are persistent, etc.

 

The only problem is that when I run the script to construct the new units on the MP server, the Event Handler does not seem to be detecting the event. The menu items do not appear.

 

DM

Digital Combat Simulator  Black Shark Screenshot 2021.08.03 - 07.22.51.35.png

Digital Combat Simulator  Black Shark Screenshot 2021.08.03 - 07.23.06.44.png

You can see my debug message in the upper right indicating the event handler ran the menu function.

 

DM

[PC] ASUS X570E - Ryzen 9  5950X - RX 6900 XT - 32GB 3600Mhz

Hornet, A-4E-C, Huey, Ka-50, Mi-8, F-15E, F-14

Join us on Death Dealers PvE server.

Link to comment
Share on other sites

Just now, Death Merchant said:

The only problem is that when I run the script to construct the new units on the MP server, the Event Handler does not seem to be detecting the event. The menu items do not appear.

 

Thank you for explaining. Some additional questions:

  • Don't the menu items appear at all, or do they not appear on some clients?
  • Also, is one player self-hosting, or are you using a stand-alone server? 

 

In cases like this I use heavy 'logging' (well, it's called that when I devlelop on other machines, but the concept is the same). by using trigger.action.outtext("I am here", 30) (or similar) to trace what invocations are made. In this case, I'd simply add outtext() to the code that's invoked by the event manager and output all events to see if you are being invoked for player_enter_unit. If so, we'll proceed further down the code to see where the break happens (i.e. the next step is to verify your guard that assumes that you get a playerName back)

 

Link to comment
Share on other sites

Thanks for the images. I do not see the part of the code that logs "Menu function set up for ", so perhaps let's look at the code. To begin and see if perhaps all we have is a group isse, make sure you are not using missionCommands.addCommandForGroup() but the global addCommand() to see if it is invoked correctly, and you are running into a problem where you are not part of the group that owns the invoking unit. Make sure to log the group, and coalition that owns the unit as well


Edited by cfrag
Link to comment
Share on other sites

cfrag,

 

If you look at the upper right hand corner of the images, you'll see a message 'Menu Functions....'. that's the output I used as a trace to verify it got to the menu set up portion of the code.

 

I'm hosting on a stand-alone server.

 

I'm going to add some more messages for trace.

 

DM

[PC] ASUS X570E - Ryzen 9  5950X - RX 6900 XT - 32GB 3600Mhz

Hornet, A-4E-C, Huey, Ka-50, Mi-8, F-15E, F-14

Join us on Death Dealers PvE server.

Link to comment
Share on other sites

24 minutes ago, Death Merchant said:

If you look at the upper right hand corner of the images, you'll see a message 'Menu Functions....'. that's the output I used

 

Thank you -- I did see that, but I did not see that particular line represented in the code you kindly provided. There is no telling for me what got invoked with which values, only that the output claims that the menu functions where called. From the results you say that you see no menu, which indicates that it either was not invoked, or invoked with values that will not show the menu to your group (which happens when addCommandForCoalition() or addCommandForGroup() is invoked with parameters that exclude you). That is why I think we may want to look at how you set up missionCommands.addCommand() and what values are passed. 

Link to comment
Share on other sites

The code works perfectly in SP, but fails at the:

 

function TigrUnit:OnEventPlayerEnterUnit(EventData)

 

on the MP server.

 

Here is the code for the event handler function. You can see the first message in the screenshot, but not the next.
I can enter and take control of the Tigr, but the event does not seem to trigger the event handler.

 

In SP I get the second message and the menu.

 

--// Subscribe to Event //--
    if Cargo_Type_name == "Tigr_233036" then
        
        trigger.action.outText("Unit Detected Hercules Cargo", 300)
        
        U = 1
        TigrUnitName = Herc_Cargo_Spawn.units[U].name
        TigrUnit = UNIT:FindByName(TigrUnitName)
        TigrUnit:HandleEvent(EVENTS.PlayerEnterUnit)
        
        function TigrUnit:OnEventPlayerEnterUnit(EventData)
    
            trigger.action.outText("Event Detected", 30)
            
            EventGroup = EventData.IniGroup
            EventGroupID = EventGroup:GetID()

            SetupConstructionMenu(EventGroupID, EventGroup)
            
            trigger.action.outText("Menu Setup Function Run", 30)
                  
        end
    end

 

 

Digital Combat Simulator  Black Shark Screenshot 2021.08.03 - 11.07.10.63.png
 

[PC] ASUS X570E - Ryzen 9  5950X - RX 6900 XT - 32GB 3600Mhz

Hornet, A-4E-C, Huey, Ka-50, Mi-8, F-15E, F-14

Join us on Death Dealers PvE server.

Link to comment
Share on other sites

Since I don't know how TigrUnit.OnEventPlayerEnterUnit() is invoked in your code (through TigrUnit:HandleEvent(EVENTS.PlayerEnterUnit) perhaps - in that case you may need to first define the callback function and then invoke the event (this should really not be the issue, but you never know)). So how does your code really invoke OnEventPlayerEnterUnit()? Perhaps show that code and place some outtext around the guards that decide to invoke.

 

Link to comment
Share on other sites

It's invoked by the event handler. That's the problem.

In fact I've found some other threads talking about how the event handler does not work properly for all events in MP, specifically the PlayerEnterUnit.
So it seems to be a MP issue. I'm going to experiment with onBirth and see if that will work the way I want.

 

DM

 

Nope, that didn't work.

 

Anyone have any other ideas?


Edited by Death Merchant

[PC] ASUS X570E - Ryzen 9  5950X - RX 6900 XT - 32GB 3600Mhz

Hornet, A-4E-C, Huey, Ka-50, Mi-8, F-15E, F-14

Join us on Death Dealers PvE server.

Link to comment
Share on other sites

onBirth won't really solve your problem for CA-units. Best to make your own event handler via timer.scheduleFunction'ing:

 

- (dynamically) store the (spawned) units in a data base, i.e. table, e.g. via groupID and groupName as key/value

- execute a looping function via timer.scheduleFunction every n seconds, iterating over all stored groups and units in the data base

- a player entered/is in a unit if that unit returns a getPlayerName() string value 

 

I've attached a simple demo mission, you can find the corresponding script (player_in_unit_eventhandler.lua) inside. This is only to give you a rough idea: dynamically spawned units are not included, only the first unit of the group is tested for player presence, etc.

 

player_in_unit_test.miz

 

Link to comment
Share on other sites

  • 1 year later...
On 8/3/2021 at 5:04 PM, Death Merchant said:

It's invoked by the event handler. That's the problem.

In fact I've found some other threads talking about how the event handler does not work properly for all events in MP, specifically the PlayerEnterUnit.
So it seems to be a MP issue. I'm going to experiment with onBirth and see if that will work the way I want.

 

DM

 

Nope, that didn't work.

 

Anyone have any other ideas?

 

I'm running into this exact problem. 

I can't believe that this hasn't been addressed. It's a HUGE FREAKIN' problem!!

 

Did you get this solved? 

I've bugged it - for all the good it will do...
 

 


Edited by Elphaba
Link to comment
Share on other sites

--- Initialise this script
-- @param #table newPlayerData <required> [the custom player object to have their menu setup]
-- @return none
function TIS:Initialise()

    self:InitialiseTables()

    world.addEventHandler(TIS)

    self:LogWrite("TIS", "INFO", "Initialisation Complete. Version %s", self.Version)

end

---------------------------------------------------------------------------------------------------
-- onEvent
---------------------------------------------------------------------------------------------------

--- Subscribed DCS Event Handler
-- @param #event event <required> [the name of the event to be handled (or not)]
-- @return none
function TIS:onEvent(event)

    if event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT then
        self:LogWrite("TIS", "INFO", "S_EVENT_PLAYER_ENTER_UNIT")
        self:AddNewPlayerUsing(event)
    
    elseif event.id == world.event.S_EVENT_PILOT_DEAD then

        self:LogWrite("TIS", "INFO", "S_EVENT_PILOT_DEAD")
        self:RemoveDeadPlayerFromListOfPlayersUsing(event)

    elseif event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT then

        self:LogWrite("TIS", "INFO", "S_EVENT_PLAYER_LEAVE_UNIT")
        self:RemoveDeadPlayerFromListOfPlayersUsing(event)

    end

end

In a mission made for MP - i.e. many 'CLIENT' aircraft, but running it on my PC for just me i.e. NOT on a server, this all works fine.

If I run it on my server, with NO changes. This damn event never fires. 

Link to comment
Share on other sites

  

On 11/8/2022 at 2:14 AM, Elphaba said:

This damn event never fires. 

 

I've tried your code, and simplified it a bit (see below). For me it works well, even on MP. I therefore suspect that either your TIS code isn't inited on your client, or you are checking the wrong log file, or something else is going wrong with recording the event - it seems to work with me:

stupid null

image.png

(please ignore the v1.1.0-beta, I'm testing an interesting mod at the same time 🙂 )

TIS = {} -- all new TIS

function TIS:Initialise()

    world.addEventHandler(TIS)

	trigger.action.outText("init TIS done", 30)
end

---------------------------------------------------------------------------------------------------
-- onEvent
---------------------------------------------------------------------------------------------------

function TIS:onEvent(event)

    if event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT then
		trigger.action.outText("Player Enter unit triggered", 30)

    elseif event.id == world.event.S_EVENT_PILOT_DEAD then
		trigger.action.outText("Player Pilot DEAD triggered", 30)

    elseif event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT then
		trigger.action.outText("Player LEAVE unit triggered", 30)

    end
end

TIS:Initialise()

 

Test TIS.miz


Edited by cfrag
Link to comment
Share on other sites

Hey @cfrag

So yeah, if I run the mission on my pc using my standalone DCS game, then it works perfectly.

If I install DCS Server and run it on that and then connect to that via my standalone DCS game and join, then the event's don't fire.

I've also tried this on a 3rd party's DCS Server - and it won't fire. 

But always fires perfectly on my standalone DCS game.

Is this what you saw?

Link to comment
Share on other sites

Confirmed. I don't see the Player Enter. This may be because you aren't really connected to the mission when not in the plane as client. If you want, I can host, you or I can enter and we can see if other clients (and therefore the host) get the enter event when they are in.

 

  • Like 1
Link to comment
Share on other sites

I've just checked how I handle this in my missions, because I was sure that I detect players checking in. Turns out my code iterates all players once a second and notices new and absent faces. Some auxiliary methods in my code home in on the birth event, and query getPlayerName (if it's implemented, and if so, get the player's name). It seems indeed that player_enter can't be trusted.

  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...