

Bearfoot
Members-
Posts
1647 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Everything posted by Bearfoot
-
I, too, am with the majority here. Pointless waste of effort. Not to mention, a pointless waste of effort that clutters my desktop. And this clutter will only increase as more theaters are added and as we start getting into 2.5 beta, 2.5 alpha etc. etc. So, it's a strong "Noooooooooope" for me. Sorry.
-
Can anyone post the control mappings of the PAK-FA that this grip is based on? Here it is in Russian: This post helps out with translating some of them ... can anyone complete the rest or otherwise provide more information? Also, as the linked post says, the annotations may not be so accurate. So if anyone has got accurate ones, that would be great!
-
Not just resurrected, but with some new bits and pieces as well! Relevant parts reproduced below:
-
Introducing the VKB-Sim ‘Modern Combat Grip’ (MCG)
Bearfoot replied to rrohde's topic in VKB-SIM Flight Gear
For me, it says "$184.00 charged at a future date", though my cc shows that a charge went through on Dec 26. Either way, no tracking number :( -
Nope. That's not it. I actually think everyone understood EXACTLY what you were saying, and Kippy's clarification, great as it was, does not change the picture ;) We get the argument. We just don't buy it. You can teach the fundamentals of aviation in a virtual world in an A-10C as well as any other "trainer" bird. It is really an easy aircraft to fly (as in actually aviate in, rather than fight). One of the easiest, I think: very forgiving and great recovery characteristics. The reason they don't put a student in the seat of an A-10 (or an F-15 or a Su-25 etc.) on day one in RL is because it would be a very expensive trainer bird, both in terms of numbers to make available for training as well as if accidents happen. In a simulator, that is not an issue. Even if the DCS jet a/c are more dangerous to learn to fly in than the type of a/c you are describing, they are still a good enough a/c to learn flying in a simulator because there is no cost to crashing/dying and trying again. And, of course, in the simulator world, the cheap/no-cost-learning-curve arguments would apply to any a/c, so might as well learn the fundamentals of flight in the a/c you plan to use anyway, even if it is as twitchy as the Spitfire or the Harrier! As you can guess, my answer to your question is a pretty solid "no" :) I honestly do not see why any other a/c would be easier/better to learn the fundamentals of flying in than any of the pickings we have, for the reason I describe above, AND since there is no cost I think I would rather learn on the a/c I plan to fly anyway.
-
Thanks! That is useful.
-
Ah, OK. That clears things up. Thanks!
-
I cannot seem to find these under any infantry category. Everyone is armed with either RPG's or rifles. Am I missing anything or looking in the wrong place?
-
Very nice, and very needed!
-
how is everyone dealing with clickable cockpit in VR?
Bearfoot replied to hannibal's topic in Virtual Reality
I have that exact kneeboard. I used to use it it with a mini-keyboard, but can see it working quite well for a touchpad. It, too, would be my solution, though I would think you might want a piece of stiff board/plate to mount the touchpad on and strap the whole thing to the kneeboard for good resuslts. In any case, with a little bit of tinkering, it should work great. -
how is everyone dealing with clickable cockpit in VR?
Bearfoot replied to hannibal's topic in Virtual Reality
I think moving the mouse around is just too fiddly a proposition, especially in VR. You want to know exactly where it is without looking at all times. I think a full touchpad on your thigh would work best if you can take your hand off the throttle and find it again blind (which is what you would do in RL for the manipulations that require you to use the mouse anyway, e.g., flipping switches etc.) or a trackball strapped to the throttle as you originally proposed and what I do. Of course, in this day and age of mail ordering and easy/free returns, you could just try both out and see what you prefer and return the other! -
Putting it altogether in working but very, very, very, very, very ugly code (more a experiment right now, plan to refactor into clean class logic), we have the following. Added functionality includes not just loading but unloading, but also the flight engineer counting down the operation providing an estimate of time remaining etc. --------------------------------------------------------------------------------- -- Get handles on key zone, groups, etc. ConflictZone1 = ZONE:New( "Conflict Zone 1" ) PickupZone1 = ZONE:New( "Pickup Zone 1" ) ZoneCaptureCoalition1 = ZONE_CAPTURE_COALITION:New( ConflictZone1, coalition.side.RED ) AlliedLightInfantrySpawner1 = SPAWN:New( "Allied Light Infantry Squad Spawn Template #001" ) AlliedLightInfantrySpawner1.__GroupSize = GROUP:FindByName("Allied Light Infantry Squad Spawn Template #001"):GetSize() -- ||| USING DIRECT SPAWNING --------------------------------------------------------------------------------- -- Global Book-Keeping LiftLoads = {} --------------------------------------------------------------------------------- -- Setup Lift Helo Client function SetupClientLiftHelo(ClientUnitName) ClientLiftHelo = CLIENT:FindByName(ClientUnitName) ClientLiftHelo:Alive( function() local Menu = MENU_GROUP_COMMAND:New( ClientLiftHelo:GetGroup(), "Load troops", nil, LoadLiftElement, {LiftElement=ClientLiftHelo, PickupZone=PickupZone1, LiftedGroupSpawner=AlliedLightInfantrySpawner1, CargoGroupType="Infantry", CargoGroupDescription="Troops", CargoGroupUnitsDescription="troopers"}) local Menu = MENU_GROUP_COMMAND:New( ClientLiftHelo:GetGroup(), "Unload troops", nil, UnloadLiftElement, {LiftElement=ClientLiftHelo, TargetZone=ConflictZone1}) local Menu = MENU_GROUP_COMMAND:New( ClientLiftHelo:GetGroup(), "Report load status", nil, ReportLoadStatus, {LiftElement=ClientLiftHelo}) end, nil ) end function LoadLiftElement(args) local LiftElement = args.LiftElement local LiftedGroupSpawner = args.LiftedGroupSpawner local CargoGroupType = args.CargoGroupType local CargoGroupDescription = args.CargoGroupDescription local CargoGroupUnitsDescription = args.CargoGroupUnitsDescription local PickupZone = args.PickupZone local SecondsPerUnitLoading = args.SecondsPerUnitLoading or 1 local SecondsPerUnitUnloading = args.SecondsPerUnitUnloading or 1 if LiftElement:InAir() then LiftElement:Message( string.format("%s cannot be loaded while in the air, sir!", CargoGroupDescription), 1, "Flight Engineer") elseif LiftLoads[LiftElement] then LiftElement:Message( string.format("%s already loaded, sir!", CargoGroupDescription), 1, "Flight Engineer") elseif not LiftElement:IsInZone(PickupZone) then LiftElement:Message("Not in designated pick-up zone, sir!", 1, "Flight Engineer") else LiftElement:Message( string.format("%s loading, sir!", CargoGroupDescription), 1, "Flight Engineer") local CargoGroupNumUnits = LiftedGroupSpawner.__GroupSize local LiftLoad = {Spawner=LiftedGroupSpawner, CargoGroupDescription=CargoGroupDescription, CargoGroupUnitsDescription=CargoGroupUnitsDescription, CargoGroupNumUnits=CargoGroupNumUnits, SecondsPerUnitLoading=SecondsPerUnitLoading, SecondsPerUnitUnloading=SecondsPerUnitUnloading} timer.scheduleFunction( ExecuteCargoTransferOperation, {CarrierUnit=LiftElement, LiftLoad=LiftLoad, NumUnitsTransferring=CargoGroupNumUnits, NumUnitsTransferred=0, SecondsPerTransferringUnit=SecondsPerUnitLoading, TransactionFn=function() LiftLoads[LiftElement] = LiftLoad end, SuccessMessage=string.format("%s loaded, sir!", CargoGroupDescription), CancelMessage="Loading canceled, sir!"}, timer.getTime() + SecondsPerUnitLoading) end end function UnloadLiftElement(args) local LiftElement = args.LiftElement local TargetZone = args.TargetZone if LiftLoads[LiftElement] then if LiftElement:InAir() then LiftElement:Message( string.format("%s cannot be unloaded while in the air, sir!", LiftLoads[LiftElement].CargoGroupDescription), 1, "Flight Engineer") else LiftElement:Message( string.format("%s unloading, sir!", LiftLoads[LiftElement].CargoGroupDescription), 1, "Flight Engineer") local CargoGroupNumUnits = LiftLoads[LiftElement].CargoGroupNumUnits local SecondsPerUnitUnloading = LiftLoads[LiftElement].SecondsPerUnitUnloading timer.scheduleFunction( ExecuteCargoTransferOperation, {CarrierUnit=LiftElement, LiftLoad=LiftLoads[LiftElement], NumUnitsTransferring=CargoGroupNumUnits, NumUnitsTransferred=0, SecondsPerTransferringUnit=SecondsPerUnitUnloading, TransactionFn=function() local Spawner = LiftLoads[LiftElement].Spawner local Spawned = Spawner:SpawnFromUnit(LiftElement) local TargetCoord = TargetZone:GetRandomCoordinate() Spawned:RouteGroundTo( TargetCoord, 14, "Vee", 1 ) LiftLoads[LiftElement] = nil end, SuccessMessage=string.format("%s unloaded, sir!", LiftLoads[LiftElement].CargoGroupDescription), CancelMessage="Unloading canceled, sir!"}, timer.getTime() + SecondsPerUnitUnloading) end else LiftElement:Message( "We're not carrying any loads, sir!", 1, "Flight Engineer") end end function ReportLoadStatus(args) local LiftElement = args.LiftElement if LiftLoads[LiftElement] then LiftElement:Message( string.format("%s %s loaded, sir!", LiftLoads[LiftElement].CargoGroupNumUnits, LiftLoads[LiftElement].CargoGroupUnitsDescription), 1, "Flight Engineer") else LiftElement:Message( "Nothing loaded, sir!", 1, "Flight Engineer") end end function ExecuteCargoTransferOperation(args, time) local CarrierUnit = args.CarrierUnit local LiftLoad = args.LiftLoad local NumUnitsTransferring = args.NumUnitsTransferring local NumUnitsTransferred = args.NumUnitsTransferred or 0 local SecondsPerTransferringUnit = args.SecondsPerTransferringUnit or 1 local TransactionFn = args.TransactionFn local SuccessMessage = args.SuccessMessage local CancelMessage = args.CancelMessage if not CarrierUnit:InAir() then NumUnitsTransferred = NumUnitsTransferred + 1 if NumUnitsTransferred < NumUnitsTransferring then local estimatedTimeRemaining = math.ceil((NumUnitsTransferring - NumUnitsTransferred) * SecondsPerTransferringUnit) if estimatedTimeRemaining > 60 and (estimatedTimeRemaining % 60 == 0) then CarrierUnit:Message(string.format("%s minutes to go, sir!", math.floor(estimatedTimeRemaining/60)), 1, "FlightEngineer") elseif estimatedTimeRemaining == 60 then CarrierUnit:Message("1 minute to go, sir!", 1, "FlightEngineer") elseif estimatedTimeRemaining == 30 then CarrierUnit:Message("30 seconds to go, sir!", 1, "FlightEngineer") elseif estimatedTimeRemaining == 10 then CarrierUnit:Message("10 seconds to go, sir!", 1, "FlightEngineer") elseif estimatedTimeRemaining == 5 then CarrierUnit:Message("5 seconds to go, sir!", 1, "FlightEngineer") end timer.scheduleFunction( ExecuteCargoTransferOperation, {CarrierUnit=CarrierUnit, LiftLoad=LiftLoad, NumUnitsTransferring=NumUnitsTransferring, NumUnitsTransferred=NumUnitsTransferred, SecondsPerTransferringUnit=SecondsPerTransferringUnit, TransactionFn=TransactionFn, SuccessMessage=SuccessMessage, CancelMessage=CancelMessage}, time + SecondsPerTransferringUnit) return nil else TransactionFn() CarrierUnit:Message(SuccessMessage, 1, "FlightEngineer") return nil end else CarrierUnit:Message(CancelMessage, 1, "FlightEngineer") return nil end end SetupClientLiftHelo("helo")
-
The idea would be a three-part process. The first part sets things up and calls the scheduled function. The scheduled function will check the conditions, and if all are met call the third function which carries out its duties safe in the assumption that conditions are met. If needed, the first function can pass the function to call as an argument to the schedule function Maybe I can share with you my problem and solution so you might find it useful. The idea is that a carrier (helo) is going to load/unload some cargo. We do not want the cargo unloading to be instantaneous, and if the carrier takes off half-way through, the operation is canceled. The naive way has us (pseudo-pseudo-code): function Unload(helo, load, seconds_per_unit) local num_units = load:getSize() -- dummy code, but you get the idea local num_unloaded = 0 while num_unloaded < num_units and helo:inAir() do wait(seconds_per_unit) num_unloaded = num_unloaded + 1 end if num_unloaded < num_units: helo:message("Unloading cancelled!") else -- do stuff here to simulate the unloading -- e.g., spawn units in situ etc. load.spawn(100, 10, 10, 10) -- dummy code, but you get the idea helo:message("Unloading completed!") end end This will not work because we do not have a ``wait`` function, and even if we did, a blocking wait like this would kill DCS. So, refactoring this logic gives us the pseudo-pseudo-code below. Note how the scheduled function continuous reschedules ANOTHER VERSION of itself with updated parameters and returns ``nil`` so it itself is not continuously executed, and note that how the calling function passes in the functions with both the success and fail conditions to the scheduled function. function Unload(helo, load, seconds_per_unit) local num_units = load:getSize() -- dummy code, but you get the idea if helo:inAir() then helo:message("Cannot unload while in the air!") else helo:message("Beginning unloading!") timer.scheduleFunction(ExecuteUnloading, {helo=helo, load=load, num_units=num_units, num_unloaded=0, seconds_per_unit=seconds_per_unit, success_fn=function() -- do stuff here to simulate the unloading -- e.g., spawn units in situ etc. load.spawn(100, 10, 10, 10) -- dummy code, but you get the idea helo:message("Unloading completed!") end, fail_fn=function() helo:message("Unloading cancelled!") end}, timer.getTime() + (num_units * seconds_per_unit)) end end function ExecuteUnloading(args) local helo = args.helo local load = args.load local num_units = args.num_units local num_unloaded = args.num_unloaded local seconds_per_unit = args.seconds_per_unit if helo:inAir() then args.fail_fn() return nil else num_unloaded = num_unloaded + 1 if num_unloaded == num_units then args.success_fn() return nil end timer.scheduleFunction(ExecuteUnloading, {helo=helo, load=load, num_units=num_units, num_unloaded=0, seconds_per_unit=seconds_per_unit, success_fn=args.success_fn, fail_fn=args.fail_fn}, timer.getTime() + (num_units * seconds_per_unit)) return nil end end
-
how is everyone dealing with clickable cockpit in VR?
Bearfoot replied to hannibal's topic in Virtual Reality
Yep, I thought so ... because I myself made the SAME mistake when looking for a second portable touchpad! It really is deceptive or, at least, confusing, calling it a "touchpad mouse" :) if you are ready to shell out $80, then the Logitech one would be my choice based on online reviews (I've never had one myself), or the good old Apple. I have the latter, and it is still going strong after several years. But the Logitech one has dedicated buttons which I think might be nice if it holds up to the Apple in the precision/sensitivity/reliability dept. -
+1
-
how is everyone dealing with clickable cockpit in VR?
Bearfoot replied to hannibal's topic in Virtual Reality
This looks like a good solution, but if I am not mistaken, you still have to move the mouse to get the mouse movement registered? So your plan is to use it just for the click and scrolls, but rely on a regular mouse or head movement to actually move the mouse cursor? -
I just worked through this problem. Short answer is "don't sleep, schedule". Longer answer: As you saw, you have no access to `os`. If you dig around the DCS documentation, you will see that there is a "timer.getTime()", "timer.getAbsTime()" etc. and you will think, "aha!", I could just do something like: start_time = timer.getTime() repeat until timer.getTime() > (start + delay) You would be wrong :) . The above goes into a infinite loop, because you never return control to the DCS thread, which means that the internal clocks never get updated. Furthermore, after digging around, you will realize the fundamental flaw in this whole approach -- DCS works asynchrnously, and when you block like this (even if you could, by, e.g. running huge loops), the ENTIRE DCS world blocks waiting for this to finish. Every single individual object, from the lowliest infantry to the mighty A-10C, stops, freezes, and waits for this function to finish. Soooo, the CORRECT way to do this is to refactor your logic such that you use `scheduleFunction`: http://wiki.hoggit.us/view/DCS_func_scheduleFunction This is going to take some planning. So, typically you would split the stuff that happens before the wait into one part, and then write another function that does all the part after the wait, and schedule it in the first part. You would have to maintain and communicate state, of course, and you would do this by passing in all variables for this (as well as those needed to complete execution) in table argument to the scheduled function call. Your scheduled function call can, in turn, schedule another function to be called at the appropriate time (or even call itself with the same or different arguments).
-
Introducing the VKB-Sim ‘Modern Combat Grip’ (MCG)
Bearfoot replied to rrohde's topic in VKB-SIM Flight Gear
I had an X-55. The build quality is crap so life is limited, but the throttle ergonomics are great (better than the TMWH) and stick is decent (with the lighter strings, actually better than the TMWH). But, flying helos 99% of the time, I can tell you this: (1) while the stock TMWH stick is terrible for helo flying due to stiffness/sticktion, with a 20 cm extension it is a universe better than the X-55 could ever hope to be. No question, no competition. (2) the VKB base + extension is ten universes better than even that. No question, no competition. -
how is everyone dealing with clickable cockpit in VR?
Bearfoot replied to hannibal's topic in Virtual Reality
I do pretty much the same thing: standard mouse on right, and trackball velcro'd to side of TMWH throttle box for in-flight manipulation. I tried a number of trackballs, and settled on this for two reasons: https://www.amazon.com/Wireless-Trackball-Left-Handed-buttons-M-XT4DRBK/dp/B016QCPRBM (1) Left-handed trackball (2) Scroll wheel The first is self-explanatory, though, obviously a center ball would do just as well, especially if you prefer rolling it with your index finger rather than your thumb. Not having (2) is a deal-breaker. So many dials to rotate become a horrendous PIA when needing to press and move your head or the mouse. You "slip" off the control point too easily, or otherwise spend too much time concentrating on keeping the cursor on point while rotating the dial that your aircraft goes all over the place. Waaaaay too frustrating. I had a fairly expensive Kensington ambidextrous trackball that promised a touch/scroll wheel that is now sitting useless in a box because it really sucked for dials. The Logitech series makes the BEST scroll wheels in existence ... but unfortunately, I cannot find a left hand trackball mouse anymore. Which is why I settled on the mouse linked to above. In fact, to be honest, if there was a way I could have JUST the scroll wheel and attach that to my throttle, that would be great. Maybe VKB will deliver one with this built-in the future? I think if I was starting from scratch today, I would probably try out a touchpad instead of a trackball, if it supported multi-finger gestures for scrolling etc. -
how is everyone dealing with clickable cockpit in VR?
Bearfoot replied to hannibal's topic in Virtual Reality
I currently use a left-hand trackball, velcro'd to the side of my throttle quadrant. Previously, I used to use a mini-keyboard on a pilot's kneeboard on my thigh. Either way, instead of using the mouse to move, you may want to uncheck "use mouse" or whatever in the VR options, then the cursor becomes a fixed point following your head direction, and you simply use your head to look at a switch/dial and then the mouse buttons or scroll wheel to manipulate. -
How to Rearm Ground Units to Simulate Air Dropped Resupply?
Bearfoot replied to Bearfoot's topic in Mission Editor
Thanks! +1 -
This IMHO indeed is the weakest point of the X-55!!!! So mushy, it's like twiddling your thumb in play-doh. When I "upgraded" to the TMWH, I was in for a shock when the it's nipple was even worse --- like twiddling your index finger in oatmeal! The X-56 did things right by making it a simple 4 or 8 way hat. Aaaaaanway, to answer your question --- I got it to work decently enough by using the Saitek software to program it in bands, and sending the ";", ",", ".","/" key strokes for the various directions. So, essentially behaving like a 4-way hat instead of an analog device. Didn't like it, but learned to live with it :)
-
There is no disputing that everyone's preference is individual, and I am not going to try and convince you otherwise ... but I do feel compelled to point out that a thumb stick in no way precludes you from (comfortably/easily) hitting a whole bunch of other switches with your thumb --- including multiple hat switches, multiple multi-stage push buttons, multiple rotaries etc. The Saitek X-55/56 is a POS in terms of build quality, but in terms of ergonomics, it is a universe and a half ahead of the TMWH IMHO ...