johnv2pt0 Posted August 27, 2019 Posted August 27, 2019 Hey guys and gals, I'm trying to make a script that detects when a client joins a multiplayer slot and then dynamically spawns a unit in front of them facing reciprocally (like a crew chief is in front of your plane). Here's what I've got: --DETECT CLIENT BIRTH AND SPAWN CREW CHIEF IN FRONT ClientSpawnHandler = {}; function ClientSpawnHandler:onEvent(event) if (world.event.S_EVENT_BIRTH == event.id) then local client = event.initiator local clientName = client:getName() local clientPos = client:getPosition() env.info(clientPos) if clientName == { 'CAS ROOK 1' } then mist.dynAddStatic{ country = 2, category = 1, x = (clientPos.x + 5), y = (clientPos.y + 5), type = "Soldier M4" } end end end world.addEventHandler(ClientSpawnHandler) Nothing is happening though, so first question is why not? Is S_EVENT_BIRTH not working? 2nd question: How to do the math for their vec2 position and heading. Right now I've just got a 5 meter offset in both directions as a baby step. 3rd question: Is there an easier way to detect if the birth event was from a client instead of having a huge list of unit names?CREW CHIEF SPAWN TEST.miz
Grimes Posted August 27, 2019 Posted August 27, 2019 1. Last I checked birth events were working, but they all had a time of 0 for some reason. Perhaps the env.info() of a table is what is messing it up. 2. Use mist.getHeading on the client object. Then use sin and cosine (I forget which value corresponds to which) for the x and y coordinates. local heading = mist.getHeading(client, true) x = clientPos.p.x + (math.cos(heading) * 5) y = clientPos.p.y + (math.sin(heading) * 5) 3. Since you are using mist do a check of the unit name to the DB that is already created. if mist.DBs.clientsByName[clientName] then -- spawn code end The right man in the wrong place makes all the difference in the world. Current Projects: Grayflag Server, Scripting Wiki Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread) SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum
Hardcard Posted August 27, 2019 Posted August 27, 2019 (edited) Nothing is happening though, so first question is why not? Is S_EVENT_BIRTH not working? Yes, S_EVENT_BIRTH definitely works. If you're trying to spawn a static on the deck of a carrier (I guess this is the case, since I see that you're using mist.dynAddStatic), I'm afraid I have bad news. I tried to do this sort of stuff while developing SWAPR, but I just couldn't make it work. Statics were spawned either at the bottom of the sea or not at all (even when linking the static to the carrier unit, forcing fixation and setting the offsets & angle via scripting). Unfortunately, looks like the only way of making statics appear on a carrier's deck is by using the ME interface (link unit and OFFSET FIXATION)... for now, looks like we have to accept this limitation in DCS. :cry: Helicopters and carrier-based planes (units) can be made to spawn via scripting (which is what SWAPR does, basically), but only if they are linked to specific parking spots on deck (sometimes it's trickier than that). As for infantry units (and ground vehicles), they can't be placed on the sea, so DCS won't even allow you to put them on a ship's deck. Even if you modify ground unit scripts ( gamedir\Scripts\Database\chassis ) to make them deployable on sea, they still won't be placed on the carrier's deck... they'll appear on the surface of the sea instead. And even if you modify some parameters to make these ground units appear ~20 meters above sea level (which is about the height of a carrier deck in DCS), they'll still clip through the carrier model, as if it weren't there. Also, this offset will apply to ALL ground units of the same type in the mission, which is pretty bad. Bottom line, I've already gone down this particular rabbit hole before... it led me to frustration and despair :badmood: 2nd question: How to do the math for their vec2 position and heading. Right now I've just got a 5 meter offset in both directions as a baby step. Since we're talking about carriers (which move along the X and Z axes and change their heading), you'll need to use a transformation matrix. If you open the file Matrix33.lua ( gamedir\Scripts ), you'll see the transformation functions that DCS uses. I was looking into this stuff back in January and, fortunately, I didn't come out empty-handed ;) https://forums.eagle.ru/showpost.php?p=3764379&postcount=20 Funkyfranky ended up turning the script into a MOOSE method for POSITIONABLE class. If you're using MOOSE, the method is :GetOffsetCoordinate(x,y,z) (you'll need to use a relatively recent develop version of MOOSE, older versions don't include it). If you aren't using MOOSE, the script can be turned into standard DCS code quite easily. Also, if you're only interested in using it on ships, you can skip the Y axis transform altogether (that would be the rotation along the Z axis). EDIT: Grimes' method seems easier to work with, now that I've seen it. If it successfully transforms X and Y (which is actually Z in 3D space) based on bearing, that might be a simpler solution 3rd question: Is there an easier way to detect if the birth event was from a client instead of having a huge list of unit names? Sure, if you're only interested in knowing whether the birth unit is a player, you can use :getPlayerName() . If it returns nil, the initiator isn't a client / player, if not, then it must be a client. Edited August 27, 2019 by Hardcard [sIGPIC][/sIGPIC]
johnv2pt0 Posted August 27, 2019 Author Posted August 27, 2019 I've been trying to get this to work with no avail. Here's what I've got now: --DETECT CLIENT BIRTH AND SPAWN CREW CHIEF IN FRONT ClientSpawnHandler = {}; function ClientSpawnHandler:onEvent(event) if (world.event.S_EVENT_BIRTH == event.id) then local client = event.initiator local clientName = client:getPlayerName() local clientPos = client:getPosition() local clientHdg = mist.getHeading(client, true) if clientName then mist.dynAddStatic{ country = 2, category = 3, x = clientPos.p.x + ( math.cos(clientHdg)*5 ), y = clientPos.p.y + ( math.sin(clientHdg)*5 ), type = "Soldier M4" } end end end world.addEventHandler(ClientSpawnHandler) The soldier spawns, but always at what I am assuming is the origin on the map, and facing in different directions. I'm afraid I don't understand the math well enough to troubleshoot further. I've been experimenting to try to make sense of it, but I just don't get it. Hardcard, I actually don't care about spawning stuff on the carriers and I'm glad that's the case because ain't nobody got time for those types of problems! Another probably dumb question: why "clientPos.p.x" and not "clientPos.x"?CREW CHIEF SPAWN TEST.miz
Hardcard Posted August 27, 2019 Posted August 27, 2019 (edited) Hardcard, I actually don't care about spawning stuff on the carriers and I'm glad that's the case because ain't nobody got time for those types of problems! Sorry, I was half asleep when I replied, for some reason I automatically associated "crew chief" with "deck chief", so I assumed you were talking about static spawning on carriers (I guess I'm kind of traumatized by this :megalol: ) If you just want to spawn statics on the map (land, not sea or carriers) then it's totally doable. Keep in mind that static infantry (M4 soldier, in this case) is problematic, you won't be able to give it a custom name or mess around with its template parameters (much). It's one of the static types in my "black list". I seem to recall that MANPAD statics didn't give me such trouble... but perhaps I'm recalling it wrong, they might be a pita too :doh: (stay away from static infantry... use AI infantry instead) Many static ground vehicles, planes, helicopters and structures work (though there are exceptions as well). As for statics spawning at the origin of the map, that's probably because you aren't giving the custom static template the proper parameters. I can see that you're giving the p.y value to the y coordinate, that's wrong... give it the p.z value instead (2D y value is actually the 3D z value in DCS). Here, this custom static template table + DCS method worked for me: local Static_Template = { ["heading"] = math.random(1,359), -- I don't recall if the heading value had to be given in degrees or radians... try both approaches ["shape_name"] = shape name, -- I don't recall if this was required (shape name can be obtained from the static's desc table , ["type"] = type name, ["name"] = custom name of the static, -- This must be a unique name, otherwise the static will be automatically removed from the map (like I said, static M4 soldiers won't accept custom names, sadly) ["y"] = Z coordinate value , -- This must be the Z value, not the Y! ["x"] = X coordinate value , ["dead"] = false, } coalition.addStaticObject(country enumerator , Static_Template ) In any case, if the statics you're interested in spawning refuse to work with this method, you can always spawn uncontrolled units instead, using a custom group template (it's pretty much the same kind of method... but the template table is different). why "clientPos.p.x" and not "clientPos.x"? Because the Position3 table is actually made of several subtables, it looks like this: Position3 = { p = {x = value , y = value , z = value}, -- Position subtable (coordinates relative to the map origin), for position stuff, always work with this one x = {x = value , y = value , z = value}, -- Orientation subtable along the X axis y = {x = value , y = value , z = value}, -- Orientation subtable along the Y axis z = {x = value , y = value , z = value} -- Orientation subtable along the Z axis } Edited August 27, 2019 by Hardcard [sIGPIC][/sIGPIC]
Recommended Posts