예제 #1
0
 public Platform(RoomScene room, byte subType, FVector pos, Dictionary <string, short> paramList) : base(room, subType, pos, paramList)
 {
     // Physics + Collisions
     this.physics = new Physics(this);
     this.physics.SetGravity(FInt.Create(0));
     this.SetCollide(CollideEnum.NoTileCollide);
 }
예제 #2
0
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            // Get the SubType
            byte subType = room.tilemap.GetMainSubType(gridX, gridY);

            // Transparent Exclaim Blocks only Collide From Below
            if (subType == (byte)ExclaimBlockSubType.Transparent)
            {
                if (dir != DirCardinal.Up)
                {
                    return(false);
                }
            }

            // If hitting an active or transparent exclaim block from below:
            if (dir == DirCardinal.Up && subType != (byte)ExclaimBlockSubType.Inactive)
            {
                // Swap to an Inactive Block
                room.tilemap.SetTileSubType(gridX, gridY, (byte)ExclaimBlockSubType.Inactive);

                room.PlaySound(Systems.sounds.shellThud, 1f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
            }

            return(base.RunImpact(room, actor, gridX, gridY, dir));
        }
예제 #3
0
        private static void AddObjectToScene(RoomScene room, short gridX, short gridY, byte objectId, byte subType = 0, Dictionary <string, short> paramList = null)
        {
            // Adjust for World Gaps
            gridX += (byte)TilemapEnum.GapLeft;
            gridY += (byte)TilemapEnum.GapUp;

            // Prepare Position
            FVector pos = FVector.Create(
                Snap.GridToPos((short)TilemapEnum.TileWidth, gridX),
                Snap.GridToPos((short)TilemapEnum.TileHeight, gridY)
                );

            GameMapper mapper = Systems.mapper;

            // Identify Object Class Type
            Type classType;
            bool hasType = mapper.ObjectTypeDict.TryGetValue(objectId, out classType);

            if (!hasType || classType == null)
            {
                return;
            }

            // Create Object
            GameObject gameObj = (GameObject)Activator.CreateInstance(classType, new object[] { room, (byte)subType, (FVector)pos, (Dictionary <string, short>)paramList });

            // Add the Object to the Scene
            if (gameObj is GameObject)
            {
                room.AddToScene((GameObject)gameObj, true);
            }
        }
예제 #4
0
 protected override void TouchFlag(RoomScene room, Character character, short gridX, short gridY)
 {
     if (Systems.handler.levelState.SetRetry(room.roomID, gridX, gridY))
     {
         room.PlaySound(Systems.sounds.flag, 1f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
     }
 }
예제 #5
0
        public override void Draw(RoomScene room, byte subType, int posX, int posY)
        {
            // Drawing For Editor
            if (room == null)
            {
                this.atlas.Draw(this.Texture[subType], posX, posY);
                return;
            }

            byte num = 1;

            switch (subType)
            {
            case (byte)ConveyorSubType.SlowRight: num = (byte)(4 - AnimGlobal.Get3PHSAnimId(Systems.timer)); break;

            case (byte)ConveyorSubType.SlowLeft: num = AnimGlobal.Get3PHSAnimId(Systems.timer); break;

            case (byte)ConveyorSubType.Right: num = (byte)(4 - AnimGlobal.Get3PQSAnimId(Systems.timer)); break;

            case (byte)ConveyorSubType.Left: num = AnimGlobal.Get3PQSAnimId(Systems.timer); break;
            }

            // Draw the Track using the Global Animation AnimId
            string tex = this.TrackStr + num.ToString();

            this.atlas.Draw(tex, posX, posY);
        }
예제 #6
0
        public static ShurikenProjectile Create(RoomScene room, byte subType, FVector pos, FVector velocity)
        {
            // Retrieve an available projectile from the pool.
            ShurikenProjectile projectile = ProjectilePool.ShurikenProjectile.GetObject();

            projectile.ResetProjectile(room, subType, pos, velocity);

            // Assign Projectile Appearance
            switch (subType)
            {
            case (byte)ShurikenSubType.Green: projectile.SetSpriteName("Weapon/ShurikenGreen"); break;

            case (byte)ShurikenSubType.Red: projectile.SetSpriteName("Weapon/ShurikenRed"); break;

            case (byte)ShurikenSubType.Blue: projectile.SetSpriteName("Weapon/ShurikenBlue"); break;

            case (byte)ShurikenSubType.Yellow: projectile.SetSpriteName("Weapon/ShurikenYellow"); break;
            }

            projectile.AssignBoundsByAtlas(2, 2, -2, -2);

            // Assign the beginning of the shuriken attack:
            projectile.physics.SetGravity(FInt.Create(0));             // Switches to 0.4 after MotionStart finished.
            projectile.SetState((byte)CommonState.MotionStart);
            projectile.gravFrame = Systems.timer.Frame + 10;
            projectile.spinRate  = projectile.physics.velocity.X > 0 ? 0.14f : -0.14f;

            // Add the Projectile to Scene
            room.AddToScene(projectile, false);

            return(projectile);
        }
예제 #7
0
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            if (!ToggleBlock.TogCollides(room, this.toggleBR, this.isOn))
            {
                return(false);
            }

            // Actor must cross the UP threshold for this ledge; otherwise, it shouldn't compute any collision.
            if (!actor.physics.CrossedThresholdUp(gridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.TileHeight))
            {
                return(false);
            }

            if (actor is Projectile)
            {
                if (!CollideTileFacing.RunImpactTest(dir, DirCardinal.Down))
                {
                    return(false);
                }
                return(TileProjectileImpact.RunImpact((Projectile)actor, gridX, gridY, dir));
            }

            // Allow Dropdown Mechanic
            if (actor is Character)
            {
                Character character = (Character)actor;
                character.physics.touch.onMover = true;
                if (character.status.action is DropdownAction)
                {
                    return(false);
                }
            }

            return(CollideTileFacing.RunImpact(actor, gridX, gridY, dir, DirCardinal.Down));
        }
예제 #8
0
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            if (this.isToggleBox || ToggleBlock.TogCollides(room, this.toggleBR, this.isOn))
            {
                if (actor is Projectile)
                {
                    if (actor is ShurikenProjectile && this.isToggleBox)
                    {
                        room.colors.ToggleColor(this.toggleBR);
                    }
                    return(TileProjectileImpact.RunImpact((Projectile)actor, gridX, gridY, dir));
                }

                TileSolidImpact.RunImpact(actor, gridX, gridY, dir);

                // If a ToggleBox was hit from below:
                if (this.isToggleBox && dir == DirCardinal.Up)
                {
                    room.colors.ToggleColor(this.toggleBR);
                }

                // Additional Character Collisions (such as Wall Jumps)
                if (actor is Character)
                {
                    TileCharBasicImpact.RunWallImpact((Character)actor, dir);
                }

                return(true);
            }

            return(false);
        }
예제 #9
0
        public void SetupTile(RoomScene room, short gridX, short gridY)
        {
            // Identify the subtype and params for this tile.
            Dictionary <string, short> paramList = room.tilemap.GetParamList(gridX, gridY);

            this.AddNextAttackCycle(room, paramList, gridX, gridY);
        }
예제 #10
0
파일: Box.cs 프로젝트: tarsupin/Nexus
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            if (actor is Projectile)
            {
                if (actor is GloveProjectile)
                {
                    this.DestroyBox(room, gridX, gridY);
                    return(false);
                }
                return(TileProjectileImpact.RunImpact((Projectile)actor, gridX, gridY, dir));
            }

            // Slam-Down Action can break boxes.
            if (actor is Character && ((Character)actor).status.action is SlamAction)
            {
                this.DestroyBox(room, gridX, gridY);
                return(true);
            }

            // Destroy Box
            if (dir == DirCardinal.Up)
            {
                BlockTile.DamageAbove(room, gridX, gridY);
                this.DestroyBox(room, gridX, gridY);
            }

            return(base.RunImpact(room, actor, gridX, gridY, dir));
        }
예제 #11
0
파일: Placer.cs 프로젝트: tarsupin/Nexus
        public bool SetupTile(RoomScene room, short gridX, short gridY)
        {
            //// Track the activations for this cannon.
            //Dictionary<string, short> paramList = room.tilemap.GetParamList(gridX, gridY);

            //// Reject this Cycle if the cannon isn't triggered on at least one beat (considers first beat required)
            //short beat1 = (short)((paramList.ContainsKey("beat1") ? (byte)paramList["beat1"] : 0) - 1);
            //if(beat1 == -1) { return false; }

            //short beat2 = (short)((paramList.ContainsKey("beat2") ? (byte)paramList["beat2"] : 0) - 1);
            //short beat3 = (short)((paramList.ContainsKey("beat3") ? (byte)paramList["beat3"] : 0) - 1);
            //short beat4 = (short)((paramList.ContainsKey("beat4") ? (byte)paramList["beat4"] : 0) - 1);

            //bool[] addToBeat = new bool[4] { false, false, false, false };

            //// Since Cannon Beats check against tempo 8 or 16, we have to run a modulus 4 check to accomodate the QueueEvent.beatEvents.
            //if(beat1 > -1) { addToBeat[beat1 % 4] = true; }
            //if(beat2 > -1) { addToBeat[beat2 % 4] = true; }
            //if(beat3 > -1) { addToBeat[beat3 % 4] = true; }
            //if(beat4 > -1) { addToBeat[beat4 % 4] = true; }

            //// Add All Relevant Beat Events
            //if(addToBeat[0]) { room.queueEvents.AddBeatEvent(this.tileId, (short)gridX, (short)gridY, 0); }
            //if(addToBeat[1]) { room.queueEvents.AddBeatEvent(this.tileId, (short)gridX, (short)gridY, 1); }
            //if(addToBeat[2]) { room.queueEvents.AddBeatEvent(this.tileId, (short)gridX, (short)gridY, 2); }
            //if(addToBeat[3]) { room.queueEvents.AddBeatEvent(this.tileId, (short)gridX, (short)gridY, 3); }

            return(true);
        }
예제 #12
0
        public override bool RunSpecialDetection(RoomScene room, Character actor, short gridX, short gridY, DirCardinal dir)
        {
            // Check to see if the actor has already received a checkpoint at this X value. If so, end the function.
            if (Systems.handler.levelState.checkpoint.active && Systems.handler.levelState.checkpoint.gridX == gridX)
            {
                return(false);
            }

            // Otherwise, attempt to locate the checkpoint at this X value:
            short gridYScan = (short)(gridY + 1);

            byte[] tile = room.tilemap.GetTileDataAtGrid(gridX, gridYScan);

            // If the location below is another DetectorCheckpointPass (this tile type), then continue the trend:
            if (tile[0] == this.tileId)
            {
                DetectorCheckpointPass det = (DetectorCheckpointPass)Systems.mapper.TileDict[(byte)TileEnum.DetectCheckpointPass];
                return(det.RunSpecialDetection(room, actor, gridX, gridYScan, dir));
            }

            // If we found the Check Pass Flag from the next scan test, return the impact.
            if (tile[0] == (byte)TileEnum.CheckFlagPass)
            {
                return(Systems.mapper.TileDict[(byte)TileEnum.CheckFlagPass].RunImpact(actor.room, actor, gridX, gridYScan, dir));
            }

            // Check if the checkpoint is above:
            return(Systems.mapper.TileDict[(byte)TileEnum.CheckFlagPass].RunImpact(actor.room, actor, gridX, (short)(gridY - 1), dir));
        }
예제 #13
0
 public TestTileCollisions()
 {
     this.levelScene = (LevelScene)Systems.scene;
     this.roomScene  = (RoomScene)this.levelScene.rooms[0];
     this.character  = Systems.localServer.MyCharacter;
     this.tilemap    = this.roomScene.tilemap;
 }
예제 #14
0
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            if (!base.RunImpact(room, actor, gridX, gridY, dir))
            {
                return(false);
            }

            // Get the SubType
            byte subType = room.tilemap.GetMainSubType(gridX, gridY);

            if (subType == (byte)SpringFixedSubType.Up && dir == DirCardinal.Down)
            {
                if (actor is Character)
                {
                    ActionMap.Jump.StartAction((Character)actor, 10, 0, 6, true, false);
                    room.PlaySound(Systems.sounds.spring, 0.4f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
                }
                else
                {
                    actor.BounceUp(gridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.HalfWidth, 8, 0, 5);
                    room.PlaySound(Systems.sounds.spring, 0.4f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
                }
            }

            else if (subType == (byte)SpringFixedSubType.Rev && dir == DirCardinal.Up)
            {
                actor.BounceUp(gridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.HalfWidth, -9, 0, 5);
                room.PlaySound(Systems.sounds.spring, 0.4f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
            }

            return(true);
        }
예제 #15
0
        public int frozenFrame = 0;             // The frame that the character is frozen until (after resets, etc).

        public Character(RoomScene room, byte subType, FVector pos, Dictionary <string, short> paramList) : base(room, subType, pos, paramList)
        {
            this.Meta = Systems.mapper.ObjectMetaData[(byte)ObjectEnum.Character].meta;

            this.SetSpriteName("Stand");

            // Physics, Collisions, etc.
            this.AssignBounds(8, 12, 28, 44);
            this.physics = new Physics(this);
            this.physics.SetGravity(FInt.Create(0.7));

            // Default Stats & Statuses
            this.stats  = new CharacterStats(this);
            this.status = new CharacterStatus();
            this.wounds = new CharacterWounds(this);

            // Attachments
            this.trailKeys  = new TrailingKeys(this);
            this.heldItem   = new HeldItem(this);
            this.magiShield = new MagiShield(this);
            this.nameplate  = new Nameplate(this, "Lana", false, false);

            // Images and Animations
            this.animate = new Animate(this, "/");

            // Reset Character, Set Default Values
            this.ResetCharacter();

            // Assign SubTypes and Params
            this.AssignSubType(subType);
            this.AssignParams(paramList);
        }
예제 #16
0
        public override bool InteractWithDoor(Character character, RoomScene room, short gridX, short gridY)
        {
            // The door is locked. Must have a key, or prevent entry.
            if (!character.trailKeys.HasKey)
            {
                room.PlaySound(Systems.sounds.click3, 1f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
                return(false);
            }

            // Check if the door is locked.
            byte subType = room.tilemap.GetMainSubType(gridX, gridY);

            // Find Destination Door. If none exist, then no reason to unlock it.
            (RoomScene destRoom, short gridX, short gridY)doorLink = Door.GetLinkingDoor(room, subType, gridX, gridY);

            if (doorLink.gridX == 0 && doorLink.gridY == 0)
            {
                room.PlaySound(Systems.sounds.collectDisable, 0.4f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
                return(false);
            }

            // Unlock Door
            Door.UnlockDoor(character, room, subType, gridX, gridY, true);

            return(true);
        }
예제 #17
0
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            if (!ToggleBlock.TogCollides(room, this.toggleBR, this.isOn))
            {
                return(false);
            }

            // Actor must cross the DOWN threshold for this ledge; otherwise, it shouldn't compute any collision.
            if (!actor.physics.CrossedThresholdDown(gridY * (byte)TilemapEnum.TileHeight))
            {
                return(false);
            }

            if (actor is Projectile)
            {
                if (!CollideTileFacing.RunImpactTest(dir, DirCardinal.Up))
                {
                    return(false);
                }
                return(TileProjectileImpact.RunImpact((Projectile)actor, gridX, gridY, dir));
            }

            bool collided = CollideTileFacing.RunImpact(actor, gridX, gridY, dir, DirCardinal.Up);

            // Additional Character Collisions (such as Wall Jumps)
            if (collided && actor is Character)
            {
                TileCharBasicImpact.RunWallImpact((Character)actor, dir);
            }

            return(collided);
        }
예제 #18
0
파일: Leaf.cs 프로젝트: tarsupin/Nexus
        // Trigger Event: BeginShake, Break Apart, Reform
        public override bool TriggerEvent(RoomScene room, short gridX, short gridY, short triggerType = 0, short val2 = 0)
        {
            // Break Apart Event
            if (triggerType == (byte)LeafTriggerEvent.BreakApart)
            {
                byte subType = room.tilemap.GetMainSubType(gridX, gridY);

                // Display Leaf Breaking
                ExplodeEmitter.BoxExplosion(room, "Particles/Leaf", gridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.HalfWidth, gridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.HalfHeight);

                // Reforming Leafs will be reformed.
                if (subType == (byte)LeafSubType.InvisibleReform || subType == (byte)LeafSubType.Reform || subType == (byte)LeafSubType.UntouchableReform)
                {
                    room.tilemap.SetTileSubType(gridX, gridY, (byte)LeafSubType.UntouchableReform);
                    room.queueEvents.AddEvent(Systems.timer.Frame + 60, this.tileId, gridX, gridY, (byte)LeafTriggerEvent.Reform);
                }

                // Basic Leaf gets destroyed.
                else
                {
                    room.tilemap.SetMainTile(gridX, gridY, 0, 0);
                }

                room.PlaySound(Systems.sounds.thudTap, 1f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
            }

            // Reform Event
            else if (triggerType == (byte)LeafTriggerEvent.Reform)
            {
                room.tilemap.SetTileSubType(gridX, gridY, (byte)LeafSubType.Reform);
            }

            return(true);
        }
예제 #19
0
파일: Cannon.cs 프로젝트: tarsupin/Nexus
        // Only return false if (and/or when) the event should no longer be looped in the QueueEvent class. For Cannons, this shouldn't occur.
        public override bool TriggerEvent(RoomScene room, short gridX, short gridY, short val1 = 0, short val2 = 0)
        {
            // Track the activations for this cannon.
            byte subType = room.tilemap.GetMainSubType(gridX, gridY);
            Dictionary <string, short> paramList = room.tilemap.GetParamList(gridX, gridY);

            // Reject this Cycle if the cannon isn't triggered on this beat.
            short beat1 = (short)((paramList.ContainsKey("beat1") ? (byte)paramList["beat1"] : 0) - 1);
            short beat2 = (short)((paramList.ContainsKey("beat2") ? (byte)paramList["beat2"] : 0) - 1);
            short beat3 = (short)((paramList.ContainsKey("beat3") ? (byte)paramList["beat3"] : 0) - 1);
            short beat4 = (short)((paramList.ContainsKey("beat4") ? (byte)paramList["beat4"] : 0) - 1);

            // Make sure this beat is one of the targets assigned.
            byte beatMod16 = Systems.timer.beat16Modulus;

            if (beat1 != beatMod16 && beat2 != beatMod16 && beat3 != beatMod16 && beat4 != beatMod16)
            {
                return(true);
            }

            byte cannonSpeed = paramList.ContainsKey("speed") ? (byte)paramList["speed"] : ParamsBeats.DefaultSpeed;

            // Run Cannon Activation
            this.ActivateCannon(room, subType, gridX, gridY, cannonSpeed);

            return(true);
        }
예제 #20
0
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            // Get the Direction of an Inner Boundary
            DirCardinal newDir = TileSolidImpact.RunInnerImpact(actor, gridX * (byte)TilemapEnum.TileWidth, gridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight, gridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.HalfHeight);

            if (newDir == DirCardinal.None)
            {
                return(false);
            }

            if (newDir == DirCardinal.Down)
            {
                // Get the SubType
                byte subType = room.tilemap.GetMainSubType(gridX, gridY);

                if (subType <= (byte)ConveyorSubType.Left)
                {
                    actor.physics.SetExtraMovement(subType == (byte)ConveyorSubType.SlowLeft ? -2 : -4, 0);
                }
                else
                {
                    actor.physics.SetExtraMovement(subType == (byte)ConveyorSubType.SlowRight ? 2 : 4, 0);
                }
            }

            if (actor is Character)
            {
                return(TileCharBasicImpact.RunWallImpact((Character)actor, dir));
            }

            return(true);
        }
예제 #21
0
        public override void SetupTile(RoomScene room, short gridX, short gridY)
        {
            base.SetupTile(room, gridX, gridY);

            // Place a Detector beneath the flag:
            room.tilemap.SetMainTile(gridX, (short)(gridY + 1), (byte)TileEnum.DetectRetry, 0);
        }
예제 #22
0
        private static void GenerateObjectLayer(RoomScene room, Dictionary <string, Dictionary <string, ArrayList> > layer)
        {
            // Loop through YData within the Layer Provided:
            foreach (KeyValuePair <string, Dictionary <string, ArrayList> > yData in layer)
            {
                short gridY = short.Parse(yData.Key);

                // Loop through XData
                foreach (KeyValuePair <string, ArrayList> xData in yData.Value)
                {
                    short gridX = short.Parse(xData.Key);

                    if (xData.Value.Count == 2)
                    {
                        RoomGenerate.AddObjectToScene(room, gridX, gridY, Convert.ToByte(xData.Value[0]), Convert.ToByte(xData.Value[1]));
                    }
                    else if (xData.Value.Count > 2)
                    {
                        // ERRORS HERE MEAN: The json data saved a string instead of a short; e.g. {"Suit", "WhiteNinja"} instead of {"Suit", 2}
                        // To fix it, we need to run LevelConvert updates that make the appropriate changes.
                        Dictionary <string, short> paramList = JsonConvert.DeserializeObject <Dictionary <string, short> >(xData.Value[2].ToString());
                        RoomGenerate.AddObjectToScene(room, gridX, gridY, Convert.ToByte(xData.Value[0]), Convert.ToByte(xData.Value[1]), paramList);
                    }
                }
            }
        }
예제 #23
0
        public override void Collect(RoomScene room, Character character, short gridX, short gridY)
        {
            byte subType = room.tilemap.GetMainSubType(gridX, gridY);
            byte border  = subType == (byte)CoinsSubType.Coin ? (byte)10 : (byte)2;

            // Get the Direction of an Inner Boundary
            DirCardinal newDir = TileSolidImpact.RunOverlapTest(character, gridX * (byte)TilemapEnum.TileWidth + border, gridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.TileWidth - border, gridY * (byte)TilemapEnum.TileHeight + border, gridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.TileHeight - border);

            if (newDir == DirCardinal.None)
            {
                return;
            }

            // Collect Coins
            room.PlaySound(Systems.sounds.coin, 0.6f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);

            if (subType == (byte)CoinsSubType.Coin)
            {
                Systems.handler.levelState.AddCoins(character, 1);
            }
            else if (subType == (byte)CoinsSubType.Gem)
            {
                Systems.handler.levelState.AddCoins(character, 10);
            }

            base.Collect(room, character, gridX, gridY);
        }
예제 #24
0
파일: Shell.cs 프로젝트: tarsupin/Nexus
        public Shell(RoomScene room, byte subType, FVector pos, Dictionary <string, short> paramList) : base(room, subType, pos, paramList)
        {
            this.Meta          = Systems.mapper.ObjectMetaData[(byte)ObjectEnum.Shell].meta;
            this.ThrowStrength = 14;
            this.KickStrength  = 7;

            // Grip Points (When Held)
            this.gripLeft  = -31;
            this.gripRight = 21;
            this.gripLift  = -8;

            // Physics
            this.physics.SetGravity(FInt.Create(0.4));

            this.AssignSubType(subType);
            this.AssignBoundsByAtlas(10, 2, -2, 0);

            // Handle Params
            if (paramList != null && paramList.ContainsKey("x"))
            {
                this.physics.velocity.X = FInt.Create(paramList["x"]);
            }
            if (paramList != null && paramList.ContainsKey("y"))
            {
                this.physics.velocity.Y = FInt.Create(paramList["y"]);
            }
        }
예제 #25
0
        public static bool UnlockDoor(Character character, RoomScene room, byte subTypeId, short gridX, short gridY, bool requiresKey = true)
        {
            // The door is locked. Must have a key, or prevent entry.
            if (requiresKey && !character.trailKeys.HasKey)
            {
                return(false);
            }

            // Check if the tile is locked:
            byte[] tileData = room.tilemap.GetTileDataAtGrid(gridX, gridY);
            if (tileData[0] != (byte)TileEnum.DoorLock)
            {
                return(false);
            }

            // Remove the Key, Unlock the Door.
            if (requiresKey)
            {
                character.trailKeys.RemoveKey();
            }
            room.PlaySound(Systems.sounds.unlock, 1f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);

            // Change Door to Unlocked
            room.tilemap.SetMainTile(gridX, gridY, (byte)TileEnum.Door, subTypeId);

            return(true);
        }
예제 #26
0
        public virtual bool InteractWithDoor(Character character, RoomScene room, short gridX, short gridY)
        {
            // Identify the destination door.
            byte subType = room.tilemap.GetMainSubType(gridX, gridY);

            (RoomScene destRoom, short gridX, short gridY)arrivalExit = Door.GetLinkingDoor(room, subType, gridX, gridY);

            // Make sure the matching door is valid.
            if (arrivalExit.gridX == 0 && arrivalExit.gridY == 0)
            {
                // No matching door exists. Can announce error.
                room.PlaySound(Systems.sounds.collectDisable, 0.4f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
                return(false);
            }

            // Open Door
            room.PlaySound(Systems.sounds.door, 1f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);

            // Transport Character to Destination Door
            ActionMap.Transport.StartAction(character, arrivalExit.destRoom.roomID, arrivalExit.gridX * (byte)TilemapEnum.TileWidth + 6, arrivalExit.gridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.TileHeight * 2 - character.bounds.Bottom);

            // Unlock the arrival door (if applicable), since you came from within.
            Door.UnlockDoor(character, arrivalExit.destRoom, subType, arrivalExit.gridX, arrivalExit.gridY, false);

            return(true);
        }
예제 #27
0
        public override bool RunImpact(RoomScene room, GameObject actor, short gridX, short gridY, DirCardinal dir)
        {
            // Only Characters interact with doors.
            if (actor is Character == false)
            {
                return(false);
            }

            Character character = (Character)actor;

            // Display "Interaction" Prompt for Character (draws the 'interaction' hand icon above character head)
            //if(Systems.timer.frame16Modulus % 8 == 5) {
            //	StationaryParticle.SetParticle(character.room, Systems.mapper.atlas[(byte)AtlasGroup.Tiles], "Prompt/Hand", new Vector2(gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight - (byte)TilemapEnum.HalfHeight), Systems.timer.Frame + 8);
            //}

            // Make sure the character is overlapping the inner door.
            if (!CollideRect.IsTouchingRect(character, gridX * (byte)TilemapEnum.TileWidth + 16, gridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.TileWidth - 12, gridY * (byte)TilemapEnum.TileHeight, gridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.TileHeight * 2))
            {
                return(false);
            }

            // Make sure the Character is actually attempting to interact with the door.
            if (!character.input.isPressed(IKey.YButton))
            {
                return(false);
            }

            return(this.InteractWithDoor(character, room, gridX, gridY));
        }
예제 #28
0
        public static (short gridX, short gridY) FindExitType(RoomScene destRoom, byte fromRoomId, byte toTileId, byte altTileId, byte toSubTypeId, short fromGridX, short fromGridY)
        {
            var exits = destRoom.roomExits.exits;

            (short gridX, short gridY)result = (0, 0);

            foreach (var exit in exits)
            {
                // Check if the grid has the same tileId and subType.
                if (exit.subTypeId != toSubTypeId || (exit.tileId != toTileId && exit.tileId != altTileId))
                {
                    continue;
                }

                // Skip the origin door. We only want to find any matching doors.
                if (exit.gridX == fromGridX && exit.gridY == fromGridY && destRoom.roomID == fromRoomId)
                {
                    continue;
                }

                if (exit.gridY > result.gridY)
                {
                    result = (exit.gridX, exit.gridY);
                }
                else if (exit.gridY == result.gridY && exit.gridX > result.gridX)
                {
                    result = (exit.gridX, exit.gridY);
                }
            }

            return(result);
        }
예제 #29
0
 public ElementalEarth(RoomScene room, byte subType, FVector pos, Dictionary <string, short> paramList) : base(room, subType, pos, paramList)
 {
     this.Meta     = Systems.mapper.ObjectMetaData[(byte)ObjectEnum.ElementalEarth].meta;
     this.attack   = new AttackSequence(paramList);
     this.attSpeed = (sbyte)Math.Round((paramList != null && paramList.ContainsKey("speed") ? paramList["speed"] : 100) * 0.01 * BaseAttackSpeed);
     this.AssignSubType(subType);
     this.AssignBoundsByAtlas(2, 4, -4, -12);
 }
예제 #30
0
 protected override void TouchFlag(RoomScene room, Character character, short gridX, short gridY)
 {
     if (Systems.handler.levelState.SetCheckpoint(room.roomID, gridX, gridY))
     {
         room.PlaySound(Systems.sounds.flag, 1f, gridX * (byte)TilemapEnum.TileWidth, gridY * (byte)TilemapEnum.TileHeight);
         this.ReceiveFlagUpgrades(room, character, gridX, gridY);
     }
 }