Skip to content

Instantly share code, notes, and snippets.

@StarCheater
Created June 12, 2020 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save StarCheater/e290aae396774c833aaf8d770f4d65c8 to your computer and use it in GitHub Desktop.
Save StarCheater/e290aae396774c833aaf8d770f4d65c8 to your computer and use it in GitHub Desktop.
Try to get a mod for a block with rotating sides and two behaviors when the essence is standing on it.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using Vintagestory.API.Client;
using Vintagestory.API.Common;
using Vintagestory.API.Common.Entities;
using Vintagestory.API.Datastructures;
using Vintagestory.API.MathTools;
using Vintagestory.API.Server;
using Vintagestory.GameContent;
using Action = System.Action;
namespace Ticking
{
public class Ticking : ModSystem
{
public override void Start(ICoreAPI api)
{
base.Start(api);
api.RegisterBlockClass("block_tickingcounter", typeof(T_BlockClass));
api.RegisterBlockBehaviorClass("bh_tickingcounter", typeof(TickingBlockBehavior));
}
}
class Runner
{
class item
{
public double SecondsPassed;
public double LastCollideMs;
public dynamic value;
}
public Vintagestory.API.Common.Action<dynamic> action;
Dictionary<long, item> list = new Dictionary<long, item>();
public ICoreAPI Api;
public double WaitTimeMs = 100;
public double WaitSeconds = 0;
public void Add(long id, dynamic d)
{
if (!list.ContainsKey(id))
{
item item = new item() { value = d };
list.Add(id, item);
}
list[id].LastCollideMs = Api.World.ElapsedMilliseconds;
}
public void Method(float dt)
{
List<long> to_remove = new List<long>();
foreach (var item in list)
{
item.Value.SecondsPassed += Math.Min(0.5f, dt);
if (Api.World.ElapsedMilliseconds - item.Value.LastCollideMs > WaitTimeMs)
{
to_remove.Add(item.Key);
continue;
}
if (item.Value.SecondsPassed > WaitSeconds)
{
action?.Invoke(item.Value.value);
to_remove.Add(item.Key);
}
}
foreach (long id in to_remove)
{
list.Remove(id);
}
to_remove.Clear();
}
}
public class T_BlockClass : Block
{
private Runner run;
void RunAction(dynamic _entity)
{
if (_entity is Entity entity)
{
BlockPos pos = entity.Pos.AsBlockPos.DownCopy();
Block block = entity.Api.World.BlockAccessor.GetBlock(pos);
entity.Properties.CanClimbAnywhere = true;
if (block == null || !block.Code.ToString().Contains("tickingcounter")) return;
double dx = 0, dz = 0;
BlockFacing rotFacing = BlockFacing.FromCode(block.LastCodePart());
double z = entity.Pos.Z - (pos.Z + 0.5);
double x = entity.Pos.X - (pos.X + 0.5);
double k = 15;
double movement = 0.1;
if (rotFacing == BlockFacing.NORTH)
{
dx = movement;
dz = 0;
if (Math.Abs(z) > 0.1)
{
dz = (-z) / k;
}
}
if (rotFacing == BlockFacing.EAST)
{
dx = 0;
dz = movement;
if (Math.Abs(x) > 0.1)
{
dx = (-x) / k;
}
}
if (rotFacing == BlockFacing.SOUTH)
{
dx = -1 * movement;
dz = 0;
if (Math.Abs(z) > 0.1)
{
dz = (-z) / k;
}
}
if (rotFacing == BlockFacing.WEST)
{
dx = 0;
dz = -1 * movement;
if (Math.Abs(x) > 0.1)
{
dx = (-x) / k;
}
}
if (block.Code.ToString().Contains("-on"))
{
entity.ServerPos.Motion = Vec3d.Zero;
entity.Pos.Motion = Vec3d.Zero;
entity.ServerPos.X += dx;
entity.ServerPos.Z += dz;
entity.Pos.X += dx;
entity.Pos.Z += dz;
}
else
{
entity.ServerPos.Motion.Set(dx, 0, dz);
entity.Pos.Motion.Set(dx, 0, dz);
}
entity.Pos.Dirty = true;
}
}
public override void OnLoaded(ICoreAPI api)
{
run = new Runner();
run.Api = api;
run.action = RunAction;
if(api.Side == EnumAppSide.Server) api.Event.RegisterGameTickListener(run.Method, 10);
base.OnLoaded(api);
}
public override void OnEntityCollide(IWorldAccessor world, Entity entity, BlockPos pos, BlockFacing facing, Vec3d collideSpeed,
bool isImpact)
{
run?.Add(entity.EntityId, entity);
}
}
public class TickingBlockBehavior : BlockBehavior
{
public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
{
ItemStack stack = byPlayer.InventoryManager.ActiveHotbarSlot.Itemstack;
if (stack == null || !stack.Collectible.Code.Path.Contains("stick")) return false;
handling = EnumHandling.PreventDefault;
BlockPos pos = blockSel.Position;
world.BlockAccessor.ExchangeBlock(world.BlockAccessor.GetBlock(GetRotatedBlockCode(90, ref handling)).Id, pos);
world.BlockAccessor.MarkBlockDirty(pos);
world.BlockAccessor.GetChunkAtBlockPos(pos)?.MarkModified();
return true;
}
public override AssetLocation GetRotatedBlockCode(int angle, ref EnumHandling handled)
{
handled = EnumHandling.PreventDefault;
BlockFacing beforeFacing = BlockFacing.FromCode(block.LastCodePart());
int rotatedIndex = GameMath.Mod(beforeFacing.HorizontalAngleIndex - angle / 90, 4);
BlockFacing nowFacing = BlockFacing.HORIZONTALS_ANGLEORDER[rotatedIndex];
return block.CodeWithParts(nowFacing.Code);
}
public TickingBlockBehavior(Block block) : base(block)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment