private void EntityGlowingAgent_OnTaskStarted(IAiTask task) { if (task is AiTaskSeekEntity) { WatchedAttributes.SetFloat("aggroTime", 10); } }
public override bool TryGiveItemStack(ItemStack itemstack) { if (itemstack == null || itemstack.StackSize == 0) { return(false); } ItemSlot dummySlot = new DummySlot(null); dummySlot.Itemstack = itemstack.Clone(); ItemStackMoveOperation op = new ItemStackMoveOperation(World, EnumMouseButton.Left, 0, EnumMergePriority.AutoMerge, itemstack.StackSize); WeightedSlot wslot = inv.GetBestSuitedSlot(dummySlot, new List <ItemSlot>()); if (wslot.weight > 0) { dummySlot.TryPutInto(wslot.slot, ref op); itemstack.StackSize -= op.MovedQuantity; WatchedAttributes.MarkAllDirty(); return(op.MovedQuantity > 0); } return(false); }
private void IsColliding(EntityPos pos, double impactSpeed) { pos.Motion.Set(0, 0, 0); if (!beforeCollided && World is IServerWorldAccessor && World.ElapsedMilliseconds > msCollide + 500) { if (impactSpeed >= 0.07) { World.PlaySoundAt(new AssetLocation("sounds/arrow-impact"), this, null, false, 32); // Resend position to client WatchedAttributes.MarkAllDirty(); if (DamageStackOnImpact) { ProjectileStack.Collectible.DamageItem(World, this, new DummySlot(ProjectileStack)); } int leftDurability = ProjectileStack == null ? 1 : ProjectileStack.Attributes.GetInt("durability", 1); if (leftDurability <= 0) { Die(); } } TryAttackEntity(impactSpeed); msCollide = World.ElapsedMilliseconds; beforeCollided = true; } }
private void IsColliding(EntityPos pos, double impactSpeed) { pos.Motion.Set(0, 0, 0); if (!beforeCollided && World is IServerWorldAccessor && World.ElapsedMilliseconds > msCollide + 500) { if (impactSpeed >= 0.07) { World.PlaySoundAt(new AssetLocation("sounds/arrow-impact"), this, null, false, 32); // Slighty randomize orientation to make it a bit more realistic //pos.Yaw += (float)(World.Rand.NextDouble() * 0.05 - 0.025); //pos.Roll += (float)(World.Rand.NextDouble() * 0.05 - 0.025); // Resend position to client WatchedAttributes.MarkAllDirty(); int leftDurability = ProjectileStack == null ? 1 : ProjectileStack.Attributes.GetInt("durability", 1); if (leftDurability <= 0) { Die(); } } TryAttackEntity(impactSpeed); msCollide = World.ElapsedMilliseconds; beforeCollided = true; } }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { // Temporary code for VS 1.15 dev team to remove previously created "land" salmon which don't have the correct entity if (properties.Habitat == EnumHabitat.Underwater && !(this.GetType().Name == "EntityFish")) { this.Alive = false; } base.Initialize(properties, api, InChunkIndex3d); if (World.Side == EnumAppSide.Server) { servercontrols = controls; } WatchedAttributes.RegisterModifiedListener("mountedOn", updateMountedState); if (WatchedAttributes["mountedOn"] != null) { MountedOn = World.ClassRegistry.CreateMountable(WatchedAttributes["mountedOn"] as TreeAttribute); if (MountedOn != null) { TryMount(MountedOn); } } }
/// <summary> /// Gets the walk speed multiplier. /// </summary> /// <param name="groundDragFactor">The amount of drag provided by the current ground. (Default: 0.3)</param> public override double GetWalkSpeedMultiplier(double groundDragFactor = 0.3) { Block belowBlock = World.BlockAccessor.GetBlock((int)LocalPos.X, (int)(LocalPos.Y - 0.05f), (int)LocalPos.Z); Block insideblock = World.BlockAccessor.GetBlock((int)LocalPos.X, (int)(LocalPos.Y + 0.01f), (int)LocalPos.Z); double multiplier = (servercontrols.Sneak ? GlobalConstants.SneakSpeedMultiplier : 1.0) * (servercontrols.Sprint ? GlobalConstants.SprintSpeedMultiplier : 1.0); if (FeetInLiquid) { multiplier /= 2.5; } double mul1 = belowBlock.Code.Path.Contains("metalspike") ? 1 : belowBlock.WalkSpeedMultiplier; double mul2 = insideblock.Code.Path.Contains("metalspike") ? 1 : insideblock.WalkSpeedMultiplier; multiplier *= mul1 * mul2; // Apply walk speed modifiers. var attribute = WatchedAttributes.GetTreeAttribute("walkSpeedModifiers"); if (attribute?.Count > 0) { // Enumerate over all values in this attribute as tree attributes, then // multiply their "Value" properties together with the current multiplier. multiplier *= attribute.Values.Cast <ITreeAttribute>() .Aggregate(1.0F, (current, modifier) => current * modifier.GetFloat("Value")); } return(multiplier); }
protected virtual void updateMountedState() { if (WatchedAttributes.HasAttribute("mountedOn")) { var mountable = World.ClassRegistry.CreateMountable(WatchedAttributes["mountedOn"] as TreeAttribute); this.MountedOn = mountable; controls.StopAllMovement(); if (mountable == null) { WatchedAttributes.RemoveAttribute("mountedOn"); return; } if (MountedOn?.SuggestedAnimation != null) { string anim = MountedOn.SuggestedAnimation.ToLowerInvariant(); AnimManager?.StartAnimation(anim); } mountable.DidMount(this); } else { TryUnmount(); } }
public EntityBlockFalling(Block block, BlockEntity blockEntity, BlockPos initialPos, AssetLocation fallSound, float impactDamageMul, bool canFallSideways, float dustIntensity) { this.impactDamageMul = impactDamageMul; this.fallSound = fallSound; this.canFallSideways = canFallSideways; this.dustIntensity = dustIntensity; WatchedAttributes.SetBool("canFallSideways", canFallSideways); WatchedAttributes.SetFloat("dustIntensity", dustIntensity); if (fallSound != null) { WatchedAttributes.SetString("fallSound", fallSound.ToShortString()); } this.Code = new AssetLocation("blockfalling"); this.blockCode = block.Code; this.removedBlockentity = blockEntity; this.initialPos = initialPos.Copy(); // Must have a Copy() here! ServerPos.SetPos(initialPos); ServerPos.X += 0.5; ServerPos.Z += 0.5; Pos.SetFrom(ServerPos); }
public override void OnEntitySpawn() { base.OnEntitySpawn(); if (World.Api.Side == EnumAppSide.Server) { EntityBehaviorTaskAI taskAi = GetBehavior <EntityBehaviorTaskAI>(); taskAi.taskManager.ShouldExecuteTask = (task) => tradingWith == null || (task is AiTaskIdle || task is AiTaskSeekEntity || task is AiTaskGotoEntity); if (TradeProps != null) { RefreshBuyingSellingInventory(); WatchedAttributes.SetDouble("lastRefreshTotalDays", World.Calendar.TotalDays - World.Rand.NextDouble() * 6); Inventory.GiveToTrader((int)TradeProps.Money.nextFloat(1f, World.Rand)); } else { World.Logger.Warning("Trader TradeProps not set during trader entity spawn. Won't have any items for sale/purchase."); } Personality = Personalities.GetKeyAtIndex(World.Rand.Next(Personalities.Count)); (AnimManager as TraderAnimationManager).Personality = this.Personality; } }
public override void FromBytes(BinaryReader reader, bool forClient) { base.FromBytes(reader, forClient); initialPos = new BlockPos(); initialPos.X = reader.ReadInt32(); initialPos.Y = reader.ReadInt32(); initialPos.Z = reader.ReadInt32(); blockCode = new AssetLocation(reader.ReadString()); bool beIsNull = reader.ReadBoolean(); if (!beIsNull) { blockEntityAttributes = new TreeAttribute(); blockEntityAttributes.FromBytes(reader); blockEntityClass = reader.ReadString(); } if (WatchedAttributes.HasAttribute("fallSound")) { fallSound = new AssetLocation(WatchedAttributes.GetString("fallSound")); } canFallSideways = WatchedAttributes.GetBool("canFallSideways"); dustIntensity = WatchedAttributes.GetFloat("dustIntensity"); DoRemoveBlock = reader.ReadBoolean(); }
public override void Initialize(EntityProperties properties, ICoreAPI api, long chunkindex3d) { base.Initialize(properties, api, chunkindex3d); if (Itemstack == null || !Itemstack.ResolveBlockOrItem(World)) { Die(); this.Itemstack = null; return; } // If attribute was modified and resent to client, make sure we still have the resolved thing in memory WatchedAttributes.RegisterModifiedListener("itemstack", () => { if (Itemstack != null && Itemstack.Collectible == null) { Itemstack.ResolveBlockOrItem(World); } Slot.Itemstack = Itemstack; }); itemSpawnedMilliseconds = World.ElapsedMilliseconds; Swimming = FeetInLiquid = World.BlockAccessor.GetBlock(Pos.AsBlockPos).IsLiquid(); tmpPos.Set(Pos.XInt, Pos.YInt, Pos.ZInt); windLoss = World.BlockAccessor.GetDistanceToRainFall(tmpPos) / 4f; }
public override void OnGameTick(float dt) { base.OnGameTick(dt); if (Alive && AnimManager.ActiveAnimationsByAnimCode.Count == 0) { AnimManager.StartAnimation(new AnimationMetaData() { Code = "idle", Animation = "idle", EaseOutSpeed = 10000, EaseInSpeed = 10000 }); } if (World.Side == EnumAppSide.Client) { talkUtil.OnGameTick(dt); } else { if (tickCount++ > 200) { double lastRefreshTotalDays = WatchedAttributes.GetDouble("lastRefreshTotalDays", World.Calendar.TotalDays - 10); int maxRefreshes = 10; while (World.Calendar.TotalDays - lastRefreshTotalDays > doubleRefreshIntervalDays && tradingWith == null && maxRefreshes-- > 0) { int traderAssets = Inventory.GetTraderAssets(); double giveRel = 0.07 + World.Rand.NextDouble() * 0.21; float nowWealth = TradeProps.Money.nextFloat(1f, World.Rand); int toGive = (int)Math.Max(-3, Math.Min(nowWealth, traderAssets + giveRel * (int)nowWealth) - traderAssets); Inventory.GiveToTrader(toGive); RefreshBuyingSellingInventory(0.5f); lastRefreshTotalDays += doubleRefreshIntervalDays; WatchedAttributes.SetDouble("lastRefreshTotalDays", lastRefreshTotalDays); tickCount = 1; } if (maxRefreshes <= 0) { WatchedAttributes.SetDouble("lastRefreshTotalDays", World.Calendar.TotalDays + 1 + World.Rand.NextDouble() * 5); } } } if (tradingWith != null && (tradingWith.Pos.SquareDistanceTo(this.Pos) > 5 || Inventory.openedByPlayerGUIds.Count == 0 || !Alive)) { dlg?.TryClose(); IPlayer tradingPlayer = tradingWith?.Player; if (tradingPlayer != null) { Inventory.Close(tradingPlayer); } } }
public override void Initialize(EntityProperties properties, ICoreAPI api, long chunkindex3d) { base.Initialize(properties, api, chunkindex3d); inv.LateInitialize("gearinv-" + EntityId, api); Name = WatchedAttributes.GetTreeAttribute("nametag")?.GetString("name"); }
public override void FromBytes(BinaryReader reader, bool forClient) { base.FromBytes(reader, forClient); lastRunningHeldUseAnimation = WatchedAttributes.GetString("lrHeldUseAnim"); lastRunningHeldHitAnimation = WatchedAttributes.GetString("lrHeldHitAnim"); lastRunningRightHeldIdleAnimation = WatchedAttributes.GetString("lrRightHeldIdleAnim"); }
private void GearInv_SlotModified(int t1) { ITreeAttribute tree = new TreeAttribute(); WatchedAttributes["inventory"] = tree; gearInv.ToTreeAttributes(tree); WatchedAttributes.MarkPathDirty("inventory"); }
public override void ToBytes(BinaryWriter writer, bool forClient) { if (Inventory != null && Inventory.Count > 0 && WatchedAttributes != null) { WatchedAttributes.SetString("invid", Inventory.InventoryID); Inventory.ToTreeAttributes(WatchedAttributes); } base.ToBytes(writer, forClient); }
public override void OnInteract(EntityAgent byEntity, ItemSlot slot, Vec3d hitPosition, EnumInteractMode mode) { base.OnInteract(byEntity, slot, hitPosition, mode); if ((byEntity as EntityPlayer)?.Controls.Sneak == true && mode == EnumInteractMode.Interact && byEntity.World.Side == EnumAppSide.Server) { inv.DiscardAll(); WatchedAttributes.MarkAllDirty(); } }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { if (removedBlockentity != null) { this.blockEntityAttributes = new TreeAttribute(); removedBlockentity.ToTreeAttributes(blockEntityAttributes); blockEntityClass = api.World.ClassRegistry.GetBlockEntityClass(removedBlockentity.GetType()); } SimulationRange = (int)(0.75f * GlobalConstants.DefaultTrackingRange); base.Initialize(properties, api, InChunkIndex3d); // Need to capture this now before we remove the block and start to fall drops = Block.GetDrops(api.World, initialPos, null); lightHsv = Block.GetLightHsv(World.BlockAccessor, initialPos); SidedPos.Motion.Y = -0.02; blockAsStack = new ItemStack(Block); if (api.Side == EnumAppSide.Client && fallSound != null && fallingNow.Count < 100) { fallingNow.Add(EntityId); ICoreClientAPI capi = api as ICoreClientAPI; sound = capi.World.LoadSound(new SoundParams() { Location = fallSound.WithPathPrefixOnce("sounds/").WithPathAppendixOnce(".ogg"), Position = new Vec3f((float)Pos.X, (float)Pos.Y, (float)Pos.Z), Range = 32, Pitch = 0.8f + (float)capi.World.Rand.NextDouble() * 0.3f, Volume = 1, SoundType = EnumSoundType.Ambient }); sound.Start(); soundStartDelay = 0.05f + (float)capi.World.Rand.NextDouble() / 3f; } canFallSideways = WatchedAttributes.GetBool("canFallSideways"); dustIntensity = WatchedAttributes.GetFloat("dustIntensity"); if (WatchedAttributes.HasAttribute("fallSound")) { fallSound = new AssetLocation(WatchedAttributes.GetString("fallSound")); } if (api.World.Side == EnumAppSide.Client) { particleSys = api.ModLoader.GetModSystem <FallingBlockParticlesModSystem>(); particleSys.Register(this); physicsBh = GetBehavior <EntityBehaviorPassivePhysics>(); } }
ITreeAttribute GetOrCreateTradeStore() { if (!WatchedAttributes.HasAttribute("traderInventory")) { ITreeAttribute tree = new TreeAttribute(); Inventory.ToTreeAttributes(tree); WatchedAttributes["traderInventory"] = tree; } return(WatchedAttributes["traderInventory"] as ITreeAttribute); }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); if (api.Side == EnumAppSide.Client) { WatchedAttributes.RegisterModifiedListener("sitHeight", () => { (Properties.Client.Renderer as EntityShapeRenderer).WindWaveIntensity = WatchedAttributes.GetDouble("sitHeight"); }); } }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); if (Inventory == null) { Inventory = new InventoryTrader("traderInv", "" + EntityId, api); } if (api.Side == EnumAppSide.Server) { try { string json = Properties.Server.Attributes["tradeProps"].ToJsonToken(); TradeProps = new JsonObject(json).AsObject <TradeProperties>(); } catch (Exception e) { api.World.Logger.Error("Failed deserializing TradeProperties for trader {0}, exception logged to verbose debug", properties.Code); api.World.Logger.VerboseDebug("Failed deserializing TradeProperties: {0}", e); api.World.Logger.VerboseDebug("================="); api.World.Logger.VerboseDebug("Tradeprops json:"); api.World.Logger.VerboseDebug("{0}", Properties.Server.Attributes["tradeProps"].ToJsonToken()); } if (OutfitCodes == null) { OutfitCodes = api.ModLoader.GetModSystem <TraderOutfits>().GetRandomOutfit(); } } else { talkUtil = new TalkUtil(api as ICoreClientAPI, this); } try { Inventory.LateInitialize("traderInv-" + EntityId, api, this); } catch (Exception e) { api.World.Logger.Error("Failed initializing trader inventory. Will recreate. Exception logged to verbose debug"); api.World.Logger.VerboseDebug("Failed initializing trader inventory. Will recreate. Exception {0}", e); WatchedAttributes.RemoveAttribute("traderInventory"); Inventory = new InventoryTrader("traderInv", "" + EntityId, api); Inventory.LateInitialize("traderInv-" + EntityId, api, this); RefreshBuyingSellingInventory(); } (AnimManager as TraderAnimationManager).Personality = this.Personality; this.Personality = this.Personality; // to update the talkutil }
public override void TeleportToDouble(double x, double y, double z, Action onTeleported = null) { Teleporting = true; ICoreServerAPI sapi = this.World.Api as ICoreServerAPI; if (sapi != null) { sapi.WorldManager.LoadChunkColumnPriority((int)ServerPos.X / World.BlockAccessor.ChunkSize, (int)ServerPos.Z / World.BlockAccessor.ChunkSize, new ChunkLoadOptions() { OnLoaded = () => { Pos.SetPos(x, y, z); ServerPos.SetPos(x, y, z); PreviousServerPos.SetPos(-99, -99, -99); PositionBeforeFalling.Set(x, y, z); Pos.Motion.Set(0, 0, 0); if (this is EntityPlayer) { sapi.Network.BroadcastEntityPacket(EntityId, 1, SerializerUtil.Serialize(ServerPos.XYZ)); IServerPlayer player = this.Player as IServerPlayer; int chunksize = World.BlockAccessor.ChunkSize; player.CurrentChunkSentRadius = 0; sapi.Event.RegisterCallback((bla) => { if (player.ConnectionState == EnumClientState.Offline) { return; } if (!sapi.WorldManager.HasChunk((int)x / chunksize, (int)y / chunksize, (int)z / chunksize, player)) { sapi.WorldManager.SendChunk((int)x / chunksize, (int)y / chunksize, (int)z / chunksize, player, false); } // Oherwise we get an endlessly looping exception spam and break the server player.CurrentChunkSentRadius = 0; }, 50); } WatchedAttributes.SetInt("positionVersionNumber", WatchedAttributes.GetInt("positionVersionNumber", 0) + 1); onTeleported?.Invoke(); Teleporting = false; }, }); } }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); if (api.Side == EnumAppSide.Server) { GetBehavior <EntityBehaviorTaskAI>().taskManager.OnTaskStarted += EntityGlowingAgent_OnTaskStarted; } else { WatchedAttributes.RegisterModifiedListener("aggroTime", () => { aggroTime = WatchedAttributes.GetFloat("aggroTime"); }); } aggroTime = WatchedAttributes.GetFloat("aggroTime"); }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); if (gearInv == null) { gearInv = new InventoryGeneric(17, "gear-" + EntityId, api, onNewSlot); gearInv.SlotModified += GearInv_SlotModified; } if (api.Side == EnumAppSide.Client) { WatchedAttributes.RegisterModifiedListener("inventory", readInventoryFromAttributes); } readInventoryFromAttributes(); }
/// <summary> /// Loads the entity from a stored byte array from the SaveGame /// </summary> /// <param name="reader"></param> /// <param name="forClient"></param> public override void FromBytes(BinaryReader reader, bool forClient) { try { base.FromBytes(reader, forClient); controls.FromBytes(reader, LoadControlsFromServer); } catch (EndOfStreamException e) { Exception ex = new Exception("EndOfStreamException thrown while reading entity, you might be able to recover your savegame through repair mode", e); throw ex; } if (!WatchedAttributes.HasAttribute("mountedOn") && MountedOn != null) { TryUnmount(); } }
/// <summary> /// Attempts to mount the player on a target. /// </summary> /// <param name="onmount">The mount to mount</param> /// <returns>Whether it was mounted or not.</returns> public bool TryMount(IMountable onmount) { if (MountedOn != onmount) { if (!TryUnmount()) { return(false); } } TreeAttribute mountableTree = new TreeAttribute(); onmount?.MountableToTreeAttributes(mountableTree); WatchedAttributes["mountedOn"] = mountableTree; WatchedAttributes.MarkPathDirty("mountedOn"); // -> this calls updateMountedState() return(true); }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { base.Initialize(properties, api, InChunkIndex3d); if (api.Side == EnumAppSide.Server) { GetBehavior <EntityBehaviorTaskAI>().TaskManager.OnTaskStarted += EntityGlowingAgent_OnTaskStarted; } else { WatchedAttributes.RegisterModifiedListener("aggroTime", () => { aggroTime = WatchedAttributes.GetFloat("aggroTime"); }); } aggroTime = WatchedAttributes.GetFloat("aggroTime"); lightHsv = properties.Attributes["lightHsv"].AsObject <byte[]>(new byte[] { 10, 5, 10 }); onlyWhenAggroed = properties.Attributes["onlyWhenAggroed"].AsBool(true); }
public override void FromBytes(BinaryReader reader, bool forClient) { base.FromBytes(reader, forClient); if (!forClient) { ITreeAttribute ctree = WatchedAttributes.GetTreeAttribute("commandQueue"); if (ctree == null) { return; } ITreeAttribute commands = ctree.GetTreeAttribute("commands"); if (commands == null) { return; } foreach (var val in commands) { ITreeAttribute attr = val.Value as ITreeAttribute; string type = attr.GetString("type"); INpcCommand command = null; switch (type) { case "tp": command = new NpcTeleportCommand(this, null); break; case "goto": command = new NpcGotoCommand(this, null, null, 0); break; case "anim": command = new NpcPlayAnimationCommand(this, null, 1f); break; } command.FromAttribute(attr); Commands.Add(command); } } }
public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d) { if (removedBlockentity != null) { this.blockEntityAttributes = new TreeAttribute(); removedBlockentity.ToTreeAttributes(blockEntityAttributes); blockEntityClass = api.World.ClassRegistry.GetBlockEntityClass(removedBlockentity.GetType()); } SimulationRange = 3 * api.World.BlockAccessor.ChunkSize; base.Initialize(properties, api, InChunkIndex3d); // Need to capture this now before we remove the block and start to fall drops = Block.GetDrops(api.World, initialPos, null); lightHsv = Block.GetLightHsv(World.BlockAccessor, initialPos); LocalPos.Motion.Y = -0.02; blockAsStack = new ItemStack(Block); if (api.Side == EnumAppSide.Client && fallSound != null) { ICoreClientAPI capi = api as ICoreClientAPI; sound = capi.World.LoadSound(new SoundParams() { Location = fallSound.WithPathPrefixOnce("sounds/").WithPathAppendixOnce(".ogg"), Position = new Vec3f((float)Pos.X, (float)Pos.Y, (float)Pos.Z), Range = 32, Pitch = 0.8f + (float)capi.World.Rand.NextDouble() * 0.3f, Volume = 1, SoundType = EnumSoundType.Ambient }); soundStartDelay = 0.05f + (float)capi.World.Rand.NextDouble() / 3f; } canFallSideways = WatchedAttributes.GetBool("canFallSideways"); dustyFall = WatchedAttributes.GetBool("dustyFall"); if (WatchedAttributes.HasAttribute("fallSound")) { fallSound = new AssetLocation(WatchedAttributes.GetString("fallSound")); } }
/// <summary> /// Attempts to un-mount the player. /// </summary> /// <returns>Whether or not unmounting was successful</returns> public bool TryUnmount() { if (MountedOn?.SuggestedAnimation != null) { string anim = MountedOn.SuggestedAnimation.ToLowerInvariant(); AnimManager?.StopAnimation(anim); } MountedOn?.DidUnmount(this); this.MountedOn = null; if (WatchedAttributes.HasAttribute("mountedOn")) { WatchedAttributes.RemoveAttribute("mountedOn"); } return(true); }