예제 #1
0
        void ProcessStartSpatialPropAnim(ThnEvent ev)
        {
            var obj = Objects[(string)ev.Targets[0]];

            var     props  = (LuaTable)ev.Properties["spatialprops"];
            Matrix4?orient = null;
            object  tmp;

            if (ev.Properties.TryGetValue("orient", out tmp))
            {
                orient = ThnScript.GetMatrix((LuaTable)tmp);
            }
            if (obj.Camera != null)
            {
                if (orient != null)
                {
                    obj.Camera.Orientation = orient.Value;
                }
                if (ev.Duration > 0)
                {
                    FLLog.Error("Thn", "spatialpropanim.duration > 0 - unimplemented");
                    //return;
                }
            }
            if (obj.Camera == null)
            {
                FLLog.Error("Thn", "StartSpatialPropAnim unimplemented");
            }
        }
예제 #2
0
        void PlayScript(StoryCutsceneIni ct, CutsceneState state)
        {
            ui.Visible = false;
            cState     = CutsceneState.Regular;
            string scName = ct.Encounters[0].Action;

            if (!string.IsNullOrEmpty(ct.Encounters[0].Offer))
            {
                scName = ct.Encounters[0].Offer;
                cState = CutsceneState.Offer;
            }
            switch (state)
            {
            case CutsceneState.Decision:
                scName = ct.Encounters[0].Decision;
                cState = state;
                break;

            case CutsceneState.Accept:
                scName = ct.Encounters[0].Accept;
                cState = state;
                break;

            case CutsceneState.Reject:
                scName = ct.Encounters[0].Reject;
                cState = state;
                break;
            }
            var script = new ThnScript(session.Game.GameData.ResolveDataPath(scName));

            currentCutscene = ct;
            RoomDoSceneScript(script, ScriptState.Cutscene);
        }
예제 #3
0
        public void RunScript(ThnScript thn, Action onFinish = null)
        {
            AddEntities(thn);
            var evArr  = events.ToArray();
            var evsNew = new List <ThnEvent>(evArr);

            foreach (var ev in thn.Events)
            {
                totalDuration = Math.Max(totalDuration, thn.Duration);
                ev.TimeOffset = currentTime;
                evsNew.Add(ev);
            }
            if (onFinish != null)
            {
                evsNew.Add(new ThnEvent()
                {
                    TimeOffset   = thn.Duration,
                    CustomAction = onFinish
                });
            }
            evsNew.Sort((x, y) => x.Time.CompareTo(y.Time));
            events = new Queue <ThnEvent>();
            foreach (var item in evsNew)
            {
                events.Enqueue(item);
            }
        }
예제 #4
0
 public ThnScriptInstance(Cutscene cs, ThnScript script)
 {
     this.thn = script;
     Duration = script.Duration;
     Cutscene = cs;
     foreach (var ev in script.Events)
     {
         events.Enqueue(ev);
     }
 }
예제 #5
0
 private bool firstFrame = false; //Stops a desync in scene starting
 void RoomDoSceneScript(ThnScript sc, ScriptState state)
 {
     hotspots     = new List <RTCHotspot>();
     firstFrame   = true;
     currentState = state;
     if (sc == null)
     {
         currentState = ScriptState.None;
     }
     waitingForFinish = sc;
     scene.BeginScene(Scripts(sceneScripts, new[] { sc }));
     string[] ships = Array.Empty <string>();
     if (session.Ships != null)
     {
         ships = session.Ships.Select(x => Game.GameData.GetShip(x.ShipCRC).Nickname).ToArray();
     }
     for (int i = 0; (i < ships.Length && i < currentRoom.ForSaleShipPlacements.Count); i++)
     {
         ThnObject marker = scene.GetObject(currentRoom.ForSaleShipPlacements[i]);
         if (marker == null)
         {
             FLLog.Error("Base", "Couldn't display " + ships[i] + " on " + currentRoom.ForSaleShipPlacements[i]);
             continue;
         }
         var toSellShip = Game.GameData.GetShip(ships[i]);
         //Set up object
         var obj = new GameObject(toSellShip.ModelFile.LoadFile(Game.ResourceManager), Game.ResourceManager)
         {
             Parent = marker.Object
         };
         obj.PhysicsComponent = null;
         marker.Object.Children.Add(obj);
         if (obj.HardpointExists("HpMount"))
         {
             Matrix4x4.Invert(obj.GetHardpoint("HpMount").Transform, out var tr);
             obj.SetLocalTransform(tr);
         }
     }
     if (sc == null)
     {
         SetRoomCameraAndShip();
         letterboxAmount = -1;
         ui.Visible      = true;
     }
     else
     {
         ui.Visible      = false;
         letterboxAmount = 1;
     }
     if (cState == CutsceneState.Decision)
     {
         letterboxAmount = -1;
     }
 }
예제 #6
0
 private void SceneOnScriptFinished(ThnScript obj)
 {
     if (waitingForFinish != null && obj == waitingForFinish)
     {
         if (currentCutscene != null)
         {
             if (cState == CutsceneState.Decision)
             {
                 return;
             }
             FadeOut(0.25, () =>
             {
                 RoomDoSceneScript(null, ScriptState.None);
                 ui.Visible = true;
                 FLLog.Info("Thn", "Finished cutscene");
                 if (cState == CutsceneState.Regular)
                 {
                     session.FinishCutscene(currentCutscene);
                     currentCutscene = null;
                     if (toPlay.Count > 0)
                     {
                         ProcessNextCutscene();
                     }
                 }
                 else if (cState == CutsceneState.Offer)
                 {
                     PlayScript(currentCutscene, CutsceneState.Decision);
                     ui.Event("MissionOffer", currentCutscene.Encounters[0].MissionTextId);
                 }
                 FadeIn(0.2, 0.25);
             });
         }
         else if (currentState == ScriptState.Launch)
         {
             SendLaunch();
         }
         else
         {
             currentState = ScriptState.None;
             SetRoomCameraAndShip();
             animatingLetterbox = true;
         }
     }
 }
        public void HandlePacket(IPacket pkt)
        {
            if (!(pkt is ObjectUpdatePacket))
            {
                FLLog.Debug("Client", "Got packet of type " + pkt.GetType());
            }
            switch (pkt)
            {
            case CallThornPacket ct:
                AddGameplayAction(gp => {
                    var thn = new ThnScript(Game.GameData.ResolveDataPath(ct.Thorn));
                    gp.Thn  = new Cutscene(new ThnScript[] { thn }, gp);
                });
                break;

            case AddRTCPacket rtc:
                AddRTC(rtc.RTC);
                break;

            case MsnDialogPacket msndlg:
                AddGameplayAction(gp =>
                {
                    RunDialog(msndlg.Lines);
                });
                break;

            case PlaySoundPacket psnd:
                PlaySound(psnd.Sound);
                break;

            case PlayMusicPacket mus:
                PlayMusic(mus.Music);
                break;

            case SpawnPlayerPacket p:
                PlayerBase        = null;
                PlayerSystem      = p.System;
                PlayerPosition    = p.Position;
                PlayerOrientation = Matrix4x4.CreateFromQuaternion(p.Orientation);
                SetSelfLoadout(p.Ship);
                SceneChangeRequired();
                break;

            case BaseEnterPacket b:
                PlayerBase = b.Base;
                SetSelfLoadout(b.Ship);
                SceneChangeRequired();
                break;

            case SpawnObjectPacket p:
                var shp = Game.GameData.GetShip((int)p.Loadout.ShipCRC);
                //Set up player object + camera
                var newobj = new GameObject(shp, Game.ResourceManager);
                newobj.Name      = "NetPlayer " + p.ID;
                newobj.Transform = Matrix4x4.CreateFromQuaternion(p.Orientation) *
                                   Matrix4x4.CreateTranslation(p.Position);
                objects.Add(p.ID, newobj);
                if (worldReady)
                {
                    gp.world.Objects.Add(newobj);
                }
                else
                {
                    toAdd.Add(newobj);
                }
                break;

            case ObjectUpdatePacket p:
                foreach (var update in p.Updates)
                {
                    UpdateObject(update);
                }
                break;

            case DespawnObjectPacket p:
                var despawn = objects[p.ID];
                if (worldReady)
                {
                    gp.world.Objects.Remove(despawn);
                }
                else
                {
                    toAdd.Remove(despawn);
                }
                objects.Remove(p.ID);
                break;

            default:
                if (ExtraPackets != null)
                {
                    ExtraPackets(pkt);
                }
                else
                {
                    FLLog.Error("Network", "Unknown packet type " + pkt.GetType().ToString());
                }
                break;
            }
        }
예제 #8
0
        void DoTrigger(int i, SpaceGameplay gameplay)
        {
            active[i] = true;
            var tr = msn.Triggers[i];

            if (!CheckConditions(tr))
            {
                return;
            }
            FLLog.Debug("Mission", "Running trigger " + tr.Nickname);
            if (timers.ContainsKey(tr.Nickname))
            {
                timers.Remove(tr.Nickname);
            }
            triggered[i] = true;

            foreach (var act in tr.Actions)
            {
                switch (act.Type)
                {
                case TriggerActions.Act_ActTrig:
                    var trname = act.Entry[0].ToString();
                    for (int j = 0; j < msn.Triggers.Count; j++)
                    {
                        if (trname.Equals(msn.Triggers[j].Nickname, StringComparison.OrdinalIgnoreCase))
                        {
                            DoTrigger(j, gameplay);
                            break;
                        }
                    }
                    break;

                case TriggerActions.Act_PlaySoundEffect:
                    session.Game.Sound.PlaySound(act.Entry[0].ToString());
                    break;

                case TriggerActions.Act_ForceLand:
                    session.ForceLand(act.Entry[0].ToString());
                    break;

                case TriggerActions.Act_AdjAcct:
                    session.Credits += act.Entry[0].ToInt32();
                    break;

                case TriggerActions.Act_SpawnSolar:
                    SpawnSolar(act.Entry[0].ToString(), gameplay.world);
                    break;

                case TriggerActions.Act_StartDialog:
                    RunDialog(msn.Dialogs.First((x) => x.Nickname.Equals(act.Entry[0].ToString(), StringComparison.OrdinalIgnoreCase)));
                    break;

                case TriggerActions.Act_MovePlayer:
                    gameplay.player.Transform = Matrix4.CreateTranslation(act.Entry[0].ToSingle(), act.Entry[1].ToSingle(), act.Entry[2].ToSingle());
                    //last param seems to always be one?
                    break;

                case TriggerActions.Act_LightFuse:
                    var fuse    = session.Game.GameData.GetFuse(act.Entry[1].ToString());
                    var gameObj = gameplay.world.GetObject(act.Entry[0].ToString());
                    var fzr     = new FuseRunnerComponent(gameObj)
                    {
                        Fuse = fuse
                    };
                    gameObj.Components.Add(fzr);
                    fzr.Run();
                    break;

                case TriggerActions.Act_PlayMusic:
                    session.Game.Sound.PlayMusic(act.Entry[3].ToString());
                    break;

                case TriggerActions.Act_CallThorn:
                    var thn = new ThnScript(gameplay.FlGame.GameData.ResolveDataPath(act.Entry[0].ToString()));
                    gameplay.Thn = new Cutscene(new ThnScript[] { thn }, gameplay);
                    break;

                case TriggerActions.Act_SetShipAndLoadout:
                    if (!act.Entry[0].ToString().Equals("none", StringComparison.OrdinalIgnoreCase))
                    {
                        var loadout = session.Game.GameData.Ini.Loadouts.FindLoadout(act.Entry[1].ToString());
                        if (loadout != null)
                        {
                            session.PlayerShip = act.Entry[0].ToString();
                            session.Mounts     = new List <EquipMount>();
                            foreach (var equip in loadout.Equip)
                            {
                                if (equip.Value == null)
                                {
                                    continue;
                                }
                                var hp = equip.Key.StartsWith("__noHardpoint")
                                        ? null
                                        : equip.Key;
                                session.Mounts.Add(new EquipMount(hp, equip.Value));
                            }
                        }
                    }
                    break;
                }
            }
        }
예제 #9
0
        void AddEntities(ThnScript thn)
        {
            foreach (var kv in thn.Entities)
            {
                if (Objects.ContainsKey(kv.Key))
                {
                    continue;
                }
                if ((kv.Value.ObjectFlags & ThnObjectFlags.Reference) == ThnObjectFlags.Reference)
                {
                    continue;
                }
                var obj = new ThnObject();
                obj.Name      = kv.Key;
                obj.Translate = kv.Value.Position ?? Vector3.Zero;
                obj.Rotate    = kv.Value.RotationMatrix ?? Matrix4.Identity;
                //PlayerShip object
                if (spawnObjects && scriptContext.PlayerShip != null && kv.Value.Type == EntityTypes.Compound &&
                    kv.Value.Template.Equals("playership", StringComparison.InvariantCultureIgnoreCase))
                {
                    obj.Object = scriptContext.PlayerShip;
                    obj.Object.RenderComponent.LitDynamic = (kv.Value.ObjectFlags & ThnObjectFlags.LitDynamic) == ThnObjectFlags.LitDynamic;
                    obj.Object.RenderComponent.LitAmbient = (kv.Value.ObjectFlags & ThnObjectFlags.LitAmbient) == ThnObjectFlags.LitAmbient;
                    obj.Object.RenderComponent.NoFog      = kv.Value.NoFog;
                    ((ModelRenderer)obj.Object.RenderComponent).LightGroup = kv.Value.LightGroup;
                    obj.Entity = kv.Value;
                    Vector3 transform = kv.Value.Position ?? Vector3.Zero;
                    obj.Object.Transform = (kv.Value.RotationMatrix ?? Matrix4.Identity) * Matrix4.CreateTranslation(transform);
                    obj.HpMount          = scriptContext.PlayerShip.GetHardpoint("HpMount");
                    World.Objects.Add(obj.Object);
                    Objects.Add(kv.Key, obj);
                    continue;
                }

                var    template = kv.Value.Template;
                string replacement;
                if (scriptContext != null &&
                    scriptContext.Substitutions.TryGetValue(kv.Value.Template, out replacement))
                {
                    template = replacement;
                }
                if (spawnObjects && kv.Value.Type == EntityTypes.Compound)
                {
                    bool getHpMount = false;
                    //Fetch model
                    IDrawable drawable;
                    switch (kv.Value.MeshCategory.ToLowerInvariant())
                    {
                    case "solar":
                        drawable = gameData.GetSolar(template);
                        break;

                    case "ship":
                    case "spaceship":
                        getHpMount = true;
                        var sh = gameData.GetShip(template);
                        sh.LoadResources();
                        drawable = sh.Drawable;
                        break;

                    case "prop":
                        drawable = gameData.GetProp(template);
                        break;

                    case "room":
                        drawable = gameData.GetRoom(template);
                        break;

                    case "equipment cart":
                        drawable = gameData.GetCart(template);
                        break;

                    case "equipment":
                        var eq = gameData.GetEquipment(template);
                        eq.LoadResources();
                        drawable = eq.GetDrawable();
                        break;

                    case "asteroid":
                        drawable = gameData.GetAsteroid(kv.Value.Template);
                        break;

                    default:
                        throw new NotImplementedException("Mesh Category " + kv.Value.MeshCategory);
                    }
                    if (kv.Value.UserFlag != 0)
                    {
                        //This is a starsphere
                        var transform = (kv.Value.RotationMatrix ?? Matrix4.Identity) * Matrix4.CreateTranslation(kv.Value.Position ?? Vector3.Zero);
                        layers.Add(new Tuple <IDrawable, Matrix4, int>(drawable, transform, kv.Value.SortGroup));
                    }
                    else
                    {
                        obj.Object                  = new GameObject(drawable, game.GetService <ResourceManager>(), true, false);
                        obj.Object.Name             = kv.Value.Name;
                        obj.Object.PhysicsComponent = null; //Jitter seems to interfere with directly setting orientation
                        if (getHpMount)
                        {
                            obj.HpMount = obj.Object.GetHardpoint("HpMount");
                        }
                        var r = (ModelRenderer)obj.Object.RenderComponent;
                        r.LightGroup = kv.Value.LightGroup;
                        r.LitDynamic = (kv.Value.ObjectFlags & ThnObjectFlags.LitDynamic) == ThnObjectFlags.LitDynamic;
                        r.LitAmbient = (kv.Value.ObjectFlags & ThnObjectFlags.LitAmbient) == ThnObjectFlags.LitAmbient;
                        //HIDDEN just seems to be an editor flag?
                        //r.Hidden = (kv.Value.ObjectFlags & ThnObjectFlags.Hidden) == ThnObjectFlags.Hidden;
                        r.NoFog = kv.Value.NoFog;
                    }
                }
                else if (kv.Value.Type == EntityTypes.PSys)
                {
                    var fx = gameData.GetEffect(kv.Value.Template);
                    obj.Object = new GameObject();
                    obj.Object.RenderComponent = new ParticleEffectRenderer(fx)
                    {
                        Active = false
                    };
                }
                else if (kv.Value.Type == EntityTypes.Scene)
                {
                    if (hasScene)
                    {
                        //throw new Exception("Thn can only have one scene");
                        //TODO: This needs to be handled better
                        continue;
                    }
                    var amb = kv.Value.Ambient.Value;
                    if (amb.X == 0 && amb.Y == 0 && amb.Z == 0)
                    {
                        continue;
                    }
                    hasScene = true;
                    Renderer.SystemLighting.Ambient = new Color4(amb.X / 255f, amb.Y / 255f, amb.Z / 255f, 1);
                }
                else if (kv.Value.Type == EntityTypes.Light)
                {
                    var lt = new DynamicLight();
                    lt.LightGroup = kv.Value.LightGroup;
                    lt.Active     = kv.Value.LightProps.On;
                    lt.Light      = kv.Value.LightProps.Render;
                    obj.Light     = lt;
                    obj.LightDir  = lt.Light.Direction;
                    if (kv.Value.RotationMatrix.HasValue)
                    {
                        var m = kv.Value.RotationMatrix.Value;
                        lt.Light.Direction = (new Vector4(lt.Light.Direction.Normalized(), 0) * m).Xyz.Normalized();
                    }
                    if (Renderer != null)
                    {
                        Renderer.SystemLighting.Lights.Add(lt);
                    }
                }
                else if (kv.Value.Type == EntityTypes.Camera)
                {
                    obj.Camera             = new ThnCameraTransform();
                    obj.Camera.Position    = kv.Value.Position.Value;
                    obj.Camera.Orientation = kv.Value.RotationMatrix ?? Matrix4.Identity;
                    obj.Camera.FovH        = kv.Value.FovH ?? obj.Camera.FovH;
                    obj.Camera.AspectRatio = kv.Value.HVAspect ?? obj.Camera.AspectRatio;
                }
                else if (kv.Value.Type == EntityTypes.Marker)
                {
                    obj.Object          = new GameObject();
                    obj.Object.Name     = "Marker";
                    obj.Object.Nickname = "";
                }
                else if (kv.Value.Type == EntityTypes.Sound)
                {
                    obj.Sound         = new ThnSound(kv.Value.Template, game.GetService <SoundManager>(), kv.Value.AudioProps, obj);
                    obj.Sound.Spatial = (kv.Value.ObjectFlags & ThnObjectFlags.Spatial) == ThnObjectFlags.Spatial;
                }
                if (obj.Object != null)
                {
                    Vector3 transform = kv.Value.Position ?? Vector3.Zero;
                    obj.Object.Transform = (kv.Value.RotationMatrix ?? Matrix4.Identity) * Matrix4.CreateTranslation(transform);
                    World.Objects.Add(obj.Object);
                }
                obj.Entity      = kv.Value;
                Objects[kv.Key] = obj;
            }
        }
예제 #10
0
        public void Process(ThnEvent ev, Cutscene cs)
        {
            if (ev.Targets.Capacity == 0)
            {
                return;
            }
            ThnObject objA;

            if (!cs.Objects.TryGetValue((string)ev.Targets[0], out objA))
            {
                FLLog.Error("Thn", "Object does not exist " + (string)ev.Targets[0]);
                return;
            }

            bool       hasPos   = false;
            Quaternion?q_orient = null;

            if (ev.Targets.Capacity >= 1)
            {
                var     props = (LuaTable)ev.Properties["spatialprops"];
                Vector3 pos;
                object  tmp;
                if (props.TryGetValue("q_orient", out tmp))
                {
                    var tb = (LuaTable)tmp;
                    q_orient = new Quaternion((float)tb[1], (float)tb[2], (float)tb[3], (float)tb[0]);
                }

                if (props.TryGetValue("orient", out tmp))
                {
                    var orient = ThnScript.GetMatrix((LuaTable)tmp);
                    q_orient = orient.ExtractRotation();
                }

                AxisRotation axisRotation = null;
                if (props.TryGetValue("axisrot", out tmp))
                {
                    var axisRot_Table = (LuaTable)tmp;
                    axisRotation = new AxisRotation();
                    if (!axisRot_Table.TryGetVector3(1, out axisRotation.Axis))
                    {
                        FLLog.Error("Thn", "invalid axisrot");
                        return;
                    }
                    axisRotation.Axis           = Vector3.TransformNormal(axisRotation.Axis, objA.Rotate);
                    axisRotation.Degrees        = (float)axisRot_Table[0];
                    axisRotation.OriginalRotate = objA.Rotate;
                }

                hasPos = props.TryGetVector3("pos", out pos);
                if (ev.Targets.Capacity > 1)
                {
                    ThnObject objB;
                    if (!cs.Objects.TryGetValue((string)ev.Targets[1], out objB))
                    {
                        FLLog.Error("Thn", "Object does not exist " + (string)ev.Targets[1]);
                        return;
                    }
                    if (ev.Duration < float.Epsilon)
                    {
                        objA.Translate = objB.Translate;
                        objA.Rotate    = objB.Rotate;
                    }
                    else
                    {
                        cs.Coroutines.Add(new FollowSpatialRoutine()
                        {
                            Duration = ev.Duration,
                            HasPos   = hasPos,
                            HasQuat  = q_orient != null,
                            This     = objA,
                            Follow   = objB
                        });
                    }
                }
                else
                {
                    if (ev.Duration < float.Epsilon)
                    {
                        if (hasPos)
                        {
                            objA.Translate = pos;
                        }
                        if (q_orient != null)
                        {
                            objA.Rotate = Matrix4x4.CreateFromQuaternion(q_orient.Value);
                        }
                    }
                    else
                    {
                        cs.Coroutines.Add(new StaticSpatialRoutine()
                        {
                            Duration = ev.Duration,
                            HasPos   = hasPos,
                            HasQuat  = q_orient != null,
                            EndPos   = pos,
                            EndQuat  = q_orient ?? Quaternion.Identity,
                            This     = objA,
                            AxisRot  = axisRotation
                        });
                    }
                }
            }
        }
예제 #11
0
 public ThnScriptContext(ThnScript set)
 {
     SetScript = set;
 }
예제 #12
0
 public void FidgetScript(ThnScript scene)
 {
     SceneSetup(new[] { scene }, false);
 }
예제 #13
0
 public void OnScriptFinished(ThnScript thn) => ScriptFinished?.Invoke(thn);
        public void Process(ThnEvent ev, Cutscene cs)
        {
            if (ev.Targets.Capacity == 0)
            {
                return;
            }
            ThnObject objA;

            if (!cs.Objects.TryGetValue((string)ev.Targets[0], out objA))
            {
                FLLog.Error("Thn", "Object does not exist " + (string)ev.Targets[0]);
                return;
            }
            if (ev.Targets.Capacity == 1)
            {
                var        props    = (LuaTable)ev.Properties["spatialprops"];
                Quaternion?q_orient = null;
                Vector3    pos;
                object     tmp;
                if (props.TryGetValue("q_orient", out tmp))
                {
                    var tb = (LuaTable)tmp;
                    q_orient = new Quaternion((float)tb[1], (float)tb[2], (float)tb[3], (float)tb[0]);
                }
                if (props.TryGetValue("orient", out tmp))
                {
                    var orient = ThnScript.GetMatrix((LuaTable)tmp);
                    q_orient = orient.ExtractRotation();
                }
                bool hasPos = props.TryGetVector3("pos", out pos);
                if (ev.Duration < float.Epsilon)
                {
                    if (hasPos)
                    {
                        objA.Translate = pos;
                    }
                    if (q_orient != null)
                    {
                        objA.Rotate = Matrix4.CreateFromQuaternion(q_orient.Value);
                    }
                }
                else
                {
                    cs.Coroutines.Add(new StaticSpatialRoutine()
                    {
                        Duration = ev.Duration,
                        HasPos   = hasPos,
                        HasQuat  = q_orient != null,
                        EndPos   = pos,
                        EndQuat  = q_orient ?? Quaternion.Identity,
                        This     = objA
                    });
                }
            }
            else
            {
                ThnObject objB;
                if (!cs.Objects.TryGetValue((string)ev.Targets[1], out objB))
                {
                    FLLog.Error("Thn", "Object does not exist " + (string)ev.Targets[1]);
                    return;
                }
                if (ev.Duration < float.Epsilon)
                {
                    objA.Translate = objB.Translate;
                    objA.Rotate    = objB.Rotate;
                }
                else
                {
                    cs.Coroutines.Add(new FollowSpatialRoutine()
                    {
                        Duration = ev.Duration,
                        HasPos   = true,
                        HasQuat  = true,
                        This     = objA,
                        Follow   = objB
                    });
                }
            }
        }
예제 #15
0
        public void HandlePacket(IPacket pkt)
        {
            if (!(pkt is ObjectUpdatePacket))
            {
                FLLog.Debug("Client", "Got packet of type " + pkt.GetType());
            }
            switch (pkt)
            {
            case CallThornPacket ct:
                RunSync(() => {
                    var thn = new ThnScript(Game.GameData.ResolveDataPath(ct.Thorn));
                    gp.Thn  = new Cutscene(new ThnScript[] { thn }, gp);
                });
                break;

            case UpdateRTCPacket rtc:
                AddRTC(rtc.RTCs);
                break;

            case MsnDialogPacket msndlg:
                RunSync(() => {
                    RunDialog(msndlg.Lines);
                });
                break;

            case PlaySoundPacket psnd:
                PlaySound(psnd.Sound);
                break;

            case PlayMusicPacket mus:
                PlayMusic(mus.Music);
                break;

            case SpawnPlayerPacket p:
                PlayerBase        = null;
                PlayerSystem      = p.System;
                PlayerPosition    = p.Position;
                PlayerOrientation = Matrix4x4.CreateFromQuaternion(p.Orientation);
                SetSelfLoadout(p.Ship);
                SceneChangeRequired();
                break;

            case BaseEnterPacket b:
                PlayerBase = b.Base;
                SetSelfLoadout(b.Ship);
                SceneChangeRequired();
                AddRTC(b.RTCs);
                break;

            case SpawnSolarPacket solar:
                RunSync(() =>
                {
                    foreach (var si in solar.Solars)
                    {
                        if (!objects.ContainsKey(si.ID))
                        {
                            var arch          = Game.GameData.GetSolarArchetype(si.Archetype);
                            var go            = new GameObject(arch, Game.ResourceManager, true);
                            go.StaticPosition = si.Position;
                            go.Transform      = Matrix4x4.CreateFromQuaternion(si.Orientation) *
                                                Matrix4x4.CreateTranslation(si.Position);
                            go.Nickname = $"$Solar{si.ID}";
                            go.World    = gp.world;
                            go.Register(go.World.Physics);
                            go.CollisionGroups = arch.CollisionGroups;
                            FLLog.Debug("Client", $"Spawning object {si.ID}");
                            gp.world.Objects.Add(go);
                            objects.Add(si.ID, go);
                        }
                    }
                });
                break;

            case DestroyPartPacket p:
                RunSync(() =>
                {
                    objects[p.ID].DisableCmpPart(p.PartName);
                });
                break;

            case SpawnDebrisPacket p:
                RunSync(() =>
                {
                    var arch = Game.GameData.GetSolarArchetype(p.Archetype);
                    var mdl  =
                        ((IRigidModelFile)arch.ModelFile.LoadFile(Game.ResourceManager)).CreateRigidModel(true);
                    var newpart  = mdl.Parts[p.Part].Clone();
                    var newmodel = new RigidModel()
                    {
                        Root          = newpart,
                        AllParts      = new[] { newpart },
                        MaterialAnims = mdl.MaterialAnims,
                        Path          = mdl.Path,
                    };
                    var go       = new GameObject($"debris{p.ID}", newmodel, Game.ResourceManager, p.Part, p.Mass, true);
                    go.Transform = Matrix4x4.CreateFromQuaternion(p.Orientation) *
                                   Matrix4x4.CreateTranslation(p.Position);
                    go.World = gp.world;
                    go.Register(go.World.Physics);
                    gp.world.Objects.Add(go);
                    objects.Add(p.ID, go);
                });
                break;

            case SpawnObjectPacket p:
                RunSync(() =>
                {
                    var shp = Game.GameData.GetShip((int)p.Loadout.ShipCRC);
                    //Set up player object + camera
                    var newobj       = new GameObject(shp, Game.ResourceManager);
                    newobj.Name      = "NetPlayer " + p.ID;
                    newobj.Transform = Matrix4x4.CreateFromQuaternion(p.Orientation) *
                                       Matrix4x4.CreateTranslation(p.Position);
                    if (connection is GameNetClient)
                    {
                        newobj.Components.Add(new CNetPositionComponent(newobj));
                    }
                    objects.Add(p.ID, newobj);
                    gp.world.Objects.Add(newobj);
                });
                break;

            case ObjectUpdatePacket p:
                RunSync(() =>
                {
                    foreach (var update in p.Updates)
                    {
                        UpdateObject(p.Tick, update);
                    }
                });
                break;

            case DespawnObjectPacket p:
                RunSync(() =>
                {
                    var despawn = objects[p.ID];
                    gp.world.Objects.Remove(despawn);
                    objects.Remove(p.ID);
                });
                break;

            default:
                if (ExtraPackets != null)
                {
                    ExtraPackets(pkt);
                }
                else
                {
                    FLLog.Error("Network", "Unknown packet type " + pkt.GetType().ToString());
                }
                break;
            }
        }