private void Awake() { fighter = GetComponent <Fighter>(); health = GetComponent <Health>(); mover = GetComponent <PMove>(); player = GameObject.FindWithTag("Player"); }
/// <summary> /// Plays a move. /// </summary> /// <param name="uci">The move in uci format.</param> public void PlayMove(string uci) { if (socket != null) { PMove move = new PMove() { Uci = uci, Lag = (int)Client.ClientLag }; PData <PMove> pmove = new PData <PMove>(move); socket.Send(pmove); } }
private void InterpolatePlayerState(bool grabAngles) { float f; int i; var gamestate = CDataModel.GameState; PlayerState outP = predictedPlayerState; SnapShot prev = gamestate.snap; SnapShot next = gamestate.nextSnap; gamestate.snap.playerState.CopyTo(outP); var cl = CDataModel.GameState.ClActive; if (grabAngles) { UserCmd cmd; int cmdNum = cl.cmdNum; CDataModel.GameState.GetUserCmd(cmdNum, out cmd); PMove.UpdateViewAngles(outP, cmd); } if (gamestate.nextFrameTeleport) { return; } if (next == null || next.serverTime <= prev.serverTime) { return; } f = (float)(gamestate.time - prev.serverTime) / (next.serverTime - prev.serverTime); i = next.playerState.bobCycle; if (i < prev.playerState.bobCycle) { i += 256; } outP.bobCycle = prev.playerState.bobCycle + (int)(f * (i - prev.playerState.bobCycle)); for (i = 0; i < 3; i++) { outP.origin[i] = prev.playerState.origin[i] * (int)(f * (next.playerState.origin[i] - prev.playerState.origin[i])); if (!grabAngles) { outP.viewangles[i] = CUtils.LerpAngles(prev.playerState.viewangles[i], next.playerState.viewangles[i], f); } outP.velocity[i] = prev.playerState.velocity[i] + f * (next.playerState.velocity[i] - prev.playerState.velocity[i]); } }
private void Init() { stats = PlayerParameters.Instance; m_PInput = gameObject.AddComponent <PInput>(); m_PInput.Init(this); m_PMove = gameObject.AddComponent <PMove>(); m_PMove.Init(this); m_PCamera = gameObject.AddComponent <PCamera>(); m_PCamera.Init(this); m_PShoot = gameObject.AddComponent <PShoot>(); m_PShoot.Init(this); m_PUI = gameObject.AddComponent <PUI>(); m_PUI.Init(this); }
public void Pmove(pmove_t pmove) { PMove.Pmove(pmove); }
public virtual void Pmove(pmove_t pmove) { PMove.Pmove(pmove); }
public static void PredictMovement() { if (Globals.cls.state != Defines.ca_active) { return; } if (Globals.cl_paused.value != 0F) { return; } if (Globals.cl_predict.value == 0F || (Globals.cl.frame.playerstate.pmove.pm_flags & pmove_t.PMF_NO_PREDICTION) != 0) { for (int i = 0; i < 3; i++) { Globals.cl.predicted_angles[i] = Globals.cl.viewangles[i] + Math3D.SHORT2ANGLE(Globals.cl.frame.playerstate.pmove.delta_angles[i]); } return; } int ack = Globals.cls.netchan.incoming_acknowledged; int current = Globals.cls.netchan.outgoing_sequence; if (current - ack >= Defines.CMD_BACKUP) { if (Globals.cl_showmiss.value != 0F) { Com.Printf("exceeded CMD_BACKUP\\n"); } return; } pmove_t pm = new pmove_t(); pm.trace = new AnonymousTraceAdapter(); pm.pointcontents = new AnonymousPointContentsAdapter(); PMove.pm_airaccelerate = Lib.Atof(Globals.cl.configstrings[Defines.CS_AIRACCEL]); pm.s.Set(Globals.cl.frame.playerstate.pmove); int frame = 0; usercmd_t cmd; while (++ack < current) { frame = ack & (Defines.CMD_BACKUP - 1); cmd = Globals.cl.cmds[frame]; pm.cmd.Set(cmd); PMove.Pmove(pm); Math3D.VectorCopy(pm.s.origin, Globals.cl.predicted_origins[frame]); } int oldframe = (ack - 2) & (Defines.CMD_BACKUP - 1); int oldz = Globals.cl.predicted_origins[oldframe][2]; int step = pm.s.origin[2] - oldz; if (step > 63 && step < 160 && (pm.s.pm_flags & pmove_t.PMF_ON_GROUND) != 0) { Globals.cl.predicted_step = step * 0.125F; Globals.cl.predicted_step_time = (int)(Globals.cls.realtime - Globals.cls.frametime * 500); } Globals.cl.predicted_origin[0] = pm.s.origin[0] * 0.125F; Globals.cl.predicted_origin[1] = pm.s.origin[1] * 0.125F; Globals.cl.predicted_origin[2] = pm.s.origin[2] * 0.125F; Math3D.VectorCopy(pm.viewangles, Globals.cl.predicted_angles); }
private void PredictPlayerState() { int cmdNum, current; PlayerState oldPlayerState; bool moved; UserCmd oldestCmd; UserCmd latestCmd; int stateIndex = 0, predictCmd = 0; int numPredicted = 0, numPlayedBack = 0; var gamestate = CDataModel.GameState; gamestate.hyperspace = false; if (!validPPS) { validPPS = true; predictedPlayerState = gamestate.snap.playerState; } //如果是播回放,那么就复制移动,不做预测 if (gamestate.demoPlayback || (gamestate.snap.playerState.pmFlags & PMoveFlags.FOLLOW) != PMoveFlags.NONE) { InterpolatePlayerState(false); return; } //非预测的本地移动会抓取最近的视角 if (CConstVar.NoPredict || CConstVar.SynchronousClients) { InterpolatePlayerState(true); return; } pmove.playerState = predictedPlayerState; if (pmove.playerState.pmType == PMoveType.DEAD) { // pmove.tracemask = } else { // pmove.tracemask } // if(gamestate.snap.playerState.persistant[3] == ) // pmove.noFootsteps = gamestate.dm oldPlayerState = predictedPlayerState; current = CDataModel.GameState.ClActive.cmdNum; //如果没有紧接着snapshot之后的comands,就不能精确预测当前的位置,所以就停在最后的正确位置上 cmdNum = current - CConstVar.CMD_BACKUP + 1; CDataModel.GameState.GetUserCmd(cmdNum, out oldestCmd); if (oldestCmd.serverTime > gamestate.snap.playerState.commandTime && oldestCmd.serverTime < gamestate.time) { if (CConstVar.ShowMiss > 0) { CLog.Info("exceeded Packet_Backup on commands"); } return; } CDataModel.GameState.GetUserCmd(current, out latestCmd); if (gamestate.nextSnap != null && !gamestate.nextFrameTeleport && !gamestate.thisFrameTeleport) { predictedPlayerState = gamestate.nextSnap.playerState; gamestate.physicsTime = gamestate.nextSnap.serverTime; } else { predictedPlayerState = gamestate.snap.playerState; gamestate.physicsTime = gamestate.snap.serverTime; } if (CConstVar.PMoveMsec < 8) { CConstVar.PMoveMsec = 8; } else if (CConstVar.PMoveMsec > 33) { CConstVar.PMoveMsec = 33; } pmove.pmoveFixed = CConstVar.PMoveFixed; pmove.pmoveMsec = CConstVar.PMoveMsec; pmove.pmoveFloat = CConstVar.PMoveFloat; // pmove.pmv if (CConstVar.OptimizePrediction) { if (gamestate.nextFrameTeleport || gamestate.thisFrameTeleport) { gamestate.lastPredictedCommand = 0; gamestate.stateTail = gamestate.stateHead; predictCmd = current - CConstVar.CMD_BACKUP + 1; } else if (gamestate.time == gamestate.lastServerTime) { predictCmd = gamestate.lastPredictedCommand + 1; } else { bool error = true; for (int i = gamestate.stateHead; i != gamestate.stateTail; i = (i + 1) % CConstVar.NUM_SAVED_STATES) { if (gamestate.savedPmoveState[i].commandTime == predictedPlayerState.commandTime) { int errorcode = IsUnacceptableError(predictedPlayerState, gamestate.savedPmoveState[i]); if (errorcode > 0) { if (CConstVar.ShowMiss > 0) { CLog.Info("errorcode %d at %d", errorcode, gamestate.time); } break; } pmove.playerState = gamestate.savedPmoveState[i]; gamestate.stateHead = (i + 1) % CConstVar.NUM_SAVED_STATES; predictCmd = gamestate.lastPredictedCommand + 1; error = false; break; } } if (error) { gamestate.lastPredictedCommand = 0; gamestate.stateTail = gamestate.stateHead; predictCmd = current - CConstVar.CMD_BACKUP + 1; } } gamestate.lastServerTime = gamestate.physicsTime; stateIndex = gamestate.stateHead; } moved = false; for (cmdNum = current - CConstVar.CMD_BACKUP + 1; cmdNum <= current; cmdNum++) { CDataModel.GameState.GetUserCmd(current, out pmove.cmd); if (pmove.pmoveFixed > 0) { PMove.UpdateViewAngles(pmove.playerState, pmove.cmd); } if (pmove.cmd.serverTime <= predictedPlayerState.commandTime) { continue; } if (pmove.cmd.serverTime > latestCmd.serverTime) { continue; } if (predictedPlayerState.commandTime == oldPlayerState.commandTime) { Vector3 delta; float len; if (gamestate.thisFrameTeleport) { gamestate.predictedError = Vector3.zero; if (CConstVar.ShowMiss > 0) { CLog.Info("PredictionTeleport"); } gamestate.thisFrameTeleport = false; } else { Vector3 adjusted, new_angles; AdjustPositionForMover(predictedPlayerState.origin, predictedPlayerState.groundEntityNum, gamestate.physicsTime, gamestate.oldTime, out adjusted, predictedPlayerState.viewangles, out new_angles); if (CConstVar.ShowMiss > 0) { if (oldPlayerState.origin != adjusted) { CLog.Info("prediction error"); } } delta = oldPlayerState.origin - adjusted; len = delta.magnitude; if (len > 0.1) { if (CConstVar.ShowMiss > 0) { CLog.Info("Prediction miss: %d", len); } if (CConstVar.ErrorDecay > 0) { int t = gamestate.time - gamestate.predictedErrorTime; float f = (CConstVar.ErrorDecay - t) / CConstVar.ErrorDecay; if (f < 0f) { f = 0f; } if (f > 0f && CConstVar.ShowMiss > 0) { CLog.Info("Double prediction decay: %d", f); } gamestate.predictedError = gamestate.predictedError * f; } else { gamestate.predictedError = Vector3.zero; } gamestate.predictedError = delta + gamestate.predictedError; gamestate.predictedErrorTime = gamestate.oldTime; } } } pmove.gauntletHit = false; if (pmove.pmoveFixed > 0) { pmove.cmd.serverTime = ((pmove.cmd.serverTime + CConstVar.PMoveMsec - 1) / CConstVar.PMoveMsec) * CConstVar.PMoveMsec; } if (CConstVar.OptimizePrediction) { if (cmdNum >= predictCmd || (stateIndex + 1) % CConstVar.NUM_SAVED_STATES == gamestate.stateHead) { pmove.Move(); numPredicted++; gamestate.lastPredictedCommand = cmdNum; if ((stateIndex + 1) % CConstVar.NUM_SAVED_STATES != gamestate.stateHead) { gamestate.savedPmoveState[stateIndex] = pmove.playerState; stateIndex = (stateIndex + 1) % CConstVar.NUM_SAVED_STATES; gamestate.stateTail = stateIndex; } } else { numPlayedBack++; if (CConstVar.ShowMiss > 0 && gamestate.savedPmoveState[stateIndex].commandTime != pmove.cmd.serverTime) { CLog.Info("saved state miss"); } pmove.playerState = gamestate.savedPmoveState[stateIndex]; stateIndex = (stateIndex + 1) % CConstVar.NUM_SAVED_STATES; } } else { pmove.Move(); numPredicted++; } moved = true; } if (CConstVar.ShowMiss > 1) { CLog.Info("[%d : %d] ", pmove.cmd.serverTime, gamestate.time); } if (!moved) { if (CConstVar.ShowMiss > 0) { CLog.Info("not moved"); } return; } AdjustPositionForMover(predictedPlayerState.origin, predictedPlayerState.groundEntityNum, gamestate.physicsTime, gamestate.time, out predictedPlayerState.origin, predictedPlayerState.viewangles, out predictedPlayerState.viewangles); if (CConstVar.ShowMiss > 0) { if (predictedPlayerState.eventSequence > oldPlayerState.eventSequence + CConstVar.MAX_PS_EVENTS) { CLog.Info("dropped event"); } } }
private void PMoveSingle(PMove pMove) { pMove.numTouch = 0; if (pMove.playerState.states[CConstVar.STAT_HEALTH] <= 0) { // } if (Mathf.Abs(pMove.cmd.forwardmove) > 64 || Mathf.Abs(pMove.cmd.rightmove) > 64) { pMove.cmd.buttons &= ~ButtonsDef.BUTTON_WALKING; } if (pMove.playerState.states[CConstVar.STAT_HEALTH] > 0 && (pMove.cmd.buttons & ButtonsDef.BUTTON_ATTACK) == 0) { pMove.playerState.pmFlags &= ~PMoveFlags.RESPAWNED; } if (impl == null) { impl = new PMoveImp(); } else { impl.Reset(); } impl.msec = pMove.cmd.serverTime - pMove.playerState.commandTime; if (impl.msec < 1) { impl.msec = 1; } else if (impl.msec > 200) { impl.msec = 200; } pMove.playerState.commandTime = pMove.cmd.serverTime; impl.prevOrigin = pMove.playerState.origin; impl.prevVelocity = pMove.playerState.velocity; impl.frameTime = impl.msec * 0.001f; UpdateViewAngles(pMove.playerState, pMove.cmd); AngleVectors(pMove.playerState.viewangles, ref impl.forward, ref impl.right, ref impl.up); if (pMove.cmd.upmove < 10) { pMove.playerState.pmFlags &= ~PMoveFlags.JUMP_HELD; } if (pMove.cmd.forwardmove < 0) { pMove.playerState.pmFlags |= PMoveFlags.BACKWARDS_RUN; } else if (pMove.cmd.forwardmove > 0 || (pMove.cmd.forwardmove == 0 && pMove.cmd.rightmove > 0)) { pMove.playerState.pmFlags &= ~PMoveFlags.BACKWARDS_RUN; } if (pMove.playerState.pmType >= PMoveType.DEAD) { pMove.cmd.forwardmove = 0; pMove.cmd.rightmove = 0; pMove.cmd.upmove = 0; } if (pMove.playerState.pmType == PMoveType.SPECTATOR) { pMove.CheckDuck(); // FlyMove(); // DropTimers(); return; } if (pMove.playerState.pmType == PMoveType.NOCLIP) { pMove.NoClipMove(); // DropTimers(); return; } if (pMove.playerState.pmType == PMoveType.FREEZE) { return; } if (pMove.playerState.pmType == PMoveType.INTERMISSION || pMove.playerState.pmType == PMoveType.SPINGTERMISSION) { return; } pMove.CheckDuck(); pMove.GroundTrace(); if (pMove.playerState.pmType == PMoveType.DEAD) { pMove.DeadMove(); } if (impl.walking) { WalkMove(); } else { AirMove(); } }
private void ClientImpacts(GameEntity ent, ref PMove pm) { }
private void ClientThink_real(GameEntity ent) { GameClient cl = ent.client; if (cl.pers.connected != ClientConnState.CONNECTED) { return; } UserCmd ucmd = ent.client.pers.cmd; if (ucmd.forwardmove != 0 || ucmd.rightmove != 0) { CLog.Info("cmd move {0}, {1}", ucmd.forwardmove, ucmd.rightmove); } if (ucmd.serverTime > time + 200) { ucmd.serverTime = time + 200; } if (ucmd.serverTime < time - 1000) { ucmd.serverTime = time - 1000; } //unlagged - backward reconciliation #4 //frameOffset应该是一帧内收到命令数据包的偏移毫秒数,依赖于服务器运行RunFrame的速度 cl.frameOffset = CDataModel.InputEvent.Milliseconds() - frameStartTime; //unlagged - backward reconciliation #4 //unlagged - lag simulation #3 if (cl.pers.plOut > 0) { float thresh = cl.pers.plOut / 100f; if (CUtils.Random() < thresh) { //这是丢失了的命令,不做任何事情 return; } } //unlagged - lag simulation #3 //unlagged - true ping cl.pers.pingSamples[cl.pers.sampleHead] = prevTime + cl.frameOffset - ucmd.serverTime; cl.pers.sampleHead++; if (cl.pers.sampleHead >= CConstVar.NUM_PING_SAMPLES) { cl.pers.sampleHead -= CConstVar.NUM_PING_SAMPLES; } if (CConstVar.TruePing) { int sum = 0; for (int i = 0; i < CConstVar.NUM_PING_SAMPLES; i++) { sum += cl.pers.pingSamples[i]; } cl.pers.realPing = sum / CConstVar.NUM_PING_SAMPLES; } else { cl.pers.realPing = cl.playerState.ping; } //unlagged - true ping //unlagged - lag simulation #2 // cl.pers.cmdqueue[cl.pers.cmdhead] = cl.pers.cmd; // cl.pers.cmdhead++; // if(cl.pers.cmdhead >= CConstVar.MAX_LATENT_CMDS){ // cl.pers.cmdhead -= CConstVar.MAX_LATENT_CMDS; // } // if(cl.pers.latentCmds > 0){ // int time = ucmd.serverTime; // int cmdindex = cl.pers.cmdhead - cl.pers.latentCmds - 1; // while(cmdindex < 0){ // cmdindex += CConstVar.MAX_LATENT_CMDS; // } // cl.pers.cmd = cl.pers.cmdqueue[cmdindex]; // cl.pers.realPing += time - ucmd.serverTime; // } //unlagged - lag simulation #2 cl.attackTime = ucmd.serverTime; cl.lastUpdateFrame = frameNum; //unlagged - lag simulation #1 // if(cl.pers.latentSnaps > 0){ // cl.pers.realPing += cl.pers.latentSnaps * (1000 / CConstVar.SV_FPS); // cl.attackTime -= cl.pers.latentSnaps * (1000 / CConstVar.SV_FPS); // } //unlagged - lag simulation #1 //unlagged - true ping if (cl.pers.realPing < 0) { cl.pers.realPing = 0; } //unlagged - true ping int msec = ucmd.serverTime - cl.playerState.commandTime; if (msec > 200) { msec = 200; } if (CConstVar.PMoveMsec < 8) { CConstVar.PMoveMsec = 8; } if (CConstVar.PMoveMsec > 33) { CConstVar.PMoveMsec = 33; } if (CConstVar.PMoveFixed > 0 || cl.pers.pmoveFixed) { ucmd.serverTime = ((ucmd.serverTime + CConstVar.PMoveMsec - 1) / CConstVar.PMoveMsec) * CConstVar.PMoveMsec; } if (cl.sess.sessionTeam == TeamType.TEAM_SPECTATOR || cl.isEliminated) { if (cl.sess.spectatorState == SpectatorState.SCOREBOARD) { return; } SpectatorThink(ent, ucmd); return; } if (cl.noclip) { cl.playerState.pmType = PMoveType.NOCLIP; } else if (cl.playerState.states[CConstVar.STAT_HEALTH] <= 0) { cl.playerState.pmType = PMoveType.DEAD; } else { cl.playerState.pmType = PMoveType.NORMAL; } // cl.playerState.gravity = cl.playerState.speed = CConstVar.Speed; int oldEventSeq = cl.playerState.eventSequence; PMove pm = new PMove(); pm.playerState = cl.playerState; pm.agent = cl.agent.Model; ucmd.CopyTo(pm.cmd); if (pm.playerState.pmType == PMoveType.DEAD) { // pm.tracemask } else if ((ent.sEnt.r.svFlags & SVFlags.BOT) != SVFlags.NONE) { // pm. } else { } pm.pmoveFixed = CConstVar.PMoveFixed | (cl.pers.pmoveFixed ? 1 : 0); pm.pmoveMsec = CConstVar.PMoveMsec; pm.pmoveFloat = CConstVar.PMoveFloat; pm.pmvoveFlags = CConstVar.dmFlags; cl.oldOrigin = cl.playerState.origin; pm.Move(); if (ent.client.playerState.eventSequence != oldEventSeq) { ent.eventTime = time; } if (CConstVar.SmoothClients > 1) { CUtils.BG_PlayerStateToEntityStateExtraPolate(ent.client.playerState, ref ent.sEnt.s, ent.client.playerState.commandTime, true); } else { CUtils.PlayerStateToEntityState(ent.client.playerState, ref ent.sEnt.s, true); } SendingPredictableEvents(ent.client.playerState); if ((ent.client.playerState.entityFlags & EntityFlags.FIRING) == 0) { // cl.fireHeld = false; } ent.sEnt.s.pos.GetTrBase(ref ent.sEnt.r.currentOrigin); // ent.sEnt.r.mins = pm.mins; //执行客户端事件 ClientEvents(ent, oldEventSeq); Server.Instance.LinkEntity(ent); if (!ent.client.noclip) { TouchTrigger(ent); } ent.sEnt.r.currentOrigin = ent.client.playerState.origin; ClientImpacts(ent, ref pm); //保存触发器和客户端事件 if (ent.client.playerState.eventSequence != oldEventSeq) { ent.eventTime = time; } cl.oldButtons = cl.buttons; cl.buttons = ucmd.buttons; cl.latched_buttons |= cl.buttons & ~cl.oldButtons; if (cl.playerState.states[CConstVar.STAT_HEALTH] <= 0) { if ((time > cl.respawnTime)) { ClientRespawn(ent); } return; } }
void Awake() { anim = GetComponent <Animator> (); playerMovement = GetComponent <PMove> (); currentHealth = startingHealth; }