private void InputLogic(InputBasic2d action, SnapHistory <NentBasic2d, NentStaticBasic2d> h, byte pid, float delta) { // process the inputs for this action h.Shots[h.CurrentIndex].XVel = RMathF.Clamp(action.Horizontal, -1f, 1f) * PlayerSpeed; h.Shots[h.CurrentIndex].YVel = RMathF.Clamp(action.Vertical, -1f, 1f) * PlayerSpeed; // set our rotation, but only if we're not mid-dash if (h.Shots[h.CurrentIndex].Free1 <= 0) { h.Shots[h.CurrentIndex].Rot = action.Rotation; } // dash action if ((action.Inputs & InputBasic2d.INPUT_A) != 0 && h.Shots[h.CurrentIndex].Free1 == 0) { // if input A is pressed, dash forward according to rotation // we use Free1 to store the dash timer. We can only begin a // dash if Free1 is equal to 0 (e.g. dash is over). h.Shots[h.CurrentIndex].Free1 = DashTimerMax; // we don't need to set XVel/YVel here because this is done // in AdvanceLogic } // finally, do AdvanceLogic over the delta window AdvanceLogic(h, delta); }
// returns false if we have no inputs private bool InputChecker(SnapHistory <NentBasic2d, NentStaticBasic2d> h, byte pid) { InputBasic2d[] actions = Input.GetPlayerInputs(pid, out int index, out int count, out ushort[] timestamps, out float[] tickms); if (count == 0) { return(false); } ushort simstamp = NetSnapper.SimulateTimestamp; // timestamps are ordered from oldest --> latest // loop through seeking our current timestamp float lastms = 0; InputBasic2d lastAction = new InputBasic2d(); bool hasLastAction = false; for (int i = 0; i < count; i++) { // if timestamps[index] is later than our timestamp, stop // if timestamps[index] is earlier than our timestamp, keep going // if timestamps[index] is equal to our timestamp, process it if (timestamps[index] == simstamp) { // process it if (hasLastAction) { InputLogic(lastAction, h, pid, tickms[index] - lastms); } hasLastAction = true; lastms = tickms[index]; lastAction = actions[index]; } else if (simstamp >= ushort.MaxValue / 2) { if (timestamps[index] > simstamp || timestamps[index] < simstamp - (ushort.MaxValue / 2)) { // later break; } } else { if (timestamps[index] > simstamp && timestamps[index] < simstamp + (ushort.MaxValue / 2)) { // later break; } } index++; if (index >= actions.Length) { index -= actions.Length; } } // process the last action, now that we're done if (hasLastAction) { // we use the tickrate here bbecause this action stretches until the end // of the tick, since there are no subsequent actions in this tick InputLogic(lastAction, h, pid, NetSnapper.TickMSTarget - lastms); } return(true); }