diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..11d6ad4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode/ +*.tiled-session \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 9d9cd18..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "Kristal"] - path = Kristal - url = https://github.com/KristalTeam/Kristal diff --git a/Kristal b/Kristal deleted file mode 160000 index 4f6de32..0000000 --- a/Kristal +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4f6de329a7336d85c732aaef704533dc37544c98 diff --git a/assets/sounds/squeak.wav b/assets/sounds/squeak.wav new file mode 100644 index 0000000..2d6c494 Binary files /dev/null and b/assets/sounds/squeak.wav differ diff --git a/assets/sprites/bullets/arenahazard.png b/assets/sprites/bullets/arenahazard.png new file mode 100644 index 0000000..b2dca05 Binary files /dev/null and b/assets/sprites/bullets/arenahazard.png differ diff --git a/assets/sprites/bullets/smallbullet.png b/assets/sprites/bullets/smallbullet.png new file mode 100644 index 0000000..2eff0db Binary files /dev/null and b/assets/sprites/bullets/smallbullet.png differ diff --git a/assets/sprites/enemies/dummy/idle.png b/assets/sprites/enemies/dummy/idle.png new file mode 100644 index 0000000..280f9dd Binary files /dev/null and b/assets/sprites/enemies/dummy/idle.png differ diff --git a/assets/sprites/npcs/starwalker.png b/assets/sprites/npcs/starwalker.png new file mode 100644 index 0000000..ee74969 Binary files /dev/null and b/assets/sprites/npcs/starwalker.png differ diff --git a/assets/sprites/npcs/wall_1.png b/assets/sprites/npcs/wall_1.png new file mode 100644 index 0000000..174a9fb Binary files /dev/null and b/assets/sprites/npcs/wall_1.png differ diff --git a/assets/sprites/npcs/wall_2.png b/assets/sprites/npcs/wall_2.png new file mode 100644 index 0000000..2877f59 Binary files /dev/null and b/assets/sprites/npcs/wall_2.png differ diff --git a/assets/sprites/tilesets/castle.png b/assets/sprites/tilesets/castle.png new file mode 100644 index 0000000..e1f9d81 Binary files /dev/null and b/assets/sprites/tilesets/castle.png differ diff --git a/halloween_hack.tiled-project b/halloween_hack.tiled-project new file mode 100644 index 0000000..7b0999c --- /dev/null +++ b/halloween_hack.tiled-project @@ -0,0 +1,12 @@ +{ + "automappingRulesFile": "", + "commands": [ + ], + "extensionsPath": "extensions", + "folders": [ + "scripts/world" + ], + "objectTypesFile": "", + "propertyTypes": [ + ] +} diff --git a/mod.json b/mod.json new file mode 100644 index 0000000..61445f0 --- /dev/null +++ b/mod.json @@ -0,0 +1,70 @@ +{ + // The ID of your project. Should be unique!! + "id": "halloween_hack", + // Displays on the main menu. + "name": "Halloween_hack", + // Displays underneath the name. Optional. + "subtitle": "", + + // The version of your project. + "version": "v1.0.0", + // What version of the engine your project was made with. + "engineVer": "v0.10.0-dev", + + // The Deltarune chapter you'd like to base your project off of. + // Do keep in mind that you can control chapter-specific features + // one by one using the config below. + "chapter": 4, + + // The map that you start in when first starting the project. + "map": "room1", + + // The party. The first character is the player. + "party": ["kris", "susie", "ralsei"], + + // The inventory. Contains three darkburgers, a cell phone and a shadow crystal by default. + "inventory": { + "items": ["glowshard", "darkburger", "darkburger", "darkburger"], + "key_items": ["cell_phone", "shadowcrystal"] + }, + + // Equipment for your party. Not specifying equipment defaults to the following. + "equipment": { + "kris": { + "weapon": "wood_blade", + "armor": ["amber_card", "amber_card"] + }, + "susie": { + "weapon": "mane_ax", + "armor": ["amber_card", "amber_card"] + }, + "ralsei": { + "weapon": "red_scarf", + "armor": ["amber_card", "amber_card"] + } + }, + + // Should never be true, but just in case. Restarts the entire engine when leaving the project. + // If you need this, you're most likely doing something wrong. + "hardReset": false, + + // Whether the project is hidden from the project selection. + "hidden": false, + + // Whether the game window's title should be set to the project's name, and the icon to the image + // in the file `window_icon.png`. + // When your project is configured as the engine's target project, it's automatically done unless if + // this option is explicitly set to false; else, it's done if this is set to true. + "setWindowTitleAndIcon": null, + + // Config values for the engine and any libraries you may have. + // These config values can control chapter-specific features as well. + "config": { + "kristal": { + // End of config + } + }, + + // Whether or not to enable dev mode. Dev mode enables debug keys and the console. + "dev": true +} \ No newline at end of file diff --git a/mod.lua b/mod.lua new file mode 100644 index 0000000..cc2ed5d --- /dev/null +++ b/mod.lua @@ -0,0 +1,6 @@ +function Mod:init() + Game:registerEvent("squeak", function(data) + return Squeak(data.x, data.y, {data.width, data.height, data.polygon}) + end) + print("Loaded " .. self.info.name .. "!") +end diff --git a/scripts/battle/bullets/arenahazard.lua b/scripts/battle/bullets/arenahazard.lua new file mode 100644 index 0000000..a901f33 --- /dev/null +++ b/scripts/battle/bullets/arenahazard.lua @@ -0,0 +1,30 @@ +---@class ArenaHazard : Bullet +local ArenaHazard, super = Class(Bullet) + +---@param x number # The X position of the bullet +---@param y number # The Y position of the bullet +---@param rot number # The rotation (in radians) of the bullet +function ArenaHazard:init(x, y, rot) + -- Last argument = sprite path + super.init(self, x, y, "bullets/arenahazard") + + -- Top-center origin point (will be rotated around it) + self:setOrigin(0.5, 0) + + -- The hitbox where the player will be damaged by the bullet (affected by scale and rotation) + self:setHitbox(0, 0, self.width, 8) + + -- Rotation of the bullet (in radians) + self.rotation = rot + + -- Don't destroy this bullet when it damages the player + self.destroy_on_hit = false +end + +function ArenaHazard:update() + -- For more complicated bullet behaviours, code here gets called every update + + super.update(self) +end + +return ArenaHazard diff --git a/scripts/battle/bullets/smallbullet.lua b/scripts/battle/bullets/smallbullet.lua new file mode 100644 index 0000000..4eb9582 --- /dev/null +++ b/scripts/battle/bullets/smallbullet.lua @@ -0,0 +1,24 @@ +---@class SmallBullet : Bullet +local SmallBullet, super = Class(Bullet) + +---@param x number # The X position of the bullet +---@param y number # The Y position of the bullet +---@param dir number # The dir (in radians) of the bullet +---@param speed number # The speed the bullet will move at in the specified direction +function SmallBullet:init(x, y, dir, speed) + -- Last argument = sprite path + super.init(self, x, y, "bullets/smallbullet") + + -- Move the bullet in dir radians (0 = right, pi = left, clockwise rotation) + self.physics.direction = dir + -- Speed the bullet moves (pixels per frame at 30FPS) + self.physics.speed = speed +end + +function SmallBullet:update() + -- For more complicated bullet behaviours, code here gets called every update + + super.update(self) +end + +return SmallBullet diff --git a/scripts/battle/cutscenes/dummy.lua b/scripts/battle/cutscenes/dummy.lua new file mode 100644 index 0000000..353c28d --- /dev/null +++ b/scripts/battle/cutscenes/dummy.lua @@ -0,0 +1,24 @@ +return { + -- The inclusion of the below line tells the language server that the first parameter of the cutscene is `BattleCutscene`. + -- This allows it to fetch us useful documentation that shows all of the available cutscene functions while writing our cutscenes! + + ---@param cutscene BattleCutscene + susie_punch = function(cutscene, battler, enemy) + -- Open textbox and wait for completion + cutscene:text("* Susie threw a punch at\nthe dummy.") + + -- Hurt the target enemy for 1 damage + Assets.playSound("damage") + enemy:hurt(1, battler) + -- Wait 1 second + cutscene:wait(1) + + -- Susie text + cutscene:text("* You,[wait:5] uh,[wait:5] look like a weenie.[wait:5]\n* I don't like beating up\npeople like that.", "nervous_side", "susie") + + if cutscene:getCharacter("ralsei") then + -- Ralsei text, if he's in the party + cutscene:text("* Aww,[wait:5] Susie!", "blush_pleased", "ralsei") + end + end +} \ No newline at end of file diff --git a/scripts/battle/encounters/dummy.lua b/scripts/battle/encounters/dummy.lua new file mode 100644 index 0000000..9ba7cae --- /dev/null +++ b/scripts/battle/encounters/dummy.lua @@ -0,0 +1,21 @@ +local Dummy, super = Class(Encounter) + +function Dummy:init() + super.init(self) + + -- Text displayed at the bottom of the screen at the start of the encounter + self.text = "* The tutorial begins...?" + + -- Battle music ("battle" is rude buster) + self.music = "battle" + -- Enables the purple grid battle background + self.background = true + + -- Add the dummy enemy to the encounter + self:addEnemy("dummy") + + --- Uncomment this line to add another! + --self:addEnemy("dummy") +end + +return Dummy diff --git a/scripts/battle/enemies/dummy.lua b/scripts/battle/enemies/dummy.lua new file mode 100644 index 0000000..f3d5fbc --- /dev/null +++ b/scripts/battle/enemies/dummy.lua @@ -0,0 +1,96 @@ +local Dummy, super = Class(EnemyBattler) + +function Dummy:init() + super.init(self) + + -- Enemy name + self.name = "Dummy" + -- Sets the actor, which handles the enemy's sprites (see scripts/data/actors/dummy.lua) + self:setActor("dummy") + + -- Enemy health + self.max_health = 450 + self.health = 450 + -- Enemy attack (determines bullet damage) + self.attack = 4 + -- Enemy defense (usually 0) + self.defense = 0 + -- Enemy reward + self.money = 100 + + -- Mercy given when sparing this enemy before its spareable (20% for basic enemies) + self.spare_points = 20 + + -- List of possible wave ids, randomly picked each turn + self.waves = { + "basic", + "aiming", + "movingarena" + } + + -- Dialogue randomly displayed in the enemy's speech bubble + self.dialogue = { + "..." + } + + -- Check text (automatically has "ENEMY NAME - " at the start) + self.check = "AT 4 DF 0\n* Cotton heart and button eye\n* Looks just like a fluffy guy." + + -- Text randomly displayed at the bottom of the screen each turn + self.text = { + "* The dummy gives you a soft\nsmile.", + "* The power of fluffy boys is\nin the air.", + "* Smells like cardboard.", + } + -- Text displayed at the bottom of the screen when the enemy has low health + self.low_health_text = "* The dummy looks like it's\nabout to fall over." + + -- Register act called "Smile" + self:registerAct("Smile") + -- Register party act with Ralsei called "Tell Story" + -- (second argument is description, usually empty) + self:registerAct("Tell Story", "", {"ralsei"}) +end + +function Dummy:onAct(battler, name) + if name == "Smile" then + -- Give the enemy 100% mercy + self:addMercy(100) + -- Change this enemy's dialogue for 1 turn + self.dialogue_override = "... ^^" + -- Act text (since it's a list, multiple textboxes) + return { + "* You smile.[wait:5]\n* The dummy smiles back.", + "* It seems the dummy just wanted\nto see you happy." + } + + elseif name == "Tell Story" then + -- Loop through all enemies + for _, enemy in ipairs(Game.battle.enemies) do + -- Make the enemy tired + enemy:setTired(true) + end + return "* You and Ralsei told the dummy\na bedtime story.\n* The enemies became [color:blue]TIRED[color:reset]..." + + elseif name == "Standard" then --X-Action + -- Give the enemy 50% mercy + self:addMercy(50) + if battler.chara.id == "ralsei" then + -- R-Action text + return "* Ralsei bowed politely.\n* The dummy spiritually bowed\nin return." + elseif battler.chara.id == "susie" then + -- S-Action: start a cutscene (see scripts/battle/cutscenes/dummy.lua) + Game.battle:startActCutscene("dummy", "susie_punch") + return + else + -- Text for any other character (like Noelle) + return "* "..battler.chara:getName().." straightened the\ndummy's hat." + end + end + + -- If the act is none of the above, run the base onAct function + -- (this handles the Check act) + return super.onAct(self, battler, name) +end + +return Dummy \ No newline at end of file diff --git a/scripts/battle/waves/aiming.lua b/scripts/battle/waves/aiming.lua new file mode 100644 index 0000000..df83723 --- /dev/null +++ b/scripts/battle/waves/aiming.lua @@ -0,0 +1,30 @@ +local Aiming, super = Class(Wave) + +function Aiming:onStart() + -- Every 0.5 seconds... + self.timer:every(1 / 2, function() + -- Get all enemies that selected this wave as their attack + local attackers = self:getAttackers() + + -- Loop through all attackers + for _, attacker in ipairs(attackers) do + + -- Get the attacker's center position + local x, y = attacker:getRelativePos(attacker.width / 2, attacker.height / 2) + + -- Get the angle between the bullet position and the soul's position + local angle = MathUtils.angle(x, y, Game.battle.soul.x, Game.battle.soul.y) + + -- Spawn smallbullet angled towards the player with speed 8 (see scripts/battle/bullets/smallbullet.lua) + self:spawnBullet("smallbullet", x, y, angle, 8) + end + end) +end + +function Aiming:update() + -- Code here gets called every frame + + super.update(self) +end + +return Aiming diff --git a/scripts/battle/waves/basic.lua b/scripts/battle/waves/basic.lua new file mode 100644 index 0000000..02db057 --- /dev/null +++ b/scripts/battle/waves/basic.lua @@ -0,0 +1,25 @@ +local Basic, super = Class(Wave) + +function Basic:onStart() + -- Every 0.33 seconds... + self.timer:every(1 / 3, function() + -- Our X position is offscreen, to the right + local x = SCREEN_WIDTH + 20 + -- Get a random Y position between the top and the bottom of the arena + local y = MathUtils.random(Game.battle.arena.top, Game.battle.arena.bottom) + + -- Spawn smallbullet going left with speed 8 (see scripts/battle/bullets/smallbullet.lua) + local bullet = self:spawnBullet("smallbullet", x, y, math.rad(180), 8) + + -- Dont remove the bullet offscreen, because we spawn it offscreen + bullet.remove_offscreen = false + end) +end + +function Basic:update() + -- Code here gets called every frame + + super.update(self) +end + +return Basic diff --git a/scripts/battle/waves/movingarena.lua b/scripts/battle/waves/movingarena.lua new file mode 100644 index 0000000..18d4f8d --- /dev/null +++ b/scripts/battle/waves/movingarena.lua @@ -0,0 +1,38 @@ +local MovingArena, super = Class(Wave) + +function MovingArena:init() + super.init(self) + + -- Initialize timer + self.siner = 0 +end + +function MovingArena:onStart() + -- Get the arena object + local arena = Game.battle.arena + + -- Spawn spikes on top of arena + self:spawnBulletTo(Game.battle.arena, "arenahazard", arena.width / 2, 0, math.rad(0)) + + -- Spawn spikes on bottom of arena (rotated 180 degrees) + self:spawnBulletTo(Game.battle.arena, "arenahazard", arena.width / 2, arena.height, math.rad(180)) + + -- Store starting arena position + self.arena_start_x = arena.x + self.arena_start_y = arena.y +end + +function MovingArena:update() + -- Increment timer for arena movement + self.siner = self.siner + DT + + -- Calculate the arena Y offset + local offset = math.sin(self.siner * 1.5) * 60 + + -- Move the arena + Game.battle.arena:setPosition(self.arena_start_x, self.arena_start_y + offset) + + super.update(self) +end + +return MovingArena diff --git a/scripts/data/actors/dummy.lua b/scripts/data/actors/dummy.lua new file mode 100644 index 0000000..c97eb8f --- /dev/null +++ b/scripts/data/actors/dummy.lua @@ -0,0 +1,54 @@ +local actor, super = Class(Actor, "dummy") + +function actor:init() + super.init(self) + + -- Display name (optional) + self.name = "Dummy" + + -- Width and height for this actor, used to determine its center + self.width = 27 + self.height = 45 + + -- Hitbox for this actor in the overworld (optional, uses width and height by default) + self.hitbox = { 0, 25, 19, 14 } + + -- Color for this actor used in outline areas (optional, defaults to red) + self.color = { 1, 0, 0 } + + -- Whether this actor flips horizontally (optional, values are "right" or "left", indicating the flip direction) + self.flip = nil + + -- Path to this actor's sprites (defaults to "") + self.path = "enemies/dummy" + -- This actor's default sprite or animation, relative to the path (defaults to "") + self.default = "idle" + + -- Sound to play when this actor speaks (optional) + self.voice = nil + -- Path to this actor's portrait for dialogue (optional) + self.portrait_path = nil + -- Offset position for this actor's portrait (optional) + self.portrait_offset = nil + + -- Whether this actor as a follower will blush when close to the player + self.can_blush = false + + -- Table of talk sprites and their talk speeds (default 0.25) + self.talk_sprites = {} + + -- Table of sprite animations + self.animations = { + -- Looping animation with 0.25 seconds between each frame + -- (even though there's only 1 idle frame) + ["idle"] = { "idle", 0.25, true }, + } + + -- Table of sprite offsets (indexed by sprite name) + self.offsets = { + -- Since the width and height is the idle sprite size, the offset is 0,0 + ["idle"] = { 0, 0 }, + } +end + +return actor diff --git a/scripts/data/actors/starwalker.lua b/scripts/data/actors/starwalker.lua new file mode 100644 index 0000000..d435adf --- /dev/null +++ b/scripts/data/actors/starwalker.lua @@ -0,0 +1,47 @@ +local actor, super = Class(Actor, "starwalker") + +function actor:init() + super.init(self) + + -- Display name (optional) + self.name = "Starwalker" + + -- Width and height for this actor, used to determine its center + self.width = 37 + self.height = 36 + + -- Hitbox for this actor in the overworld (optional, uses width and height by default) + self.hitbox = { 2, 26, 27, 10 } + + -- Color for this actor used in outline areas (optional, defaults to red) + self.color = { 1, 1, 0 } + + -- Whether this actor flips horizontally (optional, values are "right" or "left", indicating the flip direction) + self.flip = nil + + -- Path to this actor's sprites (defaults to "") + self.path = "npcs/starwalker" + -- This actor's default sprite or animation, relative to the path (defaults to "") + self.default = "" + + -- Sound to play when this actor speaks (optional) + self.voice = nil + -- Path to this actor's portrait for dialogue (optional) + self.portrait_path = nil + -- Offset position for this actor's portrait (optional) + self.portrait_offset = nil + + -- Whether this actor as a follower will blush when close to the player + self.can_blush = false + + -- Table of talk sprites and their talk speeds (default 0.25) + self.talk_sprites = {} + + -- Table of sprite animations + self.animations = {} + + -- Table of sprite offsets (indexed by sprite name) + self.offsets = {} +end + +return actor diff --git a/scripts/data/actors/wall.lua b/scripts/data/actors/wall.lua new file mode 100644 index 0000000..5a66215 --- /dev/null +++ b/scripts/data/actors/wall.lua @@ -0,0 +1,49 @@ +local actor, super = Class(Actor, "wall") + +function actor:init() + super.init(self) + + -- Display name (optional) + self.name = "Wall" + + -- Width and height for this actor, used to determine its center + self.width = 60 + self.height = 70 + + -- Hitbox for this actor in the overworld (optional, uses width and height by default) + self.hitbox = { 0, 50, 60, 20 } + + -- Color for this actor used in outline areas (optional, defaults to red) + self.color = { 1, 0, 0 } + + -- Whether this actor flips horizontally (optional, values are "right" or "left", indicating the flip direction) + self.flip = nil + + -- Path to this actor's sprites (defaults to "") + self.path = "npcs/wall" + -- This actor's default sprite or animation, relative to the path (defaults to "") + self.default = "" + + -- Sound to play when this actor speaks (optional) + self.voice = nil + -- Path to this actor's portrait for dialogue (optional) + self.portrait_path = nil + -- Offset position for this actor's portrait (optional) + self.portrait_offset = nil + + -- Whether this actor as a follower will blush when close to the player + self.can_blush = false + + -- Table of talk sprites and their talk speeds (default 0.25) + self.talk_sprites = { + [""] = 0.2 + } + + -- Table of sprite animations + self.animations = {} + + -- Table of sprite offsets (indexed by sprite name) + self.offsets = {} +end + +return actor diff --git a/scripts/data/items/ultimate_candy.lua b/scripts/data/items/ultimate_candy.lua new file mode 100644 index 0000000..2a8a0a0 --- /dev/null +++ b/scripts/data/items/ultimate_candy.lua @@ -0,0 +1,58 @@ +-- Instead of Item, create a HealItem, a convenient class for consumable healing items +local item, super = Class(HealItem, "ultimate_candy") + +function item:init() + super.init(self) + + -- Display name + self.name = "UltimatCandy" + -- Name displayed when used in battle (optional) + self.use_name = "ULTIMATE CANDY" + + -- Item type (item, key, weapon, armor) + self.type = "item" + -- Item icon (for equipment) + self.icon = nil + + -- Battle description + self.effect = "Best\nhealing" + -- Shop description + self.shop = "Perfection" + -- Menu description + self.description = "Sparkles with perfection.\nMust be shared with everyone. +??HP" + + -- Amount healed (HealItem variable) + self.heal_amount = 1 + + -- Default shop price (sell price is halved) + self.price = 100 + -- Whether the item can be sold + self.can_sell = true + + -- Consumable target mode (ally, party, enemy, enemies, or none) + self.target = "party" + -- Where this item can be used (world, battle, all, or none) + self.usable_in = "all" + -- Item this item will get turned into when consumed + self.result_item = nil + -- Will this item be instantly consumed in battles? + self.instant = false + + -- Equip bonuses (for weapons and armor) + self.bonuses = {} + -- Bonus name and icon (displayed in equip menu) + self.bonus_name = nil + self.bonus_icon = nil + + -- Equippable characters (default true for armors, false for weapons) + self.can_equip = {} + + -- Character reactions (key = party member id) + self.reactions = { + susie = "Hey! It's hollow inside!", + ralsei = "I like the texture!", + noelle = "That was underwhelming...", + } +end + +return item diff --git a/scripts/objects/Squeak.lua b/scripts/objects/Squeak.lua new file mode 100644 index 0000000..820824c --- /dev/null +++ b/scripts/objects/Squeak.lua @@ -0,0 +1,13 @@ +---@class Squeak : Event +local Squeak, super = Class(Event) + +function Squeak:init(x, y, shape) + super.init(self, x, y, shape) +end + +function Squeak:onInteract(player, dir) + Assets.playSound("squeak") + return true +end + +return Squeak diff --git a/scripts/world/cutscenes/room1.lua b/scripts/world/cutscenes/room1.lua new file mode 100644 index 0000000..dd97b09 --- /dev/null +++ b/scripts/world/cutscenes/room1.lua @@ -0,0 +1,74 @@ +return { + -- The inclusion of the below line tells the language server that the first parameter of the cutscene is `WorldCutscene`. + -- This allows it to fetch us useful documentation that shows all of the available cutscene functions while writing our cutscenes! + + ---@param cutscene WorldCutscene + wall = function(cutscene, event) + -- Open textbox and wait for completion + cutscene:text("* The wall seems cracked.") + + -- If we have Susie, play a cutscene + local susie = cutscene:getCharacter("susie") + if susie then + -- Detach camera and followers (since characters will be moved) + cutscene:detachCamera() + cutscene:detachFollowers() + + -- All text from now is spoken by Susie + cutscene:setSpeaker(susie) + cutscene:text("* Hey,[wait:5] think I can break\nthis wall?", "smile") + + -- Get the bottom-center of the broken wall + local x = event.x + event.width / 2 + local y = event.y + event.height / 2 + + -- Move Susie up to the wall over 0.75 seconds + cutscene:walkTo(susie, x, y + 40, 0.75, "up") + -- Move other party members behind Susie + cutscene:walkTo(Game.world.player, x, y + 100, 0.75, "up") + if cutscene:getCharacter("ralsei") then + cutscene:walkTo("ralsei", x + 60, y + 100, 0.75, "up") + end + if cutscene:getCharacter("noelle") then + cutscene:walkTo("noelle", x - 60, y + 100, 0.75, "up") + end + + -- Wait 1.5 seconds + cutscene:wait(1.5) + + -- Walk back, + cutscene:wait(cutscene:walkTo(susie, x, y + 60, 0.5, "up", true)) + -- and run forward! + cutscene:wait(cutscene:walkTo(susie, x, y + 20, 0.2)) + + -- Slam!! + Assets.playSound("impact") + susie:shake(4) + susie:setSprite("shock_up") + + -- Slide back a bit + cutscene:slideTo(susie, x, y + 40, 0.1) + cutscene:wait(1.5) + + -- owie + susie:setAnimation({ "away_scratch", 0.25, true }) + susie:shake(4) + Assets.playSound("wing") + + cutscene:wait(1) + cutscene:text("* Guess not.", "nervous") + + -- Reset Susie's sprite + susie:resetSprite() + + -- Reattach the camera + cutscene:attachCamera() + + -- Align the follower positions behind Kris's current position + cutscene:alignFollowers() + -- And reattach them, making them return to their target positions + cutscene:attachFollowers() + Game:setFlag("wall_hit", true) + end + end +} diff --git a/scripts/world/maps/room1.lua b/scripts/world/maps/room1.lua new file mode 100644 index 0000000..29cb11f --- /dev/null +++ b/scripts/world/maps/room1.lua @@ -0,0 +1,550 @@ +return { + version = "1.5", + luaversion = "5.1", + tiledversion = "1.8.4", + orientation = "orthogonal", + renderorder = "right-down", + width = 20, + height = 24, + tilewidth = 40, + tileheight = 40, + nextlayerid = 6, + nextobjectid = 37, + properties = { + ["name"] = "Test Map - Room 1" + }, + tilesets = { + { + name = "castle", + firstgid = 1, + filename = "../tilesets/castle.tsx" + } + }, + layers = { + { + type = "tilelayer", + x = 0, + y = 0, + width = 20, + height = 24, + id = 1, + name = "tiles", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + encoding = "lua", + data = { + 0, 22, 13, 23, 23, 13, 23, 23, 23, 13, 23, 23, 13, 24, 0, 0, 0, 0, 0, 0, + 0, 22, 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 24, 0, 0, 0, 0, 0, 0, + 0, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 0, 0, 0, 0, 0, 0, + 0, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 0, 0, 0, 0, 0, 0, + 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, + 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, + 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 15, 15, 15, 15, 15, 15, + 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, + 0, 14, 15, 15, 11, 11, 11, 11, 11, 11, 11, 15, 15, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 14, 15, 11, 11, 11, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 22, 23, 24, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 22, 9, 24, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 0, + 0, 6, 7, 7, 7, 7, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 11, 11, 12, 0, + 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 15, 15, 15, 15, 16, 0, + 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, + 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, 0, 0, 0, 0, 0, + 0, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + type = "tilelayer", + x = 0, + y = 0, + width = 20, + height = 24, + id = 2, + name = "decal", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + encoding = "lua", + data = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 34, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + type = "objectgroup", + draworder = "topdown", + id = 3, + name = "collision", + visible = true, + opacity = 0.5, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + objects = { + { + id = 1, + name = "", + type = "", + shape = "rectangle", + x = 40, + y = 80, + width = 520, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 2, + name = "", + type = "", + shape = "rectangle", + x = 560, + y = 120, + width = 40, + height = 80, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 3, + name = "", + type = "", + shape = "rectangle", + x = 600, + y = 160, + width = 200, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 4, + name = "", + type = "", + shape = "rectangle", + x = 560, + y = 280, + width = 40, + height = 80, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 5, + name = "", + type = "", + shape = "rectangle", + x = 600, + y = 280, + width = 200, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 6, + name = "", + type = "", + shape = "rectangle", + x = 440, + y = 360, + width = 120, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 7, + name = "", + type = "", + shape = "rectangle", + x = 360, + y = 400, + width = 80, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 8, + name = "", + type = "", + shape = "rectangle", + x = 360, + y = 680, + width = 280, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 9, + name = "", + type = "", + shape = "rectangle", + x = 560, + y = 800, + width = 40, + height = 120, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 10, + name = "", + type = "", + shape = "rectangle", + x = 40, + y = 920, + width = 520, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 11, + name = "", + type = "", + shape = "rectangle", + x = 0, + y = 720, + width = 40, + height = 200, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 12, + name = "", + type = "", + shape = "rectangle", + x = 40, + y = 680, + width = 200, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 14, + name = "", + type = "", + shape = "rectangle", + x = 160, + y = 400, + width = 80, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 15, + name = "", + type = "", + shape = "rectangle", + x = 40, + y = 360, + width = 120, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 16, + name = "", + type = "", + shape = "rectangle", + x = 0, + y = 120, + width = 40, + height = 240, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 17, + name = "", + type = "", + shape = "rectangle", + x = 200, + y = 440, + width = 40, + height = 240, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 18, + name = "", + type = "", + shape = "rectangle", + x = 360, + y = 440, + width = 40, + height = 240, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 23, + name = "", + type = "", + shape = "rectangle", + x = 600, + y = 640, + width = 40, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 24, + name = "", + type = "", + shape = "rectangle", + x = 640, + y = 600, + width = 120, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 25, + name = "", + type = "", + shape = "rectangle", + x = 760, + y = 640, + width = 40, + height = 160, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 26, + name = "", + type = "", + shape = "rectangle", + x = 600, + y = 800, + width = 160, + height = 40, + rotation = 0, + visible = true, + properties = {} + } + } + }, + { + type = "objectgroup", + draworder = "topdown", + id = 4, + name = "objects", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + objects = { + { + id = 19, + name = "npc", + type = "", + shape = "rectangle", + x = 480, + y = 840, + width = 40, + height = 40, + rotation = 0, + visible = true, + properties = { + ["actor"] = "starwalker", + ["text1"] = "* These [color:yellow]stairs[color:reset] are [color:yellow]Pissing[color:reset] me\noff...", + ["text2"] = "* I'm the original [color:yellow]Starwalker[color:reset]" + } + }, + { + id = 27, + name = "savepoint", + type = "", + shape = "rectangle", + x = 80, + y = 210, + width = 40, + height = 40, + rotation = 0, + visible = true, + properties = { + ["text1"] = "* Silence echoes in the darkness\nof this familiar-yet-different\nscenery.", + ["text2"] = "* The power of avoiding copying\nofficial music shines within\nyou." + } + }, + { + id = 28, + name = "squeak", + type = "", + shape = "rectangle", + x = 680, + y = 600, + width = 40, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 29, + name = "transition", + type = "", + shape = "rectangle", + x = 800, + y = 200, + width = 40, + height = 80, + rotation = 0, + visible = true, + properties = { + ["map"] = "room2", + ["marker"] = "entry" + } + }, + { + id = 33, + name = "interactable", + type = "", + shape = "rectangle", + x = 280, + y = 80, + width = 40, + height = 40, + rotation = 0, + visible = true, + properties = { + ["cutscene"] = "room1.wall", + ["once"] = true + } + }, + { + id = 35, + name = "npc", + type = "", + shape = "point", + x = 300, + y = 160, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = { + ["actor"] = "wall", + ["flagcheck"] = "wall_hit", + ["text1"] = "* I Am the Wall Guardian.[wait:5]\n* This Wall is Off Limits for you\nno-good wall slammers." + } + } + } + }, + { + type = "objectgroup", + draworder = "topdown", + id = 5, + name = "markers", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + objects = { + { + id = 20, + name = "spawn", + type = "", + shape = "point", + x = 300, + y = 250, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 30, + name = "entry", + type = "", + shape = "point", + x = 760, + y = 240, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = {} + } + } + } + } +} diff --git a/scripts/world/maps/room1.tmx b/scripts/world/maps/room1.tmx new file mode 100644 index 0000000..60ca6ca --- /dev/null +++ b/scripts/world/maps/room1.tmx @@ -0,0 +1,140 @@ + + + + + + + + + + + +0,22,13,23,23,13,23,23,23,13,23,23,13,24,0,0,0,0,0,0, +0,22,23,23,23,23,23,21,23,23,23,23,23,24,0,0,0,0,0,0, +0,26,27,27,27,27,27,27,27,27,27,27,27,28,0,0,0,0,0,0, +0,6,7,7,7,7,7,7,7,7,7,7,7,8,0,0,0,0,0,0, +0,10,11,11,11,11,11,11,11,11,11,11,11,12,0,0,0,0,0,0, +0,10,11,11,11,11,11,11,11,11,11,11,11,11,7,7,7,7,7,7, +0,10,11,11,11,11,11,11,11,11,11,11,11,11,15,15,15,15,15,15, +0,10,11,11,11,11,11,11,11,11,11,11,11,12,0,0,0,0,0,0, +0,14,15,15,11,11,11,11,11,11,11,15,15,16,0,0,0,0,0,0, +0,0,0,0,14,15,11,11,11,15,16,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,18,19,20,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,22,23,24,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,22,9,24,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,10,11,12,0, +0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,10,11,12,0, +0,6,7,7,7,7,11,11,11,7,7,7,7,7,7,7,11,11,12,0, +0,10,11,11,11,11,11,11,11,11,11,11,11,11,15,15,15,15,16,0, +0,10,11,11,11,11,11,11,11,11,11,11,11,12,0,0,0,0,0,0, +0,10,11,11,11,11,11,11,11,11,11,11,11,12,0,0,0,0,0,0, +0,14,15,15,15,15,15,15,15,15,15,15,15,16,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,30,31,32,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,34,35,36,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,38,39,40,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * These [color:yellow]stairs[color:reset] are [color:yellow]Pissing[color:reset] me +off... + + + + + + * Silence echoes in the darkness +of this familiar-yet-different +scenery. + * The power of avoiding copying +official music shines within +you. + + + + + + + + + + + + + + + + + + + + * I Am the Wall Guardian.[wait:5] +* This Wall is Off Limits for you +no-good wall slammers. + + + + + + + + + + + + + diff --git a/scripts/world/maps/room2.lua b/scripts/world/maps/room2.lua new file mode 100644 index 0000000..ca1b109 --- /dev/null +++ b/scripts/world/maps/room2.lua @@ -0,0 +1,255 @@ +return { + version = "1.5", + luaversion = "5.1", + tiledversion = "1.8.4", + orientation = "orthogonal", + renderorder = "right-down", + width = 20, + height = 12, + tilewidth = 40, + tileheight = 40, + nextlayerid = 6, + nextobjectid = 12, + properties = { + ["name"] = "Test Map - Room 2" + }, + tilesets = { + { + name = "castle", + firstgid = 1, + filename = "../tilesets/castle.tsx" + } + }, + layers = { + { + type = "tilelayer", + x = 0, + y = 0, + width = 20, + height = 12, + id = 1, + name = "tiles", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + encoding = "lua", + data = { + 0, 0, 0, 0, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 0, + 0, 0, 0, 0, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 0, + 0, 0, 0, 0, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 0, + 0, 0, 0, 0, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 0, + 0, 0, 0, 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, + 0, 0, 0, 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, + 0, 0, 0, 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, + 0, 0, 0, 0, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, + 7, 7, 7, 7, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + type = "tilelayer", + x = 0, + y = 0, + width = 20, + height = 12, + id = 2, + name = "decal", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + encoding = "lua", + data = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 36, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + type = "objectgroup", + draworder = "topdown", + id = 3, + name = "collision", + visible = true, + opacity = 0.5, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + objects = { + { + id = 1, + name = "", + type = "", + shape = "rectangle", + x = 120, + y = 120, + width = 40, + height = 200, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 2, + name = "", + type = "", + shape = "rectangle", + x = 0, + y = 400, + width = 760, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 3, + name = "", + type = "", + shape = "rectangle", + x = 760, + y = 120, + width = 40, + height = 280, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 4, + name = "", + type = "", + shape = "rectangle", + x = 160, + y = 80, + width = 600, + height = 40, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 7, + name = "", + type = "", + shape = "rectangle", + x = 0, + y = 280, + width = 120, + height = 40, + rotation = 0, + visible = true, + properties = {} + } + } + }, + { + type = "objectgroup", + draworder = "topdown", + id = 4, + name = "markers", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + objects = { + { + id = 5, + name = "spawn", + type = "", + shape = "point", + x = 360, + y = 240, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 8, + name = "entry", + type = "", + shape = "point", + x = 40, + y = 360, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = {} + } + } + }, + { + type = "objectgroup", + draworder = "topdown", + id = 5, + name = "objects", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + objects = { + { + id = 6, + name = "enemy", + type = "", + shape = "rectangle", + x = 530, + y = 220, + width = 40, + height = 40, + rotation = 0, + visible = true, + properties = { + ["actor"] = "dummy", + ["encounter"] = "dummy" + } + }, + { + id = 9, + name = "transition", + type = "", + shape = "rectangle", + x = -40, + y = 320, + width = 40, + height = 80, + rotation = 0, + visible = true, + properties = { + ["map"] = "room1", + ["marker"] = "entry" + } + } + } + } + } +} diff --git a/scripts/world/maps/room2.tmx b/scripts/world/maps/room2.tmx new file mode 100644 index 0000000..482313b --- /dev/null +++ b/scripts/world/maps/room2.tmx @@ -0,0 +1,71 @@ + + + + + + + + + + + +0,0,0,0,22,23,23,23,23,23,23,23,23,23,23,23,23,23,24,0, +0,0,0,0,22,23,23,23,23,23,23,23,23,23,23,23,23,23,24,0, +0,0,0,0,26,27,27,27,27,27,27,27,27,27,27,27,27,27,28,0, +0,0,0,0,6,7,7,7,7,7,7,7,7,7,7,7,7,7,8,0, +0,0,0,0,10,11,11,11,11,11,11,11,11,11,11,11,11,11,12,0, +0,0,0,0,10,11,11,11,11,11,11,11,11,11,11,11,11,11,12,0, +0,0,0,0,10,11,11,11,11,11,11,11,11,11,11,11,11,11,12,0, +0,0,0,0,10,11,11,11,11,11,11,11,11,11,11,11,11,11,12,0, +7,7,7,7,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,0, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,30,31,32,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,34,35,36,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,38,39,40,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/world/template.world b/scripts/world/template.world new file mode 100644 index 0000000..1cc12c8 --- /dev/null +++ b/scripts/world/template.world @@ -0,0 +1,20 @@ +{ + "maps": [ + { + "fileName": "maps/room1.tmx", + "height": 960, + "width": 800, + "x": 0, + "y": 0 + }, + { + "fileName": "maps/room2.tmx", + "height": 480, + "width": 800, + "x": 880, + "y": -120 + } + ], + "onlyShowAdjacentMaps": false, + "type": "world" +} diff --git a/scripts/world/tilesets/castle.lua b/scripts/world/tilesets/castle.lua new file mode 100644 index 0000000..ff30464 --- /dev/null +++ b/scripts/world/tilesets/castle.lua @@ -0,0 +1,31 @@ +return { + version = "1.10", + luaversion = "5.1", + tiledversion = "1.10.2", + name = "castle", + class = "", + tilewidth = 40, + tileheight = 40, + spacing = 0, + margin = 0, + columns = 4, + image = "../../../assets/sprites/tilesets/castle.png", + imagewidth = 160, + imageheight = 400, + objectalignment = "unspecified", + tilerendersize = "tile", + fillmode = "stretch", + tileoffset = { + x = 0, + y = 0 + }, + grid = { + orientation = "orthogonal", + width = 40, + height = 40 + }, + properties = {}, + wangsets = {}, + tilecount = 40, + tiles = {} +} diff --git a/scripts/world/tilesets/castle.tsx b/scripts/world/tilesets/castle.tsx new file mode 100644 index 0000000..2254cc7 --- /dev/null +++ b/scripts/world/tilesets/castle.tsx @@ -0,0 +1,7 @@ + + + + + + +