public override void Bind(Entity entity, Main main, bool creating = false) { Transform transform = entity.GetOrCreate <Transform>("Transform"); PhysicsBlock physics = entity.GetOrCreate <PhysicsBlock>("Physics"); ModelInstance model = entity.GetOrCreate <ModelInstance>("Model"); physics.Add(new TwoWayBinding <Matrix>(transform.Matrix, physics.Transform)); SceneryBlock sceneryBlock = entity.GetOrCreate <SceneryBlock>("SceneryBlock"); physics.Add(new Binding <Vector3, float>(physics.Size, x => new Vector3(x), sceneryBlock.Scale)); model.Add(new Binding <Matrix>(model.Transform, () => Matrix.CreateScale(sceneryBlock.Scale) * transform.Matrix, transform.Matrix, sceneryBlock.Scale)); this.SetMain(entity, main); entity.Add("IsAffectedByGravity", physics.IsAffectedByGravity); sceneryBlock.EditorProperties(); if (!main.EditorEnabled && !physics.IsAffectedByGravity && (sceneryBlock.Type.Value == Voxel.t.WhitePermanent || sceneryBlock.Type.Value == Voxel.t.White)) { Sound.AttachTracker(entity); AkSoundEngine.PostEvent(AK.EVENTS.PLAY_WHITE_LIGHT, entity); SoundKiller.Add(entity, AK.EVENTS.STOP_WHITE_LIGHT); physics.Add(new CommandBinding <Collidable, ContactCollection>(physics.Collided, delegate(Collidable other, ContactCollection contacts) { float impulse = contacts.Max(x => x.NormalImpulse); if (impulse > 0.2f) { AkSoundEngine.PostEvent(AK.EVENTS.PLAY_WHITE_LIGHT_HIT, entity); } })); } }
SceneryBlock AddNewBlock(Vector2 position) { // check if we have any unused blocks in the pool. if (blocksPool.Count == 0) { Debug.LogWarning("Not enough blocks in layer " + this.name); return(null); } // pick random new block from the pool int idx = Random.Range(0, blocksPool.Count); SceneryBlock block = blocksPool[idx]; // set its initial position position.x += block.width / 2; block.transform.position = position; // remove from block pool so we can't pick it again blocksPool.Remove(block); // add to visible pool visibleBlocks.Add(block); // make it visible block.transform.parent = activeBlocks.transform; numBlocksCreated++; return(block); }
void RemoveVisibleBlock(SceneryBlock block) { // make the block invisible again block.transform.parent = inactiveBlocks.transform; // remove block from visible list visibleBlocks.Remove(block); // add back into block pool blocksPool.Add(block); }
public override void Bind(Entity entity, Main main, bool creating = false) { Transform transform = entity.GetOrCreate <Transform>("Transform"); PhysicsBlock physics = entity.GetOrCreate <PhysicsBlock>("Physics"); ModelInstance model = entity.GetOrCreate <ModelInstance>("Model"); physics.Add(new TwoWayBinding <Matrix>(transform.Matrix, physics.Transform)); SceneryBlock sceneryBlock = entity.GetOrCreate <SceneryBlock>("SceneryBlock"); physics.Add(new Binding <Vector3, float>(physics.Size, x => new Vector3(x), sceneryBlock.Scale)); model.Add(new Binding <Matrix>(model.Transform, () => Matrix.CreateScale(sceneryBlock.Scale) * transform.Matrix, transform.Matrix, sceneryBlock.Scale)); this.SetMain(entity, main); entity.Add("IsAffectedByGravity", physics.IsAffectedByGravity); sceneryBlock.EditorProperties(); }
private void GenerateNewBlocks(float blockX) { // add in new blocks to make sure the screen is full while (blockCreationEnabled && blockX < ScreenRightEdge) { if (isInfinite || numBlocksCreated < maxBlockCount) { SceneryBlock block = AddNewBlock(new Vector2(blockX, 0.0f)); if (block == null) { break; } blockX += block.width; } else { // we've generated all the blocks for this layer, so now start on the next layer, starting // at the x-position we've reached. StartNextLayer(blockX); } } }
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.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.CoordDictionaryCache[c] = true; foreach (Direction adjacentDirection in DirectionExtensions.Directions) { Voxel.Coord adjacentCoord = c.Move(adjacentDirection); if (!Voxel.CoordDictionaryCache.ContainsKey(adjacentCoord)) { Voxel.t adjacentID = sockVoxel[adjacentCoord].ID; if (adjacentID == Voxel.t.Empty) { queue.Enqueue(adjacentCoord); } } } } Voxel.CoordDictionaryCache.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 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"); 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); } 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); } 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); }