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)); Sound.AttachTracker(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) { Transform transform = entity.GetOrCreate <Transform>("Transform"); this.SetMain(entity, main); VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main, true, false); attachable.Enabled.Value = true; if (!main.EditorEnabled) { // -1 means we're currently submerged, anything above 0 is the timestamp of the last time we were submerged float submerged = -1.0f; float lastEmit = 0.0f; Water submergedWater = null; Property <Vector3> coordinatePos = new Property <Vector3>(); VoxelAttachable.BindTarget(entity, coordinatePos); Action check = delegate() { Water nowSubmerged = Water.Get(coordinatePos); if (nowSubmerged == null && main.TotalTime - submerged < 1.0f) { Entity ve = attachable.AttachedVoxel.Value.Target; if (ve != null) { Voxel v = ve.Get <Voxel>(); Voxel.Box b = v.GetBox(attachable.Coord); if (b != null) { BoundingBox box = new BoundingBox(v.GetRelativePosition(b.X, b.Y, b.Z), v.GetRelativePosition(b.X + b.Width, b.Y + b.Height, b.Z + b.Depth)); if (submergedWater != null && main.TotalTime - lastEmit > 0.1f) { Water.SplashParticles(main, box.Transform(v.Transform), v, submergedWater.Position.Value.Y); lastEmit = main.TotalTime; } } } } if (nowSubmerged != null) { submerged = -1.0f; submergedWater = nowSubmerged; } else if (submerged == -1.0f && nowSubmerged == null) { Sound.PostEvent(AK.EVENTS.PLAY_WATER_SPLASH_OUT_BIG, transform.Position); submerged = main.TotalTime; } }; transform.Add(new NotifyBinding(check, coordinatePos)); entity.Add(new PostInitialization(delegate() { submerged = Water.Get(coordinatePos) != null ? -1.0f : -2.0f; })); } entity.Add("AttachOffset", attachable.Offset); entity.Add("AttachVector", attachable.Vector); }
public override void Bind(Entity entity, Main main, bool creating = false) { SpotLight light = entity.Create <SpotLight>(); light.Enabled.Value = !main.EditorEnabled; light.FieldOfView.Value = 1.0f; light.Attenuation.Value = 75.0f; Transform transform = entity.GetOrCreate <Transform>("Transform"); light.Add(new Binding <Vector3>(light.Position, transform.Position)); Turret turret = entity.GetOrCreate <Turret>("Turret"); Command die = new Command { Action = delegate() { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_TURRET_DEATH, entity); ParticleSystem shatter = ParticleSystem.Get(main, "InfectedShatter"); Random random = new Random(); for (int i = 0; i < 50; i++) { Vector3 offset = new Vector3((float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f); shatter.AddParticle(transform.Position + offset, offset); } entity.Delete.Execute(); } }; VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main, true, true, die); attachable.Enabled.Value = true; attachable.Offset.Value = 2; PointLight pointLight = entity.GetOrCreate <PointLight>(); pointLight.Serialize = false; pointLight.Add(new Binding <Vector3>(pointLight.Position, transform.Position)); LineDrawer laser = new LineDrawer { Serialize = false }; entity.Add(laser); laser.DrawOrder.Value = 0; AI ai = entity.GetOrCreate <AI>("AI"); ModelAlpha model = entity.Create <ModelAlpha>(); model.Add(new Binding <Matrix>(model.Transform, transform.Matrix)); model.Filename.Value = "AlphaModels\\pyramid"; const float defaultModelScale = 0.75f; model.Scale.Value = new Vector3(defaultModelScale); const float sightDistance = 80.0f; const float hearingDistance = 0.0f; const float operationalRadius = 100.0f; model.Add(new Binding <Vector3, string>(model.Color, delegate(string state) { switch (state) { case "Alert": return(new Vector3(1.0f, 1.0f, 0.25f)); case "Aggressive": return(new Vector3(1.0f, 0.5f, 0.25f)); case "Firing": return(new Vector3(1.0f, 0.0f, 0.0f)); case "Disabled": return(new Vector3(0.0f, 0.0f, 0.0f)); default: return(new Vector3(1.0f, 1.0f, 1.0f)); } }, ai.CurrentState)); laser.Add(new Binding <bool, string>(laser.Enabled, x => x != "Disabled" && x != "Suspended", ai.CurrentState)); light.Add(new Binding <Vector3>(light.Color, model.Color)); pointLight.Add(new Binding <Vector3>(pointLight.Color, model.Color)); Voxel.GlobalRaycastResult rayHit = new Voxel.GlobalRaycastResult(); Vector3 toReticle = Vector3.Zero; AI.Task checkOperationalRadius = new AI.Task { Interval = 2.0f, Action = delegate() { bool shouldBeActive = (transform.Position.Value - main.Camera.Position).Length() < operationalRadius && Water.Get(transform.Position) == null; if (shouldBeActive && ai.CurrentState == "Suspended") { ai.CurrentState.Value = "Idle"; } else if (!shouldBeActive && ai.CurrentState != "Suspended") { ai.CurrentState.Value = "Suspended"; } }, }; turret.Add(new CommandBinding(turret.PowerOn, delegate() { if (ai.CurrentState == "Disabled") { ai.CurrentState.Value = "Suspended"; checkOperationalRadius.Action(); } })); turret.Add(new CommandBinding(turret.PowerOff, delegate() { ai.CurrentState.Value = "Disabled"; })); light.Add(new Binding <Quaternion>(light.Orientation, delegate() { return(Quaternion.CreateFromYawPitchRoll(-(float)Math.Atan2(toReticle.Z, toReticle.X) - (float)Math.PI * 0.5f, (float)Math.Asin(toReticle.Y), 0)); }, transform.Position, turret.Reticle)); AI.Task updateRay = new AI.Task { Action = delegate() { toReticle = Vector3.Normalize(turret.Reticle.Value - transform.Position.Value); rayHit = Voxel.GlobalRaycast(transform.Position, toReticle, operationalRadius); laser.Lines.Clear(); Microsoft.Xna.Framework.Color color = new Microsoft.Xna.Framework.Color(model.Color); laser.Lines.Add(new LineDrawer.Line { A = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(transform.Position, color), B = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(rayHit.Position, color), }); } }; ai.Add(new AI.AIState { Name = "Disabled", Tasks = new AI.Task[] { }, }); ai.Add(new AI.AIState { Name = "Suspended", Tasks = new[] { checkOperationalRadius, }, }); ai.Add(new AI.AIState { Name = "Idle", Tasks = new[] { checkOperationalRadius, updateRay, 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, updateRay, 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 = "Aggressive"; } } }, }, }, }); 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"; } }, }; float lastSpotted = 0.0f; ai.Add(new AI.AIState { Name = "Aggressive", Tasks = new[] { checkTargetAgent, updateRay, new AI.Task { Action = delegate() { Entity target = ai.TargetAgent.Value.Target; turret.Reticle.Value += (target.Get <Transform>().Position - turret.Reticle.Value) * Math.Min(3.0f * main.ElapsedTime, 1.0f); } }, new AI.Task { Interval = 0.1f, Action = delegate() { if (Agent.Query(transform.Position, sightDistance, hearingDistance, ai.TargetAgent.Value.Target.Get <Agent>())) { lastSpotted = main.TotalTime; } if (ai.TimeInCurrentState.Value > 1.5f) { if (lastSpotted < main.TotalTime - 2.0f) { ai.CurrentState.Value = "Alert"; } else { Vector3 targetPos = ai.TargetAgent.Value.Target.Get <Transform>().Position.Value; Vector3 toTarget = Vector3.Normalize(targetPos - transform.Position.Value); if (Vector3.Dot(toReticle, toTarget) > 0.95f) { ai.CurrentState.Value = "Firing"; } } } } }, } }); ai.Add(new AI.AIState { Name = "Firing", Enter = delegate(AI.AIState last) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_TURRET_CHARGE, entity); }, Exit = delegate(AI.AIState next) { Voxel.State attachedState = attachable.AttachedVoxel.Value.Target.Get <Voxel>()[attachable.Coord]; if (!attachedState.Permanent && rayHit.Voxel != null && (rayHit.Position - transform.Position).Length() < 8.0f) { return; // Danger close, cease fire! } AkSoundEngine.PostEvent(AK.EVENTS.PLAY_TURRET_FIRE, entity); bool hitVoxel = true; Entity target = ai.TargetAgent.Value.Target; if (target != null && target.Active) { Vector3 targetPos = target.Get <Transform>().Position; Vector3 toTarget = targetPos - transform.Position.Value; if (Vector3.Dot(toReticle, Vector3.Normalize(toTarget)) > 0.2f) { float distance = toTarget.Length(); if (distance < rayHit.Distance) { Sound.PostEvent(AK.EVENTS.PLAY_TURRET_MISS, transform.Position + toReticle * distance); } } BEPUutilities.RayHit physicsHit; if (target.Get <Player>().Character.Body.CollisionInformation.RayCast(new Ray(transform.Position, toReticle), rayHit.Voxel == null ? float.MaxValue : rayHit.Distance, out physicsHit)) { Explosion.Explode(main, targetPos, 6, 8.0f); hitVoxel = false; } } if (hitVoxel && rayHit.Voxel != null) { Explosion.Explode(main, rayHit.Position + rayHit.Voxel.GetAbsoluteVector(rayHit.Normal.GetVector()) * 0.5f, 6, 8.0f); } Vector3 splashPos; Water w = Water.Raycast(transform.Position, toReticle, rayHit.Distance, out splashPos); if (w != null) { Sound.PostEvent(AK.EVENTS.PLAY_WATER_SPLASH, splashPos); Water.SplashParticles(main, splashPos, 3.0f); } }, Tasks = new[] { checkTargetAgent, updateRay, new AI.Task { Action = delegate() { if (ai.TimeInCurrentState.Value > 0.75f) { ai.CurrentState.Value = "Aggressive"; // This actually fires (in the Exit function) } } } } }); this.SetMain(entity, main); entity.Add("On", turret.On); entity.Add("PowerOn", turret.PowerOn); entity.Add("PowerOff", turret.PowerOff); }
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>(); Sound.AttachTracker(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) { Transform transform = entity.GetOrCreate <Transform>("Transform"); this.SetMain(entity, main); Sound.AttachTracker(entity); VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main, true, false); attachable.Offset.Value = 1; attachable.Enabled.Value = true; PowerBlockSocket socket = entity.GetOrCreate <PowerBlockSocket>("PowerBlockSocket"); socket.Add(new Binding <Voxel.Coord>(socket.Coord, attachable.Coord)); socket.Add(new Binding <Entity.Handle>(socket.AttachedVoxel, attachable.AttachedVoxel)); const float maxLightAttenuation = 15.0f; PointLight light = entity.Create <PointLight>(); light.Attenuation.Value = maxLightAttenuation; light.Add(new Binding <Vector3>(light.Position, transform.Position)); light.Add(new Binding <Vector3, Voxel.t>(light.Color, delegate(Voxel.t t) { switch (t) { case Voxel.t.GlowBlue: return(new Vector3(0.8f, 0.9f, 1.2f)); case Voxel.t.GlowYellow: return(new Vector3(1.2f, 1.2f, 0.8f)); default: return(Vector3.One); } }, socket.Type)); light.Add(new Binding <bool>(light.Enabled, socket.Powered)); PointLight animationLight = entity.Create <PointLight>(); animationLight.Add(new Binding <Vector3>(animationLight.Position, light.Position)); animationLight.Add(new Binding <Vector3>(animationLight.Color, light.Color)); animationLight.Enabled.Value = false; PlayerTrigger trigger = entity.GetOrCreate <PlayerTrigger>("PlayerTrigger"); trigger.Radius.Value = 7; trigger.Add(new Binding <Vector3>(trigger.Position, transform.Position)); const float minimumChangeTime = 1.5f; float lastChange = -minimumChangeTime; trigger.Add(new CommandBinding(trigger.PlayerEntered, delegate() { if (main.TotalTime - lastChange > minimumChangeTime) { BlockCloud cloud = PlayerFactory.Instance.Get <BlockCloud>(); bool changed = false; Voxel sockVoxel = attachable.AttachedVoxel.Value.Target.Get <Voxel>(); if (!socket.Powered && cloud.Type.Value == socket.Type.Value) { // Plug in to the socket List <Voxel.Coord> coords = new List <Voxel.Coord>(); Queue <Voxel.Coord> queue = new Queue <Voxel.Coord>(); queue.Enqueue(sockVoxel.GetCoordinate(transform.Position)); while (queue.Count > 0) { Voxel.Coord c = queue.Dequeue(); coords.Add(c); if (coords.Count >= cloud.Blocks.Length) { break; } Voxel.CoordSetCache.Add(c); foreach (Direction adjacentDirection in DirectionExtensions.Directions) { Voxel.Coord adjacentCoord = c.Move(adjacentDirection); if (!Voxel.CoordSetCache.Contains(adjacentCoord)) { Voxel.t adjacentID = sockVoxel[adjacentCoord].ID; if (adjacentID == Voxel.t.Empty) { queue.Enqueue(adjacentCoord); } } } } Voxel.CoordSetCache.Clear(); EffectBlockFactory factory = Factory.Get <EffectBlockFactory>(); int i = 0; foreach (Entity block in cloud.Blocks) { Entity effectBlockEntity = factory.CreateAndBind(main); Voxel.States.All[cloud.Type].ApplyToEffectBlock(effectBlockEntity.Get <ModelInstance>()); EffectBlock effectBlock = effectBlockEntity.Get <EffectBlock>(); effectBlock.DoScale = false; Transform blockTransform = block.Get <Transform>(); effectBlock.StartPosition = blockTransform.Position; effectBlock.StartOrientation = blockTransform.Quaternion; effectBlock.TotalLifetime = (i + 1) * 0.04f; effectBlock.Setup(sockVoxel.Entity, coords[i], cloud.Type); main.Add(effectBlockEntity); block.Delete.Execute(); i++; } cloud.Blocks.Clear(); cloud.Type.Value = Voxel.t.Empty; socket.Powered.Value = true; changed = true; } else if (socket.Powered && cloud.Type.Value == Voxel.t.Empty && !socket.PowerOnOnly) { // Pull blocks out of the socket AkSoundEngine.PostEvent(AK.EVENTS.PLAY_MAGIC_CUBES, entity); SceneryBlockFactory factory = Factory.Get <SceneryBlockFactory>(); Quaternion quat = Quaternion.CreateFromRotationMatrix(sockVoxel.Transform); cloud.Type.Value = socket.Type; List <Voxel.Coord> coords = sockVoxel.GetContiguousByType(new[] { sockVoxel.GetBox(transform.Position) }).SelectMany(x => x.GetCoords()).ToList(); sockVoxel.Empty(coords, true); sockVoxel.Regenerate(); ParticleSystem particles = ParticleSystem.Get(main, "WhiteShatter"); int count = 0; foreach (Voxel.Coord c in coords) { Vector3 pos = sockVoxel.GetAbsolutePosition(c); for (int j = 0; j < 20; j++) { Vector3 offset = new Vector3((float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f); particles.AddParticle(pos + offset, offset); } if (count < BlockCloud.TotalBlocks) { Entity block = factory.CreateAndBind(main); Transform blockTransform = block.Get <Transform>(); blockTransform.Position.Value = pos; blockTransform.Quaternion.Value = quat; SceneryBlock sceneryBlock = block.Get <SceneryBlock>(); sceneryBlock.Type.Value = socket.Type; sceneryBlock.Scale.Value = 0.5f; cloud.Blocks.Add(block); main.Add(block); } count++; } socket.Powered.Value = false; changed = true; } if (changed) { lastChange = main.TotalTime; animationLight.Enabled.Value = true; animationLight.Attenuation.Value = 0.0f; entity.Add(new Animation ( new Animation.FloatMoveTo(animationLight.Attenuation, maxLightAttenuation, 0.25f), new Animation.FloatMoveTo(animationLight.Attenuation, 0.0f, 2.0f), new Animation.Set <bool>(animationLight.Enabled, false) )); } } })); entity.Add("Type", socket.Type); entity.Add("Powered", socket.Powered, new PropertyEntry.EditorData { Readonly = true }); entity.Add("PowerOnOnly", socket.PowerOnOnly); entity.Add("OnPowerOn", socket.OnPowerOn); entity.Add("OnPowerOff", socket.OnPowerOff); entity.Add("Enabled", trigger.Enabled); entity.Add("Enable", trigger.Enable); entity.Add("Disable", trigger.Disable); }
public override void Bind(Entity entity, Main main, bool creating = false) { entity.CannotSuspendByDistance = true; PointLight light = entity.GetOrCreate <PointLight>("PointLight"); Transform transform = entity.GetOrCreate <Transform>("Transform"); VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main); attachable.Enabled.Value = true; light.Add(new Binding <Vector3>(light.Position, () => Vector3.Transform(new Vector3(0, 0, attachable.Offset), transform.Matrix), attachable.Offset, transform.Matrix)); Switch sw = entity.GetOrCreate <Switch>("Switch"); if (main.EditorEnabled) { light.Enabled.Value = true; } else { light.Add(new Binding <bool>(light.Enabled, sw.On)); CommandBinding <IEnumerable <Voxel.Coord>, Voxel> cellFilledBinding = null; entity.Add(new NotifyBinding(delegate() { Voxel m = attachable.AttachedVoxel.Value.Target.Get <Voxel>(); if (cellFilledBinding != null) { entity.Remove(cellFilledBinding); } cellFilledBinding = new CommandBinding <IEnumerable <Voxel.Coord>, Voxel>(m.CellsFilled, delegate(IEnumerable <Voxel.Coord> coords, Voxel newMap) { foreach (Voxel.Coord c in coords) { if (c.Equivalent(attachable.Coord)) { sw.On.Value = c.Data == Voxel.States.PoweredSwitch; break; } } }); entity.Add(cellFilledBinding); sw.On.Value = m[attachable.Coord] == Voxel.States.PoweredSwitch; }, attachable.AttachedVoxel)); } sw.Add(new Binding <Entity.Handle>(sw.AttachedVoxel, attachable.AttachedVoxel)); sw.Add(new Binding <Voxel.Coord>(sw.Coord, attachable.Coord)); this.SetMain(entity, main); entity.Add("AttachOffset", attachable.Offset); entity.Add("OnPowerOn", sw.OnPowerOn); entity.Add("OnPowerOff", sw.OnPowerOff); entity.Add("On", sw.On, null, true); entity.Add("PowerOnCue", sw.PowerOnCue, new PropertyEntry.EditorData { Options = WwisePicker.Get(main) }); }