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
                    });
                }
            }
        }
Beispiel #2
0
        public void Run()
        {
            FLLog.Info("Engine", "Version: " + Platform.GetInformationalVersion <Game>());
            //TODO: This makes i5-7200U on mesa 18 faster, but this should probably be a configurable option
            Environment.SetEnvironmentVariable("mesa_glthread", "true");
            SSEMath.Load();
            if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0)
            {
                FLLog.Error("SDL", "SDL_Init failed, exiting.");
                return;
            }
            SDL.SDL_SetHint(SDL.SDL_HINT_IME_INTERNAL_EDITING, "1");
            SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
            //Set GL states
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 2);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 24);
            //Create Window
            var flags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;

            if (fullscreen)
            {
                flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
            }
            var sdlWin = SDL.SDL_CreateWindow(
                "LibreLancer",
                SDL.SDL_WINDOWPOS_CENTERED,
                SDL.SDL_WINDOWPOS_CENTERED,
                width,
                height,
                flags
                );

            //Cursors
            curArrow      = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW);
            curMove       = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_CROSSHAIR);
            curTextInput  = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_IBEAM);
            curResizeNS   = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENS);
            curResizeEW   = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEWE);
            curResizeNESW = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENESW);
            curResizeNWSE = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENWSE);
            //Window sizing
            if (minWindowSize != Point.Zero)
            {
                SDL.SDL_SetWindowMinimumSize(sdlWin, minWindowSize.X, minWindowSize.Y);
            }
            if (sdlWin == IntPtr.Zero)
            {
                FLLog.Error("SDL", "Failed to create window, exiting.");
                return;
            }
            SDL.SDL_EventState(SDL.SDL_EventType.SDL_DROPFILE, SDL.SDL_ENABLE);
            windowptr = sdlWin;
            var glcontext = SDL.SDL_GL_CreateContext(sdlWin);

            if (glcontext == IntPtr.Zero || !GL.CheckStringSDL())
            {
                SDL.SDL_GL_DeleteContext(glcontext);
                if (Platform.RunningOS == OS.Windows)
                {
                    SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR, "Librelancer", "Failed to create OpenGL context, exiting.", IntPtr.Zero);
                }
                FLLog.Error("OpenGL", "Failed to create OpenGL context, exiting.");
                return;
            }
            else
            {
                GL.LoadSDL();
                Renderer = string.Format("{0} ({1})", GL.GetString(GL.GL_VERSION), GL.GetString(GL.GL_RENDERER));
            }
            SetVSync(true);
            //Init game state
            RenderState = new RenderState();
            Load();
            //Start game
            running = true;
            timer   = new Stopwatch();
            timer.Start();
            double last    = 0;
            double elapsed = 0;

            SDL.SDL_Event e;
            SDL.SDL_StopTextInput();
            while (running)
            {
                //Pump message queue
                while (SDL.SDL_PollEvent(out e) != 0)
                {
                    switch (e.type)
                    {
                    case SDL.SDL_EventType.SDL_QUIT:
                    {
                        if (WillClose != null)
                        {
                            WillClose();
                        }
                        running = false;         //TODO: Raise Event
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEMOTION:
                    {
                        Mouse.X = e.motion.x;
                        Mouse.Y = e.motion.y;
                        Mouse.OnMouseMove();
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        Mouse.Buttons |= btn;
                        Mouse.OnMouseDown(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        Mouse.Buttons &= ~btn;
                        Mouse.OnMouseUp(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEWHEEL:
                    {
                        Mouse.OnMouseWheel(e.wheel.y);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_TEXTINPUT:
                    {
                        Keyboard.OnTextInput(GetEventText(ref e));
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYDOWN:
                    {
                        Keyboard.OnKeyDown((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod, e.key.repeat != 0);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYUP:
                    {
                        Keyboard.OnKeyUp((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_WINDOWEVENT:
                        if (e.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
                        {
                            SDL.SDL_GetWindowSize(windowptr, out width, out height);
                            OnResize();
                        }
                        break;

                    case SDL.SDL_EventType.SDL_DROPFILE:
                    {
                        var file = UnsafeHelpers.PtrToStringUTF8(e.drop.file);
                        OnDrop(file);
                        SDL.SDL_free(e.drop.file);
                        break;
                    }
                    }
                }

                //Do game things
                if (!running)
                {
                    break;
                }
                Action work;
                while (actions.TryDequeue(out work))
                {
                    work();
                }
                totalTime = timer.Elapsed.TotalSeconds;
                Update(elapsed);
                if (!running)
                {
                    break;
                }
                Draw(elapsed);
                //Frame time before, FPS after
                var tk = timer.Elapsed.TotalSeconds - totalTime;
                frameTime = CalcAverageTime(tk);
                if (_screenshot)
                {
                    TakeScreenshot();
                    _screenshot = false;
                }
                SDL.SDL_GL_SwapWindow(sdlWin);
                if (GL.FrameHadErrors()) //If there was a GL error, track it down.
                {
                    GL.ErrorChecking = true;
                }
                elapsed         = timer.Elapsed.TotalSeconds - last;
                renderFrequency = (1.0 / CalcAverageTick(elapsed));
                last            = timer.Elapsed.TotalSeconds;
                totalTime       = timer.Elapsed.TotalSeconds;
                if (elapsed < 0)
                {
                    elapsed = 0;
                    FLLog.Warning("Timing", "Stopwatch returned negative time!");
                }
            }
            Cleanup();
            SDL.SDL_Quit();
        }
Beispiel #3
0
        void NetworkThread()
        {
            var conf = new NetPeerConfiguration(NetConstants.DEFAULT_APP_IDENT);

            client = new NetClient(conf);
            client.Start();
            NetIncomingMessage im;

            while (running)
            {
                while ((im = client.ReadMessage()) != null)
                {
                    try
                    {
                        switch (im.MessageType)
                        {
                        case NetIncomingMessageType.DebugMessage:
                        case NetIncomingMessageType.ErrorMessage:
                        case NetIncomingMessageType.WarningMessage:
                        case NetIncomingMessageType.VerboseDebugMessage:
                            FLLog.Info("Lidgren", im.ReadString());
                            break;

                        case NetIncomingMessageType.DiscoveryResponse:
                            if (ServerFound != null)
                            {
                                var info = new LocalServerInfo();
                                info.EndPoint       = im.SenderEndPoint;
                                info.Name           = im.ReadString();
                                info.Description    = im.ReadString();
                                info.CurrentPlayers = im.ReadInt32();
                                info.MaxPlayers     = im.ReadInt32();
                                mainThread.QueueUIThread(() => ServerFound(info));
                            }
                            break;

                        case NetIncomingMessageType.StatusChanged:
                            var status = (NetConnectionStatus)im.ReadByte();
                            if (status == NetConnectionStatus.Disconnected)
                            {
                                connecting = false;
                                Disconnected(im.ReadString());
                            }
                            break;

                        case NetIncomingMessageType.Data:
                            var kind = (PacketKind)im.ReadByte();
                            if (connecting)
                            {
                                if (kind == PacketKind.Authentication)
                                {
                                    FLLog.Info("Net", "Authentication Packet Received");
                                    var authkind = (AuthenticationKind)im.ReadByte();
                                    if (authkind == AuthenticationKind.Token)
                                    {
                                        FLLog.Info("Net", "Token");
                                        AuthenticationRequired(im.ReadString());
                                    }
                                    else if (authkind == AuthenticationKind.GUID)
                                    {
                                        FLLog.Info("Net", "GUID");
                                        var response = client.CreateMessage();
                                        response.Write((byte)PacketKind.Authentication);
                                        response.Write((byte)AuthenticationKind.GUID);
                                        var arr = UUID.ToByteArray();
                                        foreach (var b in arr)
                                        {
                                            response.Write(b);
                                        }
                                        client.SendMessage(response, NetDeliveryMethod.ReliableOrdered);
                                    }
                                    else
                                    {
                                        client.Shutdown("Invalid Packet");
                                    }
                                }
                                else if (kind == PacketKind.AuthenticationSuccess)
                                {
                                    connecting = false;
                                    var inf = new CharacterSelectInfo();
                                    inf.ServerNews = im.ReadString();
                                    mainThread.QueueUIThread(() => CharacterSelection(inf));
                                }
                                else
                                {
                                    client.Shutdown("Invalid Packet");
                                }
                                break;
                            }
                            switch (kind)
                            {
                            case PacketKind.NewCharacter:

                                break;
                            }
                            break;
                        }
                    }
                    catch (Exception)
                    {
                        FLLog.Error("Net", "Error reading message of type " + im.MessageType.ToString());
                    }
                    client.Recycle(im);
                }
                Thread.Sleep(1);
            }
            FLLog.Info("Lidgren", "Client shutdown");
            client.Shutdown("Shutdown");
        }
Beispiel #4
0
        public void Process(ThnEvent ev, Cutscene cs)
        {
            ThnObject objA;
            ThnObject objB;

            if (!cs.Objects.TryGetValue((string)ev.Targets[0], out objA))
            {
                FLLog.Error("Thn", "Object doesn't exist " + (string)ev.Targets[0]);
                return;
            }
            if (!cs.Objects.TryGetValue((string)ev.Targets[1], out objB))
            {
                FLLog.Error("Thn", "Object doesn't exist " + (string)ev.Targets[1]);
                return;
            }
            var    targetType = ThnEnum.Check <TargetTypes>(ev.Properties["target_type"]);
            var    flags      = AttachFlags.Position | AttachFlags.Orientation;
            object tmp;

            if (ev.Properties.TryGetValue("flags", out tmp))
            {
                flags = ThnEnum.Check <AttachFlags>(tmp);
            }
            //Attach GameObjects to eachother
            GameObject part = null;
            string     tgt_part;

            ev.Properties.TryGetValue("target_part", out tmp);
            tgt_part = (tmp as string);
            if (targetType == TargetTypes.Hardpoint && !string.IsNullOrEmpty(tgt_part))
            {
                if (objB.Object == null)
                {
                    FLLog.Error("Thn", "Could not get hardpoints on " + objB.Name);
                }
                else
                {
                    part            = new GameObject();
                    part.Parent     = objB.Object;
                    part.Attachment = objB.Object.GetHardpoint(ev.Properties["target_part"].ToString());
                }
            }
            if (targetType == TargetTypes.Part && !string.IsNullOrEmpty(tgt_part))
            {
                if (objB.Object == null || objB.Object.CmpConstructs == null)
                {
                    FLLog.Error("Thn", "Could not get hardpoints on " + objB.Name);
                }
                else
                {
                    var hp = new Hardpoint(null,
                                           objB.Object.CmpConstructs.Find(ev.Properties["target_part"]
                                                                          .ToString())); //Create a dummy hardpoint to attach to
                    part            = new GameObject();
                    part.Parent     = objB.Object;
                    part.Attachment = hp;
                }
            }
            Vector3 offset = Vector3.Zero;

            if (ev.Properties.TryGetValue("offset", out tmp))
            {
                offset = ((LuaTable)tmp).ToVector3();
            }
            Quaternion lastRotate = Quaternion.Identity;

            if ((flags & AttachFlags.Orientation) == AttachFlags.Orientation &&
                (flags & AttachFlags.OrientationRelative) == AttachFlags.OrientationRelative)
            {
                if (part != null)
                {
                    lastRotate = part.GetTransform().ExtractRotation();
                }
                else
                {
                    lastRotate = objB.Rotate.ExtractRotation();
                }
            }
            cs.Coroutines.Add(new AttachRoutine()
            {
                Duration            = ev.Duration,
                Child               = objA,
                Parent              = objB,
                Part                = part,
                Position            = ((flags & AttachFlags.Position) == AttachFlags.Position),
                Orientation         = ((flags & AttachFlags.Orientation) == AttachFlags.Orientation),
                OrientationRelative = ((flags & AttachFlags.OrientationRelative) == AttachFlags.OrientationRelative),
                EntityRelative      = ((flags & AttachFlags.EntityRelative) == AttachFlags.EntityRelative),
                LookAt              = ((flags & AttachFlags.LookAt) == AttachFlags.LookAt),
                LastRotate          = lastRotate,
                Offset              = offset
            });
        }
Beispiel #5
0
        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 UpdateRTCPacket rtc:
                AddRTC(rtc.RTCs);
                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();
                AddRTC(b.RTCs);
                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;
            }
        }
Beispiel #6
0
        public void HandlePacket(IPacket pkt)
        {
            switch (pkt)
            {
            case SpawnPlayerPacket p:
                PlayerBase        = null;
                PlayerSystem      = p.System;
                PlayerPosition    = p.Position;
                PlayerOrientation = Matrix3.CreateFromQuaternion(p.Orientation);
                SetSelfLoadout(p.Ship);
                Start();
                break;

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

            case SpawnObjectPacket p:
                var shp = Game.GameData.GetShip((int)p.Loadout.ShipCRC);
                shp.LoadResources();
                //Set up player object + camera
                var newobj = new GameObject(shp, Game.ResourceManager);
                newobj.Name      = "NetPlayer " + p.ID;
                newobj.Transform = Matrix4.CreateFromQuaternion(p.Orientation) *
                                   Matrix4.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;
            }
        }
Beispiel #7
0
        void FinishLoad()
        {
            var shp = Game.GameData.GetShip(session.PlayerShip);

            //Set up player object + camera
            player       = new GameObject(shp.ModelFile.LoadFile(Game.ResourceManager), Game.ResourceManager, true, false);
            control      = new ShipPhysicsComponent(player);
            control.Ship = shp;
            shipInput    = new ShipInputComponent(player);
            player.Components.Add(shipInput);
            player.Components.Add(control);
            weapons = new WeaponControlComponent(player);
            player.Components.Add(weapons);
            player.Transform             = session.PlayerOrientation * Matrix4x4.CreateTranslation(session.PlayerPosition);
            player.PhysicsComponent.Mass = shp.Mass;
            if (shp.Mass < 0)
            {
                FLLog.Error("Ship", "Mass < 0");
            }
            player.Nickname = "player";
            foreach (var equipment in session.Mounts)
            {
                var equip = Game.GameData.GetEquipment(equipment.Item);
                if (equip == null)
                {
                    continue;
                }
                EquipmentObjectManager.InstantiateEquipment(player, Game.ResourceManager, true, equipment.Hardpoint, equip);
            }
            powerCore = player.GetComponent <PowerCoreComponent>();
            if (powerCore == null)
            {
                throw new Exception("Player launched without a powercore equipped!");
            }
            camera = new ChaseCamera(Game.Viewport);
            camera.ChasePosition    = session.PlayerPosition;
            camera.ChaseOrientation = player.Transform.ClearTranslation();
            var offset = shp.ChaseOffset;

            camera.DesiredPositionOffset = offset;
            if (shp.CameraHorizontalTurnAngle > 0)
            {
                camera.HorizontalTurnAngle = shp.CameraHorizontalTurnAngle;
            }
            if (shp.CameraVerticalTurnUpAngle > 0)
            {
                camera.VerticalTurnUpAngle = shp.CameraVerticalTurnUpAngle;
            }
            if (shp.CameraVerticalTurnDownAngle > 0)
            {
                camera.VerticalTurnDownAngle = shp.CameraVerticalTurnDownAngle;
            }
            camera.Reset();

            sysrender = new SystemRenderer(camera, Game.GameData, Game.ResourceManager, Game);
            world     = new GameWorld(sysrender);
            world.LoadSystem(sys, Game.ResourceManager);
            session.WorldReady();
            player.World = world;
            world.Objects.Add(player);
            world.RenderUpdate  += World_RenderUpdate;
            world.PhysicsUpdate += World_PhysicsUpdate;
            player.Register(world.Physics);
            Game.Sound.PlayMusic(sys.MusicSpace);
            debugphysics = new PhysicsDebugRenderer();
            //world.Physics.EnableWireframes(debugphysics);
            cur_arrow                = Game.ResourceManager.GetCursor("cross");
            cur_reticle              = Game.ResourceManager.GetCursor("fire_neutral");
            current_cur              = cur_arrow;
            Game.Keyboard.TextInput += Game_TextInput;
            Game.Keyboard.KeyDown   += Keyboard_KeyDown;
            Game.Mouse.MouseDown    += Mouse_MouseDown;
            input = new InputManager(Game);
            input.ToggleActivated       += Input_ToggleActivated;
            input.ToggleUp              += Input_ToggleUp;
            pilotcomponent               = new AutopilotComponent(player);
            pilotcomponent.DockComplete += Pilotcomponent_DockComplete;
            player.Components.Add(pilotcomponent);
            player.World              = world;
            world.MessageBroadcasted += World_MessageBroadcasted;
            Game.Sound.ResetListenerVelocity();
            FadeIn(0.5, 0.5);
        }
Beispiel #8
0
        public void Run()
        {
            SSEMath.Load();
            if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0)
            {
                FLLog.Error("SDL", "SDL_Init failed, exiting.");
                return;
            }
            SDL.SDL_SetHint(SDL.SDL_HINT_IME_INTERNAL_EDITING, "1");
            SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
            //Set GL states
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 2);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 24);
            //Create Window
            var flags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;

            if (fullscreen)
            {
                flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
            }
            var sdlWin = SDL.SDL_CreateWindow(
                "LibreLancer",
                SDL.SDL_WINDOWPOS_CENTERED,
                SDL.SDL_WINDOWPOS_CENTERED,
                width,
                height,
                flags
                );

            if (minWindowSize != Point.Zero)
            {
                SDL.SDL_SetWindowMinimumSize(sdlWin, minWindowSize.X, minWindowSize.Y);
            }
            if (sdlWin == IntPtr.Zero)
            {
                FLLog.Error("SDL", "Failed to create window, exiting.");
                return;
            }
            windowptr = sdlWin;
            if (forceANGLE)
            {
                LoadANGLE();
            }
            else
            {
                var  glcontext = SDL.SDL_GL_CreateContext(sdlWin);
                bool check     = GL.CheckStringSDL();
                if (!check)
                {
                    FLLog.Warning("GL", "GL Version Insufficient - Using DX9");
                    SDL.SDL_GL_DeleteContext(glcontext);
                }
                if (glcontext == IntPtr.Zero || !check)
                {
                    if (Platform.RunningOS == OS.Windows)
                    {
                        LoadANGLE();
                    }
                    else
                    {
                        FLLog.Error("OpenGL", "Failed to create OpenGL context, exiting.");
                        return;
                    }
                }
                else
                {
                    GL.LoadSDL();
                    Renderer = string.Format("{0} ({1})", GL.GetString(GL.GL_VERSION), GL.GetString(GL.GL_RENDERER));
                }
            }
            SetVSync(true);
            //Init game state
            RenderState = new RenderState();
            Load();
            //Start game
            running = true;
            var timer = new Stopwatch();

            timer.Start();
            double last    = 0;
            double elapsed = 0;

            SDL.SDL_Event e;
            SDL.SDL_StopTextInput();
            while (running)
            {
                //Pump message queue
                while (SDL.SDL_PollEvent(out e) != 0)
                {
                    switch (e.type)
                    {
                    case SDL.SDL_EventType.SDL_QUIT:
                    {
                        if (WillClose != null)
                        {
                            WillClose();
                        }
                        running = false;                                 //TODO: Raise Event
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEMOTION:
                    {
                        Mouse.X = e.motion.x;
                        Mouse.Y = e.motion.y;
                        Mouse.OnMouseMove();
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        Mouse.Buttons |= btn;
                        Mouse.OnMouseDown(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        Mouse.Buttons &= ~btn;
                        Mouse.OnMouseUp(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEWHEEL:
                    {
                        Mouse.OnMouseWheel(e.wheel.y);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_TEXTINPUT:
                    {
                        Keyboard.OnTextInput(GetEventText(ref e));
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYDOWN:
                    {
                        Keyboard.OnKeyDown((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod, e.key.repeat != 0);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYUP:
                    {
                        Keyboard.OnKeyUp((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_WINDOWEVENT:
                        if (e.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
                        {
                            SDL.SDL_GetWindowSize(windowptr, out width, out height);
                        }
                        break;
                    }
                }

                //Do game things
                if (!running)
                {
                    break;
                }
                Action work;
                while (actions.TryDequeue(out work))
                {
                    work();
                }
                totalTime = timer.Elapsed.TotalSeconds;
                Update(elapsed);
                if (!running)
                {
                    break;
                }
                Draw(elapsed);
                //Frame time before, FPS after
                var tk = timer.Elapsed.TotalSeconds - totalTime;
                frameTime = CalcAverageTime(tk);
                if (_screenshot)
                {
                    TakeScreenshot();
                    _screenshot = false;
                }
                if (angle != null)
                {
                    angle.SwapBuffers();
                }
                else
                {
                    SDL.SDL_GL_SwapWindow(sdlWin);
                }
                if (GL.FrameHadErrors())                  //If there was a GL error, track it down.
                {
                    GL.ErrorChecking = true;
                }
                elapsed         = timer.Elapsed.TotalSeconds - last;
                renderFrequency = (1.0 / CalcAverageTick(elapsed));
                last            = timer.Elapsed.TotalSeconds;
                totalTime       = timer.Elapsed.TotalSeconds;
                if (elapsed < 0)
                {
                    elapsed = 0;
                    FLLog.Warning("Timing", "Stopwatch returned negative time!");
                }
            }
            Cleanup();
            SDL.SDL_Quit();
        }
        void AddAsteroidToBuffer(StaticAsteroid ast, Material mat, bool singleMat)
        {
            var model = (ModelFile)ast.Drawable.LoadFile(sys.ResourceManager);

            model.Initialize(sys.ResourceManager);
            var l0        = model.Levels[0];
            var vertType  = l0.Mesh.VertexBuffer.VertexType.GetType();
            var transform = ast.RotationMatrix * Matrix4x4.CreateTranslation(ast.Position * field.CubeSize);
            var norm      = transform;

            Matrix4x4.Invert(norm, out norm);
            norm = Matrix4x4.Transpose(norm);
            int vertOffset = verts.Count;

            for (int i = 0; i < l0.Mesh.VertexCount; i++)
            {
                VertexPositionNormalDiffuseTexture vert;
                if (vertType == typeof(VertexPositionNormalDiffuseTexture))
                {
                    vert = l0.Mesh.verticesVertexPositionNormalDiffuseTexture[i];
                }
                else if (vertType == typeof(VertexPositionNormalTexture))
                {
                    var v = l0.Mesh.verticesVertexPositionNormalTexture[i];
                    vert = new VertexPositionNormalDiffuseTexture(
                        v.Position,
                        v.Normal,
                        (uint)Color4.White.ToAbgr(),
                        v.TextureCoordinate);
                }
                else if (vertType == typeof(VertexPositionNormalTextureTwo))
                {
                    var v = l0.Mesh.verticesVertexPositionNormalTextureTwo[i];
                    vert = new VertexPositionNormalDiffuseTexture(
                        v.Position,
                        v.Normal,
                        (uint)Color4.White.ToAbgr(),
                        v.TextureCoordinate);
                }
                else if (vertType == typeof(VertexPositionNormalDiffuseTextureTwo))
                {
                    var v = l0.Mesh.verticesVertexPositionNormalDiffuseTextureTwo[i];
                    vert = new VertexPositionNormalDiffuseTexture(
                        v.Position,
                        v.Normal,
                        v.Diffuse,
                        v.TextureCoordinate);
                }
                else
                {
                    FLLog.Error("Render", "Asteroids: " + vertType.FullName + " not support");
                    return;
                }
                vert.Position = Vector3.Transform(vert.Position, transform);
                cubeRadius    = Math.Max(cubeRadius, vert.Position.Length());
                vert.Normal   = Vector3.TransformNormal(vert.Normal, norm);
                verts.Add(vert);
            }
            for (int i = l0.StartMesh; i < l0.StartMesh + l0.MeshCount; i++)
            {
                var m = l0.Mesh.Meshes[i];
                if (m.Material != mat && !singleMat)
                {
                    continue;
                }
                var baseVertex = vertOffset + l0.StartVertex + m.StartVertex;
                int indexStart = m.TriangleStart;
                int indexCount = m.NumRefVertices;
                for (int j = indexStart; j < indexStart + indexCount; j++)
                {
                    var idx = baseVertex + l0.Mesh.Indices[j];
                    if (idx > ushort.MaxValue)
                    {
                        throw new Exception();
                    }
                    indices.Add((ushort)idx);
                }
            }
        }
Beispiel #10
0
        void NetworkThread()
        {
            sw = Stopwatch.StartNew();
            var listener = new EventBasedNetListener();

            client = new NetManager(listener)
            {
                UnconnectedMessagesEnabled = true,
                IPv6Mode         = IPv6Mode.SeparateSocket,
                NatPunchEnabled  = true,
                EnableStatistics = true,
                ChannelsCount    = 3
            };
            listener.NetworkReceiveUnconnectedEvent += (remote, msg, type) =>
            {
                if (type == UnconnectedMessageType.Broadcast)
                {
                    return;
                }
                if (msg.GetInt() == 0)
                {
                    lock (srvinfo)
                    {
                        foreach (var info in srvinfo)
                        {
                            if (info.EndPoint.Equals(remote))
                            {
                                var t = sw.ElapsedMilliseconds;
                                info.Ping = (int)(t - info.LastPingTime);
                                if (info.Ping < 0)
                                {
                                    info.Ping = 0;
                                }
                            }
                        }
                    }
                }
                else if (ServerFound != null)
                {
                    var info = new LocalServerInfo();
                    info.EndPoint       = remote;
                    info.Unique         = msg.GetInt();
                    info.Name           = msg.GetString();
                    info.Description    = msg.GetString();
                    info.DataVersion    = msg.GetString();
                    info.CurrentPlayers = msg.GetInt();
                    info.MaxPlayers     = msg.GetInt();
                    info.LastPingTime   = sw.ElapsedMilliseconds;
                    NetDataWriter writer = new NetDataWriter();
                    writer.Put(LNetConst.PING_MAGIC);
                    client.SendUnconnectedMessage(writer, remote);
                    lock (srvinfo)
                    {
                        bool add = true;
                        for (int i = 0; i < srvinfo.Count; i++)
                        {
                            if (srvinfo[i].Unique == info.Unique)
                            {
                                add = false;
                                //Prefer IPv6
                                if (srvinfo[i].EndPoint.AddressFamily != AddressFamily.InterNetwork &&
                                    info.EndPoint.AddressFamily == AddressFamily.InterNetwork)
                                {
                                    srvinfo[i].EndPoint = info.EndPoint;
                                }
                                break;
                            }
                        }
                        if (add)
                        {
                            srvinfo.Add(info);
                            mainThread.QueueUIThread(() => ServerFound?.Invoke(info));
                        }
                    }
                }
                msg.Recycle();
            };
            listener.NetworkReceiveEvent += (peer, reader, channel, method) =>
            {
#if !DEBUG
                try
                {
#endif
                var packetCount = reader.GetByte();     //reliable packets can be merged
                if (packetCount > 1)
                {
                    FLLog.Debug("Net", $"Received {packetCount} merged packets");
                }
                for (int i = 0; i < packetCount; i++)
                {
                    var pkt = Packets.Read(reader);
                    if (connecting)
                    {
                        if (pkt is AuthenticationPacket)
                        {
                            var auth = (AuthenticationPacket)pkt;
                            FLLog.Info("Net", "Authentication Packet Received");
                            if (auth.Type == AuthenticationKind.Token)
                            {
                                FLLog.Info("Net", "Token");
                                var str = reader.GetString();
                                mainThread.QueueUIThread(() => AuthenticationRequired(str));
                            }
                            else if (auth.Type == AuthenticationKind.GUID)
                            {
                                FLLog.Info("Net", "GUID");
                                SendPacket(new AuthenticationReplyPacket()
                                {
                                    Guid = this.UUID
                                },
                                           PacketDeliveryMethod.ReliableOrdered);
                            }
                        }
                        else if (pkt is LoginSuccessPacket)
                        {
                            FLLog.Info("Client", "Login success");
                            connecting = false;
                        }
                        else
                        {
                            client.DisconnectAll();
                        }
                    }
                    else
                    {
                        packets.Enqueue(pkt);
                    }
                }
#if !DEBUG
            }

            catch (Exception e)
            {
                FLLog.Error("Client", "Error reading packet");
                client.DisconnectAll();
            }
#endif
            };
            listener.PeerDisconnectedEvent += (peer, info) =>
            {
                mainThread.QueueUIThread(() => { Disconnected?.Invoke(info.Reason.ToString()); });
            };
            client.Start();
            while (running)
            {
                if (Interlocked.Read(ref localPeerRequests) > 0)
                {
                    Interlocked.Decrement(ref localPeerRequests);
                    var dw = new NetDataWriter();
                    dw.Put(LNetConst.BROADCAST_KEY);
                    client.SendBroadcast(dw, LNetConst.DEFAULT_PORT);
                }
                //ping servers
                lock (srvinfo)
                {
                    foreach (var inf in srvinfo)
                    {
                        var nowMs = sw.ElapsedMilliseconds;
                        if (nowMs - inf.LastPingTime > 2000) //ping every 2 seconds?
                        {
                            inf.LastPingTime = nowMs;
                            var om = new NetDataWriter();
                            om.Put(LNetConst.PING_MAGIC);
                            client.SendUnconnectedMessage(om, inf.EndPoint);
                        }
                    }
                }
                //events
                client.PollEvents();
                Thread.Sleep(1);
            }
            client.DisconnectAll();
            client.Stop();
        }
Beispiel #11
0
        public Task <ShipPurchaseStatus> PurchaseShip(int package, MountId[] mountedPlayer, MountId[] mountedPackage, SellCount[] sellPlayer,
                                                      SellCount[] sellPackage)
        {
            var b        = Game.GameData.GetBase(Base);
            var resolved = Game.GameData.GetShipPackage((uint)package);

            if (resolved == null)
            {
                return(Task.FromResult(ShipPurchaseStatus.Fail));
            }
            if (b.SoldShips.All(x => x.Package != resolved))
            {
                FLLog.Error("Player", $"{Name} tried to purchase ship package not available on base");
                return(Task.FromResult(ShipPurchaseStatus.Fail));
            }
            var included = new List <PackageAddon>();

            foreach (var a in resolved.Addons)
            {
                included.Add(new PackageAddon()
                {
                    Equipment = a.Equipment, Amount = a.Amount
                });
            }
            long shipPrice = resolved.BasePrice;

            //Sell included Items
            foreach (var item in sellPackage)
            {
                var a = included[item.ID];
                if (a == null)
                {
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                if (item.Count > a.Amount)
                {
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                var price = GetUnitPrice(a.Equipment);
                shipPrice -= (long)price * item.Count;
                a.Amount  -= item.Count;
                if (a.Amount <= 0)
                {
                    included[item.ID] = null;
                }
            }
            if (shipPrice < 0)
            {
                shipPrice = 0;
            }
            //Deduct ship worth
            shipPrice -= (long)GetShipWorth();
            //Add price of rest of items
            foreach (var a in included)
            {
                if (a == null)
                {
                    continue;
                }
                var price = GetUnitPrice(a.Equipment);
                shipPrice += (long)price * a.Amount;
            }
            Dictionary <int, int> counts = new Dictionary <int, int>();

            //Calculate player items price
            foreach (var item in sellPlayer)
            {
                var slot = Character.Items.FirstOrDefault(x => x.ID == item.ID);
                if (slot == null)
                {
                    FLLog.Error("Player", $"{Name} tried to sell unknown slot {item.ID}");
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                if (!counts.TryGetValue(slot.ID, out int count))
                {
                    counts[slot.ID] = slot.Count;
                }
                if (count < item.Count)
                {
                    FLLog.Error("Player", $"{Name} tried to oversell slot");
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                var price = GetUnitPrice(slot.Equipment);
                if (slot.Equipment is not CommodityEquipment)
                {
                    price = (ulong)(price * TradeConstants.EQUIP_RESALE_MULTIPLIER);
                }
                shipPrice      -= (long)price * item.Count;
                counts[slot.ID] = (count - item.Count);
            }
            //Check if we have credits
            if (shipPrice > Character.Credits)
            {
                FLLog.Error("Player", $"{Name} does not have enough credits");
                return(Task.FromResult(ShipPurchaseStatus.Fail));
            }
            //Check that all mounts are valid
            HashSet <int>    mountedP       = new HashSet <int>();
            HashSet <int>    mountedInc     = new HashSet <int>();
            HashSet <string> usedHardpoints = new HashSet <string>();

            foreach (var item in mountedPackage)
            {
                if (included[item.ID] == null)
                {
                    FLLog.Error("Player", $"{Name} tried to mount sold item");
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                var hp = item.Hardpoint.ToLowerInvariant();
                if (mountedInc.Contains(item.ID))
                {
                    FLLog.Error("Player", $"{Name} tried to mount from package twice");
                    mountedInc.Add(item.ID);
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                if (hp != "internal" && usedHardpoints.Contains(hp))
                {
                    FLLog.Error("Player", $"{Name} tried to mount to hardpoint {hp} twice");
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                if (hp != "internal")
                {
                    usedHardpoints.Add(hp);
                }
            }
            foreach (var item in mountedPlayer)
            {
                var slot = Character.Items.FirstOrDefault(x => x.ID == item.ID);
                if (slot == null)
                {
                    FLLog.Error("Player", $"{Name} tried to mount non-existant item");
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                if (counts.TryGetValue(item.ID, out var nc) && nc == 0)
                {
                    FLLog.Error("Player", $"{Name} tried to mount sold item");
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                var hp = item.Hardpoint.ToLowerInvariant();
                if (mountedP.Contains(item.ID))
                {
                    FLLog.Error("Player", $"{Name} tried to mount item twice");
                    mountedP.Add(item.ID);
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                if (hp != "internal" && usedHardpoints.Contains(hp))
                {
                    FLLog.Error("Player", $"{Name} tried to mount to hardpoint {hp} twice");
                    return(Task.FromResult(ShipPurchaseStatus.Fail));
                }
                if (hp != "internal")
                {
                    usedHardpoints.Add(hp);
                }
            }
            //Remove sold items
            foreach (var item in counts)
            {
                var slot = Character.Items.FirstOrDefault(x => x.ID == item.Key);
                Character.RemoveCargo(slot, slot.Count - item.Value);
            }
            //Unmount items and remove items without a good
            List <NetCargo> toRemove = new List <NetCargo>();

            foreach (var item in Character.Items)
            {
                item.Hardpoint = null;
                if (item.DbItem != null)
                {
                    item.DbItem.Hardpoint = null;
                }
                if (item.Equipment.Good == null)
                {
                    toRemove.Add(item);
                }
            }
            foreach (var item in toRemove)
            {
                Character.RemoveCargo(item, item.Count);
            }
            //Set Ship
            Character.SetShip(Game.GameData.GetShip(resolved.Ship));
            //Install new cargo and mount
            foreach (var item in mountedPlayer)
            {
                var slot = Character.Items.FirstOrDefault(x => x.ID == item.ID);
                slot.Hardpoint = item.Hardpoint;
                if (slot.DbItem != null)
                {
                    slot.DbItem.Hardpoint = item.Hardpoint;
                }
            }
            foreach (var item in mountedPackage)
            {
                var inc = included[item.ID];
                Character.AddCargo(inc.Equipment, item.Hardpoint, inc.Amount);
                included[item.ID] = null;
            }
            foreach (var item in included)
            {
                if (item == null)
                {
                    continue;
                }
                Character.AddCargo(item.Equipment, item.Equipment.Good == null ? item.Hardpoint : null, item.Amount);
            }
            Character.UpdateCredits(Character.Credits - shipPrice);
            rpcClient.UpdateInventory(Character.Credits, GetShipWorth(), Character.EncodeLoadout());
            //Success
            return(Task.FromResult(shipPrice < 0 ? ShipPurchaseStatus.SuccessGainCredits : ShipPurchaseStatus.Success));
        }
Beispiel #12
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;
            }
        }
Beispiel #13
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 = objA.Translate;
                        objA.Rotate    = objA.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 = 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,
                            AxisRot  = axisRotation
                        });
                    }
                }
            }
        }
Beispiel #14
0
        public GameData.Nebula GetNebula(GameData.StarSystem sys, Legacy.Universe.Nebula nbl)
        {
            var n = new GameData.Nebula();

            n.Zone = sys.Zones.Where((z) => z.Nickname.ToLower() == nbl.ZoneName.ToLower()).First();
            var panels = new Legacy.Universe.TexturePanels(nbl.TexturePanels.Files[0]);

            foreach (var txmfile in panels.Files)
            {
                resource.LoadResourceFile(Compatibility.VFS.GetPath(fldata.Freelancer.DataPath + txmfile));
            }
            n.ExteriorFill        = nbl.ExteriorFillShape;
            n.ExteriorColor       = nbl.ExteriorColor ?? Color4.White;
            n.FogColor            = nbl.FogColor ?? Color4.Black;
            n.FogEnabled          = (nbl.FogEnabled ?? 0) != 0;
            n.FogRange            = new Vector2(nbl.FogNear ?? 0, nbl.FogDistance ?? 0);
            n.SunBurnthroughScale = n.SunBurnthroughIntensity = 1f;
            if (nbl.NebulaLights != null && nbl.NebulaLights.Count > 0)
            {
                n.AmbientColor            = nbl.NebulaLights[0].Ambient;
                n.SunBurnthroughScale     = nbl.NebulaLights[0].SunBurnthroughScaler ?? 1f;
                n.SunBurnthroughIntensity = nbl.NebulaLights[0].SunBurnthroughIntensity ?? 1f;
            }
            if (nbl.CloudsPuffShape != null)
            {
                n.HasInteriorClouds = true;
                GameData.CloudShape[] shapes = new GameData.CloudShape[nbl.CloudsPuffShape.Count];
                for (int i = 0; i < shapes.Length; i++)
                {
                    var name = nbl.CloudsPuffShape[i];
                    if (!panels.Shapes.ContainsKey(name))
                    {
                        FLLog.Error("Nebula", "Shape " + name + " does not exist in " + nbl.TexturePanels.Files[0]);
                        shapes[i].Texture    = ResourceManager.NullTextureName;
                        shapes[i].Dimensions = new RectangleF(0, 0, 1, 1);
                    }
                    else
                    {
                        shapes[i].Texture    = panels.Shapes[name].TextureName;
                        shapes[i].Dimensions = panels.Shapes[name].Dimensions;
                    }
                }
                n.InteriorCloudShapes = new WeightedRandomCollection <GameData.CloudShape>(
                    shapes,
                    nbl.CloudsPuffWeights.ToArray()
                    );
                n.InteriorCloudColorA       = nbl.CloudsPuffColorA.Value;
                n.InteriorCloudColorB       = nbl.CloudsPuffColorB.Value;
                n.InteriorCloudRadius       = nbl.CloudsPuffRadius.Value;
                n.InteriorCloudCount        = nbl.CloudsPuffCount.Value;
                n.InteriorCloudMaxDistance  = nbl.CloudsMaxDistance.Value;
                n.InteriorCloudMaxAlpha     = nbl.CloudsPuffMaxAlpha ?? 1f;
                n.InteriorCloudFadeDistance = nbl.CloudsNearFadeDistance.Value;
                n.InteriorCloudDrift        = nbl.CloudsPuffDrift.Value;
            }
            if (nbl.ExteriorShape != null)
            {
                n.HasExteriorBits = true;
                GameData.CloudShape[] shapes = new GameData.CloudShape[nbl.ExteriorShape.Count];
                for (int i = 0; i < shapes.Length; i++)
                {
                    var name = nbl.ExteriorShape[i];
                    if (!panels.Shapes.ContainsKey(name))
                    {
                        FLLog.Error("Nebula", "Shape " + name + " does not exist in " + nbl.TexturePanels.Files[0]);
                        shapes[i].Texture    = ResourceManager.NullTextureName;
                        shapes[i].Dimensions = new RectangleF(0, 0, 1, 1);
                    }
                    else
                    {
                        shapes[i].Texture    = panels.Shapes[name].TextureName;
                        shapes[i].Dimensions = panels.Shapes[name].Dimensions;
                    }
                }
                n.ExteriorCloudShapes = new WeightedRandomCollection <GameData.CloudShape>(
                    shapes,
                    nbl.ExteriorShapeWeights.ToArray()
                    );
                n.ExteriorMinBits            = nbl.ExteriorMinBits.Value;
                n.ExteriorMaxBits            = nbl.ExteriorMaxBits.Value;
                n.ExteriorBitRadius          = nbl.ExteriorBitRadius.Value;
                n.ExteriorBitRandomVariation = nbl.ExteriorBitRadiusRandomVariation ?? 0;
                n.ExteriorMoveBitPercent     = nbl.ExteriorMoveBitPercent ?? 0;
            }
            if (nbl.ExclusionZones != null)
            {
                n.ExclusionZones = new List <GameData.ExclusionZone>();
                foreach (var excz in nbl.ExclusionZones)
                {
                    if (excz.Exclusion == null)
                    {
                        continue;
                    }
                    var e = new GameData.ExclusionZone();
                    e.Zone   = sys.Zones.Where((z) => z.Nickname.ToLower() == excz.Exclusion.Nickname.ToLower()).First();
                    e.FogFar = excz.FogFar ?? n.FogRange.Y;
                    if (excz.ZoneShellPath != null)
                    {
                        var pth = Compatibility.VFS.GetPath(fldata.Freelancer.DataPath + excz.ZoneShellPath);
                        e.Shell         = resource.GetDrawable(pth);
                        e.ShellTint     = excz.Tint ?? Color3f.White;
                        e.ShellScalar   = excz.ShellScalar ?? 1f;
                        e.ShellMaxAlpha = excz.MaxAlpha ?? 1f;
                    }
                    n.ExclusionZones.Add(e);
                }
            }
            if (nbl.BackgroundLightningDuration != null)
            {
                n.BackgroundLightning         = true;
                n.BackgroundLightningDuration = nbl.BackgroundLightningDuration.Value;
                n.BackgroundLightningColor    = nbl.BackgroundLightningColor.Value;
                n.BackgroundLightningGap      = nbl.BackgroundLightningGap.Value;
            }
            if (nbl.DynamicLightningDuration != null)
            {
                n.DynamicLightning         = true;
                n.DynamicLightningGap      = nbl.DynamicLightningGap.Value;
                n.DynamicLightningColor    = nbl.DynamicLightningColor.Value;
                n.DynamicLightningDuration = nbl.DynamicLightningDuration.Value;
            }
            if (nbl.CloudsLightningDuration != null)
            {
                n.CloudLightning          = true;
                n.CloudLightningDuration  = nbl.CloudsLightningDuration.Value;
                n.CloudLightningColor     = nbl.CloudsLightningColor.Value;
                n.CloudLightningGap       = nbl.CloudsLightningGap.Value;
                n.CloudLightningIntensity = nbl.CloudsLightningIntensity.Value;
            }
            return(n);
        }
Beispiel #15
0
        public GameData.StarSystem GetSystem(string id)
        {
            var legacy = fldata.Universe.FindSystem(id);

            if (fldata.Stars != null)
            {
                foreach (var txmfile in fldata.Stars.TextureFiles)
                {
                    resource.LoadResourceFile(Compatibility.VFS.GetPath(fldata.Freelancer.DataPath + txmfile));
                }
            }
            var sys = new GameData.StarSystem();

            sys.AmbientColor    = legacy.AmbientColor ?? Color4.White;
            sys.Name            = legacy.StridName;
            sys.Id              = legacy.Nickname;
            sys.BackgroundColor = legacy.SpaceColor ?? Color4.Black;
            sys.MusicSpace      = legacy.MusicSpace;
            sys.FarClip         = legacy.SpaceFarClip ?? 20000f;
            if (legacy.BackgroundBasicStarsPath != null)
            {
                try {
                    sys.StarsBasic = resource.GetDrawable(legacy.BackgroundBasicStarsPath);
                } catch (Exception) {
                    sys.StarsBasic = null;
                    FLLog.Error("System", "Failed to load starsphere " + legacy.BackgroundBasicStarsPath);
                }
            }

            if (legacy.BackgroundComplexStarsPath != null)
            {
                try {
                    sys.StarsComplex = resource.GetDrawable(legacy.BackgroundComplexStarsPath);
                } catch (Exception) {
                    sys.StarsComplex = null;
                    FLLog.Error("System", "Failed to load starsphere " + legacy.BackgroundComplexStarsPath);
                }
            }

            if (legacy.BackgroundNebulaePath != null)
            {
                try {
                    sys.StarsNebula = resource.GetDrawable(legacy.BackgroundNebulaePath);
                } catch (Exception) {
                    sys.StarsNebula = null;
                    FLLog.Error("System", "Failed to load starsphere " + legacy.BackgroundNebulaePath);
                }
            }

            if (legacy.LightSources != null)
            {
                foreach (var src in legacy.LightSources)
                {
                    var lt = new RenderLight();
                    lt.Color       = src.Color.Value;
                    lt.Position    = src.Pos.Value;
                    lt.Range       = src.Range.Value;
                    lt.Direction   = src.Direction ?? new Vector3(0, 0, 1);
                    lt.Kind        = ((src.Type ?? Legacy.Universe.LightType.Point) == Legacy.Universe.LightType.Point) ? LightKind.Point : LightKind.Directional;
                    lt.Attenuation = src.Attenuation ?? Vector3.UnitY;
                    if (src.AttenCurve != null)
                    {
                        lt.Kind        = LightKind.PointAttenCurve;
                        lt.Attenuation = ApproximateCurve.GetQuadraticFunction(
                            fldata.Graphs.FindFloatGraph(src.AttenCurve).Points.ToArray()
                            );
                    }
                    sys.LightSources.Add(lt);
                }
            }
            foreach (var obj in legacy.Objects)
            {
                sys.Objects.Add(GetSystemObject(obj));
            }
            if (legacy.Zones != null)
            {
                foreach (var zne in legacy.Zones)
                {
                    var z = new GameData.Zone();
                    z.Nickname     = zne.Nickname;
                    z.EdgeFraction = zne.EdgeFraction ?? 0.25f;
                    z.Position     = zne.Pos.Value;
                    if (zne.Rotate != null)
                    {
                        var r = zne.Rotate.Value;

                        var qx = Quaternion.FromEulerAngles(
                            MathHelper.DegreesToRadians(r.X),
                            MathHelper.DegreesToRadians(r.Y),
                            MathHelper.DegreesToRadians(r.Z)
                            );
                        z.RotationMatrix = Matrix4.CreateFromQuaternion(qx);
                        z.RotationAngles = new Vector3(
                            MathHelper.DegreesToRadians(r.X),
                            MathHelper.DegreesToRadians(r.Y),
                            MathHelper.DegreesToRadians(r.Z)
                            );
                    }
                    else
                    {
                        z.RotationMatrix = Matrix4.Identity;
                        z.RotationAngles = Vector3.Zero;
                    }
                    switch (zne.Shape.Value)
                    {
                    case Legacy.Universe.ZoneShape.ELLIPSOID:
                        z.Shape = new GameData.ZoneEllipsoid(z,
                                                             zne.Size.Value.X,
                                                             zne.Size.Value.Y,
                                                             zne.Size.Value.Z
                                                             );
                        break;

                    case Legacy.Universe.ZoneShape.SPHERE:
                        z.Shape = new GameData.ZoneSphere(z,
                                                          zne.Size.Value.X
                                                          );
                        break;

                    case Legacy.Universe.ZoneShape.BOX:
                        z.Shape = new GameData.ZoneBox(z,
                                                       zne.Size.Value.X,
                                                       zne.Size.Value.Y,
                                                       zne.Size.Value.Z
                                                       );
                        break;

                    case Legacy.Universe.ZoneShape.CYLINDER:
                        z.Shape = new GameData.ZoneCylinder(z,
                                                            zne.Size.Value.X,
                                                            zne.Size.Value.Y
                                                            );
                        break;

                    case Legacy.Universe.ZoneShape.RING:
                        z.Shape = new GameData.ZoneRing(z,
                                                        zne.Size.Value.X,
                                                        zne.Size.Value.Y,
                                                        zne.Size.Value.Z
                                                        );
                        break;

                    default:
                        Console.WriteLine(zne.Nickname);
                        Console.WriteLine(zne.Shape.Value);
                        throw new NotImplementedException();
                    }
                    sys.Zones.Add(z);
                }
            }
            if (legacy.Asteroids != null)
            {
                foreach (var ast in legacy.Asteroids)
                {
                    sys.AsteroidFields.Add(GetAsteroidField(sys, ast));
                }
            }

            if (legacy.Nebulae != null)
            {
                foreach (var nbl in legacy.Nebulae)
                {
                    sys.Nebulae.Add(GetNebula(sys, nbl));
                }
            }
            return(sys);
        }