Jump to content

Mount crashes


Recommended Posts

I really cannot understand why is my mountable entity crashing. I have copied most of code from bed block entity, the difference is that my entity is EntityAgent and not BlockEntity, and that it does not have any sleep-related code. Just trying to make player mount an entity, no other functionality at this moment.

Main class:

Spoiler
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vintagestory.API.Common;
using Vintagestory.API.Client;
using Vintagestory.API.Server;
using Vintagestory.GameContent;
using ProtoBuf;
using Vintagestory.API.Datastructures;
using Vintagestory.API.MathTools;

namespace aeronautics.src
{

    [ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
    public class ControlMessage
    {
        public string message;
    }

    public class Main : ModSystem
    {
        #region Client
        public static void BalloonControl(IClientPlayer player, ICoreClientAPI api, IClientNetworkChannel ch)
        {
            /* PgUp is hardcoded to switch burner on. */
            if (api.Input.KeyboardKeyStateRaw[((int)GlKeys.PageUp)])
            {
                if (player.Entity.MountedOn != null && player.Entity.MountedOn.GetType() == typeof(HotAirBalloon))
                {
                    /* Turning on balloon burner on server */
                    ch.SendPacket(new ControlMessage()
                    {
                        message = "ON"
                    });
                }
            }

            /* PgDown is hardcoded to switch burner off.*/
            if (api.Input.KeyboardKeyStateRaw[((int)GlKeys.PageDown)])
            {
                if (player.Entity.MountedOn != null && player.Entity.MountedOn.GetType() == typeof(HotAirBalloon))
                {
                    /* Turning on balloon burner on server */
                    ch.SendPacket(new ControlMessage()
                    {
                        message = "OFF"
                    });
                }
            }

            /* Insert is hardcoded to refuel.*/
            if (api.Input.KeyboardKeyStateRaw[((int)GlKeys.Insert)])
            {
                if (player.Entity.MountedOn != null && player.Entity.MountedOn.GetType() == typeof(HotAirBalloon))
                {
                    /* Trying to refuel balloon */
                    ch.SendPacket(new ControlMessage()
                    {
                        message = "REFUEL"
                    });
                }
            }
        }
        #endregion

        public override void Start(ICoreAPI api)
        {
            base.Start(api);
            api.RegisterMountable("HotAirBalloon", HotAirBalloon.GetMountable);
            api.RegisterEntity("HotAirBalloon", typeof(HotAirBalloon));

        }

        public override bool ShouldLoad(EnumAppSide side) => true;


        #region Client
        IClientNetworkChannel clientChannel;
        ICoreClientAPI clientApi;
        public override void StartClientSide(ICoreClientAPI api)
        {
            clientApi = api;

            clientChannel =
                api.Network.RegisterChannel("aeronautics")
                .RegisterMessageType(typeof(ControlMessage));

            base.StartClientSide(api);
        }
        #endregion



        #region Server
        IServerNetworkChannel serverChannel;
        ICoreServerAPI serverApi;
        public override void StartServerSide(ICoreServerAPI api)
        {
            serverApi = api;
            serverChannel =
            api.Network.RegisterChannel("aeronautics")
                .RegisterMessageType(typeof(ControlMessage))
                .SetMessageHandler<ControlMessage>(OnControlMessage)
            ;

            base.StartServerSide(api);
        }

        /* Control message handler */
        private void OnControlMessage(IServerPlayer player, ControlMessage msg)
        {
 
        }        
        #endregion
    }
}

 

Entity class:

Spoiler
namespace aeronautics.src
{
    using Vintagestory.API.Common;
    using Vintagestory.API.Datastructures;
    using Vintagestory.API.MathTools;

    public class HotAirBalloon : EntityAgent, IMountable
    {
        public HotAirBalloon()
        {
            base.AllowDespawn = false;
        }

        public EntityAgent MountedBy;

        public Vec3d MountPosition
        {
            get
            {
                return (base.SidedPos.XYZ);
            }
        }
        public string SuggestedAnimation
        {
            get { return "sitflooridle"; }
        }

        public void MountableToTreeAttributes(TreeAttribute tree)
        {
            tree.SetString("className", "HotAirBalloon");
            tree.SetInt("posx", ((int)this.ServerPos.X));
            tree.SetInt("posy", ((int)this.ServerPos.Y));
            tree.SetInt("posz", ((int)this.ServerPos.Z));
        }

        public void DidUnmount(EntityAgent entityAgent)
        {
            MountedBy = null;
            entityAgent.TeleportTo(this.ServerPos.XYZ.Add(1.0, 1.0, 1.0));
        }

        public void DidMount(EntityAgent entityAgent)
        {
            if (MountedBy != null)
            {
                entityAgent.TryUnmount();
                return;
            }
            MountedBy = entityAgent;
        }

        public float? MountYaw
        {
            get
            {
                return this.BodyYaw;
            }
        }

        public static IMountable GetMountable(IWorldAccessor world, TreeAttribute tree)
        {
            Vec3d position = new Vec3d(tree.GetInt("posx", 0) + 0.25, tree.GetInt("posy", 0) + 0.25, tree.GetInt("posz", 0) + 0.25);
            return (world.GetNearestEntity(position, 0.1f, 0.1f, null) as HotAirBalloon);
        }

        public override void OnInteract(EntityAgent byEntity, ItemSlot slot, Vec3d hitPosition, EnumInteractMode mode)
        {
            if ((mode != EnumInteractMode.Interact) || !(byEntity is EntityPlayer))
            {
                base.OnInteract(byEntity, slot, hitPosition, mode);
            }

            if (byEntity != null && byEntity is EntityPlayer)
            {

                if(this.MountedBy != null)
                {
                    this.TryUnmount();
                }
                byEntity.TryMount(this);
            }
        }
    }
}

Crash log:

Spoiler

 

Spoiler
System.ArgumentNullException
  HResult=0x80004003
  Сообщение = Значение не может быть неопределенным.
Имя параметра: key
  Источник = mscorlib
  Трассировка стека:
   в System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
   в System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   в System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   в Vintagestory.Common.ClassRegistry.CreateMountable(IWorldAccessor world, TreeAttribute tree)
   в Vintagestory.API.Common.EntityAgent.<Initialize>b__30_0()
   в Vintagestory.API.Datastructures.SyncedTreeAttribute.MarkPathDirty(String path)
   в Vintagestory.API.Common.EntityAgent.TryMount(IMountable onmount)
   в aeronautics.src.HotAirBalloon.OnInteract(EntityAgent byEntity, ItemSlot slot, Vec3d hitPosition, EnumInteractMode mode) в Z:\Dev\VintageStory\Mods\mods\aeronautics\src\HotAirBalloon.cs:строка 80
   в Vintagestory.Client.NoObf.SystemMouseInWorldInteractions.HandleMouseInteractionsNoBlockSelected(Single dt)
   в Vintagestory.Client.NoObf.SystemMouseInWorldInteractions.OnFinalizeFrame(Single dt)
   в Vintagestory.Client.NoObf.ClientEventManager.TriggerRenderStage(EnumRenderStage stage, Single dt)
   в Vintagestory.Client.NoObf.ClientMain.TriggerRenderStage(EnumRenderStage stage, Single dt)
   в Vintagestory.Client.NoObf.ClientMain.RenderToDefaultFramebuffer(Single dt)
   в _RpDe0Jt5dbuWGpUxAyvHOIbDBGg._tu5y7iPBPWTBAhlukeXpnCcwz6W(Single )
   в _NLF4wmb6UPVLzv4DtU2r1ijDMNo._g5gGlJCvd5tg8L2OIzh5Cqwv60N(Single )
   в _NLF4wmb6UPVLzv4DtU2r1ijDMNo._0gqbRXtZfqKlQCIZaKgLGM2FkhV(Single )
   в Vintagestory.Client.NoObf.ClientPlatformWindows.window_RenderFrame(Object sender, FrameEventArgs e)
   в System.EventHandler`1.Invoke(Object sender, TEventArgs e)
   в OpenTK.GameWindow.RaiseRenderFrame(Double elapsed, Double& timestamp)
   в OpenTK.GameWindow.DispatchRenderFrame()
   в OpenTK.GameWindow.Run(Double updates_per_second, Double frames_per_second)
   в _nFNsDM20as86sGo44HbF6xxAkUD._UjMaM1bzP5Ozg5ilu06DMFIxPyO(_uhgd4BSf8z6N7PAibzFcq8c5IRD , String[] )
   в _Y4Bk3tLdFsgoJryQq19g4IoitkE._UjMaM1bzP5Ozg5ilu06DMFIxPyO(ThreadStart )
   в _nFNsDM20as86sGo44HbF6xxAkUD._uGIMddfWgVMG3Q8EvXiBxar6tZB(String[] )

 

 

Entity JSON:

Spoiler

 

{
  "code": "HotAirBalloon",
  "class": "HotAirBalloon",
  "entityClass": "HotAirBalloon",
  "canClimbAnywhere": true,
  //"habitat": "Air",
  "hitboxSize": {
    "x": 2,
    "y": 2
  },
  "deadHitboxSize": {
    "x": 2,
    "y": 2
  },
  "eyeHeight": 1.0,
  "drops": [],
  "sounds": {
    "hurt": "crack",
    "death": "crack_loud"
  },
  "client": {
    "renderer": "Shape",
    "shape": { "base": "entity/air/hot_air_balloon" },
    "textures": {
      "ceramic": { "base": "aeronautics:entity/air/balloon/ceramic" },
      "basket": { "base": "aeronautics:entity/air/balloon/basket" },
      "normal1": { "base": "aeronautics:entity/air/balloon/normal1" },
      "rope_hi_res": { "base": "aeronautics:entity/air/balloon/rope_hi_res" },
      "leather": { "base": "aeronautics:entity/air/balloon/leather" }
    },
    "behaviors": [
      { "code": "repulseagents" },
      {
        "code": "controlledphysics",
        "stepHeight": 1.1
      },
      { "code": "interpolateposition" }
    ],
    "animations": []
  },
  "server": {
    "behaviors": [
      { "code": "repulseagents" },
      {
        "code": "controlledphysics",
        "stepHeight": 1.1
      },
      {
        "code": "health",
        "currenthealth": 40,
        "maxhealth": 40
      }
    ]
  }
}
Edited by MadAlchemist
Making long text more readable
Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.