public override void Awake() { base.Awake(); AkGameObjectTracker.Attach(this.Entity, this.Position); this.particles = ParticleSystem.Get(this.main, "Rift"); this.EnabledInEditMode = false; this.EnabledWhenPaused = false; this.Add(new CommandBinding(this.Enable, (Action)this.go)); rifts.Add(this); }
public override void Bind(Entity entity, Main main, bool creating = false) { entity.CannotSuspendByDistance = true; Transform transform = entity.GetOrCreate <Transform>("Transform"); Transform mapTransform = entity.GetOrCreate <Transform>("MapTransform"); mapTransform.Selectable.Value = false; StaticSlider slider = entity.GetOrCreate <StaticSlider>("StaticSlider"); Factory.Get <VoxelFactory>().InternalBind(entity, main, creating, mapTransform); slider.Add(new TwoWayBinding <Matrix>(slider.Transform, mapTransform.Matrix)); slider.Add(new Binding <Matrix>(slider.EditorTransform, transform.Matrix)); Voxel voxel = entity.Get <Voxel>(); slider.Add(new Binding <Vector3>(voxel.LinearVelocity, slider.LinearVelocity)); AkGameObjectTracker.Attach(entity, voxel.Transform); SoundKiller.Add(entity, AK.EVENTS.STOP_ALL_OBJECT); if (main.EditorEnabled) { entity.Add(new Binding <Matrix>(entity.GetOrCreate <SliderCommon>("SliderCommon").OriginalTransform, voxel.Transform)); } entity.Add("Forward", slider.Forward); entity.Add("Backward", slider.Backward); entity.Add("OnHitMax", slider.OnHitMax); entity.Add("OnHitMin", slider.OnHitMin); entity.Add("Direction", slider.Direction); entity.Add("Minimum", slider.Minimum); entity.Add("Maximum", slider.Maximum); entity.Add("Speed", slider.Speed); entity.Add("Goal", slider.Goal); entity.Add("StartAtMinimum", slider.StartAtMinimum); entity.Add("EnablePhysics", voxel.EnablePhysics); entity.Add("Position", slider.Position, new PropertyEntry.EditorData { Readonly = true }); entity.Add("MovementLoop", slider.MovementLoop, new PropertyEntry.EditorData { Options = WwisePicker.Get(main) }); entity.Add("MovementStop", slider.MovementStop, new PropertyEntry.EditorData { Options = WwisePicker.Get(main) }); entity.Add("UVRotation", voxel.UVRotation); entity.Add("UVOffset", voxel.UVOffset); if (main.EditorEnabled) { this.attachEditorComponents(entity, main); } }
public override void Awake() { base.Awake(); AkGameObjectTracker.Attach(this.Entity, this.Position); this.particles = ParticleSystem.Get(this.main, "Rift"); this.EnabledInEditMode = false; this.EnabledWhenPaused = false; this.Add(new CommandBinding(this.Enable, delegate() { if (this.Coords.Length == 0) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_RIFT_OPEN, this.Entity); if (PlayerFactory.Instance != null) { PlayerFactory.Instance.Get <CameraController>().Shake.Execute(this.Position, 30.0f); } Entity voxelEntity = this.Voxel.Value.Target; if (voxelEntity != null && voxelEntity.Active) { Voxel v = voxelEntity.Get <Voxel>(); Voxel.Coord center = this.Coordinate; Vector3 pos = v.GetRelativePosition(center); int radius = this.Radius; List <VoxelFill.CoordinateEntry> coords = Rift.coordSortCache; for (Voxel.Coord x = center.Move(Direction.NegativeX, radius); x.X < center.X + radius; x.X++) { for (Voxel.Coord y = x.Move(Direction.NegativeY, radius); y.Y < center.Y + radius; y.Y++) { for (Voxel.Coord z = y.Move(Direction.NegativeZ, radius); z.Z < center.Z + radius; z.Z++) { float distance = (pos - v.GetRelativePosition(z)).Length(); if (distance <= radius && v[z] != Components.Voxel.States.Empty) { coords.Add(new VoxelFill.CoordinateEntry { Coord = z.Clone(), Distance = distance }); } } } } coords.Sort(new LambdaComparer <VoxelFill.CoordinateEntry>((x, y) => x.Distance.CompareTo(y.Distance))); this.Coords.AddAll(coords.Select(x => x.Coord)); coords.Clear(); } } })); rifts.Add(this); }
public override void Awake() { base.Awake(); AkGameObjectTracker.Attach(this.Entity, this.Position); this.Entity.CannotSuspendByDistance = !this.Is3D; this.Entity.Add(new NotifyBinding(delegate() { this.Entity.CannotSuspendByDistance = !this.Is3D; }, this.Is3D)); this.Play.Action = this.play; this.Add(new CommandBinding(this.Disable, (Action)this.stop)); this.Add(new CommandBinding(this.OnSuspended, (Action)this.stop)); }
public override void Bind(Entity entity, Main main, bool creating = false) { Transform transform = entity.GetOrCreate <Transform>("Transform"); PlayerTrigger trigger = entity.GetOrCreate <PlayerTrigger>("PlayerTrigger"); trigger.Serialize = false; VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main); trigger.Radius.Value = 3; trigger.Add(new Binding <Vector3>(trigger.Position, transform.Position)); Collectible collectible = entity.GetOrCreate <Collectible>("Collectible"); collectible.Add(new CommandBinding(trigger.PlayerEntered, collectible.PlayerTouched)); AkGameObjectTracker.Attach(entity, trigger.Position); PointLight light = entity.Create <PointLight>(); light.Serialize = false; light.Attenuation.Value = 10.0f; light.Color.Value = new Vector3(1.25f, 1.75f, 2.0f); light.Add(new Binding <Vector3>(light.Position, transform.Position)); ParticleEmitter distortionEmitter = entity.GetOrCreate <ParticleEmitter>("DistortionEmitter"); distortionEmitter.Serialize = false; distortionEmitter.Add(new Binding <Vector3>(distortionEmitter.Position, trigger.Position)); distortionEmitter.ParticleType.Value = "Distortion"; distortionEmitter.ParticlesPerSecond.Value = 4; distortionEmitter.Jitter.Value = new Vector3(0.5f); Model model = entity.GetOrCreate <Model>("Model"); model.MapContent.Value = true; model.Filename.Value = "Models\\sphere"; model.Serialize = false; model.Scale.Value = new Vector3(0.5f); model.Add(new Binding <Matrix>(model.Transform, transform.Matrix)); this.SetMain(entity, main); attachable.EditorProperties(); entity.Add("Collected", collectible.PlayerTouched); }
public override void Bind(Entity entity, Main main, bool creating = false) { Slider slider = entity.GetOrCreate <Slider>("Slider"); JointFactory.Bind(entity, main, slider.CreateJoint, false, creating); Components.Joint joint = entity.GetOrCreate <Components.Joint>("Joint"); slider.Add(new Binding <Direction>(slider.Direction, joint.Direction)); DynamicVoxel voxel = entity.Get <DynamicVoxel>(); voxel.KineticFriction.Value = voxel.StaticFriction.Value = 0; AkGameObjectTracker.Attach(entity, voxel.Transform); SoundKiller.Add(entity, AK.EVENTS.STOP_ALL_OBJECT); if (main.EditorEnabled) { entity.Add(new Binding <Matrix>(entity.GetOrCreate <SliderCommon>("SliderCommon").OriginalTransform, voxel.Transform)); } entity.Add("Forward", slider.Forward); entity.Add("Backward", slider.Backward); entity.Add("OnHitMax", slider.OnHitMax); entity.Add("OnHitMin", slider.OnHitMin); entity.Add("MovementLoop", slider.MovementLoop, new PropertyEntry.EditorData { Options = WwisePicker.Get(main) }); entity.Add("MovementStop", slider.MovementStop, new PropertyEntry.EditorData { Options = WwisePicker.Get(main) }); entity.Add("Direction", joint.Direction); entity.Add("Minimum", slider.Minimum); entity.Add("Maximum", slider.Maximum); entity.Add("Locked", slider.Locked); entity.Add("Speed", slider.Speed); entity.Add("Goal", slider.Goal); entity.Add("Servo", slider.Servo); entity.Add("StartAtMinimum", slider.StartAtMinimum); entity.Add("MaxForce", slider.MaxForce); entity.Add("UVRotation", voxel.UVRotation); entity.Add("UVOffset", voxel.UVOffset); entity.Add("CannotSuspendByDistance", voxel.CannotSuspendByDistance); }
public override void Bind(Entity entity, Main main, bool creating = false) { Transform transform = entity.GetOrCreate <Transform>("Transform"); this.SetMain(entity, main); VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main); attachable.Enabled.Value = true; entity.Add("AttachOffset", attachable.Offset); if (!main.EditorEnabled) { Property <Vector3> soundPosition = new Property <Vector3>(); VoxelAttachable.BindTarget(entity, soundPosition); AkGameObjectTracker.Attach(entity, soundPosition); AkSoundEngine.PostEvent(AK.EVENTS.PLAY_WHITE_LIGHT, entity); SoundKiller.Add(entity, AK.EVENTS.STOP_WHITE_LIGHT); } }
public override void Bind(Entity entity, Main main, bool creating = false) { Main.Config settings = main.Settings; Transform transform = entity.GetOrCreate <Transform>("Transform"); entity.CannotSuspend = true; PlayerFactory.Instance = entity; this.SetMain(entity, main); FPSInput input = new FPSInput(); input.EnabledWhenPaused = false; entity.Add("Input", input); Updater parkour = entity.Create <Updater>(); Updater jumper = entity.Create <Updater>(); Player player = entity.GetOrCreate <Player>("Player"); AnimatedModel firstPersonModel = entity.GetOrCreate <AnimatedModel>("FirstPersonModel"); firstPersonModel.MapContent = false; firstPersonModel.Serialize = false; firstPersonModel.Filename.Value = "Models\\joan-firstperson"; firstPersonModel.CullBoundingBox.Value = false; AnimatedModel model = entity.GetOrCreate <AnimatedModel>("Model"); model.MapContent = false; model.Serialize = false; model.Filename.Value = "Models\\joan"; model.CullBoundingBox.Value = false; AnimationController anim = entity.GetOrCreate <AnimationController>("AnimationController"); RotationController rotation = entity.GetOrCreate <RotationController>("Rotation"); BlockPredictor predictor = entity.GetOrCreate <BlockPredictor>("BlockPredictor"); Jump jump = entity.GetOrCreate <Jump>("Jump"); RollKickSlide rollKickSlide = entity.GetOrCreate <RollKickSlide>("RollKickSlide"); Vault vault = entity.GetOrCreate <Vault>("Vault"); WallRun wallRun = entity.GetOrCreate <WallRun>("WallRun"); VoxelTools voxelTools = entity.GetOrCreate <VoxelTools>("VoxelTools"); Footsteps footsteps = entity.GetOrCreate <Footsteps>("Footsteps"); FallDamage fallDamage = entity.GetOrCreate <FallDamage>("FallDamage"); CameraController cameraControl = entity.GetOrCreate <CameraController>("CameraControl"); FPSCamera fpsCamera = entity.GetOrCreate <FPSCamera>("FPSCamera"); fpsCamera.Enabled.Value = false; Rumble rumble = entity.GetOrCreate <Rumble>("Rumble"); Property <Vector3> floor = new Property <Vector3>(); transform.Add(new Binding <Vector3>(floor, () => transform.Position + new Vector3(0, player.Character.Height * -0.5f, 0), transform.Position, player.Character.Height)); AkGameObjectTracker.Attach(entity, floor); predictor.Add(new Binding <Vector3>(predictor.FootPosition, floor)); predictor.Add(new Binding <Vector3>(predictor.LinearVelocity, player.Character.LinearVelocity)); predictor.Add(new Binding <float>(predictor.Rotation, rotation.Rotation)); predictor.Add(new Binding <float>(predictor.MaxSpeed, player.Character.MaxSpeed)); predictor.Add(new Binding <float>(predictor.JumpSpeed, player.Character.JumpSpeed)); predictor.Add(new Binding <bool>(predictor.IsSupported, player.Character.IsSupported)); jump.Add(new Binding <bool>(jump.Crouched, player.Character.Crouched)); jump.Add(new TwoWayBinding <bool>(player.Character.IsSupported, jump.IsSupported)); jump.Add(new TwoWayBinding <bool>(player.Character.HasTraction, jump.HasTraction)); jump.Add(new TwoWayBinding <Vector3>(player.Character.LinearVelocity, jump.LinearVelocity)); jump.Add(new TwoWayBinding <BEPUphysics.Entities.Entity>(jump.SupportEntity, player.Character.SupportEntity)); jump.Add(new TwoWayBinding <Vector3>(jump.SupportVelocity, player.Character.SupportVelocity)); jump.Add(new Binding <Vector2>(jump.AbsoluteMovementDirection, player.Character.MovementDirection)); jump.Add(new Binding <WallRun.State>(jump.WallRunState, wallRun.CurrentState)); jump.Add(new Binding <float>(jump.Rotation, rotation.Rotation)); jump.Add(new Binding <Vector3>(jump.Position, transform.Position)); jump.Add(new Binding <Vector3>(jump.FloorPosition, floor)); jump.Add(new Binding <float>(jump.MaxSpeed, player.Character.MaxSpeed)); jump.Add(new Binding <float>(jump.JumpSpeed, player.Character.JumpSpeed)); jump.Add(new Binding <float>(jump.Mass, player.Character.Mass)); jump.Add(new Binding <float>(jump.LastRollKickEnded, rollKickSlide.LastRollKickEnded)); jump.Add(new Binding <Voxel>(jump.WallRunMap, wallRun.WallRunVoxel)); jump.Add(new Binding <Direction>(jump.WallDirection, wallRun.WallDirection)); jump.Add(new CommandBinding <Voxel, Voxel.Coord, Direction>(jump.WalkedOn, footsteps.WalkedOn)); jump.Add(new CommandBinding(jump.DeactivateWallRun, (Action)wallRun.Deactivate)); jump.Add(new CommandBinding <float>(jump.FallDamage, fallDamage.ApplyJump)); jump.Predictor = predictor; jump.Bind(model); jump.Add(new TwoWayBinding <Voxel>(wallRun.LastWallRunMap, jump.LastWallRunMap)); jump.Add(new TwoWayBinding <Direction>(wallRun.LastWallDirection, jump.LastWallDirection)); jump.Add(new TwoWayBinding <bool>(rollKickSlide.CanKick, jump.CanKick)); jump.Add(new TwoWayBinding <float>(player.Character.LastSupportedSpeed, jump.LastSupportedSpeed)); wallRun.Add(new Binding <bool>(wallRun.IsSwimming, player.Character.IsSwimming)); wallRun.Add(new TwoWayBinding <Vector3>(player.Character.LinearVelocity, wallRun.LinearVelocity)); wallRun.Add(new TwoWayBinding <Vector3>(transform.Position, wallRun.Position)); wallRun.Add(new TwoWayBinding <bool>(player.Character.IsSupported, wallRun.IsSupported)); wallRun.Add(new CommandBinding(wallRun.LockRotation, (Action)rotation.Lock)); wallRun.Add(new CommandBinding <float>(wallRun.UpdateLockedRotation, rotation.UpdateLockedRotation)); vault.Add(new CommandBinding(wallRun.Vault, delegate() { vault.Go(true); })); wallRun.Predictor = predictor; wallRun.Add(new Binding <float>(wallRun.Height, player.Character.Height)); wallRun.Add(new Binding <float>(wallRun.JumpSpeed, player.Character.JumpSpeed)); wallRun.Add(new Binding <float>(wallRun.MaxSpeed, player.Character.MaxSpeed)); wallRun.Add(new TwoWayBinding <float>(rotation.Rotation, wallRun.Rotation)); wallRun.Add(new TwoWayBinding <bool>(player.Character.AllowUncrouch, wallRun.AllowUncrouch)); wallRun.Add(new TwoWayBinding <bool>(player.Character.HasTraction, wallRun.HasTraction)); wallRun.Add(new Binding <float>(wallRun.LastWallJump, jump.LastWallJump)); player.Add(new Binding <WallRun.State>(player.Character.WallRunState, wallRun.CurrentState)); input.Bind(rollKickSlide.RollKickButton, settings.RollKick); rollKickSlide.Add(new Binding <bool>(rollKickSlide.EnableCrouch, player.EnableCrouch)); rollKickSlide.Add(new Binding <float>(rollKickSlide.Rotation, rotation.Rotation)); rollKickSlide.Add(new Binding <bool>(rollKickSlide.IsSwimming, player.Character.IsSwimming)); rollKickSlide.Add(new Binding <bool>(rollKickSlide.IsSupported, player.Character.IsSupported)); rollKickSlide.Add(new Binding <Vector3>(rollKickSlide.FloorPosition, floor)); rollKickSlide.Add(new Binding <float>(rollKickSlide.Height, player.Character.Height)); rollKickSlide.Add(new Binding <float>(rollKickSlide.MaxSpeed, player.Character.MaxSpeed)); rollKickSlide.Add(new Binding <float>(rollKickSlide.JumpSpeed, player.Character.JumpSpeed)); rollKickSlide.Add(new Binding <Vector3>(rollKickSlide.SupportVelocity, player.Character.SupportVelocity)); rollKickSlide.Add(new TwoWayBinding <bool>(wallRun.EnableEnhancedWallRun, rollKickSlide.EnableEnhancedRollSlide)); rollKickSlide.Add(new TwoWayBinding <bool>(player.Character.AllowUncrouch, rollKickSlide.AllowUncrouch)); rollKickSlide.Add(new TwoWayBinding <bool>(player.Character.Crouched, rollKickSlide.Crouched)); rollKickSlide.Add(new TwoWayBinding <bool>(player.Character.EnableWalking, rollKickSlide.EnableWalking)); rollKickSlide.Add(new TwoWayBinding <Vector3>(player.Character.LinearVelocity, rollKickSlide.LinearVelocity)); rollKickSlide.Add(new TwoWayBinding <Vector3>(transform.Position, rollKickSlide.Position)); rollKickSlide.Predictor = predictor; rollKickSlide.Bind(model); rollKickSlide.VoxelTools = voxelTools; rollKickSlide.Add(new CommandBinding(rollKickSlide.DeactivateWallRun, (Action)wallRun.Deactivate)); rollKickSlide.Add(new CommandBinding(rollKickSlide.Footstep, footsteps.Footstep)); rollKickSlide.Add(new CommandBinding(rollKickSlide.LockRotation, (Action)rotation.Lock)); SoundKiller.Add(entity, AK.EVENTS.STOP_PLAYER_SLIDE_LOOP); vault.Add(new Binding <Vector3>(vault.Position, transform.Position)); vault.Add(new Binding <Vector3>(vault.FloorPosition, floor)); vault.Add(new Binding <float>(vault.MaxSpeed, player.Character.MaxSpeed)); vault.Add(new Binding <WallRun.State>(vault.WallRunState, wallRun.CurrentState)); vault.Add(new CommandBinding(vault.LockRotation, (Action)rotation.Lock)); vault.Add(new CommandBinding(vault.DeactivateWallRun, (Action)wallRun.Deactivate)); vault.Add(new TwoWayBinding <float>(player.Character.LastSupportedSpeed, vault.LastSupportedSpeed)); vault.Add(new CommandBinding <float>(vault.FallDamage, fallDamage.Apply)); vault.Bind(model); vault.Predictor = predictor; vault.Add(new TwoWayBinding <float>(rotation.Rotation, vault.Rotation)); vault.Add(new TwoWayBinding <bool>(player.Character.IsSupported, vault.IsSupported)); vault.Add(new TwoWayBinding <bool>(player.Character.HasTraction, vault.HasTraction)); vault.Add(new TwoWayBinding <Vector3>(player.Character.LinearVelocity, vault.LinearVelocity)); vault.Add(new TwoWayBinding <bool>(player.Character.EnableWalking, vault.EnableWalking)); vault.Add(new TwoWayBinding <bool>(player.Character.AllowUncrouch, vault.AllowUncrouch)); vault.Add(new TwoWayBinding <bool>(player.Character.Crouched, vault.Crouched)); vault.Add(new Binding <float>(vault.Radius, player.Character.Radius)); rotation.Add(new TwoWayBinding <Vector2>(rotation.Mouse, input.Mouse)); rotation.Add(new Binding <bool>(rotation.Rolling, rollKickSlide.Rolling)); rotation.Add(new Binding <bool>(rotation.Kicking, rollKickSlide.Kicking)); rotation.Add(new Binding <Vault.State>(rotation.VaultState, vault.CurrentState)); rotation.Add(new Binding <WallRun.State>(rotation.WallRunState, wallRun.CurrentState)); voxelTools.Add(new Binding <float>(voxelTools.Height, player.Character.Height)); voxelTools.Add(new Binding <float>(voxelTools.SupportHeight, player.Character.SupportHeight)); voxelTools.Add(new Binding <Vector3>(voxelTools.Position, transform.Position)); anim.Add(new Binding <bool>(anim.IsSupported, player.Character.IsSupported)); anim.Add(new Binding <WallRun.State>(anim.WallRunState, wallRun.CurrentState)); anim.Add(new Binding <bool>(anim.EnableWalking, player.Character.EnableWalking)); anim.Add(new Binding <bool>(anim.Crouched, player.Character.Crouched)); anim.Add(new Binding <Vector3>(anim.LinearVelocity, player.Character.LinearVelocity)); anim.Add(new Binding <Vector2>(anim.Movement, input.Movement)); anim.Add(new Binding <Vector2>(anim.Mouse, input.Mouse)); anim.Add(new Binding <float>(anim.Rotation, rotation.Rotation)); anim.Add(new Binding <Voxel>(anim.WallRunMap, wallRun.WallRunVoxel)); anim.Add(new Binding <Direction>(anim.WallDirection, wallRun.WallDirection)); anim.Add(new Binding <bool>(anim.IsSwimming, player.Character.IsSwimming)); anim.Add(new Binding <bool>(anim.Kicking, rollKickSlide.Kicking)); anim.Add(new Binding <Vector3>(anim.SupportVelocity, player.Character.SupportVelocity)); anim.Add ( new Binding <bool> ( anim.EnableLean, () => player.Character.EnableWalking.Value && player.Character.IsSupported.Value && input.Movement.Value.Y > 0.5f, player.Character.EnableWalking, player.Character.IsSupported, input.Movement ) ); anim.Bind(model); // Camera control model.UpdateWorldTransforms(); cameraControl.Add(new Binding <Vector2>(cameraControl.Mouse, input.Mouse)); cameraControl.Add(new Binding <float>(cameraControl.Lean, x => x * (float)Math.PI * 0.05f, anim.Lean)); cameraControl.Add(new Binding <Vector3>(cameraControl.LinearVelocity, player.Character.LinearVelocity)); cameraControl.Add(new Binding <float>(cameraControl.MaxSpeed, player.Character.MaxSpeed)); cameraControl.Add(new Binding <Matrix>(cameraControl.CameraBone, model.GetBoneTransform("Camera"))); cameraControl.Add(new Binding <Matrix>(cameraControl.HeadBone, model.GetBoneTransform("ORG-head"))); cameraControl.Add(new Binding <Matrix>(cameraControl.ModelTransform, model.Transform)); cameraControl.Add(new Binding <float>(cameraControl.BaseCameraShakeAmount, () => MathHelper.Clamp((player.Character.LinearVelocity.Value.Length() - (player.Character.MaxSpeed * 2.5f)) / (player.Character.MaxSpeed * 4.0f), 0, 1), player.Character.LinearVelocity, player.Character.MaxSpeed)); cameraControl.Offset = model.GetBoneTransform("Camera").Value.Translation - model.GetBoneTransform("ORG-head").Value.Translation; float heightOffset = 0.1f; #if VR if (main.VR) { heightOffset = 0.4f; } #endif cameraControl.Offset += new Vector3(0, heightOffset, 0); rumble.Add(new Binding <float>(rumble.CameraShake, cameraControl.TotalCameraShake)); rumble.Add(new CommandBinding <float>(fallDamage.Rumble, rumble.Go)); rumble.Add(new CommandBinding <float>(player.Rumble, rumble.Go)); rumble.Add(new CommandBinding <float>(rollKickSlide.Rumble, rumble.Go)); firstPersonModel.Add(new Binding <bool>(firstPersonModel.Enabled, x => !x, cameraControl.ThirdPerson)); model.Add(new ChangeBinding <bool>(cameraControl.ThirdPerson, delegate(bool old, bool value) { if (value && !old) { model.UnsupportedTechniques.Remove(Technique.Clip); model.UnsupportedTechniques.Remove(Technique.Render); } else if (old && !value) { model.UnsupportedTechniques.Add(Technique.Clip); model.UnsupportedTechniques.Add(Technique.Render); } })); Lemma.Console.Console.AddConCommand(new Console.ConCommand("third_person", "Toggle third-person view (WARNING: EXPERIMENTAL)", delegate(Console.ConCommand.ArgCollection args) { cameraControl.ThirdPerson.Value = !cameraControl.ThirdPerson; })); entity.Add(new CommandBinding(entity.Delete, delegate() { Lemma.Console.Console.RemoveConCommand("third_person"); })); #if DEVELOPMENT ModelAlpha debugCylinder = new ModelAlpha(); debugCylinder.Filename.Value = "AlphaModels\\cylinder"; debugCylinder.Add(new Binding <Matrix>(debugCylinder.Transform, transform.Matrix)); debugCylinder.Serialize = false; debugCylinder.Alpha.Value = 0.25f; debugCylinder.Add(new Binding <bool>(debugCylinder.Enabled, cameraControl.ThirdPerson)); debugCylinder.Add(new Binding <Vector3>(debugCylinder.Scale, delegate() { return(new Vector3(player.Character.Radius * 2.0f, player.Character.Height, player.Character.Radius * 2.0f)); }, player.Character.Height, player.Character.Radius)); entity.Add(debugCylinder); #endif // When rotation is locked, we want to make sure the player can't turn their head // 180 degrees from the direction they're facing #if VR if (main.VR) { input.MaxY.Value = input.MinY.Value = 0; } else #endif input.Add(new Binding <float>(input.MaxY, () => rotation.Locked ? (float)Math.PI * 0.3f : (float)Math.PI * 0.4f, rotation.Locked)); input.Add(new Binding <float>(input.MinX, () => rotation.Locked ? rotation.Rotation + ((float)Math.PI * -0.4f) : 0.0f, rotation.Rotation, rotation.Locked)); input.Add(new Binding <float>(input.MaxX, () => rotation.Locked ? rotation.Rotation + ((float)Math.PI * 0.4f) : 0.0f, rotation.Rotation, rotation.Locked)); input.Add(new NotifyBinding(delegate() { input.Mouse.Changed(); }, rotation.Locked)); // Make sure the rotation locking takes effect even if the player doesn't move the mouse // Setup rendering properties model.Materials = firstPersonModel.Materials = new Model.Material[3]; // Hoodie and shoes model.Materials[0] = new Model.Material { SpecularIntensity = 0.0f, SpecularPower = 1.0f, }; // Hands model.Materials[1] = new Model.Material { SpecularIntensity = 0.3f, SpecularPower = 2.0f, }; // Pants and skin model.Materials[2] = new Model.Material { SpecularIntensity = 0.5f, SpecularPower = 20.0f, }; firstPersonModel.Bind(model); // Third person model only gets rendered for shadows. No regular rendering or reflections. model.UnsupportedTechniques.Add(Technique.Clip); model.UnsupportedTechniques.Add(Technique.Render); // First-person model only used for regular rendering. No shadows or reflections. firstPersonModel.UnsupportedTechniques.Add(Technique.Shadow); firstPersonModel.UnsupportedTechniques.Add(Technique.Clip); // Build UI UIRenderer ui = new UIRenderer(); ui.DrawOrder.Value = -1; ui.EnabledWhenPaused = true; ui.EnabledInEditMode = false; entity.Add("UI", ui); input.Add(new Binding <float>(input.MouseSensitivity, settings.MouseSensitivity)); input.Add(new Binding <bool>(input.InvertMouseX, settings.InvertMouseX)); input.Add(new Binding <bool>(input.InvertMouseY, settings.InvertMouseY)); input.Add(new Binding <PCInput.PCInputBinding>(input.LeftKey, settings.Left)); input.Add(new Binding <PCInput.PCInputBinding>(input.RightKey, settings.Right)); input.Add(new Binding <PCInput.PCInputBinding>(input.BackwardKey, settings.Backward)); input.Add(new Binding <PCInput.PCInputBinding>(input.ForwardKey, settings.Forward)); model.StartClip("Idle", 0, true, AnimatedModel.DefaultBlendTime); // Set up AI agent Agent agent = entity.GetOrCreate <Agent>(); agent.Add(new TwoWayBinding <float>(player.Health, agent.Health)); agent.Add(new Binding <Vector3>(agent.Position, () => transform.Position.Value + new Vector3(0, player.Character.Height * -0.5f, 0), transform.Position, player.Character.Height)); agent.Add(new Binding <bool>(agent.Loud, () => player.Character.MovementDirection.Value.LengthSquared() > 0 && !player.Character.Crouched, player.Character.Crouched)); // Blocks BlockCloud blockCloud = entity.GetOrCreate <BlockCloud>("BlockCloud"); blockCloud.Scale.Value = 0.5f; blockCloud.Add(new Binding <Vector3>(blockCloud.Position, () => transform.Position.Value + new Vector3(0, player.Character.Height + player.Character.LinearVelocity.Value.Y, 0), transform.Position, player.Character.Height, player.Character.LinearVelocity)); blockCloud.Blocks.ItemAdded += delegate(int index, Entity.Handle block) { Entity e = block.Target; if (e != null) { e.Serialize = false; PhysicsBlock.CancelPlayerCollisions(e.Get <PhysicsBlock>()); } }; PointLight blockLight = entity.Create <PointLight>(); blockLight.Add(new Binding <Vector3>(blockLight.Position, blockCloud.AveragePosition)); blockLight.Add(new Binding <bool, int>(blockLight.Enabled, x => x > 0, blockCloud.Blocks.Length)); blockLight.Attenuation.Value = 30.0f; blockLight.Add(new Binding <Vector3, Voxel.t>(blockLight.Color, delegate(Voxel.t t) { switch (t) { case Voxel.t.GlowBlue: return(new Vector3(0.7f, 0.7f, 0.9f)); case Voxel.t.GlowYellow: return(new Vector3(0.9f, 0.9f, 0.7f)); default: return(new Vector3(0.8f, 0.8f, 0.8f)); } }, blockCloud.Type)); // Death entity.Add(new CommandBinding(player.Die, blockCloud.Clear)); entity.Add(new CommandBinding(player.Die, delegate() { Session.Recorder.Event(main, "Die"); if (agent.Killed || Agent.Query(transform.Position, 0.0f, 10.0f, x => x != agent) != null) { Session.Recorder.Event(main, "Killed"); AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_DEATH, entity); main.Spawner.RespawnDistance = Spawner.KilledRespawnDistance; main.Spawner.RespawnInterval = Spawner.KilledRespawnInterval; } entity.Add(new Animation(new Animation.Execute(entity.Delete))); })); player.EnabledInEditMode = false; Action updateFallSound = delegate() { float speed = player.Character.LinearVelocity.Value.Length(); float maxSpeed = player.Character.MaxSpeed * 1.25f; float value; if (speed > maxSpeed) { value = (speed - maxSpeed) / (maxSpeed * 2.0f); } else { value = 0.0f; } AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_PLAYER_FALL, value); }; updateFallSound(); AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_FALL, entity); player.Add(new NotifyBinding(updateFallSound, player.Character.LinearVelocity)); SoundKiller.Add(entity, AK.EVENTS.STOP_PLAYER_FALL); player.Add(new TwoWayBinding <Matrix>(transform.Matrix, player.Character.Transform)); model.Add(new Binding <Matrix>(model.Transform, delegate() { const float leanAmount = (float)Math.PI * 0.1f; return(Matrix.CreateTranslation(0, (player.Character.Height * -0.5f) - player.Character.SupportHeight, 0) * Matrix.CreateRotationZ(anim.Lean * leanAmount) * Matrix.CreateRotationY(rotation.Rotation) * transform.Matrix); }, transform.Matrix, rotation.Rotation, player.Character.Height, player.Character.SupportHeight, anim.Lean)); firstPersonModel.Add(new Binding <Matrix>(firstPersonModel.Transform, model.Transform)); firstPersonModel.Add(new Binding <Vector3>(firstPersonModel.Scale, model.Scale)); WallRun.State[] footstepWallrunStates = new[] { WallRun.State.Left, WallRun.State.Right, WallRun.State.Straight, WallRun.State.None, }; footsteps.Add(new Binding <bool>(footsteps.SoundEnabled, () => !player.Character.Crouched && footstepWallrunStates.Contains(wallRun.CurrentState) || (player.Character.IsSupported && player.Character.EnableWalking), player.Character.IsSupported, player.Character.EnableWalking, wallRun.CurrentState, player.Character.Crouched)); footsteps.Add(new Binding <Vector3>(footsteps.Position, transform.Position)); footsteps.Add(new Binding <float>(footsteps.Rotation, rotation.Rotation)); footsteps.Add(new Binding <float>(footsteps.CharacterHeight, player.Character.Height)); footsteps.Add(new Binding <float>(footsteps.SupportHeight, player.Character.SupportHeight)); footsteps.Add(new Binding <bool>(footsteps.IsSupported, player.Character.IsSupported)); footsteps.Add(new Binding <bool>(footsteps.IsSwimming, player.Character.IsSwimming)); footsteps.Add(new CommandBinding <float>(footsteps.Damage, agent.Damage)); footsteps.Add(new CommandBinding <Voxel, Voxel.Coord, Direction>(wallRun.WalkedOn, footsteps.WalkedOn)); model.Trigger("Run", 0.16f, footsteps.Footstep); model.Trigger("Run", 0.58f, footsteps.Footstep); model.Trigger("WallRunLeft", 0.16f, footsteps.Footstep); model.Trigger("WallRunLeft", 0.58f, footsteps.Footstep); model.Trigger("WallRunRight", 0.16f, footsteps.Footstep); model.Trigger("WallRunRight", 0.58f, footsteps.Footstep); model.Trigger("WallRunStraight", 0.16f, footsteps.Footstep); model.Trigger("WallRunStraight", 0.58f, footsteps.Footstep); model.Trigger("TurnLeft", 0.15f, footsteps.Footstep); model.Trigger("TurnRight", 0.15f, footsteps.Footstep); model.Trigger("TopOut", 1.0f, new Command { Action = delegate() { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_GRUNT, entity); } }); main.UI.IsMouseVisible.Value = false; SkinnedModel.Clip sprintAnimation = model["Sprint"], runAnimation = model["Run"]; // Movement binding player.Add(new Binding <Vector2>(player.Character.MovementDirection, delegate() { Vector2 movement = input.Movement; if (movement.LengthSquared() == 0.0f) { return(Vector2.Zero); } Matrix matrix = Matrix.CreateRotationY(rotation.Rotation); Vector2 forwardDir = new Vector2(matrix.Forward.X, matrix.Forward.Z); Vector2 rightDir = new Vector2(matrix.Right.X, matrix.Right.Z); return(-(forwardDir * movement.Y) - (rightDir * movement.X)); }, input.Movement, rotation.Rotation)); player.Character.Crouched.Value = true; player.Character.AllowUncrouch.Value = true; // Fall damage fallDamage.Add(new Binding <bool>(fallDamage.IsSupported, player.Character.IsSupported)); fallDamage.Add(new TwoWayBinding <Vector3>(player.Character.LinearVelocity, fallDamage.LinearVelocity)); fallDamage.Add(new TwoWayBinding <float>(player.Health, fallDamage.Health)); fallDamage.Add(new CommandBinding <BEPUphysics.BroadPhaseEntries.Collidable, ContactCollection>(player.Character.Collided, fallDamage.Collided)); fallDamage.Add(new TwoWayBinding <bool>(player.Character.EnableWalking, fallDamage.EnableWalking)); fallDamage.Add(new TwoWayBinding <bool>(player.EnableMoves, fallDamage.EnableMoves)); fallDamage.Add(new TwoWayBinding <bool>(fallDamage.Landing, rotation.Landing)); fallDamage.Add(new CommandBinding(fallDamage.LockRotation, (Action)rotation.Lock)); fallDamage.Add(new CommandBinding <float>(fallDamage.PhysicsDamage, agent.Damage)); fallDamage.Bind(model); // Swim up input.Bind(player.Character.SwimUp, settings.Jump); float parkourTime = 0; float jumpTime = 0; const float gracePeriod = 1.0f; jumper.Action = delegate(float dt) { if (player.EnableMoves && player.Character.EnableWalking && vault.CurrentState.Value == Vault.State.None && !rollKickSlide.Rolling && !rollKickSlide.Kicking && jumpTime < gracePeriod) { if (jump.Go()) { parkour.Enabled.Value = false; jumper.Enabled.Value = false; } jumpTime += dt; } else { jumper.Enabled.Value = false; } }; jumper.Add(new CommandBinding(jumper.Enable, delegate() { jumpTime = 0; })); jumper.Enabled.Value = false; entity.Add(jumper); // Jumping input.Bind(settings.Jump, PCInput.InputState.Down, delegate() { jumper.Enabled.Value = true; }); input.Bind(settings.Jump, PCInput.InputState.Up, delegate() { jumper.Enabled.Value = false; }); // Wall-run, vault, predictive parkour.Action = delegate(float dt) { if (player.EnableMoves && player.Character.EnableWalking && !(player.Character.Crouched && player.Character.IsSupported) && vault.CurrentState.Value == Vault.State.None && !rollKickSlide.Kicking && !rollKickSlide.Rolling && wallRun.CurrentState.Value == WallRun.State.None && parkourTime < gracePeriod) { bool didSomething = false; bool parkourBeganThisFrame = parkourTime == 0; if (predictor.PossibilityCount > 0) { // In slow motion, prefer left and right wall-running if (!(didSomething = wallRun.Activate(WallRun.State.Left, parkourBeganThisFrame))) { if (!(didSomething = wallRun.Activate(WallRun.State.Right, parkourBeganThisFrame))) { if (!(didSomething = vault.Go(parkourBeganThisFrame))) { didSomething = wallRun.Activate(WallRun.State.Straight, parkourBeganThisFrame); } } } } else { // In normal mode, prefer straight wall-running if (!(didSomething = vault.Go(parkourBeganThisFrame))) { if (!(didSomething = wallRun.Activate(WallRun.State.Straight, parkourBeganThisFrame))) { if (!(didSomething = wallRun.Activate(WallRun.State.Left, parkourBeganThisFrame))) { didSomething = wallRun.Activate(WallRun.State.Right, parkourBeganThisFrame); } } } } if (didSomething) { jumper.Enabled.Value = false; player.SlowMotion.Value = false; parkour.Enabled.Value = false; } else if (parkourBeganThisFrame) { if (blockCloud.Blocks.Length > 0) { player.SlowMotion.Value = true; predictor.ClearPossibilities(); predictor.PredictPlatforms(); predictor.PredictWalls(); } else if (player.EnableSlowMotion) { player.SlowMotion.Value = true; } } parkourTime += dt; } else { parkour.Enabled.Value = false; } }; parkour.Add(new CommandBinding(parkour.Enable, delegate() { parkourTime = 0; })); entity.Add(parkour); parkour.Enabled.Value = false; input.Bind(settings.Parkour, PCInput.InputState.Down, delegate() { parkour.Enabled.Value = true; }); input.Bind(settings.Parkour, PCInput.InputState.Up, delegate() { parkour.Enabled.Value = false; wallRun.Deactivate(); if (player.SlowMotion) { player.SlowMotion.Value = false; } }); input.Bind(settings.RollKick, PCInput.InputState.Down, delegate() { if (player.EnableMoves && player.Character.EnableWalking) { rollKickSlide.Go(); parkour.Enabled.Value = false; jumper.Enabled.Value = false; } }); input.Bind(settings.RollKick, PCInput.InputState.Up, delegate() { if (!rollKickSlide.Rolling && !rollKickSlide.Kicking) { player.Character.AllowUncrouch.Value = true; } }); // Special ability /* * input.Bind(settings.SpecialAbility, PCInput.InputState.Down, delegate() * { * Voxel.GlobalRaycastResult hit = Voxel.GlobalRaycast(main.Camera.Position, main.Camera.Forward, main.Camera.FarPlaneDistance, null); * if (hit.Voxel != null && hit.Voxel.GetType() != typeof(DynamicVoxel)) * { * VoxelRip.Go(hit.Voxel, hit.Coordinate.Value, 7, delegate(List<DynamicVoxel> results) * { * foreach (DynamicVoxel v in results) * { * v.IsAffectedByGravity.Value = false; * v.LinearVelocity.Value = hit.Voxel.GetAbsoluteVector(hit.Normal.GetVector()) * 7.0f + new Vector3((float)this.random.NextDouble() * 2.0f - 1.0f, (float)this.random.NextDouble() * 2.0f - 1.0f, (float)this.random.NextDouble() * 2.0f - 1.0f); + } + }); + } + }); */ // Player data bindings entity.Add(new PostInitialization { delegate() { Entity dataEntity = PlayerDataFactory.Instance; PlayerData playerData = dataEntity.Get <PlayerData>(); // HACK. Overwriting the property rather than binding the two together. Oh well. // This is because I haven't written a two-way list binding. footsteps.RespawnLocations = playerData.RespawnLocations; // Bind player data properties entity.Add(new TwoWayBinding <float>(WorldFactory.Instance.Get <World>().CameraShakeAmount, cameraControl.CameraShakeAmount)); entity.Add(new TwoWayBinding <bool>(playerData.EnableRoll, rollKickSlide.EnableRoll)); entity.Add(new TwoWayBinding <bool>(playerData.EnableCrouch, player.EnableCrouch)); entity.Add(new TwoWayBinding <bool>(playerData.EnableKick, rollKickSlide.EnableKick)); entity.Add(new TwoWayBinding <bool>(playerData.EnableWallRun, wallRun.EnableWallRun)); entity.Add(new TwoWayBinding <bool>(playerData.EnableWallRunHorizontal, wallRun.EnableWallRunHorizontal)); entity.Add(new TwoWayBinding <bool>(playerData.EnableEnhancedWallRun, wallRun.EnableEnhancedWallRun)); entity.Add(new TwoWayBinding <bool>(playerData.EnableMoves, player.EnableMoves)); entity.Add(new TwoWayBinding <float>(playerData.MaxSpeed, player.Character.MaxSpeed)); entity.Add(new TwoWayBinding <Voxel.t>(playerData.CloudType, blockCloud.Type)); entity.Add(new TwoWayBinding <bool>(playerData.ThirdPerson, cameraControl.ThirdPerson)); entity.Add(new TwoWayBinding <bool>(playerData.EnableSlowMotion, player.EnableSlowMotion)); Phone phone = dataEntity.GetOrCreate <Phone>("Phone"); entity.Add ( new Binding <bool> ( phone.CanReceiveMessages, () => player.Character.IsSupported && !player.Character.IsSwimming && !player.Character.Crouched, player.Character.IsSupported, player.Character.IsSwimming, player.Character.Crouched ) ); PhoneNote.Attach(main, entity, player, model, input, phone, player.Character.EnableWalking, playerData.PhoneActive, playerData.NoteActive); PlayerUI.Attach(main, entity, ui, player.Health, rotation.Rotation, playerData.NoteActive, playerData.PhoneActive); } }); fpsCamera.Add(new Binding <Vector2>(fpsCamera.Mouse, input.Mouse)); fpsCamera.Add(new Binding <Vector2>(fpsCamera.Movement, input.Movement)); input.Bind(fpsCamera.SpeedMode, settings.Parkour); input.Bind(fpsCamera.Up, settings.Jump); fpsCamera.Add(new Binding <bool>(fpsCamera.Down, input.GetKey(Keys.LeftControl))); Lemma.Console.Console.AddConCommand(new ConCommand("noclip", "Toggle free camera mode", delegate(ConCommand.ArgCollection args) { bool freeCameraMode = !fpsCamera.Enabled; fpsCamera.Enabled.Value = freeCameraMode; cameraControl.Enabled.Value = !freeCameraMode; firstPersonModel.Enabled.Value = !freeCameraMode; model.Enabled.Value = !freeCameraMode; ui.Enabled.Value = !freeCameraMode; player.Character.EnableWalking.Value = !freeCameraMode; player.EnableMoves.Value = !freeCameraMode; player.Character.Body.IsAffectedByGravity = !freeCameraMode; if (freeCameraMode) { AkSoundEngine.PostEvent(AK.EVENTS.STOP_PLAYER_BREATHING_SOFT, entity); } else { transform.Position.Value = main.Camera.Position; } })); entity.Add(new CommandBinding(entity.Delete, delegate() { Lemma.Console.Console.RemoveConCommand("noclip"); if (fpsCamera.Enabled) // Movement is disabled. Re-enable it. { player.Character.EnableWalking.Value = true; player.EnableMoves.Value = true; } PlayerFactory.Instance = null; })); }
public override void Bind(Entity entity, Main main, bool creating = false) { PointLight light = entity.GetOrCreate <PointLight>("PointLight"); light.Serialize = false; const float defaultLightAttenuation = 15.0f; light.Attenuation.Value = defaultLightAttenuation; Transform transform = entity.GetOrCreate <Transform>("Transform"); light.Add(new Binding <Vector3>(light.Position, transform.Position)); if (!main.EditorEnabled) { AkGameObjectTracker.Attach(entity); SoundKiller.Add(entity, AK.EVENTS.STOP_GLOWSQUARE); entity.Add(new PostInitialization { delegate() { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_GLOWSQUARE, entity); AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_GLOWSQUARE_PITCH, -1.0f, entity); } }); } AI ai = entity.GetOrCreate <AI>("AI"); ModelAlpha model = entity.GetOrCreate <ModelAlpha>(); model.Add(new Binding <Matrix>(model.Transform, transform.Matrix)); model.Filename.Value = "AlphaModels\\box"; model.Serialize = false; model.DrawOrder.Value = 15; RaycastAIMovement movement = entity.GetOrCreate <RaycastAIMovement>("Movement"); Levitator levitator = entity.GetOrCreate <Levitator>("Levitator"); const float defaultModelScale = 1.0f; model.Scale.Value = new Vector3(defaultModelScale); model.Add(new Binding <Vector3, string>(model.Color, delegate(string state) { switch (state) { case "Alert": return(new Vector3(1.5f, 1.5f, 0.5f)); case "Chase": return(new Vector3(1.5f, 0.5f, 0.5f)); case "Levitating": return(new Vector3(2.0f, 1.0f, 0.5f)); default: return(new Vector3(1.0f, 1.0f, 1.0f)); } }, ai.CurrentState)); entity.Add(new Updater ( delegate(float dt) { float source = 1.0f + ((float)this.random.NextDouble() - 0.5f) * 2.0f * 0.05f; model.Scale.Value = new Vector3(defaultModelScale * source); light.Attenuation.Value = defaultLightAttenuation * source; } )); light.Add(new Binding <Vector3>(light.Color, model.Color)); Agent agent = entity.GetOrCreate <Agent>(); agent.Add(new Binding <Vector3>(agent.Position, transform.Position)); RaycastAI raycastAI = entity.GetOrCreate <RaycastAI>("RaycastAI"); raycastAI.Add(new TwoWayBinding <Vector3>(transform.Position, raycastAI.Position)); raycastAI.Add(new Binding <Quaternion>(transform.Quaternion, raycastAI.Orientation)); AI.Task checkOperationalRadius = new AI.Task { Interval = 2.0f, Action = delegate() { bool shouldBeActive = (transform.Position.Value - main.Camera.Position).Length() < movement.OperationalRadius; if (shouldBeActive && ai.CurrentState == "Suspended") { ai.CurrentState.Value = "Idle"; } else if (!shouldBeActive && ai.CurrentState != "Suspended") { ai.CurrentState.Value = "Suspended"; } }, }; AI.Task updatePosition = new AI.Task { Action = delegate() { raycastAI.Update(); }, }; ai.Add(new AI.AIState { Name = "Suspended", Tasks = new[] { checkOperationalRadius, }, }); const float sightDistance = 30.0f; const float hearingDistance = 15.0f; ai.Add(new AI.AIState { Name = "Idle", Enter = delegate(AI.AIState previous) { AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_GLOWSQUARE_PITCH, -1.0f, entity); }, Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { raycastAI.Move(new Vector3(((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f)); } }, new AI.Task { Interval = 1.0f, Action = delegate() { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.CurrentState.Value = "Alert"; } }, }, }, }); ai.Add(new AI.AIState { Name = "Alert", Enter = delegate(AI.AIState previous) { AkSoundEngine.PostEvent(AK.EVENTS.STOP_GLOWSQUARE, entity); }, Exit = delegate(AI.AIState next) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_GLOWSQUARE, entity); }, Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { if (ai.TimeInCurrentState > 3.0f) { ai.CurrentState.Value = "Idle"; } else { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.TargetAgent.Value = a.Entity; ai.CurrentState.Value = "Chase"; } } }, }, }, }); AI.Task checkTargetAgent = new AI.Task { Action = delegate() { Entity target = ai.TargetAgent.Value.Target; if (target == null || !target.Active) { ai.TargetAgent.Value = null; ai.CurrentState.Value = "Idle"; } }, }; // Levitate const int levitateRipRadius = 4; Func <bool> tryLevitate = delegate() { Entity voxelEntity = raycastAI.Voxel.Value.Target; if (voxelEntity == null) { return(false); } Voxel map = voxelEntity.Get <Voxel>(); Voxel.Coord?candidate = map.FindClosestFilledCell(raycastAI.Coord, 3); if (!candidate.HasValue) { return(false); } if (VoxelRip.Go(map, candidate.Value, levitateRipRadius, delegate(List <DynamicVoxel> spawnedMaps) { foreach (DynamicVoxel spawnedMap in spawnedMaps) { if (spawnedMap[candidate.Value] != Voxel.States.Empty) { levitator.LevitatingVoxel.Value = spawnedMap.Entity; break; } } })) { levitator.GrabCoord.Value = candidate.Value; return(true); } return(false); }; Action delevitateMap = delegate() { Entity levitatingMapEntity = levitator.LevitatingVoxel.Value.Target; if (levitatingMapEntity == null || !levitatingMapEntity.Active) { return; } DynamicVoxel dynamicMap = levitatingMapEntity.Get <DynamicVoxel>(); VoxelRip.Consolidate(main, dynamicMap); }; // Chase AI state ai.Add(new AI.AIState { Name = "Chase", Enter = delegate(AI.AIState previous) { AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_GLOWSQUARE_PITCH, 0.0f, entity); }, Tasks = new[] { checkOperationalRadius, checkTargetAgent, new AI.Task { Interval = 0.35f, Action = delegate() { raycastAI.Move(ai.TargetAgent.Value.Target.Get <Transform>().Position.Value - transform.Position); } }, updatePosition, new AI.Task { Interval = 0.1f, Action = delegate() { Entity target = ai.TargetAgent.Value.Target; Vector3 targetPosition = target.Get <Transform>().Position; if ((targetPosition - transform.Position).Length() < 15.0f) { if (tryLevitate()) { ai.CurrentState.Value = "Levitating"; } } } } }, }); Action findNextPosition = delegate() { movement.LastPosition.Value = transform.Position.Value; float radius = 5.0f; Vector3 center = ai.TargetAgent.Value.Target.Get <Transform>().Position; Vector3 candidate; do { candidate = center + new Vector3((float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble(), (float)this.random.NextDouble() - 0.5f) * radius; radius += 1.0f; }while (!RaycastAI.DefaultPositionFilter(candidate)); movement.NextPosition.Value = candidate; movement.PositionBlend.Value = 0.0f; }; ai.Add(new AI.AIState { Name = "Levitating", Enter = delegate(AI.AIState previous) { findNextPosition(); }, Exit = delegate(AI.AIState next) { delevitateMap(); levitator.LevitatingVoxel.Value = null; //volume.Value = defaultVolume; //pitch.Value = 0.0f; }, Tasks = new[] { checkTargetAgent, new AI.Task { Action = delegate() { //volume.Value = 1.0f; //pitch.Value = 1.0f; Entity levitatingMapEntity = levitator.LevitatingVoxel.Value.Target; if (levitatingMapEntity == null || !levitatingMapEntity.Active || ai.TimeInCurrentState.Value > 8.0f) { Entity voxel = raycastAI.Voxel.Value.Target; if (voxel != null && voxel.Active) { raycastAI.Coord.Value = raycastAI.LastCoord.Value = voxel.Get <Voxel>().GetCoordinate(transform.Position); } raycastAI.Move(new Vector3(((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f)); ai.CurrentState.Value = "Alert"; return; } DynamicVoxel dynamicMap = levitatingMapEntity.Get <DynamicVoxel>(); movement.PositionBlend.Value += (main.ElapsedTime.Value / 1.0f); if (movement.PositionBlend > 1.0f) { findNextPosition(); } transform.Position.Value = Vector3.Lerp(movement.LastPosition, movement.NextPosition, movement.PositionBlend); Vector3 grabPoint = dynamicMap.GetAbsolutePosition(levitator.GrabCoord); Vector3 diff = transform.Position.Value - grabPoint; if (diff.Length() > 15.0f) { ai.CurrentState.Value = "Chase"; return; } diff *= (float)Math.Sqrt(dynamicMap.PhysicsEntity.Mass) * 0.5f; dynamicMap.PhysicsEntity.ApplyImpulse(ref grabPoint, ref diff); }, }, }, }); this.SetMain(entity, main); }
public override void Bind(Entity entity, Main main, bool creating = false) { if (ParticleSystem.Get(main, "SnakeSparks") == null) { ParticleSystem.Add(main, "SnakeSparks", new ParticleSystem.ParticleSettings { TextureName = "Particles\\splash", MaxParticles = 1000, Duration = TimeSpan.FromSeconds(1.0f), MinHorizontalVelocity = -7.0f, MaxHorizontalVelocity = 7.0f, MinVerticalVelocity = 0.0f, MaxVerticalVelocity = 7.0f, Gravity = new Vector3(0.0f, -10.0f, 0.0f), MinRotateSpeed = -2.0f, MaxRotateSpeed = 2.0f, MinStartSize = 0.3f, MaxStartSize = 0.7f, MinEndSize = 0.0f, MaxEndSize = 0.0f, BlendState = Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlend, MinColor = new Vector4(2.0f, 2.0f, 2.0f, 1.0f), MaxColor = new Vector4(2.0f, 2.0f, 2.0f, 1.0f), }); ParticleSystem.Add(main, "SnakeSparksRed", new ParticleSystem.ParticleSettings { TextureName = "Particles\\splash", MaxParticles = 1000, Duration = TimeSpan.FromSeconds(1.0f), MinHorizontalVelocity = -7.0f, MaxHorizontalVelocity = 7.0f, MinVerticalVelocity = 0.0f, MaxVerticalVelocity = 7.0f, Gravity = new Vector3(0.0f, -10.0f, 0.0f), MinRotateSpeed = -2.0f, MaxRotateSpeed = 2.0f, MinStartSize = 0.3f, MaxStartSize = 0.7f, MinEndSize = 0.0f, MaxEndSize = 0.0f, BlendState = Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlend, MinColor = new Vector4(1.4f, 0.8f, 0.7f, 1.0f), MaxColor = new Vector4(1.4f, 0.8f, 0.7f, 1.0f), }); ParticleSystem.Add(main, "SnakeSparksYellow", new ParticleSystem.ParticleSettings { TextureName = "Particles\\splash", MaxParticles = 1000, Duration = TimeSpan.FromSeconds(1.0f), MinHorizontalVelocity = -7.0f, MaxHorizontalVelocity = 7.0f, MinVerticalVelocity = 0.0f, MaxVerticalVelocity = 7.0f, Gravity = new Vector3(0.0f, -10.0f, 0.0f), MinRotateSpeed = -2.0f, MaxRotateSpeed = 2.0f, MinStartSize = 0.3f, MaxStartSize = 0.7f, MinEndSize = 0.0f, MaxEndSize = 0.0f, BlendState = Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlend, MinColor = new Vector4(1.4f, 1.4f, 0.7f, 1.0f), MaxColor = new Vector4(1.4f, 1.4f, 0.7f, 1.0f), }); } Snake snake = entity.GetOrCreate <Snake>("Snake"); entity.CannotSuspendByDistance = true; Transform transform = entity.GetOrCreate <Transform>("Transform"); AI ai = entity.GetOrCreate <AI>("AI"); Agent agent = entity.GetOrCreate <Agent>("Agent"); const float defaultSpeed = 5.0f; const float chaseSpeed = 18.0f; const float closeChaseSpeed = 12.0f; const float crushSpeed = 125.0f; VoxelChaseAI chase = entity.GetOrCreate <VoxelChaseAI>("VoxelChaseAI"); chase.Add(new TwoWayBinding <Vector3>(transform.Position, chase.Position)); chase.Speed.Value = defaultSpeed; chase.EnablePathfinding.Value = ai.CurrentState.Value == "Chase"; chase.Filter = delegate(Voxel.State state) { if (state == Voxel.States.Infected || state == Voxel.States.Neutral || state == Voxel.States.Hard || state == Voxel.States.HardInfected) { return(true); } return(false); }; entity.Add(new CommandBinding(chase.Delete, entity.Delete)); PointLight positionLight = null; if (!main.EditorEnabled) { positionLight = new PointLight(); positionLight.Serialize = false; positionLight.Color.Value = new Vector3(1.5f, 0.5f, 0.5f); positionLight.Attenuation.Value = 20.0f; positionLight.Add(new Binding <bool, string>(positionLight.Enabled, x => x != "Suspended", ai.CurrentState)); positionLight.Add(new Binding <Vector3, string>(positionLight.Color, delegate(string state) { switch (state) { case "Chase": case "Crush": return(new Vector3(1.5f, 0.5f, 0.5f)); case "Alert": return(new Vector3(1.5f, 1.5f, 0.5f)); default: return(new Vector3(1.0f, 1.0f, 1.0f)); } }, ai.CurrentState)); entity.Add("PositionLight", positionLight); ParticleEmitter emitter = entity.GetOrCreate <ParticleEmitter>("Particles"); emitter.Serialize = false; emitter.ParticlesPerSecond.Value = 100; emitter.Add(new Binding <string>(emitter.ParticleType, delegate(string state) { switch (state) { case "Chase": case "Crush": return("SnakeSparksRed"); case "Alert": return("SnakeSparksYellow"); default: return("SnakeSparks"); } }, ai.CurrentState)); emitter.Add(new Binding <Vector3>(emitter.Position, transform.Position)); emitter.Add(new Binding <bool, string>(emitter.Enabled, x => x != "Suspended", ai.CurrentState)); positionLight.Add(new Binding <Vector3>(positionLight.Position, transform.Position)); emitter.Add(new Binding <Vector3>(emitter.Position, transform.Position)); agent.Add(new Binding <Vector3>(agent.Position, transform.Position)); AkGameObjectTracker.Attach(entity); } AI.Task checkMap = new AI.Task { Action = delegate() { if (chase.Voxel.Value.Target == null || !chase.Voxel.Value.Target.Active) { entity.Delete.Execute(); } }, }; AI.Task checkOperationalRadius = new AI.Task { Interval = 2.0f, Action = delegate() { bool shouldBeActive = (transform.Position.Value - main.Camera.Position).Length() < snake.OperationalRadius; if (shouldBeActive && ai.CurrentState == "Suspended") { ai.CurrentState.Value = "Idle"; } else if (!shouldBeActive && ai.CurrentState != "Suspended") { ai.CurrentState.Value = "Suspended"; } }, }; AI.Task checkTargetAgent = new AI.Task { Action = delegate() { Entity target = ai.TargetAgent.Value.Target; if (target == null || !target.Active) { ai.TargetAgent.Value = null; ai.CurrentState.Value = "Idle"; } }, }; Func <Voxel, Direction> randomValidDirection = delegate(Voxel m) { Voxel.Coord c = chase.Coord; Direction[] dirs = new Direction[6]; Array.Copy(DirectionExtensions.Directions, dirs, 6); // Shuffle directions int i = 5; while (i > 0) { int k = this.random.Next(i); Direction temp = dirs[i]; dirs[i] = dirs[k]; dirs[k] = temp; i--; } foreach (Direction dir in dirs) { if (chase.Filter(m[c.Move(dir)])) { return(dir); } } return(Direction.None); }; Direction currentDir = Direction.None; chase.Add(new CommandBinding <Voxel, Voxel.Coord>(chase.Moved, delegate(Voxel m, Voxel.Coord c) { if (chase.Active) { string currentState = ai.CurrentState.Value; Voxel.t id = m[c].ID; if (id == Voxel.t.Hard) { m.Empty(c); m.Fill(c, Voxel.States.HardInfected); m.Regenerate(); } else if (id == Voxel.t.Neutral) { m.Empty(c); m.Fill(c, Voxel.States.Infected); m.Regenerate(); } else if (id == Voxel.t.Empty) { m.Fill(c, Voxel.States.Infected); m.Regenerate(); } AkSoundEngine.PostEvent(AK.EVENTS.PLAY_SNAKE_MOVE, entity); if (currentState == "Idle") { if (currentDir == Direction.None || !chase.Filter(m[chase.Coord.Value.Move(currentDir)]) || this.random.Next(8) == 0) { currentDir = randomValidDirection(m); } chase.Coord.Value = chase.Coord.Value.Move(currentDir); } else if (snake.Path.Length > 0) { chase.Coord.Value = snake.Path[0]; snake.Path.RemoveAt(0); } } })); ai.Setup ( new AI.AIState { Name = "Suspended", Tasks = new[] { checkOperationalRadius }, }, new AI.AIState { Name = "Idle", Enter = delegate(AI.AIState previous) { Entity voxelEntity = chase.Voxel.Value.Target; if (voxelEntity != null) { Voxel m = voxelEntity.Get <Voxel>(); if (currentDir == Direction.None || !chase.Filter(m[chase.Coord.Value.Move(currentDir)])) { currentDir = randomValidDirection(m); } chase.Coord.Value = chase.Coord.Value.Move(currentDir); } }, Tasks = new[] { checkMap, checkOperationalRadius, new AI.Task { Interval = 1.0f, Action = delegate() { Agent a = Agent.Query(transform.Position, 50.0f, snake.EnableHearing ? 20.0f : 0.0f, x => x.Entity.Type == "Player"); if (a != null) { ai.CurrentState.Value = "Alert"; } }, }, }, }, new AI.AIState { Name = "Alert", Enter = delegate(AI.AIState previous) { chase.EnableMovement.Value = false; }, Exit = delegate(AI.AIState next) { chase.EnableMovement.Value = true; }, Tasks = new[] { checkMap, checkOperationalRadius, new AI.Task { Interval = 0.4f, Action = delegate() { if (ai.TimeInCurrentState > 3.0f) { ai.CurrentState.Value = "Idle"; } else { Agent a = Agent.Query(transform.Position, 50.0f, 30.0f, x => x.Entity.Type == "Player"); if (a != null) { ai.TargetAgent.Value = a.Entity; ai.CurrentState.Value = "Chase"; } } }, }, }, }, new AI.AIState { Name = "Chase", Enter = delegate(AI.AIState previousState) { chase.EnablePathfinding.Value = true; chase.Speed.Value = chaseSpeed; }, Exit = delegate(AI.AIState nextState) { chase.EnablePathfinding.Value = false; chase.Speed.Value = defaultSpeed; }, Tasks = new[] { checkMap, checkOperationalRadius, checkTargetAgent, new AI.Task { Interval = 0.07f, Action = delegate() { Vector3 targetPosition = ai.TargetAgent.Value.Target.Get <Agent>().Position; float targetDistance = (targetPosition - transform.Position).Length(); chase.Speed.Value = targetDistance < 15.0f ? closeChaseSpeed : chaseSpeed; if (targetDistance > 50.0f || ai.TimeInCurrentState > 30.0f) // He got away { ai.CurrentState.Value = "Alert"; } else if (targetDistance < 5.0f) // We got 'im { // First, make sure we're not near a reset block Voxel v = chase.Voxel.Value.Target.Get <Voxel>(); if (VoxelAStar.BroadphaseSearch(v, chase.Coord, 6, x => x.Type == Lemma.Components.Voxel.States.Reset) == null) { ai.CurrentState.Value = "Crush"; } } else { chase.Target.Value = targetPosition; } }, }, }, }, new AI.AIState { Name = "Crush", Enter = delegate(AI.AIState lastState) { // Set up cage Voxel.Coord center = chase.Voxel.Value.Target.Get <Voxel>().GetCoordinate(ai.TargetAgent.Value.Target.Get <Agent>().Position); int radius = 1; // Bottom for (int x = center.X - radius; x <= center.X + radius; x++) { for (int z = center.Z - radius; z <= center.Z + radius; z++) { snake.Path.Add(new Voxel.Coord { X = x, Y = center.Y - 4, Z = z }); } } // Outer shell radius = 2; for (int y = center.Y - 3; y <= center.Y + 3; y++) { // Left for (int z = center.Z - radius; z <= center.Z + radius; z++) { snake.Path.Add(new Voxel.Coord { X = center.X - radius, Y = y, Z = z }); } // Right for (int z = center.Z - radius; z <= center.Z + radius; z++) { snake.Path.Add(new Voxel.Coord { X = center.X + radius, Y = y, Z = z }); } // Backward for (int x = center.X - radius; x <= center.X + radius; x++) { snake.Path.Add(new Voxel.Coord { X = x, Y = y, Z = center.Z - radius }); } // Forward for (int x = center.X - radius; x <= center.X + radius; x++) { snake.Path.Add(new Voxel.Coord { X = x, Y = y, Z = center.Z + radius }); } } // Top for (int x = center.X - radius; x <= center.X + radius; x++) { for (int z = center.Z - radius; z <= center.Z + radius; z++) { snake.Path.Add(new Voxel.Coord { X = x, Y = center.Y + 3, Z = z }); } } chase.EnablePathfinding.Value = false; chase.Speed.Value = crushSpeed; snake.CrushCoordinate.Value = chase.Coord; }, Exit = delegate(AI.AIState nextState) { chase.Speed.Value = defaultSpeed; chase.Coord.Value = chase.LastCoord.Value = snake.CrushCoordinate; snake.Path.Clear(); }, Tasks = new[] { checkMap, checkOperationalRadius, checkTargetAgent, new AI.Task { Interval = 0.01f, Action = delegate() { Agent a = ai.TargetAgent.Value.Target.Get <Agent>(); a.Damage.Execute(0.01f / 1.5f); // seconds to kill if (!a.Active) { ai.CurrentState.Value = "Alert"; } else { if ((a.Position - transform.Position.Value).Length() > 5.0f) // They're getting away { ai.CurrentState.Value = "Chase"; } } } } }, } ); this.SetMain(entity, main); entity.Add("OperationalRadius", snake.OperationalRadius); entity.Add("EnableHearing", snake.EnableHearing); }
public override void Bind(Entity entity, Main main, bool creating = false) { Transform transform = entity.GetOrCreate <Transform>("Transform"); PlayerTrigger trigger = entity.GetOrCreate <PlayerTrigger>("PlayerTrigger"); VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main); attachable.Enabled.Value = true; this.SetMain(entity, main); VoxelAttachable.BindTarget(entity, trigger.Position); PointLight light = entity.GetOrCreate <PointLight>(); light.Add(new Binding <Vector3>(light.Position, trigger.Position)); light.Color.Value = new Vector3(1.0f, 0.5f, 1.7f); Property <float> lightBaseRadius = new Property <float> { Value = 10.0f }; Updater updater = new Updater ( delegate(float dt) { light.Attenuation.Value = lightBaseRadius.Value * (1.0f + (((float)this.random.NextDouble() - 0.5f) * 0.1f)); } ); updater.EnabledInEditMode = true; entity.Add(updater); SignalTower tower = entity.GetOrCreate <SignalTower>("SignalTower"); Animation enterAnimation = null; trigger.Add(new CommandBinding(trigger.PlayerEntered, delegate() { if (!string.IsNullOrEmpty(tower.Initial) && (enterAnimation == null || !enterAnimation.Active)) { enterAnimation = new Animation ( new Animation.FloatMoveTo(lightBaseRadius, 20.0f, 0.25f), new Animation.FloatMoveTo(lightBaseRadius, 10.0f, 0.5f) ); entity.Add(enterAnimation); } })); tower.Add(new CommandBinding(trigger.PlayerEntered, tower.PlayerEnteredRange)); tower.Add(new CommandBinding(trigger.PlayerExited, tower.PlayerExitedRange)); tower.Add(new Binding <Entity.Handle>(tower.Player, trigger.Player)); AkGameObjectTracker.Attach(entity, trigger.Position); ParticleEmitter distortionEmitter = entity.GetOrCreate <ParticleEmitter>("DistortionEmitter"); distortionEmitter.Serialize = false; distortionEmitter.Add(new Binding <Vector3>(distortionEmitter.Position, trigger.Position)); distortionEmitter.ParticleType.Value = "Distortion"; distortionEmitter.ParticlesPerSecond.Value = 4; distortionEmitter.Jitter.Value = new Vector3(0.5f); ParticleEmitter purpleEmitter = entity.GetOrCreate <ParticleEmitter>("PurpleEmitter"); purpleEmitter.Serialize = false; purpleEmitter.Add(new Binding <Vector3>(purpleEmitter.Position, trigger.Position)); purpleEmitter.ParticleType.Value = "Purple"; purpleEmitter.ParticlesPerSecond.Value = 30; purpleEmitter.Jitter.Value = new Vector3(0.5f); entity.Add("AttachOffset", attachable.Offset); trigger.EditorProperties(); entity.Add("Initial", tower.Initial); }
public override void Bind(Entity entity, Main main, bool creating = false) { BlockCloud blockCloud = entity.GetOrCreate <BlockCloud>("BlockCloud"); blockCloud.Add(new CommandBinding(blockCloud.Delete, entity.Delete)); blockCloud.Add(new CommandBinding <Collidable, ContactCollection>(blockCloud.Collided, delegate(Collidable other, ContactCollection contacts) { if (other.Tag != null && other.Tag.GetType() == typeof(Character)) { // Damage the player Entity p = PlayerFactory.Instance; if (p != null && p.Active) { p.Get <Agent>().Damage.Execute(0.1f); } } })); blockCloud.Type.Value = Voxel.t.Black; Transform transform = entity.GetOrCreate <Transform>("Transform"); AkGameObjectTracker.Attach(entity); AI ai = entity.GetOrCreate <AI>("AI"); if (!main.EditorEnabled) { entity.Add(new PostInitialization { delegate() { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_EVIL_CUBES, entity); AkSoundEngine.PostEvent(ai.CurrentState == "Chase" ? AK.EVENTS.EVIL_CUBES_CHASE : AK.EVENTS.EVIL_CUBES_IDLE, entity); } }); SoundKiller.Add(entity, AK.EVENTS.STOP_EVIL_CUBES); } Agent agent = entity.GetOrCreate <Agent>(); agent.Add(new Binding <Vector3>(agent.Position, transform.Position)); RaycastAI raycastAI = entity.GetOrCreate <RaycastAI>("RaycastAI"); raycastAI.BlendTime.Value = 1.0f; raycastAI.Add(new TwoWayBinding <Vector3>(transform.Position, raycastAI.Position)); raycastAI.Add(new Binding <Quaternion>(transform.Quaternion, raycastAI.Orientation)); RaycastAIMovement movement = entity.GetOrCreate <RaycastAIMovement>("Movement"); blockCloud.Add(new Binding <Vector3>(blockCloud.Position, transform.Position)); AI.Task checkOperationalRadius = new AI.Task { Interval = 2.0f, Action = delegate() { bool shouldBeActive = (transform.Position.Value - main.Camera.Position).Length() < movement.OperationalRadius; if (shouldBeActive && ai.CurrentState == "Suspended") { ai.CurrentState.Value = "Idle"; } else if (!shouldBeActive && ai.CurrentState != "Suspended") { ai.CurrentState.Value = "Suspended"; } }, }; AI.Task updatePosition = new AI.Task { Action = delegate() { raycastAI.Update(); }, }; ai.Add(new AI.AIState { Name = "Suspended", Tasks = new[] { checkOperationalRadius, }, }); const float sightDistance = 30.0f; const float hearingDistance = 15.0f; ai.Add(new AI.AIState { Name = "Idle", Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { raycastAI.Move(new Vector3(((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f)); } }, new AI.Task { Interval = 1.0f, Action = delegate() { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.CurrentState.Value = "Alert"; } }, }, }, }); ai.Add(new AI.AIState { Name = "Alert", Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { if (ai.TimeInCurrentState > 3.0f) { ai.CurrentState.Value = "Idle"; } else { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.TargetAgent.Value = a.Entity; ai.CurrentState.Value = "Chase"; } } }, }, }, }); AI.Task checkTargetAgent = new AI.Task { Action = delegate() { Entity target = ai.TargetAgent.Value.Target; if (target == null || !target.Active || (target.Get <Transform>().Position.Value - transform.Position.Value).Length() > sightDistance * 1.25f) { ai.TargetAgent.Value = null; ai.CurrentState.Value = "Alert"; } }, }; Action findNextPosition = delegate() { movement.LastPosition.Value = transform.Position.Value; float radius = 5.0f; Vector3 center = ai.TargetAgent.Value.Target.Get <Transform>().Position; Vector3 candidate; do { candidate = center + new Vector3((float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble(), (float)this.random.NextDouble() - 0.5f) * radius; radius += 1.0f; }while (!RaycastAI.DefaultPositionFilter(candidate)); Vector3 toCandidate = candidate - movement.LastPosition; float distance = toCandidate.Length(); const float maxMovementDistance = 9.0f; if (distance > maxMovementDistance) { toCandidate *= maxMovementDistance / distance; } movement.NextPosition.Value = movement.LastPosition.Value + toCandidate; movement.PositionBlend.Value = 0.0f; }; // Chase AI state ai.Add(new AI.AIState { Name = "Chase", Enter = delegate(AI.AIState previous) { AkSoundEngine.PostEvent(AK.EVENTS.EVIL_CUBES_CHASE, entity); findNextPosition(); }, Exit = delegate(AI.AIState next) { AkSoundEngine.PostEvent(AK.EVENTS.EVIL_CUBES_IDLE, entity); }, Tasks = new[] { checkOperationalRadius, checkTargetAgent, new AI.Task { Action = delegate() { if (ai.TimeInCurrentState.Value > 20.0f) { Entity voxel = raycastAI.Voxel.Value.Target; if (voxel != null && voxel.Active) { raycastAI.Coord.Value = raycastAI.LastCoord.Value = voxel.Get <Voxel>().GetCoordinate(transform.Position); } raycastAI.Move(new Vector3(((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f)); ai.CurrentState.Value = "Alert"; } else { movement.PositionBlend.Value += (main.ElapsedTime.Value / 1.0f); if (movement.PositionBlend > 1.0f) { findNextPosition(); } transform.Position.Value = Vector3.Lerp(movement.LastPosition, movement.NextPosition, movement.PositionBlend); } } }, }, }); this.SetMain(entity, main); }
public override void Awake() { base.Awake(); this.EnabledWhenPaused = true; this.Add(new NotifyBinding(main.AlphaDrawablesModified, this.DrawOrder)); this.Add(new SetBinding <bool>(this.CannotSuspendByDistance, delegate(bool value) { this.Entity.CannotSuspendByDistance = value; })); this.Add(new NotifyBinding(delegate() { this.needResize = true; }, this.main.ScreenSize)); this.Add(new Binding <bool>(this.EnableReflection, this.main.Settings.Reflections)); Action removeFluid = delegate() { if (this.Fluid.Space != null) { this.main.Space.Remove(this.Fluid); } AkSoundEngine.PostEvent(AK.EVENTS.STOP_WATER_LOOP, this.Entity); }; Action addFluid = delegate() { if (this.Fluid.Space == null && this.Enabled && !this.Suspended) { this.main.Space.Add(this.Fluid); if (!this.main.EditorEnabled) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_WATER_LOOP, this.Entity); } } }; this.Add(new CommandBinding(this.OnSuspended, removeFluid)); this.Add(new CommandBinding(this.Disable, removeFluid)); this.Add(new CommandBinding(this.OnResumed, addFluid)); this.Add(new CommandBinding(this.Enable, addFluid)); this.camera = new Camera(); this.main.AddComponent(this.camera); this.parameters = new RenderParameters { Camera = this.camera, Technique = Technique.Clip, ReverseCullOrder = true, }; this.Add(new SetBinding <Vector3>(this.Color, delegate(Vector3 value) { this.effect.Parameters["Color"].SetValue(value); })); this.Add(new SetBinding <Vector2>(this.Scale, delegate(Vector2 value) { this.effect.Parameters["Scale"].SetValue(value); this.updatePhysics(); })); this.Add(new SetBinding <Vector3>(this.UnderwaterColor, delegate(Vector3 value) { this.effect.Parameters["UnderwaterColor"].SetValue(value); })); this.Add(new SetBinding <float>(this.Fresnel, delegate(float value) { this.effect.Parameters["Fresnel"].SetValue(value); })); this.Add(new SetBinding <float>(this.Speed, delegate(float value) { this.effect.Parameters["Speed"].SetValue(value); })); this.Add(new SetBinding <float>(this.RippleDensity, delegate(float value) { this.effect.Parameters["RippleDensity"].SetValue(value); })); this.Add(new SetBinding <float>(this.Distortion, delegate(float value) { this.effect.Parameters["Distortion"].SetValue(value); })); this.Add(new SetBinding <float>(this.Brightness, delegate(float value) { this.effect.Parameters["Brightness"].SetValue(value); })); this.Add(new SetBinding <float>(this.Refraction, delegate(float value) { this.effect.Parameters["Refraction"].SetValue(value); })); this.Add(new SetBinding <Vector3>(this.Position, delegate(Vector3 value) { this.effect.Parameters["Position"].SetValue(this.Position); if (this.CannotSuspendByDistance) { Water.BigWaterHeight.Value = value.Y; } this.updatePhysics(); })); this.Add(new SetBinding <float>(this.Depth, delegate(float value) { this.updatePhysics(); })); instances.Add(this); this.Add(new Binding <Vector3>(this.soundPosition, delegate(Vector3 pos) { BoundingBox box = this.Fluid.BoundingBox; pos.X = Math.Max(box.Min.X, Math.Min(pos.X, box.Max.X)); pos.Y = this.Position.Value.Y; pos.Z = Math.Max(box.Min.Z, Math.Min(pos.Z, box.Max.Z)); return(pos); }, this.main.Camera.Position)); AkGameObjectTracker.Attach(this.Entity, this.soundPosition); if (!this.main.EditorEnabled && this.Enabled && !this.Suspended) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_WATER_LOOP, this.Entity); } }
public override void Bind(Entity entity, Main main, bool creating = false) { Transform transform = entity.GetOrCreate <Transform>("Transform"); ModelAlpha model = entity.GetOrCreate <ModelAlpha>("Model"); model.Filename.Value = "AlphaModels\\waterfall"; model.Distortion.Value = true; this.SetMain(entity, main); VoxelAttachable.MakeAttachable(entity, main).EditorProperties(); entity.Add("Scale", model.Scale); entity.Add("Color", model.Color); entity.Add("Alpha", model.Alpha); model.Add(new Binding <Matrix>(model.Transform, transform.Matrix)); Property <Vector2> uvScale = model.GetVector2Parameter("UVScale"); model.Add(new Binding <Vector2, Vector3>(uvScale, x => new Vector2(x.X, x.Y), model.Scale)); Property <Vector3> soundPosition = new Property <Vector3>(); AkGameObjectTracker.Attach(entity, soundPosition); if (!main.EditorEnabled && !model.Suspended) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_WATERFALL_LOOP, entity); } Action stopSound = delegate() { AkSoundEngine.PostEvent(AK.EVENTS.STOP_WATERFALL_LOOP, entity); }; model.Add(new CommandBinding(model.OnSuspended, stopSound)); model.Add(new CommandBinding(model.Delete, stopSound)); model.Add(new CommandBinding(model.OnResumed, delegate() { if (!main.EditorEnabled) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_WATERFALL_LOOP, entity); } })); Property <Vector2> offset = model.GetVector2Parameter("Offset"); Updater updater = new Updater ( delegate(float dt) { offset.Value = new Vector2(0, main.TotalTime * -0.6f); Vector3 relativeCamera = Vector3.Transform(main.Camera.Position, Matrix.Invert(transform.Matrix)); Vector3 bounds = model.Scale.Value * 0.5f; relativeCamera.X = MathHelper.Clamp(relativeCamera.X, -bounds.X, bounds.X); relativeCamera.Y = Math.Min(0, relativeCamera.Y); relativeCamera.Z = MathHelper.Clamp(relativeCamera.Z, -bounds.Z, bounds.Z); soundPosition.Value = Vector3.Transform(relativeCamera, transform.Matrix); } ); updater.EnabledInEditMode = true; entity.Add(updater); }
public override void Bind(Entity entity, Main main, bool creating = false) { BlockCloud blockCloud = entity.GetOrCreate <BlockCloud>("BlockCloud"); blockCloud.Add(new CommandBinding(blockCloud.Delete, entity.Delete)); blockCloud.Add(new CommandBinding <Collidable, ContactCollection>(blockCloud.Collided, delegate(Collidable other, ContactCollection contacts) { if (other.Tag != null && other.Tag.GetType() == typeof(Character)) { // Damage the player Entity p = PlayerFactory.Instance; if (p != null && p.Active) { p.Get <Agent>().Damage.Execute(0.1f); } } })); blockCloud.Type.Value = Voxel.t.Black; Transform transform = entity.GetOrCreate <Transform>("Transform"); AkGameObjectTracker.Attach(entity); AI ai = entity.GetOrCreate <AI>("AI"); if (!main.EditorEnabled) { entity.Add(new PostInitialization { delegate() { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_EVIL_CUBES, entity); AkSoundEngine.PostEvent(ai.CurrentState == "Chase" ? AK.EVENTS.EVIL_CUBES_CHASE : AK.EVENTS.EVIL_CUBES_IDLE, entity); } }); SoundKiller.Add(entity, AK.EVENTS.STOP_EVIL_CUBES); } Agent agent = entity.GetOrCreate <Agent>(); agent.Add(new Binding <Vector3>(agent.Position, transform.Position)); RaycastAI raycastAI = entity.GetOrCreate <RaycastAI>("RaycastAI"); raycastAI.BlendTime.Value = 1.0f; raycastAI.Add(new TwoWayBinding <Vector3>(transform.Position, raycastAI.Position)); raycastAI.Add(new Binding <Quaternion>(transform.Quaternion, raycastAI.Orientation)); blockCloud.Add(new Binding <Vector3>(blockCloud.Position, transform.Position)); const float operationalRadius = 100.0f; AI.Task checkOperationalRadius = new AI.Task { Interval = 2.0f, Action = delegate() { bool shouldBeActive = (transform.Position.Value - main.Camera.Position).Length() < operationalRadius; if (shouldBeActive && ai.CurrentState == "Suspended") { ai.CurrentState.Value = "Idle"; } else if (!shouldBeActive && ai.CurrentState != "Suspended") { ai.CurrentState.Value = "Suspended"; } }, }; AI.Task updatePosition = new AI.Task { Action = delegate() { raycastAI.Update(); }, }; ai.Add(new AI.AIState { Name = "Suspended", Tasks = new[] { checkOperationalRadius, }, }); const float sightDistance = 30.0f; const float hearingDistance = 15.0f; ai.Add(new AI.AIState { Name = "Idle", Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { raycastAI.Move(new Vector3(((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f)); } }, new AI.Task { Interval = 1.0f, Action = delegate() { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.CurrentState.Value = "Alert"; } }, }, }, }); ai.Add(new AI.AIState { Name = "Alert", Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { if (ai.TimeInCurrentState > 3.0f) { ai.CurrentState.Value = "Idle"; } else { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.TargetAgent.Value = a.Entity; ai.CurrentState.Value = "Chase"; } } }, }, }, }); AI.Task checkTargetAgent = new AI.Task { Action = delegate() { Entity target = ai.TargetAgent.Value.Target; if (target == null || !target.Active) { ai.TargetAgent.Value = null; ai.CurrentState.Value = "Idle"; } }, }; // Chase AI state ai.Add(new AI.AIState { Name = "Chase", Enter = delegate(AI.AIState previous) { AkSoundEngine.PostEvent(AK.EVENTS.EVIL_CUBES_CHASE, entity); raycastAI.BlendTime.Value = 0.5f; }, Exit = delegate(AI.AIState next) { raycastAI.BlendTime.Value = 1.0f; AkSoundEngine.PostEvent(AK.EVENTS.EVIL_CUBES_IDLE, entity); }, Tasks = new[] { checkOperationalRadius, checkTargetAgent, new AI.Task { Interval = 0.5f, Action = delegate() { raycastAI.Move(ai.TargetAgent.Value.Target.Get <Transform>().Position.Value - transform.Position); } }, updatePosition, }, }); this.SetMain(entity, main); }
public override void Bind(Entity entity, Main main, bool creating = false) { PointLight light = entity.GetOrCreate <PointLight>("PointLight"); light.Serialize = false; const float defaultLightAttenuation = 15.0f; light.Attenuation.Value = defaultLightAttenuation; Transform transform = entity.GetOrCreate <Transform>("Transform"); light.Add(new Binding <Vector3>(light.Position, transform.Position)); if (!main.EditorEnabled) { AkGameObjectTracker.Attach(entity); SoundKiller.Add(entity, AK.EVENTS.STOP_GLOWSQUARE); entity.Add(new PostInitialization { delegate() { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_GLOWSQUARE, entity); AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_GLOWSQUARE_PITCH, -1.0f, entity); } }); } AI ai = entity.GetOrCreate <AI>("AI"); ModelAlpha model = entity.GetOrCreate <ModelAlpha>(); model.Add(new Binding <Matrix>(model.Transform, transform.Matrix)); model.Filename.Value = "AlphaModels\\box"; model.Serialize = false; model.DrawOrder.Value = 15; const float defaultModelScale = 1.0f; model.Scale.Value = new Vector3(defaultModelScale); model.Add(new Binding <Vector3, string>(model.Color, delegate(string state) { switch (state) { case "Alert": return(new Vector3(1.5f, 1.5f, 0.5f)); case "Chase": return(new Vector3(1.5f, 0.5f, 0.5f)); case "Explode": return(new Vector3(2.0f, 1.0f, 0.5f)); default: return(new Vector3(1.0f, 1.0f, 1.0f)); } }, ai.CurrentState)); entity.Add(new Updater ( delegate(float dt) { float source = 1.0f + ((float)this.random.NextDouble() - 0.5f) * 2.0f * 0.05f; model.Scale.Value = new Vector3(defaultModelScale * source); light.Attenuation.Value = defaultLightAttenuation * source; } )); model.Add(new Binding <bool, string>(model.Enabled, x => x != "Exploding", ai.CurrentState)); light.Add(new Binding <Vector3>(light.Color, model.Color)); Agent agent = entity.GetOrCreate <Agent>(); agent.Add(new Binding <Vector3>(agent.Position, transform.Position)); RaycastAIMovement movement = entity.GetOrCreate <RaycastAIMovement>("Movement"); Exploder exploder = entity.GetOrCreate <Exploder>("Exploder"); AI.Task checkOperationalRadius = new AI.Task { Interval = 2.0f, Action = delegate() { bool shouldBeActive = (transform.Position.Value - main.Camera.Position).Length() < movement.OperationalRadius; if (shouldBeActive && ai.CurrentState == "Suspended") { ai.CurrentState.Value = "Idle"; } else if (!shouldBeActive && ai.CurrentState != "Suspended") { ai.CurrentState.Value = "Suspended"; } }, }; RaycastAI raycastAI = entity.GetOrCreate <RaycastAI>("RaycastAI"); raycastAI.Add(new TwoWayBinding <Vector3>(transform.Position, raycastAI.Position)); raycastAI.Add(new Binding <Quaternion>(transform.Quaternion, raycastAI.Orientation)); AI.Task updatePosition = new AI.Task { Action = delegate() { raycastAI.Update(); }, }; ai.Add(new AI.AIState { Name = "Suspended", Tasks = new[] { checkOperationalRadius, }, }); const float sightDistance = 40.0f; const float hearingDistance = 15.0f; ai.Add(new AI.AIState { Name = "Idle", Enter = delegate(AI.AIState previous) { AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_GLOWSQUARE_PITCH, -1.0f, entity); }, Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { raycastAI.Move(new Vector3(((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f)); } }, new AI.Task { Interval = 0.5f, Action = delegate() { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.CurrentState.Value = "Alert"; } }, }, }, }); ai.Add(new AI.AIState { Name = "Alert", Enter = delegate(AI.AIState previous) { AkSoundEngine.PostEvent(AK.EVENTS.STOP_GLOWSQUARE, entity); }, Exit = delegate(AI.AIState next) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_GLOWSQUARE, entity); }, Tasks = new[] { checkOperationalRadius, updatePosition, new AI.Task { Interval = 1.0f, Action = delegate() { if (ai.TimeInCurrentState > 3.0f) { ai.CurrentState.Value = "Idle"; } else { Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player"); if (a != null) { ai.TargetAgent.Value = a.Entity; ai.CurrentState.Value = "Chase"; } } }, }, }, }); AI.Task checkTargetAgent = new AI.Task { Action = delegate() { Entity target = ai.TargetAgent.Value.Target; if (target == null || !target.Active) { ai.TargetAgent.Value = null; ai.CurrentState.Value = "Idle"; } }, }; ai.Add(new AI.AIState { Name = "Chase", Enter = delegate(AI.AIState previous) { AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_GLOWSQUARE_PITCH, 0.0f, entity); }, Tasks = new[] { checkOperationalRadius, checkTargetAgent, new AI.Task { Interval = 0.35f, Action = delegate() { raycastAI.Move(ai.TargetAgent.Value.Target.Get <Transform>().Position.Value - transform.Position); } }, new AI.Task { Action = delegate() { if ((ai.TargetAgent.Value.Target.Get <Transform>().Position.Value - transform.Position).Length() < 10.0f) { ai.CurrentState.Value = "Explode"; } } }, updatePosition, }, }); EffectBlockFactory factory = Factory.Get <EffectBlockFactory>(); ai.Add(new AI.AIState { Name = "Explode", Enter = delegate(AI.AIState previous) { exploder.CoordQueue.Clear(); Entity voxelEntity = raycastAI.Voxel.Value.Target; if (voxelEntity == null || !voxelEntity.Active) { ai.CurrentState.Value = "Alert"; return; } Voxel m = voxelEntity.Get <Voxel>(); Voxel.Coord c = raycastAI.Coord.Value; Direction toSupport = Direction.None; foreach (Direction dir in DirectionExtensions.Directions) { if (m[raycastAI.Coord.Value.Move(dir)].ID != 0) { toSupport = dir; break; } } Direction up = toSupport.GetReverse(); exploder.ExplosionOriginalCoord.Value = raycastAI.Coord; Direction right; if (up.IsParallel(Direction.PositiveX)) { right = Direction.PositiveZ; } else { right = Direction.PositiveX; } Direction forward = up.Cross(right); for (Voxel.Coord y = c.Clone(); y.GetComponent(up) < c.GetComponent(up) + 3; y = y.Move(up)) { for (Voxel.Coord x = y.Clone(); x.GetComponent(right) < c.GetComponent(right) + 2; x = x.Move(right)) { for (Voxel.Coord z = x.Clone(); z.GetComponent(forward) < c.GetComponent(forward) + 2; z = z.Move(forward)) { exploder.CoordQueue.Add(z); } } } }, Exit = delegate(AI.AIState next) { exploder.CoordQueue.Clear(); }, Tasks = new[] { checkOperationalRadius, new AI.Task { Interval = 0.15f, Action = delegate() { if (exploder.CoordQueue.Length > 0) { raycastAI.MoveTo(exploder.CoordQueue[0]); exploder.CoordQueue.RemoveAt(0); Entity blockEntity = factory.CreateAndBind(main); Voxel.States.Infected.ApplyToEffectBlock(blockEntity.Get <ModelInstance>()); Entity mapEntity = raycastAI.Voxel.Value.Target; if (mapEntity != null && mapEntity.Active) { EffectBlock effectBlock = blockEntity.Get <EffectBlock>(); Voxel m = mapEntity.Get <Voxel>(); effectBlock.Offset.Value = m.GetRelativePosition(raycastAI.Coord); Vector3 absolutePos = m.GetAbsolutePosition(raycastAI.Coord); effectBlock.StartPosition = absolutePos + new Vector3(0.05f, 0.1f, 0.05f); effectBlock.StartOrientation = Quaternion.CreateFromYawPitchRoll(0.15f, 0.15f, 0); effectBlock.TotalLifetime = 0.05f; effectBlock.Setup(raycastAI.Voxel.Value.Target, raycastAI.Coord, Voxel.t.Infected); main.Add(blockEntity); } } } }, new AI.Task { Action = delegate() { AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.SFX_GLOWSQUARE_PITCH, MathHelper.Lerp(0.0f, 1.0f, ai.TimeInCurrentState.Value / 2.0f), entity); if (exploder.CoordQueue.Length == 0) { // Explode ai.CurrentState.Value = "Exploding"; } }, }, updatePosition, }, }); ai.Add(new AI.AIState { Name = "Exploding", Enter = delegate(AI.AIState previous) { exploder.Exploded.Value = false; AkSoundEngine.PostEvent(AK.EVENTS.STOP_GLOWSQUARE, entity); }, Exit = delegate(AI.AIState next) { exploder.Exploded.Value = false; AkSoundEngine.PostEvent(AK.EVENTS.PLAY_GLOWSQUARE, entity); }, Tasks = new[] { new AI.Task { Interval = 0.1f, Action = delegate() { const int radius = 9; float timeInCurrentState = ai.TimeInCurrentState; if (timeInCurrentState > 1.0f && !exploder.Exploded) { Entity mapEntity = raycastAI.Voxel.Value.Target; if (mapEntity != null && mapEntity.Active) { Explosion.Explode(main, mapEntity.Get <Voxel>(), raycastAI.Coord, radius, 18.0f); } exploder.Exploded.Value = true; } if (timeInCurrentState > 2.0f) { raycastAI.Move(new Vector3(((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f, ((float)this.random.NextDouble() * 2.0f) - 1.0f)); ai.CurrentState.Value = "Alert"; } }, }, updatePosition, }, }); this.SetMain(entity, main); entity.Add("OperationalRadius", movement.OperationalRadius); }