public virtual void Accepted(CharacterEntity character, Seat seat) { GainControlOfVehiclePacketOut gcovpo = new GainControlOfVehiclePacketOut(character, this); TheRegion.SendToVisible(lPos, gcovpo); // TODO: handle players coming into/out-of view of the vehicle + driver! }
public JointVehicleMotor ConnectWheel(VehiclePartEntity wheel, bool driving, bool powered) { wheel.SetFriction(2.5f); Vector3 left = Quaternion.Transform(new Vector3(-1, 0, 0), wheel.GetOrientation()); Vector3 up = Quaternion.Transform(new Vector3(0, 0, 1), wheel.GetOrientation()); JointSlider pointOnLineJoint = new JointSlider(this, wheel, -new Location(up)); JointLAxisLimit suspensionLimit = new JointLAxisLimit(this, wheel, 0f, 0.1f, wheel.GetPosition(), wheel.GetPosition(), -new Location(up)); JointPullPush spring = new JointPullPush(this, wheel, -new Location(up), true); BEPUphysics.CollisionRuleManagement.CollisionRules.AddRule(wheel.Body, this.Body, BEPUphysics.CollisionRuleManagement.CollisionRule.NoBroadPhase); // TODO: How necessary is this? Should we replicate this clientside? if (driving) { JointSpinner spinner = new JointSpinner(this, wheel, new Location(-left)); TheRegion.AddJoint(spinner); } else { JointSwivelHinge swivelhinge = new JointSwivelHinge(this, wheel, new Location(up), new Location(-left)); TheRegion.AddJoint(swivelhinge); } TheRegion.AddJoint(pointOnLineJoint); TheRegion.AddJoint(suspensionLimit); TheRegion.AddJoint(spring); if (powered) { JointVehicleMotor motor = new JointVehicleMotor(this, wheel, new Location(driving ? left : up), !driving); TheRegion.AddJoint(motor); return(motor); } return(null); }
public void UpdatePath() { Location goal = TargetPosition; if (goal.IsNaN()) { if (TargetEntity == null) { Path = null; return; } goal = TargetEntity.GetPosition(); } Location selfpos = GetPosition(); if ((goal - selfpos).LengthSquared() > MaxPathFindDistance * MaxPathFindDistance) { TargetPosition = Location.NaN; // TODO: Configurable "can't find path" result -> giveup vs. teleport TargetEntity = null; Path = null; return; } List <Location> tpath = TheRegion.FindPathAsyncDouble(selfpos, goal, MaxPathFindDistance, new PathfinderOptions()); if (tpath == null) { TargetPosition = Location.NaN; // TODO: Configurable "can't find path" result -> giveup vs. teleport TargetEntity = null; Path = null; return; } Path = new ListQueue <Location>(tpath); PathUpdate = 1; // TODO: Configurable update time }
void Events_ContactCreated(EntityCollidable sender, Collidable other, CollidablePairHandler pair, ContactData contact) { if (TheRegion.GlobalTickTimeLocal - lastSoundTime < soundmaxrate) { return; } lastSoundTime = TheRegion.GlobalTickTimeLocal; if (other is FullChunkObject) { ((ConvexFCOPairHandler)pair).ContactInfo(/*contact.Id*/ 0, out ContactInformation info); float vellen = (float)(Math.Abs(info.RelativeVelocity.X) + Math.Abs(info.RelativeVelocity.Y) + Math.Abs(info.RelativeVelocity.Z)); float mod = vellen / 5; if (mod > 2) { mod = 2; } Location block = new Location(contact.Position - contact.Normal * 0.01f); BlockInternal bi = TheRegion.GetBlockInternal(block); MaterialSound sound = ((Material)bi.BlockMaterial).Sound(); if (sound != MaterialSound.NONE) { new DefaultSoundPacketIn() { TheClient = TheClient }.PlayDefaultBlockSound(block, sound, mod, 0.5f * mod); } MaterialSound sound2 = Mat.Sound(); if (sound2 != MaterialSound.NONE) { new DefaultSoundPacketIn() { TheClient = TheClient }.PlayDefaultBlockSound(block, sound2, mod, 0.5f * mod); } } else if (other is EntityCollidable) { BEPUphysics.Entities.Entity e = ((EntityCollidable)other).Entity; BEPUutilities.Vector3 velocity = BEPUutilities.Vector3.Zero; if (e != null) { velocity = e.LinearVelocity; } BEPUutilities.Vector3 relvel = Body.LinearVelocity - velocity; float vellen = (float)(Math.Abs(relvel.X) + Math.Abs(relvel.Y) + Math.Abs(relvel.Z)); float mod = vellen / 5; if (mod > 2) { mod = 2; } MaterialSound sound = Mat.Sound(); if (sound != MaterialSound.NONE) { new DefaultSoundPacketIn() { TheClient = TheClient }.PlayDefaultBlockSound(new Location(contact.Position), sound, mod, 0.5f * mod); } } }
public void PlayRelevantSounds() { if (SoundTimeout > 0) { SoundTimeout -= TheRegion.Delta; return; } Location vel = GetVelocity(); if (vel.LengthSquared() < 0.2) { return; } Material mat = TheRegion.GetBlockMaterial(GetPosition() + new Location(0, 0, -0.05f)); MaterialSound sound = mat.Sound(); if (sound == MaterialSound.NONE) { return; } double velLen = vel.Length(); new DefaultSoundPacketIn() { TheClient = TheClient }.PlayDefaultBlockSound(GetPosition(), sound, 1f, 0.14f * (float)velLen); TheClient.Particles.Steps(GetPosition(), mat, GetVelocity(), (float)velLen); SoundTimeout = (Utilities.UtilRandom.NextDouble() * 0.2 + 1.0) / velLen; }
public bool ConsumeFuel(double amt) { // TODO: Gamemode check! ItemStack stackf = null; foreach (ItemStack item in Items.Items) { if (item.Name == "fuel") { stackf = item; break; } } if (stackf == null) { return(false); } fuelCom += amt; if (fuelCom > 1) { fuelCom -= 1; Items.RemoveItem(stackf, 1); TheRegion.SendToVisible(GetPosition(), new FlagEntityPacketOut(this, EntityFlag.HAS_FUEL, ConsumeFuel(0) ? 1f: 0f)); } else { TheRegion.SendToVisible(GetPosition(), new FlagEntityPacketOut(this, EntityFlag.HAS_FUEL, 1f)); } return(true); }
public bool ShouldSeePosition(Location pos) { if (pos.IsNaN()) { return(false); } return(ShouldSeeChunk(TheRegion.ChunkLocFor(pos))); }
public bool ShouldSeeLODPositionOneSecondAgo(Location pos) { if (pos.IsNaN() || losPos.IsNaN()) { return(false); } return(ShouldSeeLODChunkOneSecondAgo(TheRegion.ChunkLocFor(pos))); }
public bool ShouldLoadPositionPreviously(Location pos) { if (pos.IsNaN()) { return(false); } return(ShouldLoadChunkPreviously(TheRegion.ChunkLocFor(pos))); }
public override void Accepted(CharacterEntity character, Seat seat) { base.Accepted(character, seat); // TODO: Track players entering/exiting view! FlagEntityPacketOut fepo = new FlagEntityPacketOut(this, EntityFlag.HELO_TILT_MOD, TiltMod); TheRegion.SendToVisible(lPos, fepo); }
public override void Die() { if (Removed) { return; } TheRegion.Explode(GetPosition(), 5); RemoveMe(); }
public override void Fly() { if (IsFlying) { return; } base.Fly(); TheRegion.SendToAll(new FlagEntityPacketOut(this, EntityFlag.FLYING, 1)); TheRegion.SendToAll(new FlagEntityPacketOut(this, EntityFlag.MASS, 0)); }
public override void Unfly() { if (!IsFlying) { return; } base.Unfly(); TheRegion.SendToAll(new FlagEntityPacketOut(this, EntityFlag.FLYING, 0)); TheRegion.SendToAll(new FlagEntityPacketOut(this, EntityFlag.MASS, PreFlyMass)); }
public void StartUse(Entity user) { if (!Removed) { int itemMusicType = Original.GetAttributeI("music_type", 0); double itemMusicVolume = Original.GetAttributeF("music_volume", 0.5f); double itemMusicPitch = Original.GetAttributeF("music_pitch", 1f); TheRegion.PlaySound("sfx/musicnotes/" + itemMusicType, GetPosition(), itemMusicVolume, itemMusicPitch); } }
public bool ShouldSeeLODChunkOneSecondAgo(Vector3i cpos) { Vector3i wpos = TheRegion.ChunkLocFor(losPos); if (Math.Abs(cpos.X - wpos.X) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cpos.Y - wpos.Y) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cpos.Z - wpos.Z) > (ViewRadiusInChunks + ViewRadExtra5Height)) { return(false); } return(true); }
/// <summary> /// Ticks the physics entity. /// </summary> public override void Tick() { if (!TheRegion.IsVisible(GetPosition())) { if (Body.ActivityInformation.IsActive) { wasActive = true; // TODO: Is this needed? if (Body.ActivityInformation.SimulationIsland != null) { Body.ActivityInformation.SimulationIsland.IsActive = false; } } } else if (wasActive) { wasActive = false; Body.ActivityInformation.Activate(); } Vector3i cpos = TheRegion.ChunkLocFor(GetPosition()); if (CanSave && !TheRegion.TryFindChunk(cpos, out Chunk _)) // TODO: is this really needed every tick? { TheRegion.LoadChunk(cpos); } if (!GenBlockShadow)// TODO: and world config allows trackables { if (TheRegion.GetEntitiesInRadius(GetPosition(), 1.5f, EntityType.SMASHER_PRIMTIVE).Count == 0) { // TODO: 5 * 60 -> world config TheRegion.SpawnEntity(new SmasherPrimitiveEntity(TheRegion, Math.Min((float)GetScaleEstimate(), 2f), TheRegion.TheWorld.GlobalTickTime + (5 * 60)) { Position = GetPosition() }); } } // TODO: More genericish if (TheRegion.Generator is SphereGeneratorCore) { Location pos = new Location(Body.Position); double scale = TheRegion.TheWorld.GeneratorScale; Location gravDir; if (pos.LengthSquared() > scale * scale) { gravDir = new Location(scale / pos.X, scale / pos.Y, scale / pos.Z); } else { gravDir = pos / scale; } SetGravity(gravDir * (-TheRegion.GravityStrength)); } }
public bool ShouldLoadChunk(Vector3i cpos) { Vector3i wpos = TheRegion.ChunkLocFor(LoadRelPos); if (Math.Abs(cpos.X - wpos.X) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cpos.Y - wpos.Y) > (ViewRadiusInChunks + ViewRadExtra5) || Math.Abs(cpos.Z - wpos.Z) > (ViewRadiusInChunks + ViewRadExtra5Height)) { return(false); } return(true); }
public override void SpawnBody() { base.SpawnBody(); Motion = new PlaneMotionConstraint(this); TheRegion.PhysicsWorld.Add(Motion); Wings = new JointFlyingDisc(this) { IsAPlane = true }; TheRegion.AddJoint(Wings); HandleWheels(); }
public void ConnectFlap(VehiclePartEntity flap, FDSSection flapDat) { JointBallSocket jbs = new JointBallSocket(this, flap, flap.GetPosition()); // TODO: necessity? TheRegion.AddJoint(jbs); JointNoCollide jnc = new JointNoCollide(this, flap); TheRegion.AddJoint(jnc); string mode = flapDat.GetString("mode"); VehicleFlap vf = new VehicleFlap() { MaxAngle = flapDat.GetDouble("max_angle", 10).Value, Speed = flapDat.GetDouble("corrective_speed", 2.25).Value }; if (mode == "roll/l") { JointHinge jh = new JointHinge(this, flap, new Location(1, 0, 0)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(1, 0, 0), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_RollL.Add(vf); } else if (mode == "roll/r") { JointHinge jh = new JointHinge(this, flap, new Location(1, 0, 0)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(1, 0, 0), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_RollR.Add(vf); } else if (mode == "yaw") { JointHinge jh = new JointHinge(this, flap, new Location(0, 0, 1)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(0, 0, 1), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_Yaw.Add(vf); } else if (mode == "pitch") { JointHinge jh = new JointHinge(this, flap, new Location(1, 0, 0)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(1, 0, 0), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_Pitch.Add(vf); } }
public override void Tick() { timer += TheRegion.Delta; if (timer > boomtime) { RemoveMe(); TheRegion.PaintBomb(GetPosition(), Color, 5); // TODO: radius, etc. settings } else { base.Tick(); } }
public override void Tick() { timer += TheRegion.Delta; if (timer > boomtime) { RemoveMe(); TheRegion.Explode(GetPosition()); // TODO: Damage settings, etc. } else { base.Tick(); } }
public override void SpawnBody() { base.SpawnBody(); Body.LinearDamping = 0.0; HandleWheels(); Motion = new PlaneMotionConstraint(this); TheRegion.PhysicsWorld.Add(Motion); Wings = new JointFlyingDisc(this) { IsAPlane = true }; TheRegion.AddJoint(Wings); (Wings.CurrentJoint as FlyingDiscConstraint).PlaneLiftHelper = LiftHelper; }
public void SetTypingStatus(bool isTyping) { IsTyping = isTyping; // TODO: Generic find-all-players-that-can-see-me method Vector3i ch = TheRegion.ChunkLocFor(GetPosition()); SetStatusPacketOut pack = new SetStatusPacketOut(this, ClientStatus.TYPING, (byte)(IsTyping ? 1 : 0)); foreach (PlayerEntity player in TheRegion.Players) { if (player.CanSeeChunk(ch)) { player.Network.SendPacket(pack); } } }
public override void Tick() { timer += TheRegion.Delta; while (timer > pulse) { if (SmokeLeft <= 0) { break; } Location colo = new Location(col.R / 255f, col.G / 255f, col.B / 255f); TheRegion.SendToAll(new ParticleEffectPacketOut(SmokeType, 5, GetPosition(), colo)); timer -= pulse; SmokeLeft--; } base.Tick(); }
public override void SpawnBody() { base.SpawnBody(); if (CursorMarker == null) { CursorMarker = new ModelEntity("cube", TheRegion); CursorMarker.scale = new Location(0.1f, 0.1f, 0.1f); CursorMarker.mode = ModelCollisionMode.AABB; CursorMarker.CGroup = CollisionUtil.NonSolid; CursorMarker.Visible = false; CursorMarker.CanSave = false; TheRegion.SpawnEntity(CursorMarker); } Jetpack = new JetpackMotionConstraint(this); TheRegion.PhysicsWorld.Add(Jetpack); }
public bool ShouldSeeChunk(Vector3i cpos) { if (LoadRelPos.IsNaN()) { return(false); } Vector3i wpos = TheRegion.ChunkLocFor(LoadRelPos); if (Math.Abs(cpos.X - wpos.X) > ViewRadiusInChunks || Math.Abs(cpos.Y - wpos.Y) > ViewRadiusInChunks || Math.Abs(cpos.Z - wpos.Z) > ViewRadiusInChunks) { return(false); } return(true); }
public void OnCollide(object sender, CollisionEventArgs args) { if (Stuck) { return; } double len = GetVelocity().Length(); SetPosition(args.Info.Position + (GetVelocity() / len) * 0.05f); SetVelocity(Location.Zero); Gravity = Location.Zero; if (HasHat) { SolidHat = new ModelEntity("invisbox", TheRegion); SolidHat.SetMass(0); SolidHat.SetPosition(GetPosition()); SolidHat.SetOrientation(GetOrientation()); SolidHat.scale = new Location(0.6, 1.5, 0.6); SolidHat.Visible = false; SolidHat.CanSave = false; TheRegion.SpawnEntity(SolidHat); } if (args.Info.HitEnt != null) { PhysicsEntity pe = (PhysicsEntity)args.Info.HitEnt.Tag; if (pe is EntityDamageable) { ((EntityDamageable)pe).Damage(Damage + DamageTimesVelocity * (double)len); } Vector3 loc = (args.Info.Position - pe.GetPosition()).ToBVector(); Vector3 impulse = GetVelocity().ToBVector() * DamageTimesVelocity / 1000f; pe.Body.ApplyImpulse(ref loc, ref impulse); StuckTo = pe; if (HasHat) { CollisionRules.AddRule(pe.Body, SolidHat.Body, CollisionRule.NoBroadPhase); // TODO: Broadcast this info! Perhaps abuse the joint system? } } TheRegion.SendToAll(new PrimitiveEntityUpdatePacketOut(this)); if (args.Info.HitEnt != null) { PhysicsEntity pe = (PhysicsEntity)args.Info.HitEnt.Tag; JointForceWeld jfw = new JointForceWeld(pe, this); TheRegion.AddJoint(jfw); } }
/// <summary> /// General entity render. /// </summary> public override void Render() { if (!Visible || model.Meshes.Count == 0) { return; } TheClient.SetEnts(); RigidTransform rt = new RigidTransform(Body.Position, Body.Orientation); RigidTransform.Transform(ref ModelMin, ref rt, out BEPUutilities.Vector3 bmin); RigidTransform.Transform(ref ModelMax, ref rt, out BEPUutilities.Vector3 bmax); if (TheClient.MainWorldView.CFrust != null && !TheClient.MainWorldView.CFrust.ContainsBox(new Location(bmin), new Location(bmax))) { return; } double maxr = TheClient.CVars.r_modeldistance.ValueF; double distsq = GetPosition().DistanceSquared(TheClient.MainWorldView.RenderRelative); if (GenBlockShadows && distsq > maxr * maxr) // TODO: LOD-able option? { // TODO: Rotation? model.DrawLOD(GetPosition() + ClientUtilities.ConvertD(transform.ExtractTranslation()), TheClient.MainWorldView); return; } Matrix4d orient = GetOrientationMatrix(); Matrix4d mat = (Matrix4d.Scale(ClientUtilities.ConvertD(scale)) * transform * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(new Location(Body.CollisionInformation.LocalPosition))) * orient * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(GetPosition()))); TheClient.MainWorldView.SetMatrix(2, mat); if (!TheClient.MainWorldView.RenderingShadows) { TheClient.Rendering.SetMinimumLight(0.0f, TheClient.MainWorldView); } if (model.Meshes[0].vbo.Tex == null) { TheClient.Textures.White.Bind(); } if (!TheClient.MainWorldView.RenderingShadows && ((TheClient.CVars.r_fast.ValueB && !TheClient.CVars.r_forward_lights.ValueB) || !TheClient.CVars.r_lighting.ValueB)) { OpenTK.Vector4 sadj = TheRegion.GetSunAdjust(); float skyl = TheRegion.GetSkyLightBase(GetPosition() + new Location(0, 0, ModelMax.Z)); TheClient.Rendering.SetColor(new OpenTK.Vector4(sadj.X * skyl, sadj.Y * skyl, sadj.Z * skyl, 1.0f), TheClient.MainWorldView); } model.Draw(); // TODO: Animation(s)? }
public override void Tick() { base.Tick(); Location pos = GetPosition(); Location rad = new Location(CBody.BodyRadius, CBody.BodyRadius, 0); double halfeye = CBHHeight * (CBody.StanceManager.CurrentStance == Stance.Standing ? 1.8 : 1.5) * 0.5; bool uw1 = TheRegion.InWater(pos - rad, pos + rad + new Location(0, 0, halfeye)); bool uw2 = TheRegion.InWater(pos - rad + new Location(0, 0, halfeye), pos + rad + new Location(0, 0, halfeye * 2)); if (uw1 || uw2) { double mult = uw1 ? (uw2 ? 0.6 : 0.3) : 0.3; SetForSwim(mult, Body.Space.ForceUpdater.Gravity * (1.0 - mult)); } else { SetForGround(); } }
/// <summary> /// Ticks the physics entity. /// </summary> public override void Tick() { if (!TheRegion.IsVisible(GetPosition())) { if (Body.ActivityInformation.IsActive) { wasActive = true; // TODO: Is this needed? if (Body.ActivityInformation.SimulationIsland != null) { Body.ActivityInformation.SimulationIsland.IsActive = false; } } } else if (wasActive) { wasActive = false; Body.ActivityInformation.Activate(); } Vector3i cpos = TheRegion.ChunkLocFor(GetPosition()); if (CanSave && !TheRegion.LoadedChunks.ContainsKey(cpos)) // TODO: is this really needed every tick? { TheRegion.LoadChunk(cpos); } // TODO: More genericish if (TheRegion.Generator is SphereGeneratorCore) { Location pos = new Location(Body.Position); double scale = TheRegion.TheWorld.GeneratorScale; Location gravDir; if (pos.LengthSquared() > scale * scale) { gravDir = new Location(scale / pos.X, scale / pos.Y, scale / pos.Z); } else { gravDir = pos / scale; } SetGravity(gravDir * (-TheRegion.GravityStrength)); } }