public override void _PhysicsProcess(float delta) { shootTo = new Vector3(); // FIXME - spawn projectile from middle of player, not camera? Vector3 origin = ProjectRayOrigin(_aimAt.Position); Vector3 to = ProjectRayNormal(_aimAt.Position) * _shootRange; shootTo = to + origin; PlayerCmd pCmd = new PlayerCmd(); pCmd.playerID = _player.ID; pCmd.snapshot = _game.World.LocalSnapNum; pCmd.move_forward = move_forward; pCmd.move_right = move_right; pCmd.move_up = move_up; pCmd.aim = this.GlobalTransform.basis; pCmd.cam_angle = _cameraAngle; // FIXME - basis.z.angleto(up vector) instead of rotation value pCmd.rotation = _player.Mesh.Rotation; pCmd.attack = attack; pCmd.attackDir = shootTo; pCmd._projName = ""; pCmd.impulses = impulses; impulses.Clear(); _player.pCmdQueue.Add(pCmd); }
public override void SimulateController() { if (!(up || down || left || right || (canShoot && triggerShoot))) { return; } var input = PlayerCmd.Create(); input.Up = up; input.Down = down; input.Left = left; input.Right = right; input.Attack = false; if (canShoot && triggerShoot) { input.AtkDir = DetectShoot(); input.Attack = true; } print("simulate controller"); try { entity.QueueInput(input); } catch (Exception e) { BoltLog.Error(e); entity.ClearInputQueue(); } }
public override bool Shoot(PlayerCmd pCmd, float delta) { // spawn particles Flame f = (Flame)_game.World.ParticleManager.SpawnParticle(PARTICLE.FLAMETHROWER, _playerOwner.Head.GlobalTransform, _playerOwner); f.Damage = _damage; return(true); }
public void ProcessAttack(PlayerCmd pCmd, float delta) { if (pCmd.attack == 1) { ActiveWeapon.ShootPressed = true; ActiveWeapon.Shoot(pCmd, delta); return; } ActiveWeapon.ShootPressed = false; }
private void UseHandGrenade(IMPULSE imp, PlayerCmd pCmd) { if (PrimingGren != null) { ThrowGren(pCmd.attackDir); } else { int grenCount = 0; switch (imp) { case IMPULSE.GRENONE: grenCount = _gren1Count; break; case IMPULSE.GRENTWO: grenCount = _gren2Count; break; } if (grenCount > 0) { // play timer if (this.ID == _game.Network.ID && _grenTimer != null) { _grenTimer.Play(); } WEAPONTYPE grenType = WEAPONTYPE.NONE; switch (imp) { case IMPULSE.GRENONE: _gren1Count -= 1; grenType = _gren1Type; break; case IMPULSE.GRENTWO: _gren2Count -= 1; grenType = _gren2Type; break; } Projectile proj = _game.World.ProjectileManager.AddProjectile(this, pCmd.attackDir, pCmd.projName, grenType); // FIXME - need projnames to be an array, shooting + gren on same frame pCmd.projName = proj.Name; } else { PrintGrenCount(imp); } } }
public void SendPMovementServer(int RecID, int id, PlayerCmd pCmd) { // FIXME this is obviously bad if (_id == id) { ReceivePMovementServer(id, pCmd.move_forward, pCmd.move_right, pCmd.move_up, pCmd.aim.x, pCmd.aim.y, pCmd.aim.z, pCmd.cam_angle, pCmd.rotation.x, pCmd.rotation.y, pCmd.rotation.z); } if (!IsNetworkMaster()) { RpcUnreliableId(RecID, nameof(ReceivePMovementServer), id, pCmd.move_forward, pCmd.move_right, pCmd.move_up, pCmd.aim.x, pCmd.aim.y, pCmd.aim.z, pCmd.cam_angle, pCmd.rotation.x, pCmd.rotation.y, pCmd.rotation.z); } }
private void NormalProcess(PlayerCmd pCmd, float delta) { if (IsNetworkMaster()) { int diff = _game.World.LocalSnapNum - pCmd.snapshot; if (diff < 0) { return; } _game.World.RewindPlayers(diff, delta); } this.ProcessDebuffs(delta); this.ProcessImpulses(pCmd); if (_settingDetpack) { _setDetpackTime += delta; if (_setDetpackTime >= _detpackTimeRequired) { Projectile proj = _game.World.ProjectileManager.AddProjectile(this, this.GlobalTransform.origin, "Detpack", WEAPONTYPE.DETPACK); Detpack dp = (Detpack)proj; if (_detpackTimeSetting <= 5) { dp.WarnSound.Play(); dp.WarnSoundPlayed = true; } else { dp.SetSound.Play(); } _settingDetpack = false; dp.MaxLifeTime = _detpackTimeSetting; MoveType = MOVETYPE.NORMAL; ActiveWeapon.WeaponMesh.Visible = true; } } this.ProcessAttack(pCmd, delta); if (IsNetworkMaster()) { _game.World.FastForwardPlayers(); } if (MoveType == MOVETYPE.NORMAL) { this.ProcessMovementCmd(_predictedState, pCmd, delta); } }
public void GroundMove(float delta, PlayerCmd pCmd) { Vector3 wishDir = new Vector3(); float scale = CmdScale(pCmd); wishDir += pCmd.aim.x * pCmd.move_right; wishDir -= pCmd.aim.z * pCmd.move_forward; wishDir = wishDir.Normalized(); _moveDirectionNorm = wishDir; float wishSpeed = wishDir.Length(); wishSpeed *= MoveSpeed; Accelerate(wishDir, wishSpeed, _runAcceleration, delta); if (_climbLadder) { if (pCmd.move_forward != 0f) { _playerVelocity.y = _moveSpeed * (pCmd.cam_angle / 90) * pCmd.move_forward; } else { _playerVelocity.y = 0; } if (pCmd.move_right == 0f) { _playerVelocity.x = 0; _playerVelocity.z = 0; } } // walk up stairs if (wishSpeed > 0 && _stairCatcher.IsColliding()) { Vector3 col = _stairCatcher.GetCollisionNormal(); float ang = Mathf.Rad2Deg(Mathf.Acos(col.Dot(_game.World.Up))); if (ang < _maxStairAngle) { _playerVelocity.y = _stairJumpHeight; } } if (_wishJump && IsOnFloor()) { // FIXME - if we add jump speed velocity we enable trimping right? _playerVelocity.y = _jumpSpeed; _jumpSound.Play(); } }
private void AirMove(float delta, PlayerCmd pCmd) { Vector3 wishdir = new Vector3(); float wishvel = _airAcceleration; float accel; float scale = CmdScale(pCmd); wishdir += pCmd.aim.x * pCmd.move_right; wishdir -= pCmd.aim.z * pCmd.move_forward; float wishspeed = wishdir.Length(); wishspeed *= MoveSpeed; wishdir = wishdir.Normalized(); _moveDirectionNorm = wishdir; // CPM: Aircontrol float wishspeed2 = wishspeed; if (_playerVelocity.Dot(wishdir) < 0) { accel = _airDecceleration; } else { accel = _airAcceleration; } // If the player is ONLY strafing left or right if (pCmd.move_forward == 0 && pCmd.move_right != 0) { if (wishspeed > _sideStrafeSpeed) { wishspeed = _sideStrafeSpeed; } accel = _sideStrafeAcceleration; } Accelerate(wishdir, wishspeed, accel, delta); /*if(_airControl > 0) * { * AirControl(wishdir, wishspeed2, delta); * }*/ // !CPM: Aircontrol }
private void DeadProcess(PlayerCmd pCmd, float delta) { if (_touchingGround) { _timeDead += delta; // have to wait time after touching ground to respawn } if (_timeDead > .5) { if (pCmd.attack == 1 || pCmd.move_up == 1) { _game.World.Spawn(this); _timeDead = 0; } } }
public bool Start(ITimeService time) { m_time = time; if (m_pingTimer != null) { m_pingTimer.Update(m_time.Time); } if (!enabled) { return(false); } List <Guid> notRegisteredClients = new List <Guid>(); foreach (KeyValuePair <Guid, Dictionary <Guid, Player> > kvp in m_clientIdToPlayers) { if (!m_registeredClients.Contains(kvp.Key)) { notRegisteredClients.Add(kvp.Key); } } for (int i = 0; i < notRegisteredClients.Count; ++i) { m_clientIdToPlayers.Remove(notRegisteredClients[i]); } m_prevTickTime = m_time.Time; if (ReadyToPlayAll != null) { ReadyToPlayAll(new Error(StatusCode.OK), m_readyToPlayAllArgs); } while (m_preInitCommands.Count > 0) { PlayerCmd playerCmd = m_preInitCommands.Dequeue(); m_engine.Submit(playerCmd.PlayerIndex, playerCmd.Cmd); } return(true); }
/* * ============ * PM_CmdScale * Returns the scale factor to apply to cmd movements * This allows the clients to use axial -127 to 127 values for all directions * without getting a sqrt(2) distortion in speed. * ============ */ private float CmdScale(PlayerCmd pCmd) { int max; float total; float scale; max = (int)Mathf.Abs(pCmd.move_forward); if (Mathf.Abs(pCmd.move_right) > max) { max = (int)Mathf.Abs(pCmd.move_right); } if (max <= 0) { return(0); } total = Mathf.Sqrt(pCmd.move_forward * pCmd.move_forward + pCmd.move_right * pCmd.move_right); scale = MoveSpeed * max / (_moveScale * total); return(scale); }
public override bool Shoot(PlayerCmd pCmd, float delta) { // track spin up if (_spinUpTime >= _spinUpTimeRequired) { if (Idle) { _idleSound.Play(); } else { // if spun up enough, shoot _shootSound.Play(); Vector3 shootTo = _playerOwner.Head.GlobalTransform.origin + pCmd.attackDir; PhysicsDirectSpaceState spaceState = _playerOwner.GetWorld().DirectSpaceState; Godot.Collections.Dictionary res = spaceState.IntersectRay(_playerOwner.Head.GlobalTransform.origin, shootTo, new Godot.Collections.Array { this, _playerOwner }, 1); // if hits, use that as our far point if (res.Count > 0) { Vector3 shotLoc = ((Vector3)res["position"]); Vector3 norm = (Vector3)res["normal"]; SpreadShoot(5, true, true, shotLoc, norm); } } } else { if (_spinSound != SPINSOUND.UP) { _spinUpSound.Play(); _spinSound = SPINSOUND.UP; } _spinUpTime += delta; } return(true); }
public void ProcessMovementCmd(State predState, PlayerCmd pCmd, float delta) { _playerVelocity = predState.Velocity; // queue jump if (pCmd.move_up == 1 && !_wishJump) { _wishJump = true; } if (pCmd.move_up <= 0) { _wishJump = false; } if (_touchingGround || _climbLadder) { GroundMove(delta, pCmd); } else { AirMove(delta, pCmd); } }
/** * Air control occurs when the player is in the air, it allows * players to move side to side much faster rather than being * 'sluggish' when it comes to cornering. */ private void AirControl(Vector3 wishdir, float wishspeed, float delta, PlayerCmd pCmd) { float zspeed; float speed; float dot; float k; // Can't control movement if not moving forward or backward if (Mathf.Abs(pCmd.move_forward) < 0.001 || Mathf.Abs(wishspeed) < 0.001) { return; } zspeed = _playerVelocity.y; _playerVelocity.y = 0; // Next two lines are equivalent to idTech's VectorNormalize() speed = _playerVelocity.Length(); _playerVelocity = _playerVelocity.Normalized(); dot = _playerVelocity.Dot(wishdir); k = 32; k *= _airControl * dot * dot * delta; // Change direction while slowing down if (dot > 0) { _playerVelocity.x = _playerVelocity.x * speed + wishdir.x * k; _playerVelocity.y = _playerVelocity.y * speed + wishdir.y * k; _playerVelocity.z = _playerVelocity.z * speed + wishdir.z * k; _playerVelocity = _playerVelocity.Normalized(); _moveDirectionNorm = _playerVelocity; } _playerVelocity.x *= speed; _playerVelocity.y = zspeed; // Note this line _playerVelocity.z *= speed; }
public void ReceivePMovementServer(byte[] packet) { string pkStr = Encoding.UTF8.GetString(packet); string[] split = pkStr.Split(","); int serverSnapNumAck = Convert.ToInt32(split[0]); int id = Convert.ToInt32(split[1]); Peer p = PeerList.Where(x => x.ID == id).FirstOrDefault(); if (p == null) { return; } p.Ping = (_game.World.LocalSnapNum - serverSnapNumAck) * _game.World.FrameDelta; PACKETSTATE pState = PACKETSTATE.UNINITIALISED; PlayerCmd pCmd = new PlayerCmd(); for (int i = 2; i < split.Length; i++) { switch (split[i]) { case PACKET.IMPULSE: pState = PACKETSTATE.IMPULSE; i++; break; case PACKET.HEADER: pCmd = new PlayerCmd(); pState = PACKETSTATE.HEADER; i++; break; case PACKET.END: pState = PACKETSTATE.END; break; } switch (pState) { case PACKETSTATE.UNINITIALISED: GD.Print("PACKETSTATE.UNINITIALISED"); Console.Log("PACKETSTATE.UNINITIALISED"); break; case PACKETSTATE.HEADER: pCmd.playerID = id; pCmd.snapshot = Int32.Parse(split[i++]); pCmd.move_forward = float.Parse(split[i++]); pCmd.move_right = float.Parse(split[i++]); pCmd.move_up = float.Parse(split[i++]); pCmd.aim = new Basis( new Vector3(float.Parse(split[i++]), float.Parse(split[i++]), float.Parse(split[i++])), new Vector3(float.Parse(split[i++]), float.Parse(split[i++]), float.Parse(split[i++])), new Vector3(float.Parse(split[i++]), float.Parse(split[i++]), float.Parse(split[i++])) ); pCmd.cam_angle = float.Parse(split[i++]); pCmd.rotation = new Vector3(float.Parse(split[i++]), float.Parse(split[i++]), float.Parse(split[i++])); pCmd.attack = float.Parse(split[i++]); pCmd._projName = split[i++]; pCmd.attackDir = new Vector3(float.Parse(split[i++]), float.Parse(split[i++]), float.Parse(split[i])); break; case PACKETSTATE.IMPULSE: pCmd.impulses.Add(float.Parse(split[i])); break; case PACKETSTATE.END: if (pCmd.snapshot > p.LastSnapshot) { p.Player.pCmdQueue.Add(pCmd); } break; } } }
virtual public bool Shoot(PlayerCmd pCmd, float delta) { bool shot = false; if (ClipLeft >= _minAmmoRequired) { if (_timeSinceLastShot >= _coolDown) { shot = true; ClipLeft -= _minAmmoRequired; if (_muzzleFlash != null) { _muzzleFlash.Show(); } _shootSound.Play(); TimeSinceLastShot = 0; // TODO - should we move to weapon classes? Maybe for pipebomb launcher? switch (_weaponShotType) { case WEAPONSHOTTYPE.HITSCAN: case WEAPONSHOTTYPE.MELEE: this.DoHit(pCmd.attackDir.Normalized() * _weaponRange); break; case WEAPONSHOTTYPE.SPREAD: // raycast to extremely far away Vector3 shootTo = _playerOwner.Head.GlobalTransform.origin + pCmd.attackDir; PhysicsDirectSpaceState spaceState = _playerOwner.GetWorld().DirectSpaceState; Godot.Collections.Dictionary res = spaceState.IntersectRay(_playerOwner.Head.GlobalTransform.origin, shootTo, new Godot.Collections.Array { this, _playerOwner }, 1); // if hits, use that as our far point if (res.Count > 0) { Vector3 shotLoc = ((Vector3)res["position"]); Vector3 norm = (Vector3)res["normal"]; _game.World.ParticleManager.MakePuff(PARTICLE.PUFF, shotLoc, null); Particles p = _game.World.ParticleManager.MakePuff(PARTICLE.PUFF, shotLoc, null); Transform t = p.GlobalTransform; GD.Print(norm); t.basis.y = norm; t.basis.x = -t.basis.z.Cross(norm); t.basis = t.basis.Orthonormalized(); p.GlobalTransform = t; //Vector3 tr = p.Translation; //p.Translation = new Vector3(p.Translation.x + 1, p.Translation.y, p.Translation.z); Vector3 trans = new Vector3(0, 1, 1); p.Translate(p.Transform.basis.Xform(trans)); //GD.Print(norm); /*SpreadShoot(_pelletCount / 4, true, true, shotLoc, norm); * SpreadShoot(_pelletCount / 4, true, false, shotLoc, norm); * SpreadShoot(_pelletCount / 4, false, true, shotLoc, norm); * SpreadShoot(_pelletCount / 4, false, false, shotLoc, norm);*/ } // trace to plane // get plane normal // ??? // move along plane normal break; case WEAPONSHOTTYPE.PROJECTILE: case WEAPONSHOTTYPE.GRENADE: // FIXME - i think attack button is set still and due to sync differences the client attack time is still useable? projname is empty because client never used it. // this will be an issue for hitscan weapons? if (_game.Network.ID == 1 && pCmd.playerID != 1 && pCmd.projName.Length <= 2) { return(false); } Projectile proj = _game.World.ProjectileManager.AddProjectile(_playerOwner, pCmd.attackDir, pCmd.projName, _weaponType); if (_weaponType == WEAPONTYPE.PIPEBOMBLAUNCHER) { _playerOwner.ActivePipebombs.Add(proj); } pCmd.projName = proj.Name; break; } } } else { // force a reload this.Reload(false); } return(shot); }
private void SpectatorProcess(PlayerCmd pCmd, float delta) { }
private void ProcessImpulses(PlayerCmd pCmd) { foreach (float i in pCmd.impulses) { IMPULSE imp = (IMPULSE)i; switch (imp) { case IMPULSE.WEAPONONE: if (_weapon1 != null) { ActiveWeapon = Weapon1; } break; case IMPULSE.WEAPONTWO: if (Weapon2 != null) { ActiveWeapon = Weapon2; } break; case IMPULSE.WEAPONTHREE: if (Weapon3 != null) { ActiveWeapon = Weapon3; } break; case IMPULSE.WEAPONFOUR: if (Weapon4 != null) { ActiveWeapon = Weapon4; } break; case IMPULSE.GRENONE: case IMPULSE.GRENTWO: UseHandGrenade(imp, pCmd); break; case IMPULSE.DETPIPE: Demoman.Detpipe(this); break; case IMPULSE.SPECIAL: UseSpecialSkill(); break; case IMPULSE.DETPACK5: Demoman.Detpack(this, 5, true); break; case IMPULSE.DETPACK20: Demoman.Detpack(this, 20, true); break; case IMPULSE.DETPACK50: Demoman.Detpack(this, 50, true); break; case IMPULSE.DETPACK255: Demoman.Detpack(this, 255, true); break; case IMPULSE.DETPACKUNSET: Demoman.Detpack(this, 0, false); break; } } }
public void SetMovement(PlayerCmd pCmd) { _pCmd = pCmd; }