Beispiel #1
0
    public void CorrectPosition(int lastControlCommandApplied, Vector3 correctPosition, Vector3 correctMomentum, float correctDirection, Vector3 correctVelocity, float crouch_factor)
    {
        ////Debug.Log (MyPlayer.networkView.viewID + ") " + "Correcting my position");
        LastCorrectionRespondedTo = lastControlCommandApplied;

        // 12A: Reposition the player to match when the server sent the correction
        MyPlayer.transform.position = correctPosition;
        MyPlayer.state.angle        = correctDirection;
        SceneCharacter3D p = (SceneCharacter3D)MyPlayer;

        p.state.pos      = correctPosition;
        p.state.momentum = correctMomentum;
        p.state.angle    = correctDirection;
        p.state.velocity = correctVelocity;
        p.crouch_factor  = crouch_factor;

        // 12B: Make up for control commands which were sent between when the server sent the correction and now
        ////Debug.Log (MyPlayer.networkView.viewID + ") " + "Applying missing commands, starting with " + (lastControlCommandApplied + 1) + ", up to " + CurrentControlCommandId);
        while (ControlCommands.ContainsKey(lastControlCommandApplied + 1))
        {
            Debug.Log(MyPlayer.GetComponent <NetworkView>().viewID + ") " + "Applying CC " + lastControlCommandApplied + 1);
            MyPlayer.ExecuteControlCommand(ControlCommands[lastControlCommandApplied + 1]);
            lastControlCommandApplied++;
        }

        UpdateCamera();
    }
Beispiel #2
0
 void fire_plasma(SceneCharacter3D character)
 {
     if (!character.can_fire_plasma())
     {
         return;
     }
     Projectiles.Add(Plasma.Fire(character, plasma_prefab));
 }
Beispiel #3
0
 void fire_grenade(SceneCharacter3D character)
 {
     if (character.grenades < 1)
     {
         return;
     }
     //character.grenades--;
     Projectiles.Add(Grenade.Fire(character, grenade_prefab));
 }
Beispiel #4
0
    public void ValidatePosition(int lastCorrectionRepondedTo, int lastControlApplied, Vector3 clientPosition, float clientAngle, NetworkMessageInfo info)
    {
        Player player = Players[info.sender.guid];

        // 11B: Make sure the client has used the last correction we sent
        if (lastCorrectionRepondedTo < player.LastCorrectionSent)
        {
            return;
        }

        #region 11C: Get the difference between the player's state and the server's
        ObjectState serverStateAfterControl = player.StatesAfterControls[lastControlApplied];
        if (serverStateAfterControl == null)
        {
            return;
        }

        XDiff = clientPosition.x - serverStateAfterControl.Position.x;
        YDiff = clientPosition.y - serverStateAfterControl.Position.y;
        ZDiff = clientPosition.z - serverStateAfterControl.Position.z;

        //XAngDiff = clientDirection.x - serverStateAfterControl.Forward.x;
        //YAngDiff = clientDirection.y - serverStateAfterControl.Forward.y;
        //ZAngDiff = clientDirection.z - serverStateAfterControl.Forward.z;

        AngDiff = clientAngle - serverStateAfterControl.Angle;

        Debug.Log(
            "Diff: " + XDiff.ToString() +
            ", " + YDiff.ToString() +
            ", " + ZDiff.ToString() +
            ", " + AngDiff.ToString()
            );
        #endregion 11C

        #region 11D: If the player is out of tolerance, then send a correction
        if (Mathf.Abs(XDiff) > PosTolerance ||
            Mathf.Abs(YDiff) > PosTolerance ||
            Mathf.Abs(ZDiff) > PosTolerance ||
            Mathf.Abs(AngDiff) > DirTolerance)
        //Mathf.Abs(XAngDiff) > DirTolerance ||
        //Mathf.Abs(YAngDiff) > DirTolerance ||
        //Mathf.Abs(ZAngDiff) > DirTolerance)
        {
            Debug.Log("Sending correction...");
            player.LastCorrectionSent = lastControlApplied;

            // Send the current position
            // If we send the correction to the old position, it forces the client to apply more contorl commands on its own, creating a larger margin of error
            SceneCharacter3D scenechar = (SceneCharacter3D)player.InGameCharacter;
            GetComponent <NetworkView>().RPC("CorrectPosition", info.sender, player.LastControlNumApplied, player.InGameCharacter.state.pos, scenechar.state.momentum, player.InGameCharacter.state.angle, scenechar.state.velocity, scenechar.crouch_factor);
        }
        #endregion 11D
    }
Beispiel #5
0
    void attach_cam_to_walker(SceneCharacter3D walker)
    {
        cam.transform.position = walker.head.transform.position;
        cam.transform.rotation = walker.head.transform.rotation;
        var angles = cam.transform.eulerAngles;

        angles.z -= 90;
        cam.transform.eulerAngles = angles;
        cam.transform.Translate(-.007f, 0, 0.07f);

        cam.transform.SetParent(walker.head.transform);
    }
Beispiel #6
0
    // Use this for initialization
    void Start()
    {
        walker_char = walker.GetComponent <SceneCharacter3D>();
        // Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
        //Game.recolor_walker(walker, new Color(.7f, 0f, .3f));

        Color c      = new Color(0f, 1.0f, 0f);
        Mesh  m      = floor.GetComponent <MeshFilter>().sharedMesh;
        var   colors = from n in Enumerable.Range(0, m.vertices.Length) select c;

        m.colors = colors.ToArray();
    }
Beispiel #7
0
    void attach_cam_to_walker(SceneCharacter3D walker)
    {
        cam.transform.position = walker.head.transform.position;
        cam.transform.rotation = walker.head.transform.rotation;
        var angles = cam.transform.eulerAngles;

        angles.z -= 90;
        cam.transform.eulerAngles = angles;

        var pos = cam.transform.position;

        pos += walker.state.forward_vector * .3f;
        cam.transform.position = pos;

        cam.transform.SetParent(walker.head.transform);
    }
Beispiel #8
0
    public void RequestProjectile(NetworkMessageInfo info)
    {
        if (!IsActive)
        {
            return;
        }
        var              attacker_player = Players[info.sender.guid];
        Character        attacker        = attacker_player.BaseCharacter;
        SceneCharacter3D scene_attacker  = SceneCharacters[attacker.Id];


        if (scene_attacker.can_fire_plasma())
        {
            InstantiatePlasma(scene_attacker);
            GetComponent <NetworkView>().RPC("ReceiveProjectile", RPCMode.Others, attacker.Id);
        }
    }
Beispiel #9
0
    public static Grenade Fire(SceneCharacter3D c, GameObject fab)
    {
        var pos = c.head.transform.position;

        pos += c.head.transform.forward * .7f;
        pos -= c.head.transform.right * .25f;
        var rot     = c.head.transform.rotation.eulerAngles;
        var quat    = Quaternion.Euler(rot.x, rot.y, 0);
        var go      = (GameObject)GameObject.Instantiate(fab, pos, quat);
        var grenade = go.GetComponent <Grenade>();
        var t       = go.transform;

        grenade.attack_time = Time.time;
        grenade.speed       = -1 * c.move;
        grenade.speed      += ((t.forward * 2) + t.up);
        grenade.fired_by    = c.BaseCharacter.Id;
        return(grenade);
    }
Beispiel #10
0
    // Use this for initialization
    void Start()
    {
        walker_char = walker.GetComponent <SceneCharacter3D>();
        // Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
        walker_char.recolor_walker(new Color(.7f, 0f, .3f));
        walker_char.BaseCharacter.Id = 1000;

        //Color c = new Color(.2f, .2f, .2f);
        //Mesh m = floor.GetComponent<MeshFilter>().sharedMesh;
        //var colors = from n in Enumerable.Range(0, m.vertices.Length) select c;
        //m.colors = colors.ToArray();

        ai3d                 = ai.GetComponent <AI3D>();
        ai3d.Target          = walker_char;
        ai3d.state.on_ground = true;

        Projectiles = new List <Projectile>();

        switch_level("bwadi");
    }
Beispiel #11
0
    public static Plasma Fire(SceneCharacter3D c, GameObject fab)
    {
        int   gun    = 1;
        float energy = 0;

        if (c.plasma1 < c.plasma2)
        {
            if (c.plasma2 > c.min_plasma_power)
            {
                energy    = c.plasma2;
                c.plasma2 = 0;
                gun       = -1;
            }
        }
        else   // c.plasma1 >= c.plasma2
        {
            if (c.plasma1 > c.min_plasma_power)
            {
                energy    = c.plasma1;
                c.plasma1 = 0;
            }
        }
        var pos = c.head.transform.position;

        pos += c.head.transform.forward * 1.3f;
        pos += c.head.transform.up * .40f * gun;
        pos += c.head.transform.right * -.3f;
        var rot  = c.head.transform.rotation;
        var proj = (GameObject)GameObject.Instantiate(fab, pos, rot);
        var p    = proj.GetComponent <Plasma>();

        p.set_energy(energy);
        p.fired_by = c.BaseCharacter.Id;
        p.speed    = proj.transform.forward * 2f;
        return(p);
    }
Beispiel #12
0
 public void InstantiateGrenade(SceneCharacter3D character)
 {
     Projectiles.Add(Grenade.Fire(character, GrenadePrefab));
 }
Beispiel #13
0
 public void InstantiatePlasma(SceneCharacter3D character)
 {
     Projectiles.Add(Plasma.Fire(character, PlasmaPrefab));
 }
Beispiel #14
0
    /// <summary>
    /// Update is called once per frame
    /// </summary>
    void Update()
    {
        if (!IsActive)
        {
            return;
        }

        //Debug.Log("Level: " + Application.loadedLevelName + "\n MyCharacterx: " + MyCharacter);
        if (MyCharacter == null || Application.loadedLevelName == MainMenuScene)
        {
            return;
        }

        if (SceneInformation == null)
        {
            LoadSceneInfo();
            GameLevel = new Level();
            GameLevel.load(GameLevelFile);
            GameObject level_object = GameLevel.game_object();
            level_object.transform.parent = SceneInformation.transform;
        }



        if (CharactersToInstantiate.Count > 0)
        {
            foreach (var character in CharactersToInstantiate)
            {
                InstantiateSceneCharacter(character);
            }

            CharactersToInstantiate.Clear();
        }

        if (ProjectilesToInstantiate.Count > 0)
        {
            foreach (var proj in ProjectilesToInstantiate)
            {
                InstantiatePlasma(SceneCharacters[proj]);
            }
            ProjectilesToInstantiate.Clear();
        }

        if (MyPlayer == null && SceneCharacters != null &&
            SceneCharacters.ContainsKey(MyCharacter.Id))
        {
            MyPlayer                 = SceneCharacters[MyCharacter.Id];
            MyPlayer.Client          = this;
            MyPlayer.BaseCharacter   = MyCharacter;
            MyPlayer.tag             = "Player";
            MyPlayer.BaseCharacter.R = MyColor.r;
            MyPlayer.BaseCharacter.G = MyColor.g;
            MyPlayer.BaseCharacter.B = MyColor.b;
            //recolor_walker(MyPlayer.gameObject, MyColor);
            GetComponent <NetworkView>().RPC("ClientColor", RPCMode.Server, MyColor.r, MyColor.g, MyColor.b);
        }

        if (CurrentGameState != GameStates.LevelLoaded ||
            MyPlayer == null)
        {
            return;
        }

        InterpolateCharacters();
        UpdateControls();
        MovePlayer();
        UpdateCamera();
        UpdateCombatControls();
        ValidateMyPosition();
        HandleProjectiles();
    }
Beispiel #15
0
    // 7D: Move each character closer toward its intended location
    public void InterpolateCharacters()
    {
        foreach (int charId in CharacterIntendedStates.Keys)
        {
            SceneCharacter3D character           = SceneCharacters[charId];
            float            portionOfDiffToMove = Mathf.Min(Time.deltaTime / ROUND_LENGTH, 1f);

            // Interpolate toward the intended position
            Vector3 curentPosition = character.transform.position;
            Vector3 positionDiff   = CharacterPositionDiffs[charId];

            float newXPos = curentPosition.x + (positionDiff.x * portionOfDiffToMove);
            float newYPos = curentPosition.y + (positionDiff.y * portionOfDiffToMove);
            float newZPos = curentPosition.z + (positionDiff.z * portionOfDiffToMove);

            character.transform.position = new Vector3(
                newXPos,
                newYPos,
                newZPos
                );


            // Interpolate toward the intended direction
            //Vector3 curentDirection = character.transform.forward;
            float directionDiff = CharacterDirectionDiffs[charId];

            /*float newXDir = curentDirection.x + (directionDiff.x * portionOfDiffToMove);
             * float newYDir = curentDirection.y + (directionDiff.y * portionOfDiffToMove);
             * float newZDir = curentDirection.z + (directionDiff.z * portionOfDiffToMove);
             * Vector3 newDir = new Vector3(
             *  newXDir,
             *  newYDir,
             *  newZDir
             * );*/
            //character.transform.forward = newDir;
            //var local = character.transform.InverseTransformDirection(newDir);
            //var fwd = character.transform.TransformDirection(Vector3.forward);
            //character.state.angle = Vector3.Angle(local, Vector3.forward);
            //character.state.angle = newYDir;
            //var angle = character.transform.localEulerAngles.y + (directionDiff * portionOfDiffToMove);
            //
            var angle = character.transform.localEulerAngles.y;
            if (directionDiff > 10)
            {
                Debug.Log(directionDiff);
            }
            angle = angle + (directionDiff * portionOfDiffToMove);
            if (angle > 359)
            {
                angle -= 359f;
            }
            if (angle < 0)
            {
                angle = 359f - angle;
            }
            character.transform.localEulerAngles = new Vector3(
                0, angle, 0);
            //character.state.angle = angle;


            Quaternion currentHeadRot = character.head.transform.localRotation;
            Quaternion headRotDiff    = CharacterHeadRotDiffs[charId];
            float      newXHeadRot    = currentHeadRot.x + (headRotDiff.x * portionOfDiffToMove);
            float      newYHeadRot    = currentHeadRot.y + (headRotDiff.y * portionOfDiffToMove);
            float      newZHeadRot    = currentHeadRot.z + (headRotDiff.z * portionOfDiffToMove);
            float      newWHeadRot    = currentHeadRot.w + (headRotDiff.w * portionOfDiffToMove);

            character.head.transform.localRotation = new Quaternion(
                newXHeadRot,
                newYHeadRot,
                newZHeadRot,
                newWHeadRot
                );

            float currentCrouchFactor = character.crouch_factor;
            float crouchFactorDiff    = CharacterCrouchFactorDiffs[charId];
            float newCrouchFactor     = currentCrouchFactor + (crouchFactorDiff * portionOfDiffToMove);

            character.state.velocity = CharacterIntendedStates[charId].Velocity;
            character.crouch_factor  = newCrouchFactor;
            character.LegUpdate(CharacterIntendedStates[charId].Walking);


            var temp = character.head.transform.localPosition;
            temp.z = character.head_rest_y - newCrouchFactor * SceneCharacter3D.crouch_dist;
            character.head.transform.localPosition = temp;
        }
    }
Beispiel #16
0
    public void UpdateCharacter(int charId, Vector3 position, float direction, int walking, Quaternion headRot, Vector3 velocity, float crouchfactor)
    {
        ////Debug.Log ("Update called for " + charId + " at " + position.x + ", " + position.y + ", " + position.z);

        // Don't update self if using client-side prediction
        if (CurrentGameState != Game.GameStates.LevelLoaded ||
            MyPlayer == null ||
            (ClientSidePrediction && charId.Equals(((Character)MyPlayer).Id)) ||
            !SceneCharacters.ContainsKey(charId)
            )
        {
            return;
        }

        SceneCharacter3D character = SceneCharacters[charId];
        ObjectState      charState = new ObjectState(charId, position, direction, headRot, velocity, crouchfactor, walking);

        // TODO: fix this to call a special method just updating the legs
        // character.GetComponent<SceneCharacter3D>().Move(1f, 0f, Time.deltaTime, false);

        if (!CharacterInterpolation)
        {
            character.transform.position           = position;
            character.state.velocity               = velocity;
            character.state.angle                  = direction;
            character.head.transform.localRotation = headRot;
            character.crouch_factor                = crouchfactor;
            character.transform.localEulerAngles   = new Vector3(0, direction, 0);
            return;
        }

        // 7A) Store the character state from the server
        if (CharacterIntendedStates.ContainsKey(charId))
        {
            CharacterIntendedStates.Remove(charId);
            CharacterPositionDiffs.Remove(charId);
            CharacterDirectionDiffs.Remove(charId);
            CharacterHeadRotDiffs.Remove(charId);
            CharacterCrouchFactorDiffs.Remove(charId);
        }

        CharacterIntendedStates.Add(charId, charState);

        // 7B) Calculate the position difference
        Vector3 currentCharPosition       = character.transform.position;
        Vector3 intendedCharacterPosition = charState.Position;

        CharacterPositionDiffs.Add(charId, new Vector3(
                                       intendedCharacterPosition.x - currentCharPosition.x,
                                       intendedCharacterPosition.y - currentCharPosition.y,
                                       intendedCharacterPosition.z - currentCharPosition.z
                                       ));

        // Calculate the direction difference
        float currentCharDirection       = character.transform.localEulerAngles.y;
        float intendedCharacterDirection = charState.Angle;

        /*CharacterDirectionDiffs.Add(charId, new Vector3(
         *          intendedCharacterDirection.x - currentCharDirection.x,
         *          intendedCharacterDirection.y - currentCharDirection.y,
         *          intendedCharacterDirection.z - currentCharDirection.z
         * ));
         */

        // TODO: use Mathf.DeltaAngle instead and test
        //float phi = Mathf.Abs(currentCharDirection - intendedCharacterDirection) % 360f;
        //float dist = phi > 180 ? 360 - phi : phi;
        float dist = Mathf.DeltaAngle(currentCharDirection, intendedCharacterDirection);

        CharacterDirectionDiffs.Add(charId, dist);


        Quaternion currentCharHeadRot       = character.head.transform.localRotation;
        Quaternion intendedCharacterHeadRot = charState.HeadRot;

        CharacterHeadRotDiffs.Add(charId, new Quaternion(
                                      intendedCharacterHeadRot.x - currentCharHeadRot.x,
                                      intendedCharacterHeadRot.y - currentCharHeadRot.y,
                                      intendedCharacterHeadRot.z - currentCharHeadRot.z,
                                      intendedCharacterHeadRot.w - currentCharHeadRot.w
                                      ));

        float currentCharCrouchFactor       = character.crouch_factor;
        float intendedCharacterCrouchFactor = charState.CrouchFactor;

        CharacterCrouchFactorDiffs.Add(charId, intendedCharacterCrouchFactor - currentCharCrouchFactor);
    }
Beispiel #17
0
    // 14: Server processes attack request
    public void RequestAttack(NetworkMessageInfo info)
    {
        if (!IsActive)
        {
            return;
        }

        AttackerMoved = false;

        //Debug.Log ("Client is requesting an attack");
        var              attackingPlayer = Players[info.sender.guid];
        Character        attacker        = attackingPlayer.BaseCharacter;
        SceneCharacter3D sceneAttacker   = SceneCharacters[attacker.Id];

        // 14A: Server checks attack validation
        if (!attacker.IsAlive)
        {
            return;
        }

        // 14B: Server sends attack message to all clients
        GetComponent <NetworkView>().RPC("ReceiveCharacterAttacks", RPCMode.Others, attacker.Id);

        // 16: Server calculates attack results
        #region Determine Hit

        var roundWhenPlayerAttacked = Rounds[attackingPlayer.RoundLastRespondedTo];

        // 16A: Server rewinds the attacker to its position when the client attacked
        #region Rewind Attacker State
        var presentAttackerState = new ObjectState(0,
                                                   sceneAttacker.transform.position,
                                                   sceneAttacker.state.angle,
                                                   Quaternion.identity,
                                                   sceneAttacker.state.velocity,
                                                   sceneAttacker.crouch_factor,
                                                   sceneAttacker.walking
                                                   );

        if (LatencyCompensation)
        {
            Debug.Log("Rewinding attacker");
            var oldAttackerState = roundWhenPlayerAttacked.CurrentObjectStates[attacker.Id];
            sceneAttacker.transform.position = oldAttackerState.Position;
            sceneAttacker.state.angle        = oldAttackerState.Angle;
            sceneAttacker.state.velocity     = oldAttackerState.Velocity;
            sceneAttacker.crouch_factor      = oldAttackerState.CrouchFactor;
        }
        #endregion Rewind Attacker State

        foreach (var potentialTarget in SceneCharacters.Values)
        {
            TargetMoved = false;

            // Check friendly fire
            if (!FriendlyFire && ((Character)potentialTarget).Team == attacker.Team)
            {
                continue;
            }

            // 16B: Server rewinds each potential target to its position when the client attacked
            #region Rewind Target State
            var presentTargetState = new ObjectState(0,
                                                     potentialTarget.transform.position,
                                                     potentialTarget.state.angle,
                                                     Quaternion.identity,
                                                     potentialTarget.state.velocity,
                                                     potentialTarget.crouch_factor,
                                                     potentialTarget.walking
                                                     );

            if (LatencyCompensation)
            {
                Debug.Log("Rewinding target");
                var oldTargetState = roundWhenPlayerAttacked.CurrentObjectStates[((Character)potentialTarget).Id];
                potentialTarget.transform.position = oldTargetState.Position;
                potentialTarget.state.angle        = oldTargetState.Angle;
                potentialTarget.state.velocity     = oldTargetState.Velocity;
                potentialTarget.crouch_factor      = oldTargetState.CrouchFactor;
            }
            #endregion Rewind Target State

            // 16C: Server checks attack logic
            if (potentialTarget.transform.IsWithinArc(sceneAttacker.transform, attacker.ArmLength + 2f, 120f))
            {
                CharacterHits(attacker, (Character)potentialTarget); // 16D-E
            }

            // 16F: Server returns each potential target to its current position
            #region Reset Target State
            if (LatencyCompensation && !TargetMoved)
            {
                Debug.Log("Unwinding target");
                potentialTarget.transform.position = presentTargetState.Position;
                potentialTarget.state.angle        = presentTargetState.Angle;
                potentialTarget.state.velocity     = presentTargetState.Velocity;
                potentialTarget.crouch_factor      = presentTargetState.CrouchFactor;
            }
            #endregion Reset Target State
        }

        #region Reset Attacker State

        // 16G: Server returns the attacker to the current position
        if (LatencyCompensation && !AttackerMoved)
        {
            Debug.Log("Unwinding attacker");
            sceneAttacker.transform.position = presentAttackerState.Position;
            sceneAttacker.state.angle        = presentAttackerState.Angle;
            sceneAttacker.state.velocity     = presentAttackerState.Velocity;
            sceneAttacker.crouch_factor      = presentAttackerState.CrouchFactor;
        }
        #endregion Reset Attacker State

        #endregion Determine Hit
    }