public static List <IEntity> GetEntitiesWithinArea(Vector3 Center, float Radius) { //TODO: Make this more generic, more performant Assert.ActualAssert(Radius < ChunkSize); var Output = new List <IEntity>(); var ChunkList = new List <Tuple <int, int> >(); ChunkList.Add(GetChunkTuple(Center)); ChunkList.Add(GetChunkTuple(Center + new Vector3(ChunkSize, 0, 0))); //Forward ChunkList.Add(GetChunkTuple(Center + new Vector3(-ChunkSize, 0, 0))); //Backward ChunkList.Add(GetChunkTuple(Center + new Vector3(0, 0, ChunkSize))); //Right ChunkList.Add(GetChunkTuple(Center + new Vector3(0, 0, -ChunkSize))); //Left ChunkList.Add(GetChunkTuple(Center + new Vector3(ChunkSize, 0, ChunkSize))); //Forward right ChunkList.Add(GetChunkTuple(Center + new Vector3(ChunkSize, 0, -ChunkSize))); //Forward left ChunkList.Add(GetChunkTuple(Center + new Vector3(-ChunkSize, 0, ChunkSize))); //Backward right ChunkList.Add(GetChunkTuple(Center + new Vector3(-ChunkSize, 0, -ChunkSize))); //Backward left foreach (var ChunkTuple in ChunkList) { if (Chunks.TryGetValue(ChunkTuple, out ChunkClass Chunk)) { Output = Output.Concat(Chunk.Entities).ToList(); //TODO: Eww } } return(Output); }
public static void ApplyEffectiveRecoil(float VerticalRecoil, float HorizontalRecoil) { Game.PossessedPlayer.MatchSome( (Plr) => { Assert.ActualAssert(NextRecoilDirection == 1 || NextRecoilDirection == -1); //Lessen recoil when ADS VerticalRecoil *= Plr.AdsMultiplier; HorizontalRecoil *= Plr.AdsMultiplier; //Lessen recoil when crouching if (Plr.IsCrouching) { VerticalRecoil *= CrouchAffectPercentage; HorizontalRecoil *= CrouchAffectPercentage; } Plr.ApplyLookVertical(VerticalRecoil); Plr.LookHorizontal += HorizontalRecoil * -NextRecoilDirection; Plr.RotationDegrees = new Vector3(0, Plr.LookHorizontal, 0); NextRecoilDirection = -NextRecoilDirection; } ); }
private void ReceiveTransferFromTo(NodePath FromPath, int FromSlot, NodePath ToPath, int ToSlot, Items.IntentCount CountMode) { Assert.ActualAssert(Net.Work.IsNetworkServer()); var MaybeFrom = World.EntitiesRoot.GetNodeOrNull(FromPath); var MaybeTo = World.EntitiesRoot.GetNodeOrNull(ToPath); if (MaybeFrom is IHasInventory From && MaybeTo is IHasInventory To) { From.Inventory.TransferTo(To, FromSlot, ToSlot, CountMode); }
public override void _Ready() { Parent = GetParent <IProjectile>(); Assert.ActualAssert(Parent != null); StartPoint = GetNode <Spatial>(StartPointPath); Assert.ActualAssert(StartPoint != null); EndPoint = GetNode <Spatial>(EndPointPath); Assert.ActualAssert(EndPoint != null); }
public void NotifyPickedUpItem() { if (!Possessed) { Assert.ActualAssert(Net.Work.IsNetworkServer()); Net.SteelRpc(this, nameof(NotifyPickedUpItem)); return; } SfxManager.FpPickup(); SetCooldown(0, SlotSwitchCooldown, false); }
public void NotifyPickedUpItem() { if (!Possessed) { Assert.ActualAssert(Net.Work.IsNetworkServer()); RpcId(Id, nameof(NotifyPickedUpItem)); return; } Sfx.PlayPlayer(Sfx.ID.ITEM_PICKUP, this); SetCooldown(0, SlotSwitchCooldown, false); }
private void ReceivePhaseOut(string Identifier) { Node Entity = World.EntitiesRoot.GetNodeOrNull(Identifier); if (Entity is null) { return; } Assert.ActualAssert(Entity is IEntity); ((IEntity)Entity).PhaseOut(); }
private void ReceiveDestroy(string Identifier, params object[] Args) { Node Entity = World.EntitiesRoot.GetNodeOrNull(Identifier); if (Entity is null) { return; } Assert.ActualAssert(Entity is IEntity); ((IEntity)Entity).Destroy(Args); }
public void InitialNetWorldLoad(int Id, Vector3 PlayerPosition, int RenderDistance) { if (!Net.Work.IsNetworkServer()) { throw new Exception($"Attempted to run {nameof(InitialNetWorldLoad)} on client"); } RequestChunks(Id, PlayerPosition, RenderDistance); Assert.ActualAssert(Net.Players[Id].Plr.HasValue); //Todo: Spawn the player here Net.Players[Id].Plr.ValueOrFailure().SetFreeze(false); Net.Players[Id].Plr.ValueOrFailure().GiveDefaultItems(); }
private void ReceiveUpdate(string Identifier, params object[] Args) { Node Entity = World.EntitiesRoot.GetNodeOrNull(Identifier); if (Entity is null) { RpcId(Net.ServerId, nameof(PleaseSendMeCreate), Identifier); return; } Assert.ActualAssert(Entity is IEntity); ((IEntity)Entity).Update(Args); }
public void MarkChunkLoaded(int X, int Z) //Run on server by client after receiving all chunk load RPCs { if (!Net.Work.IsNetworkServer()) { throw new Exception($"{nameof(MarkChunkLoaded)} was executed on a client"); } int SenderId = Net.Work.GetRpcSenderId(); Assert.ActualAssert(SenderId != 0); var ChunkTuple = new Tuple <int, int>(X, Z); RemoteLoadingChunks[SenderId].Remove(ChunkTuple); RemoteLoadedChunks[SenderId].Add(ChunkTuple); }
private void ReceiveInventory(string Identifier, Items.ID[] Ids, int[] Counts) { Node Entity = World.EntitiesRoot.GetNodeOrNull(Identifier); if (Entity is null) { RpcId(Net.ServerId, nameof(PleaseSendMeCreate), Identifier); return; } Assert.ActualAssert(Entity is IEntity); if (Entity is IHasInventory HasInventory) { Assert.ActualAssert(Ids.Length == Counts.Length); Assert.ActualAssert(HasInventory.Inventory.Contents.Length == Ids.Length); int Index = 0; while (Index < Ids.Length) { if (Ids[Index] == Items.ID.NONE) { HasInventory.Inventory.Contents[Index] = null; } else { var Item = new Items.Instance(Ids[Index]) { Count = Counts[Index] }; HasInventory.Inventory.Contents[Index] = Item; } Index += 1; } } else { Console.ThrowLog("Received an inventory for an entity without an inventory"); } }
public void ServerExplode(Vector3 Position) { Assert.ActualAssert(Net.Work.IsNetworkServer()); var WithinArea = World.GetEntitiesWithinArea(Position, MaxRocketDistance); foreach (Node Body in WithinArea) { if (Body is IPushable Pushable) { PhysicsDirectSpaceState State = GetWorld().DirectSpaceState; Godot.Collections.Dictionary Results = State.IntersectRay(Position, Pushable.Translation, new Godot.Collections.Array() { Pushable }, 1); if (Results.Count > 0) { continue; } Vector3 Push = CalculatePush(Pushable, Position); if (Pushable is Player Plr && Game.PossessedPlayer.HasValue && Plr != Game.PossessedPlayer.ValueOrFailure()) { continue; } Pushable.ApplyPush(Push); Entities.SendPush(Pushable, Push); } } ExplodeSoundVisual(Position); Entities.SendDestroy(Name, Position); QueueFree(); }
private void PleaseSendMeCreate(string Identifier) { if (!Net.Work.IsNetworkServer()) { throw new Exception($"Cannot run {nameof(PleaseSendMeCreate)} on client"); } int Requester = Net.Work.GetRpcSenderId(); if (Requester == 0) { throw new Exception($"{nameof(PleaseSendMeCreate)} was run not as an RPC"); } Node Entity = World.EntitiesRoot.GetNodeOrNull(Identifier); if (Entity is null) { return; } Assert.ActualAssert(Entity is IEntity); SendCreateTo(Requester, (IEntity)Entity); }
public override void _Process(float Delta) { if (!Possessed) { NetUpdateDelta += Delta; return; } if (Dying) { return; } Assert.ActualAssert(MinAdsMultiplier > 0 && MinAdsMultiplier <= 1); AdsMultiplier = Ads ? Clamp(AdsMultiplier - (Delta * (1 - MinAdsMultiplier) / AdsTime), MinAdsMultiplier, 1) : Clamp(AdsMultiplier + (Delta * (1 - MinAdsMultiplier) / AdsTime), MinAdsMultiplier, 1); Cam.Fov = Game.Fov * AdsMultiplier; float Length = Clamp(ViewmodelMomentum.Length() - Delta * ViewmodelMomentumFriction, 0, 1); ViewmodelMomentum = ViewmodelMomentum.Normalized() * Length; ViewmodelItem.RotationDegrees = new Vector3( SafeSign(ViewmodelMomentum.y) * ViewmodelMomentum.y * ViewmodelMomentum.y * MaxViewmodelItemRotation * AdsMultiplier, 180 - SafeSign(ViewmodelMomentum.x) * ViewmodelMomentum.x * ViewmodelMomentum.x * MaxViewmodelItemRotation * AdsMultiplier, 0 ); ViewmodelArmJoint.RotationDegrees = new Vector3( -SafeSign(ViewmodelMomentum.y) * ViewmodelMomentum.y * ViewmodelMomentum.y * MaxViewmodelArmRotation * AdsMultiplier, -SafeSign(ViewmodelMomentum.x) * ViewmodelMomentum.x * ViewmodelMomentum.x * MaxViewmodelArmRotation * AdsMultiplier, 0 ); ViewmodelArmJoint.Translation = new Vector3( NormalViewmodelArmX * ((AdsMultiplier - MinAdsMultiplier) * (1 / (1 - MinAdsMultiplier))), ViewmodelArmJoint.Translation.y, ViewmodelArmJoint.Translation.z ); ApplyLookVertical(0); var ToRemove = new List <Hitscan.AdditiveRecoil>(); foreach (Hitscan.AdditiveRecoil Instance in ActiveAdditiveRecoil) { Instance.Life += Delta; if (Instance.Life > Instance.Length) { ToRemove.Add(Instance); } } foreach (Hitscan.AdditiveRecoil Instance in ToRemove) { ActiveAdditiveRecoil.Remove(Instance); } if (Inventory[InventorySlot] != null) { Items.ID Id = Inventory[InventorySlot].Id; ViewmodelItem.Mesh = Items.Meshes[Id]; ShaderMaterial Mat = new ShaderMaterial(); Mat.Shader = Items.TileShader; Mat.SetShaderParam("texture_albedo", Items.Textures[Id]); ViewmodelItem.MaterialOverride = Mat; ViewmodelItem.Show(); { Items.IdInfo Info = Items.IdInfos[Inventory[InventorySlot].Id]; if (IsPrimaryFiring && CurrentCooldown >= CurrentMaxCooldown && Info.UseDelegate != null && Info.FullAuto) { Items.UseItem(Inventory[InventorySlot], this); } } } else { ViewmodelItem.Hide(); } }
public void PhaseOut() { Assert.ActualAssert(!Possessed); Destroy(); }
public Option <int[]> ItemGive(Items.Instance ToGive) { Assert.ActualAssert(Net.Work.IsNetworkServer()); return(Inventory.Give(ToGive)); }
public override void _Ready() { Cam = GetNode <Camera>("SteelCamera"); ViewmodelItem = GetNode <MeshInstance>("SteelCamera/ViewmodelArmJoint/ViewmodelTiltJoint/ViewmodelItem"); ViewmodelItem.RotationDegrees = new Vector3(0, 180, 0); ViewmodelItem.Hide(); ViewmodelTiltJoint = GetNode <Position3D>("SteelCamera/ViewmodelArmJoint/ViewmodelTiltJoint"); ViewmodelArmJoint = GetNode <Position3D>("SteelCamera/ViewmodelArmJoint"); ViewmodelArmJoint.RotationDegrees = new Vector3(); NormalViewmodelArmX = ViewmodelArmJoint.Translation.x; ViewmodelArmJoint.Translation = new Vector3(NormalViewmodelArmX, ViewmodelArmJoint.Translation.y, ViewmodelArmJoint.Translation.z); ProjectileEmitterHinge = GetNode <Spatial>("ProjectileEmitterHinge"); ProjectileEmitter = GetNode <Spatial>("ProjectileEmitterHinge/ProjectileEmitter"); BodyCollision = GetNode <CollisionShape>("BodyCollision"); BodyCapsule = (CapsuleShape)BodyCollision.Shape; Assert.ActualAssert(BodyCapsule.Height == Height); if (Possessed) { Cam.MakeCurrent(); GetNode <RayCast>("SteelCamera/RayCast").AddException(this); GetNode <Spatial>("BodyScene").Free(); AddChild(HUDInstance); GhostInstance = (Ghost)GD.Load <PackedScene>("res://World/Ghost.tscn").Instance(); GhostInstance.Hide(); GetParent().CallDeferred("add_child", GhostInstance); SfxManager = GetNode <PlayerSfxManager>("PlayerSfxManager"); } else { HeadJoint = GetNode("BodyScene").GetNode <Spatial>("HeadJoint"); LegsJoint = GetNode("BodyScene").GetNode <Spatial>("LegsJoint"); RightLegFlames = GetNode("BodyScene").GetNode <CPUParticles>("LegsJoint/RightLegFlames"); LeftLegFlames = GetNode("BodyScene").GetNode <CPUParticles>("LegsJoint/LeftLegFlames"); ThirdPersonItem = GetNode("BodyScene").GetNode <MeshInstance>("ItemMesh"); ShaderMaterial Mat = new ShaderMaterial(); Mat.Shader = Items.TileShader; ThirdPersonItem.MaterialOverride = Mat; Spatial Body = GetNode <Spatial>("BodyScene"); Body.GetNode <HitboxClass>("BodyHitbox").OwningPlayer = this; Body.GetNode <HitboxClass>("HeadJoint/HeadHitbox").OwningPlayer = this; Body.GetNode <HitboxClass>("LegsJoint/LegsHitbox").OwningPlayer = this; World.AddEntityToChunk(this); return; } Reset(); if (Net.Work.IsNetworkServer()) { SetFreeze(false); GiveDefaultItems(); } World.AddEntityToChunk(this); }
public override void _Process(float Delta) //NOTE: Only runs on server { Assert.ActualAssert(Net.Work.IsNetworkServer()); TimeSinceUpdate += Delta; if (!DepreciatedCurrentChunkTuple.Equals(World.GetChunkTuple(Translation))) { World.Chunks[DepreciatedCurrentChunkTuple].Mobs.Remove(this); World.AddMobToChunk(this); } if (CurrentArea != GridClass.CalculateArea(Translation)) { CurrentArea = GridClass.CalculateArea(Translation); World.Grid.QueueRemoveItem(this); World.Grid.AddItem(this); } UpdateFloor(); CalcWants(Floor); if (OnFloor) { TargetPoint.Match( some: Target => { if (Target.Pos.Flattened().DistanceTo(Translation.Flattened()) <= 2) { TargetPoint = PointData.None(); } else { //Apply push toward TargetPoint but don't go to fast Momentum += ClampVec3( Target.Pos.Flattened() - Translation.Flattened(), Acceleration * Delta + Friction * Delta, Acceleration * Delta + Friction * Delta ); Vector3 Clamped = ClampVec3(Momentum.Flattened(), 0, TopSpeed); Momentum.x = Clamped.x; Momentum.z = Clamped.z; } }, none: () => { } ); //Friction Vector3 Horz = Momentum.Flattened(); Horz = Horz.Normalized() * Clamp(Horz.Length() - Friction * Delta, 0, TopSpeed); Momentum.x = Horz.x; Momentum.z = Horz.z; } else //Not on floor { Momentum.y = Clamp(Momentum.y - Gravity * Delta, -MaxFallSpeed, MaxFallSpeed); //Apply gravity } var OriginalChunkTuple = World.GetChunkTuple(Translation); Momentum = Move(Momentum, Delta, 1, 60, TopSpeed); Entities.MovedTick(this, OriginalChunkTuple); Entities.AsServerMaybePhaseOut(this); Entities.SendUpdate(Name, Translation); }
public static void SetupItems() { IdInfos = new Dictionary <ID, IdInfo>() { { ID.ERROR, new IdInfo { } }, { ID.PLATFORM, new IdInfo { PositionDelegate = BuildingLogic.PlatformBuildPosition, RotationDelegate = BuildingLogic.PlatformBuildRotation, UseDelegate = null, FullAuto = false, CanAds = false, DisallowedCollisions = new ID[] { ID.PLATFORM } } }, { ID.WALL, new IdInfo { PositionDelegate = BuildingLogic.WallBuildPosition, RotationDelegate = BuildingLogic.WallBuildRotation, UseDelegate = null, FullAuto = false, CanAds = false, DisallowedCollisions = new ID[] { ID.WALL, ID.TRIANGLE_WALL } } }, { ID.SLOPE, new IdInfo { PositionDelegate = BuildingLogic.SlopeBuildPosition, RotationDelegate = BuildingLogic.SlopeBuildRotation, UseDelegate = null, FullAuto = false, CanAds = false, DisallowedCollisions = new ID[] { ID.SLOPE, ID.PIPE, ID.PIPE_JOINT } } }, { ID.TRIANGLE_WALL, new IdInfo { PositionDelegate = BuildingLogic.TriangleWallBuildPosition, RotationDelegate = BuildingLogic.TriangleWallBuildRotation, UseDelegate = null, FullAuto = false, CanAds = false, DisallowedCollisions = new ID[] { ID.TRIANGLE_WALL, ID.WALL } } }, { ID.PIPE, new IdInfo { PositionDelegate = BuildingLogic.PipeBuildPosition, RotationDelegate = BuildingLogic.PipeBuildRotation, DisallowedCollisions = new ID[] { ID.SLOPE, ID.PIPE, ID.PIPE_JOINT } } }, { ID.PIPE_JOINT, new IdInfo { PositionDelegate = BuildingLogic.PipeJointBuildPosition, RotationDelegate = BuildingLogic.PipeJointBuildRotation, DisallowedCollisions = new ID[] { ID.SLOPE, ID.PIPE, ID.PIPE_JOINT } } }, { ID.LOCKER, new IdInfo { PositionDelegate = BuildingLogic.LockerBuildPosition, RotationDelegate = BuildingLogic.LockerBuildRotation, DisallowedCollisions = new ID[] { ID.LOCKER } } }, { ID.ROCKET_JUMPER, new IdInfo { UseDelegate = RocketJumper.Fire, FullAuto = false, CanAds = false } }, { ID.THUNDERBOLT, new IdInfo { UseDelegate = Thunderbolt.Fire, FullAuto = false, CanAds = true } }, { ID.SCATTERSHOCK, new IdInfo { UseDelegate = Scattershock.Fire, FullAuto = false, CanAds = true } }, { ID.SWIFTSPARK, new IdInfo { UseDelegate = SwiftSpark.Fire, FullAuto = true, CanAds = true } }, { ID.SLIME_SPAWNER, new IdInfo { UseDelegate = (Items.Instance Item, Player UsingPlayer) => { Mobs.SpawnMob(Mobs.ID.Slime, UsingPlayer.Translation); }, FullAuto = false, CanAds = false } } }; //Lets make sure that every ID has an entry //This won't help mods but will help us greatly foreach (ID Type in System.Enum.GetValues(typeof(ID))) { if (Type == ID.NONE) { continue; } Assert.ActualAssert(IdInfos.ContainsKey(Type)); } }
public override void _Ready() { Assert.ActualAssert(GetParent() is PipeCoreLogic); Parent = GetParent() as PipeCoreLogic; }
public override void DropData(Vector2 Pos, object Data) { if (Data is int FromSlot && ParentMenu.Source != null) { if (Source == ParentMenu.Source.Source && Slot == FromSlot) { return; //Same source and slot, we dropped on ourself } Items.Instance Moving = ParentMenu.Source.Source.Inventory[FromSlot]; Assert.ActualAssert(Moving != null); if (Moving == null) { return; //Makes Roslyn happy } Items.Instance Original = Source.Inventory[Slot]; int RetrieveCount = ParentMenu.CalcRetrieveCount(Moving.Count); bool EmptyMoving = RetrieveCount == Moving.Count; //If we are moving all, empty the the source slot if (Original == null) //Replace (no item at target) { if (Net.Work.IsNetworkServer()) { Source.NetUpdateInventorySlot(Slot, Moving.Id, RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.NetEmptyInventorySlot(FromSlot); } else { ParentMenu.Source.Source.NetUpdateInventorySlot(FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } else { Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), Slot, Moving.Id, RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetEmptyInventorySlot), FromSlot); } else { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } } else { if (Moving.Id == Original.Id) //Combine at target { if (Net.Work.IsNetworkServer()) { Source.NetUpdateInventorySlot(Slot, Original.Id, Original.Count + RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.NetEmptyInventorySlot(FromSlot); } else { ParentMenu.Source.Source.NetUpdateInventorySlot(FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } else { Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), Slot, Original.Id, Original.Count + RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetEmptyInventorySlot), FromSlot); } else { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } } else if (RetrieveCount == Moving.Count) //Swap, only if we are moving all from the source slot { if (Net.Work.IsNetworkServer()) { Source.NetUpdateInventorySlot(Slot, Moving.Id, Moving.Count); ParentMenu.Source.Source.NetUpdateInventorySlot(FromSlot, Original.Id, Original.Count); } else { Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), Slot, Moving.Id, Moving.Count); ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), FromSlot, Original.Id, Original.Count); } } } } }