Showing preview only (466K chars total). Download the full file or copy to clipboard to get everything.
Repository: GDquest/make-pro-2d-games-with-godot
Branch: master
Commit: 7290681309ff
Files: 304
Total size: 399.0 KB
Directory structure:
gitextract_59bn93hr/
├── .github/
│ └── CONTRIBUTING.md
├── .gitignore
├── Demo.tscn
├── LICENSE
├── README.md
├── actors/
│ ├── Actor.gd
│ ├── Actor.tscn
│ ├── CoinsAttractor.tscn
│ ├── CoinsCollector.gd
│ ├── CoinsCollector.tscn
│ ├── CoinsFountain.gd
│ ├── CoinsFountain.tscn
│ ├── DamageSource.gd
│ ├── DamageSource.tscn
│ ├── body.png.import
│ ├── camera/
│ │ ├── ShakingCamera.gd
│ │ └── ShakingCamera.tscn
│ ├── characters/
│ │ └── seller/
│ │ ├── Seller.gd
│ │ └── Seller.tscn
│ ├── health/
│ │ ├── Stats.gd
│ │ ├── Stats.tscn
│ │ └── Status.gd
│ ├── hit_box/
│ │ ├── HitBox.gd
│ │ ├── HitBox.tscn
│ │ └── hitbox_default.tres
│ ├── player/
│ │ ├── Player.tscn
│ │ ├── PlayerController.gd
│ │ ├── PlayerStateMachine.gd
│ │ ├── body.png.import
│ │ ├── shadow.png.import
│ │ └── states/
│ │ ├── Die.gd
│ │ ├── Fall.gd
│ │ ├── combat/
│ │ │ ├── Attack.gd
│ │ │ └── Stagger.gd
│ │ ├── debug/
│ │ │ └── StateNameDisplayer.gd
│ │ └── motion/
│ │ ├── Motion.gd
│ │ ├── in_air/
│ │ │ └── Jump.gd
│ │ └── on_ground/
│ │ ├── BumpPlayer.gd
│ │ ├── Idle.gd
│ │ ├── Move.gd
│ │ └── OnGround.gd
│ ├── shadow.png.import
│ └── weapons/
│ ├── bullet/
│ │ ├── Bullet.tscn
│ │ ├── BulletSpawner.gd
│ │ └── bullet.gd
│ └── sword/
│ ├── Sword.gd
│ ├── Sword.tscn
│ ├── WeaponPivot.gd
│ └── sword.png.import
├── audio/
│ ├── AudioShuffleStepSounds.gd
│ ├── AudioStreamPlayer.tscn
│ ├── MusicPlayer.gd
│ ├── MusicPlayer.tscn
│ ├── music/
│ │ ├── birdy_pong.ogg
│ │ └── birdy_pong.ogg.import
│ └── sfx/
│ ├── menu_confirm.wav.import
│ ├── menu_navigate_01.wav.import
│ ├── menu_navigate_02.wav.import
│ ├── menu_popup_open.wav.import
│ ├── step_01.wav.import
│ └── step_02.wav.import
├── core/
│ ├── Game.gd
│ ├── LevelLoader.gd
│ ├── inventory/
│ │ ├── Inventory.gd
│ │ ├── Inventory.tscn
│ │ ├── ItemDatabase.gd
│ │ ├── ItemDatabase.tscn
│ │ └── items/
│ │ ├── Coins.gd
│ │ ├── Coins.tscn
│ │ ├── Item.gd
│ │ ├── Item.tscn
│ │ ├── coins/
│ │ │ ├── coin_single.png.import
│ │ │ ├── coins_stack.png.import
│ │ │ └── coins_three.png.import
│ │ ├── equipment/
│ │ │ ├── Equipment.gd
│ │ │ ├── Equipment.tscn
│ │ │ └── sword/
│ │ │ └── Sword.tscn
│ │ └── usable/
│ │ ├── potions/
│ │ │ ├── BaseHealthPotion.tscn
│ │ │ ├── HealthPotion.gd
│ │ │ └── restore_health/
│ │ │ ├── MinorHealthPotion.tscn
│ │ │ └── StrongHealthPotion.tscn
│ │ └── scroll_fireball/
│ │ ├── FireballScroll.gd
│ │ ├── FireballScroll.tscn
│ │ └── fireball/
│ │ ├── Fireball.gd
│ │ ├── Fireball.tscn
│ │ └── particles/
│ │ ├── FireballParticles.tscn
│ │ ├── ParticlesToggle.gd
│ │ ├── assets/
│ │ │ └── gradient_ramps/
│ │ │ ├── fire_to_black.tres
│ │ │ ├── sparkles.tres
│ │ │ └── sparkles_small.tres
│ │ ├── explosions/
│ │ │ ├── Explosion.gd
│ │ │ └── Explosion.tscn
│ │ ├── fireball/
│ │ │ ├── fireball.material
│ │ │ └── fireball_big.material
│ │ └── sprites/
│ │ ├── circle.png.import
│ │ └── smoke_clouds.png.import
│ ├── save/
│ │ ├── SaveAndLoad.gd
│ │ └── SaveAndLoad.tscn
│ ├── shop/
│ │ ├── Shop.gd
│ │ ├── Shop.tscn
│ │ └── purse/
│ │ ├── Purse.gd
│ │ └── Purse.tscn
│ └── world/
│ ├── Door.gd
│ ├── Door.tscn
│ ├── Gap.gd
│ ├── Gap.tscn
│ ├── PlayerSpawningPoint.tscn
│ ├── Rock.tscn
│ ├── pit.png.import
│ ├── rock.png.import
│ ├── stairs.png.import
│ └── tilesets/
│ ├── cave/
│ │ ├── cave.png.import
│ │ ├── cave.tres
│ │ └── cave_tileset_src.tscn
│ └── outdoor/
│ ├── outdoor.png.import
│ ├── outdoor.tres
│ ├── outdoor.tscn
│ └── pit.png.import
├── default_bus_layout.tres
├── default_env.tres
├── icon.png.import
├── interface/
│ ├── Interface.gd
│ ├── TopLevelUi.gd
│ ├── default.theme
│ ├── fonts/
│ │ ├── montserrat_black_48.tres
│ │ ├── source_code_pro_explanations.tres
│ │ └── source_code_pro_explanations_bold.tres
│ ├── gui/
│ │ ├── boss/
│ │ │ ├── BossLifebar.gd
│ │ │ ├── BossLifebar.tscn
│ │ │ ├── boss_bar_bg.png.import
│ │ │ └── boss_bar_fill.png.import
│ │ ├── lifebar/
│ │ │ ├── HookableLifeBar.tscn
│ │ │ ├── InterfaceAnchor.tscn
│ │ │ ├── Lifebar.gd
│ │ │ ├── LifebarsBuilder.gd
│ │ │ ├── LifebarsBuilder.tscn
│ │ │ ├── background.png.import
│ │ │ └── fill.png.import
│ │ └── player/
│ │ ├── PlayerGUI.gd
│ │ ├── PlayerGUI.tscn
│ │ └── life_bar/
│ │ ├── LifeBar.tscn
│ │ ├── Lifebar.gd
│ │ ├── TextureProgress.gd
│ │ ├── bg.png.import
│ │ └── fill.png.import
│ ├── items/
│ │ ├── ItemButton.gd
│ │ ├── ItemButton.tscn
│ │ ├── ItemGrid.gd
│ │ ├── ItemsList.gd
│ │ └── ItemsList.tscn
│ ├── menus/
│ │ ├── Menu.gd
│ │ ├── Menu.tscn
│ │ ├── MenuSfx.tscn
│ │ ├── MenuTitle.tscn
│ │ ├── inventory/
│ │ │ ├── InventoryMenu.gd
│ │ │ ├── InventoryMenu.tscn
│ │ │ ├── ItemButton.gd
│ │ │ ├── ItemButton.tscn
│ │ │ ├── ItemGrid.gd
│ │ │ ├── ItemsMenu.gd
│ │ │ ├── ItemsMenu.tscn
│ │ │ └── user_select/
│ │ │ ├── ActorButton.tscn
│ │ │ ├── UserSelectMenu.gd
│ │ │ └── UserSelectMenu.tscn
│ │ ├── pause/
│ │ │ ├── OptionsMenu.gd
│ │ │ ├── OptionsMenu.tscn
│ │ │ ├── PauseMenu.gd
│ │ │ ├── PauseMenu.tscn
│ │ │ ├── SoundController.gd
│ │ │ └── SoundController.tscn
│ │ ├── save_and_load/
│ │ │ ├── SaveMenu.gd
│ │ │ └── SaveMenu.tscn
│ │ ├── shared/
│ │ │ ├── Button.gd
│ │ │ └── Button.tscn
│ │ └── shop/
│ │ ├── ShopMenu.gd
│ │ ├── ShopMenu.tscn
│ │ ├── menus/
│ │ │ ├── BuySubMenu.tscn
│ │ │ ├── SellSubMenu.tscn
│ │ │ ├── ShopSubMenu.gd
│ │ │ └── ShopSubMenu.tscn
│ │ ├── panels/
│ │ │ ├── DescriptionPanel.gd
│ │ │ ├── DescriptionPanel.tscn
│ │ │ ├── InfoPanel.gd
│ │ │ ├── InfoPanel.tscn
│ │ │ └── ShopItemsList.tscn
│ │ └── popups/
│ │ ├── AmountLabel.gd
│ │ ├── AmountPopup.gd
│ │ ├── AmountPopup.tscn
│ │ └── HSlider.gd
│ └── theme/
│ ├── button/
│ │ ├── disabled.stylebox
│ │ ├── focused.stylebox
│ │ ├── hover.stylebox
│ │ ├── normal.stylebox
│ │ └── pressed.stylebox
│ ├── empty.stylebox
│ ├── fonts/
│ │ ├── comfortaa_tips.tres
│ │ ├── default_font_comfortaa.tres
│ │ └── source_code_pro_26.tres
│ ├── icons/
│ │ ├── add.png.import
│ │ ├── cancel.png.import
│ │ ├── coins.png.import
│ │ ├── fire_scroll.png.import
│ │ ├── potion_health.png.import
│ │ ├── potion_mana.png.import
│ │ ├── purse.png.import
│ │ ├── remove.png.import
│ │ └── sword.png.import
│ ├── panel/
│ │ └── panel.stylebox
│ └── slider/
│ └── slider.stylebox
├── levels/
│ ├── Cave.tscn
│ ├── Grasslands.tscn
│ ├── Level.gd
│ └── TestLevel.tscn
├── monsters/
│ ├── BossShakingCamera.gd
│ ├── BossShakingCamera.tscn
│ ├── Monster.gd
│ ├── Monster.tscn
│ ├── ObstacleDetector.gd
│ ├── bosses/
│ │ └── wild_boar/
│ │ ├── WildBoar.gd
│ │ ├── WildBoar.tscn
│ │ ├── WildBoarFSM.gd
│ │ ├── debug/
│ │ │ ├── BossStatesDisplayer.gd
│ │ │ ├── StatesStackDiplayer.tscn
│ │ │ ├── StatesStackDisplayer.gd
│ │ │ └── fonts/
│ │ │ └── source-code-pro-bold.otf
│ │ ├── sprites/
│ │ │ ├── front.png.import
│ │ │ ├── wild_boar_stomp_1.png.import
│ │ │ └── wild_boar_stomp_2.png.import
│ │ └── states/
│ │ ├── Die.gd
│ │ ├── Follow.gd
│ │ ├── ReturnToCenter.gd
│ │ ├── Spawn.gd
│ │ ├── charge/
│ │ │ ├── BumpWildBoar.gd
│ │ │ ├── Prepare.gd
│ │ │ └── Sprint.gd
│ │ ├── roam/
│ │ │ ├── MoveToRandomPosition.gd
│ │ │ ├── RoamSequence.gd
│ │ │ └── Wait.gd
│ │ └── stomp/
│ │ ├── GroundExplosion.gd
│ │ ├── GroundExplosion.tscn
│ │ ├── Stomp.gd
│ │ └── Stomp.tscn
│ ├── exclamation-mark.png.import
│ ├── exclamation-mark.svg.import
│ ├── mosquito/
│ │ ├── Mosquito.gd
│ │ ├── Mosquito.tscn
│ │ ├── Nest.gd
│ │ ├── Nest.tscn
│ │ ├── mosquito.png.import
│ │ └── nest.png.import
│ └── porcupine/
│ ├── Porcupine.gd
│ ├── Porcupine.tscn
│ └── porcupine.png.import
├── project.godot
├── utils/
│ ├── autoload/
│ │ └── Steering.gd
│ ├── debug/
│ │ ├── ControlsPanel.tscn
│ │ ├── Explanations.tscn
│ │ ├── StatesStackDiplayer.tscn
│ │ ├── StatesStackDisplayer.gd
│ │ └── TopLevelUI.gd
│ └── state/
│ ├── Sequence.gd
│ ├── Sequence.tscn
│ ├── State.gd
│ ├── StateMachine.gd
│ └── StateMachine.tscn
└── vfx/
├── Fog.gd
├── TransitionColor.gd
├── TransitionColor.tscn
├── fog.shader
├── fog_background.material
├── fog_foreground.material
├── masks/
│ └── curtain.png.import
├── particles/
│ ├── SelfDestructingParticles.gd
│ ├── assets/
│ │ └── gradient_ramps/
│ │ ├── fire_to_black.tres
│ │ ├── sparkles.tres
│ │ └── sparkles_small.tres
│ ├── dust_charge/
│ │ ├── DustCharge.tscn
│ │ ├── DustChargeLarge.tscn
│ │ └── puffs.png.import
│ ├── dust_puffs/
│ │ ├── DustPuffs.tscn
│ │ ├── DustPuffsLarge.tscn
│ │ ├── DustRun.tscn
│ │ ├── DustWalk.tscn
│ │ ├── dust_puffs_particle.tres
│ │ ├── puff_stylized.png.import
│ │ └── puffs.png.import
│ ├── explosions/
│ │ ├── Explosion.gd
│ │ ├── Explosion.tscn
│ │ ├── ExplosionFlash.tscn
│ │ └── circle.png.import
│ ├── fiery_cloud/
│ │ ├── FieryCloud.tscn
│ │ ├── Fireball.tscn
│ │ └── FireryCloud.gd
│ ├── rocks/
│ │ ├── DirectionalRock.tscn
│ │ ├── crumbs.png.import
│ │ ├── crumbs_particle.tres
│ │ ├── rocks.png.import
│ │ └── rocks_particle.tres
│ └── smoke/
│ ├── EnemySmokeScreen.tscn
│ ├── ParticlesPlayer.gd
│ ├── smoke.png.import
│ └── smoke_screen_particle.tres
├── transition.material
└── transition.shader
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing Guidelines
<!-- How to contribute -->
<!-- How to join the community -->
<!-- How to get support -->
<!-- See https://github.com/atom/atom/blob/master/CONTRIBUTING.md#reporting-bugs for reference -->
Thank you very much for helping us make the project better! 😄
We appreciate every contribution, and you taking the time to give back to the community. 🙂
At the same time, there are a few guidelines we'd ask you to follow here to help bring everyone's work together as smoothly as possible.
This guide explains how to report bugs, but how to suggest new features, where you can get support with the project as a user, and how to get in touch with other creators through the community channels.
## How Do I Submit A (Good) Bug Report?
We track both bugs and improvements in the issues tab on GitHub.
Writing a good bug report makes it a lot easier for maintainers and contributors to fix it. A good bug report:
1. Starts with a clear title that describes the issue
1. Includes a list of steps to reproduce the bug, an information about the version of the program and the platform you're working with
1. Contains the traceback or the error reported by the program in the output tab when the bug occurs
You should also mention any steps you've taken to try and solve the issue or extra information you think would be valuable to help track down and fixed a bug.
*Tips: take a quick screenshot and drag and drop it in the GitHub issue's body to help illustrate the problem! For Windows users, I recommend to use [ShareX](https://getsharex.com/) for that (open source). Ubuntu comes with a built-in tool, press <kbd>Shift</kbd> <kbd>PrtScn</kbd> by default to capture a rectangular area on your screen.*
### Bad and good bug report examples
Here's an example of a *bad* bug report:
```md
# X doesn't work
I can't make feature X work
```
This report doesn't give any information about what the bug is, what triggers it, whether it can be reproduced, if it's platform-specific, if you' re using an unsupported platform...
Here's an example of a good bug report,
```md
```
## I want to submit a new feature or improve existing code
That's great to hear! Be sure to let everyone know you're working on this by opening an issue or replying to an existing issue.
## I need help to use this project!
## Where can I chat with other contributors?
Issues
Join us on Discord! https://discord.gg/87NNb3Z
#open-source channel
If you would like to discuss an issue in private, you can find me on Twitter
================================================
FILE: .gitignore
================================================
.import
.projectile
================================================
FILE: Demo.tscn
================================================
[gd_scene load_steps=14 format=2]
[ext_resource path="res://core/Game.gd" type="Script" id=1]
[ext_resource path="res://audio/MusicPlayer.tscn" type="PackedScene" id=2]
[ext_resource path="res://vfx/fog_background.material" type="Material" id=3]
[ext_resource path="res://vfx/Fog.gd" type="Script" id=4]
[ext_resource path="res://core/LevelLoader.gd" type="Script" id=5]
[ext_resource path="res://actors/player/Player.tscn" type="PackedScene" id=6]
[ext_resource path="res://vfx/fog_foreground.material" type="Material" id=7]
[ext_resource path="res://vfx/TransitionColor.tscn" type="PackedScene" id=8]
[ext_resource path="res://interface/Interface.gd" type="Script" id=9]
[ext_resource path="res://interface/gui/player/PlayerGUI.tscn" type="PackedScene" id=10]
[ext_resource path="res://interface/menus/shop/ShopMenu.tscn" type="PackedScene" id=11]
[ext_resource path="res://interface/menus/pause/PauseMenu.tscn" type="PackedScene" id=12]
[ext_resource path="res://interface/gui/lifebar/LifebarsBuilder.tscn" type="PackedScene" id=13]
[node name="Game" type="Node"]
pause_mode = 1
script = ExtResource( 1 )
[node name="MusicPlayer" parent="." instance=ExtResource( 2 )]
[node name="Background" type="CanvasLayer" parent="."]
editor/display_folded = true
layer = -100
[node name="ColorRect" type="ColorRect" parent="Background"]
anchor_right = 1.0
anchor_bottom = 1.0
color = Color( 0.0625, 0.0549316, 0.0549316, 1 )
[node name="BackgroundFog" type="ColorRect" parent="Background"]
visible = false
material = ExtResource( 3 )
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 4 )
[node name="LevelLoader" type="Node" parent="."]
pause_mode = 1
script = ExtResource( 5 )
LEVEL_START = "res://levels/Grasslands.tscn"
[node name="Player" parent="LevelLoader" instance=ExtResource( 6 )]
[node name="Overlays" type="CanvasLayer" parent="."]
pause_mode = 2
editor/display_folded = true
layer = 50
[node name="ForegroundFog" type="ColorRect" parent="Overlays"]
visible = false
material = ExtResource( 7 )
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 4 )
[node name="TransitionColor" parent="Overlays" instance=ExtResource( 8 )]
[node name="Interface" type="CanvasLayer" parent="."]
pause_mode = 2
layer = 100
script = ExtResource( 9 )
[node name="PlayerGUI" parent="Interface" instance=ExtResource( 10 )]
[node name="ShopMenu" parent="Interface" instance=ExtResource( 11 )]
pause_mode = 2
visible = false
_sections_unfolded = [ "Pause", "Theme" ]
[node name="PauseMenu" parent="Interface" instance=ExtResource( 12 )]
visible = false
_sections_unfolded = [ "Pause", "Theme" ]
[node name="LifebarsBuilder" parent="Interface" instance=ExtResource( 13 )]
[connection signal="loaded" from="LevelLoader" to="Interface" method="_on_Level_loaded"]
[connection signal="loaded" from="LevelLoader" to="Background/BackgroundFog" method="_on_LevelLoader_loaded"]
[connection signal="loaded" from="LevelLoader" to="Overlays/ForegroundFog" method="_on_LevelLoader_loaded"]
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 GDquest
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<h1 align="center">
Make Pro 2d Games with Godot</br>
<small>Open Source A-RPG Demo</small>
</h1>
<p align='center'>
<img src="https://i.imgur.com/zW56qs0.png" alt="Banner for the project, showing the player facing the game's boss, the blue wild boar" />
</p>
<hr>
This is the full source code with all the system produced for the [Make Professional 2d Games with Godot](https://gumroad.com/l/godot-tutorial-make-professional-2d-games) course.

This game demo tries to show good Godot programming practices to support a growing game project. It has multiple interlocking systems, the core gameplay loop in place, a boss encounter, an inventory and shop systems, user interface with nested menus...

## LICENSE ##
The entire source code is available under the MIT licence and everyone is welcome to [contribute](https://github.com/GDquest/make-pro-2d-games-with-godot/issues/)! Better art, gameplay improvements, code re-factoring, and more…
All the techniques I used to build this project are in our [intermediate-level Godot course on Gumroad](https://gumroad.com/gdquest). If you're interested in getting it, be aware it's not 100% step-by-step.
If you have requests for tutorials from elements of that game demo, please feel free to [ask on Twitter](https://twitter.com/NathanGDquest)! I will not redo what's in the course but I'll gladly make extra videos that would benefit everyone! 😄
This is our first open game on GDQuest. We are looking to build more Free games and game creation tools in the future. Be sure to [subscribe to our YouTube channel](http://youtube.com/c/gdquest) to know when that happens ☺
## Dependencies ##
The project runs in **Godot 3.1**.
## Features ##
Here's a list of the gameplay features and a few of the systems you will find in the demo
### Gameplay ###
- A player that can walk, jump, and do a three hit combo with a sword
- Two monsters with steering based movement
- Boss with 3 phases, drops random stacks of coins upon dying
- Items, and inventory, and a shop that will cover your basics for an RPG game
### Core systems ###
- LevelLoader, to load maps cleanly, keep the player's data around
- Save and load system
- Game node to handle pause and initialize the game at the start
- Shader to animate the transition between levels
### User interface ###
- An inventory menu and a shop menu where you can buy and sell items between two characters
- A pause menu with sound options
- A system to create life bars that hook onto monsters and follow them in the game world, but that are still managed by the UI system
- The animated player life bar (tutorial)
- Animated boss light bar that appears when the boss spans
### Visual effects ###
- Layered particle systems like explosions, bursting fire, rock sparkles, dust
- Beautiful noise-based fog thanks to [Gonkee](https://github.com/Gonkee/Gonkee-Fog-Shader)
### A few misc extras
- Modular hit box and damage source system to create ranged and melee weapons
- Stats node to manage the player and the monsters' health
- Gaps the player can fall into
### Contributing
You can find our contributor's guides here:
- [Contributor's guide](https://www.gdquest.com/open-source/guidelines/contributing-to-gdquest-projects/)
- [GDScript best practices](https://www.gdquest.com/open-source/guidelines/godot-gdscript/)
- [Kind communication guidelines](https://www.gdquest.com/open-source/guidelines/kind-communication-guidelines/)
================================================
FILE: actors/Actor.gd
================================================
extends KinematicBody2D
signal direction_changed(new_direction)
signal position_changed(new_position)
signal died()
onready var health = $Health
var look_direction = Vector2(1, 0) setget set_look_direction
func take_damage_from(damage_source):
health.take_damage(damage_source.damage)
func set_dead(value):
set_process_input(not value)
set_physics_process(not value)
$CollisionPolygon2D.disabled = value
emit_signal('died')
func set_look_direction(value):
look_direction = value
emit_signal("direction_changed", value)
func reset(target_global_position):
global_position = target_global_position
================================================
FILE: actors/Actor.tscn
================================================
[gd_scene load_steps=11 format=2]
[ext_resource path="res://actors/health/Stats.tscn" type="PackedScene" id=1]
[ext_resource path="res://actors/body.png" type="Texture" id=2]
[ext_resource path="res://interface/theme/icons/add.png" type="Texture" id=3]
[sub_resource type="Animation" id=1]
resource_name = "SETUP"
length = 0.01
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Skin/Body:scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Skin/Body:rotation_degrees")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ 0.0 ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("Skin/Body:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 0, -31.5144 ) ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("Skin/Body:modulate")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=2]
resource_name = "heal"
length = 0.6
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Skin/Body:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.2, 0.6 ),
"transitions": PoolRealArray( 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 0, 1, 0.179688, 1 ), Color( 1, 1, 1, 1 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Skin/HealParticles:emitting")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.6 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 2,
"values": [ true, false ]
}
[sub_resource type="Gradient" id=3]
offsets = PoolRealArray( 0, 0.111475, 0.872131, 1 )
colors = PoolColorArray( 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 )
[sub_resource type="GradientTexture" id=4]
flags = 4
gradient = SubResource( 3 )
width = 2048
[sub_resource type="Curve" id=5]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.693359 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=6]
flags = 4
width = 2048
curve = SubResource( 5 )
[sub_resource type="ParticlesMaterial" id=7]
render_priority = 0
trail_divisor = 1
emission_shape = 0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 20.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 60.0
initial_velocity_random = 0.0
angular_velocity = 0.0
angular_velocity_random = 0.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = 0.0
linear_accel_random = 0.0
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 0.0
tangential_accel_random = 0.0
damping = 1.0
damping_random = 0.0
angle = 0.0
angle_random = 0.0
scale = 1.0
scale_random = 0.0
scale_curve = SubResource( 6 )
color_ramp = SubResource( 4 )
hue_variation = 0.0
hue_variation_random = 0.0
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 0.0
anim_offset_random = 0.0
anim_loop = false
_sections_unfolded = [ "Color", "Damping" ]
[node name="Actor" type="KinematicBody2D" groups=[
"actor",
]]
input_pickable = false
collision_layer = 1
collision_mask = 1
collision/safe_margin = 0.08
_sections_unfolded = [ "Transform", "Visibility" ]
[node name="Health" parent="." index="0" instance=ExtResource( 1 )]
max_health = 100
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="1"]
root_node = NodePath("..")
autoplay = "SETUP"
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/SETUP = SubResource( 1 )
anims/heal = SubResource( 2 )
blend_times = [ ]
_sections_unfolded = [ "Playback Options" ]
[node name="Skin" type="Position2D" parent="." index="2"]
_sections_unfolded = [ "Visibility" ]
[node name="Body" type="Sprite" parent="Skin" index="0"]
position = Vector2( 0, -31.5144 )
texture = ExtResource( 2 )
offset = Vector2( 1.40758, -3.05176e-005 )
_sections_unfolded = [ "Transform", "Visibility" ]
[node name="HealParticles" type="Particles2D" parent="Skin" index="1"]
position = Vector2( 37.3383, -68.3211 )
rotation = -1.19808
emitting = false
amount = 3
lifetime = 0.6
one_shot = true
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.2
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = false
draw_order = 1
process_material = SubResource( 7 )
texture = ExtResource( 3 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time" ]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="3"]
build_mode = 0
polygon = PoolVector2Array( -30, 0, -30, -40, 34, -40, 34, 0 )
_sections_unfolded = [ "Transform" ]
================================================
FILE: actors/CoinsAttractor.tscn
================================================
[gd_scene load_steps=2 format=2]
[sub_resource type="CircleShape2D" id=2]
custom_solver_bias = 0.0
radius = 41.2311
[node name="CoinsAttractor" type="Area2D"]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
collision_layer = 128
collision_mask = 64
audio_bus_override = false
audio_bus_name = "Master"
_sections_unfolded = [ "Collision" ]
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="0"]
shape = SubResource( 2 )
================================================
FILE: actors/CoinsCollector.gd
================================================
extends Area2D
signal coins_received(amount)
const Coins = preload("res://core/inventory/items/Coins.gd")
func _on_area_entered(area):
print(area)
if not area is Coins:
return
area.queue_free()
emit_signal("coins_received", area.amount)
================================================
FILE: actors/CoinsCollector.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://actors/CoinsCollector.gd" type="Script" id=1]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 44.6727
[node name="CoinsCollector" type="Area2D" index="0"]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitorable = false
collision_layer = 128
collision_mask = 64
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Collision" ]
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="0"]
shape = SubResource( 1 )
[connection signal="area_entered" from="." to="." method="_on_area_entered"]
================================================
FILE: actors/CoinsFountain.gd
================================================
extends Position2D
const Coins = preload("res://core/inventory/items/Coins.tscn")
onready var timer = $Timer
export(int) var MAX_SPAWN_COUNT = 12
var spawn_cycles = 0
func start():
timer.start()
func _on_Timer_timeout():
spawn_random_coin_stack()
func spawn_random_coin_stack():
var coins = Coins.instance()
add_child(coins)
coins.set_random_amount()
coins.throw()
spawn_cycles += 1
if spawn_cycles == MAX_SPAWN_COUNT:
timer.stop()
================================================
FILE: actors/CoinsFountain.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://actors/CoinsFountain.gd" type="Script" id=1]
[sub_resource type="GDScript" id=1]
script/source = "extends Timer
export(float) var MINIMUM_WAIT_TIME = 0.05
export(float) var MAXIMUM_WAIT_TIME = 0.1
func _init():
assert(MINIMUM_WAIT_TIME <= MAXIMUM_WAIT_TIME)
func randomize_wait_time():
wait_time = rand_range(MINIMUM_WAIT_TIME, MAXIMUM_WAIT_TIME)"
[node name="CoinsFountain" type="Position2D"]
script = ExtResource( 1 )
_sections_unfolded = [ "Transform" ]
MAX_SPAWN_COUNT = 20
[node name="Timer" type="Timer" parent="." index="0"]
process_mode = 1
wait_time = 0.05
one_shot = false
autostart = false
script = SubResource( 1 )
MINIMUM_WAIT_TIME = 0.05
MAXIMUM_WAIT_TIME = 0.1
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
[connection signal="timeout" from="Timer" to="Timer" method="randomize_wait_time"]
================================================
FILE: actors/DamageSource.gd
================================================
extends Area2D
export(int) var damage = 2
var effect
func set_active(value):
$CollisionShape2D.disabled = not value
================================================
FILE: actors/DamageSource.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://actors/DamageSource.gd" type="Script" id=1]
[node name="DamageSource" type="Area2D" index="0"]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitoring = false
collision_layer = 32
collision_mask = 4
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Collision" ]
damage = 2
================================================
FILE: actors/body.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/body.png-e947538dbfd8a8c2e1335860c186fed8.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://actors/body.png"
dest_files=[ "res://.import/body.png-e947538dbfd8a8c2e1335860c186fed8.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: actors/camera/ShakingCamera.gd
================================================
tool
extends Camera2D
export(float) var amplitude = 6.0
export(float) var duration = 0.8 setget set_duration
export(float, EASE) var DAMP_EASING = 1.0
export(bool) var shake = false setget set_shake
onready var timer = $Timer
enum States {IDLE, SHAKING}
var state = States.IDLE
func _ready():
self.duration = duration
set_process(false)
randomize()
func set_duration(value):
duration = value
if not timer:
return
timer.wait_time = duration
func set_shake(value):
shake = value
if shake:
_change_state(States.SHAKING)
else:
_change_state(States.IDLE)
func _change_state(new_state):
match new_state:
States.IDLE:
offset = Vector2()
set_process(false)
States.SHAKING:
set_process(true)
timer.start()
state = new_state
func _process(delta):
var damping = ease(timer.time_left / timer.wait_time, DAMP_EASING)
offset = Vector2(
rand_range(amplitude, -amplitude) * damping,
rand_range(amplitude, -amplitude) * damping)
func _on_ShakeTimer_timeout():
self.shake = false
================================================
FILE: actors/camera/ShakingCamera.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://actors/camera/ShakingCamera.gd" type="Script" id=1]
[node name="ShakingCamera" type="Camera2D" index="0"]
anchor_mode = 1
rotating = false
current = true
zoom = Vector2( 1, 1 )
limit_left = -10000000
limit_top = -10000000
limit_right = 10000000
limit_bottom = 10000000
limit_smoothed = false
drag_margin_h_enabled = true
drag_margin_v_enabled = true
smoothing_enabled = false
smoothing_speed = 5.0
offset_v = 0.0
offset_h = 0.0
drag_margin_left = 0.2
drag_margin_top = 0.2
drag_margin_right = 0.2
drag_margin_bottom = 0.2
editor_draw_screen = true
editor_draw_limits = false
editor_draw_drag_margin = false
script = ExtResource( 1 )
_sections_unfolded = [ "Drag Margin", "Smoothing", "Transform" ]
amplitude = 8.0
duration = 0.8
DAMP_EASING = 1.0
shake = false
[node name="Timer" type="Timer" parent="." index="0"]
process_mode = 1
wait_time = 0.8
one_shot = true
autostart = false
[connection signal="timeout" from="Timer" to="." method="_on_ShakeTimer_timeout"]
================================================
FILE: actors/characters/seller/Seller.gd
================================================
extends Area2D
signal shop_open_requested(shop, user)
const Player = preload("res://actors/player/PlayerController.gd")
func _unhandled_input(event):
if not event.is_action_pressed("ui_accept"):
return
for body in get_overlapping_bodies():
if body is Player:
emit_signal("shop_open_requested", $Shop, body)
get_tree().set_input_as_handled()
================================================
FILE: actors/characters/seller/Seller.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://actors/characters/seller/Seller.gd" type="Script" id=1]
[ext_resource path="res://core/shop/Shop.tscn" type="PackedScene" id=2]
[ext_resource path="res://actors/body.png" type="Texture" id=3]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 49.2988
[node name="Seller" type="Area2D" index="0" groups=[
"seller",
]]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Transform" ]
[node name="Shop" parent="." index="0" instance=ExtResource( 2 )]
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="1"]
shape = SubResource( 1 )
[node name="Body" type="Sprite" parent="." index="2"]
position = Vector2( 0, -20 )
texture = ExtResource( 3 )
_sections_unfolded = [ "Transform" ]
================================================
FILE: actors/health/Stats.gd
================================================
extends Node
signal health_changed(new_health)
signal damage_taken(new_health)
signal health_depleted()
var modifiers = {}
var health = 0
export(int) var max_health = 9 setget set_max_health
export(int) var strength = 2
export(int) var defense = 0
func _ready():
health = max_health
func set_max_health(value):
max_health = max(0, value)
func take_damage(amount):
health -= amount
health = max(0, health)
emit_signal("health_changed", health)
emit_signal("damage_taken", health)
if health == 0:
emit_signal("health_depleted")
func heal(amount):
health += amount
health = max(health, max_health)
emit_signal("health_changed", health)
func add_modifier(id, modifier):
modifiers[id] = modifier
func remove_modifier(id):
modifiers.erase(id)
================================================
FILE: actors/health/Stats.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://actors/health/Stats.gd" type="Script" id=1]
[node name="Stats" type="Node" index="0"]
script = ExtResource( 1 )
health = 0
max_health = 9
strength = 2
defense = 0
================================================
FILE: actors/health/Status.gd
================================================
extends Node
signal added(status)
signal removed(status)
var statuses_active = {}
# Example status
const POISON = {
'name': "Poison",
'effect': {
'periodic_damage': {
'cycles': 5,
'stat': 'health',
'damage': 1,
}
}
}
const INVINCIBLE = {
'name': "Invincible",
'effect': {
'stat_modifier': {
'add': {
'defense': 1000,
'magic_defense': 1000
}
}
}
}
func add(id, status):
statuses_active[id] = status
func remove(id):
statuses_active.erase(id)
func as_string():
var string = ""
for status in statuses_active.values():
string += "%s.%s: %s" % [status['id'], status['name'], status['effect']]
return string
================================================
FILE: actors/hit_box/HitBox.gd
================================================
extends Area2D
const DamageSource = preload("res://actors/DamageSource.gd")
func _on_area_entered(area):
if not area is DamageSource:
return
owner.take_damage_from(area)
func set_active(value):
$CollisionShape2D.disabled = not value
================================================
FILE: actors/hit_box/HitBox.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://actors/hit_box/HitBox.gd" type="Script" id=1]
[ext_resource path="res://actors/hit_box/hitbox_default.tres" type="Shape2D" id=2]
[node name="HitBox" type="Area2D" index="0"]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitorable = false
collision_layer = 4
collision_mask = 32
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Collision", "Transform" ]
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="0"]
position = Vector2( 0, -8.42273 )
shape = ExtResource( 2 )
[connection signal="area_entered" from="." to="." method="_on_area_entered"]
================================================
FILE: actors/hit_box/hitbox_default.tres
================================================
[gd_resource type="CircleShape2D" format=2]
[resource]
custom_solver_bias = 0.0
radius = 99.636
================================================
FILE: actors/player/Player.tscn
================================================
[gd_scene load_steps=37 format=2]
[ext_resource path="res://actors/player/PlayerController.gd" type="Script" id=1]
[ext_resource path="res://actors/camera/ShakingCamera.tscn" type="PackedScene" id=2]
[ext_resource path="res://actors/hit_box/HitBox.tscn" type="PackedScene" id=3]
[ext_resource path="res://actors/player/PlayerStateMachine.gd" type="Script" id=4]
[ext_resource path="res://actors/player/states/motion/on_ground/Idle.gd" type="Script" id=5]
[ext_resource path="res://actors/player/states/motion/on_ground/Move.gd" type="Script" id=6]
[ext_resource path="res://actors/player/states/motion/on_ground/BumpPlayer.gd" type="Script" id=7]
[ext_resource path="res://actors/player/states/Fall.gd" type="Script" id=8]
[ext_resource path="res://actors/player/states/motion/in_air/Jump.gd" type="Script" id=9]
[ext_resource path="res://actors/player/states/combat/Stagger.gd" type="Script" id=10]
[ext_resource path="res://actors/player/states/combat/Attack.gd" type="Script" id=11]
[ext_resource path="res://actors/player/states/Die.gd" type="Script" id=12]
[ext_resource path="res://actors/player/shadow.png" type="Texture" id=13]
[ext_resource path="res://actors/weapons/sword/WeaponPivot.gd" type="Script" id=14]
[ext_resource path="res://actors/weapons/sword/Sword.tscn" type="PackedScene" id=15]
[ext_resource path="res://actors/player/body.png" type="Texture" id=16]
[ext_resource path="res://interface/fonts/SourceCodePro-Bold.ttf" type="DynamicFontData" id=17]
[ext_resource path="res://actors/player/states/debug/StateNameDisplayer.gd" type="Script" id=18]
[ext_resource path="res://actors/health/Stats.tscn" type="PackedScene" id=19]
[ext_resource path="res://core/shop/purse/Purse.tscn" type="PackedScene" id=20]
[ext_resource path="res://core/inventory/Inventory.tscn" type="PackedScene" id=21]
[ext_resource path="res://core/inventory/items/usable/potions/restore_health/MinorHealthPotion.tscn" type="PackedScene" id=22]
[ext_resource path="res://core/inventory/items/usable/potions/restore_health/StrongHealthPotion.tscn" type="PackedScene" id=23]
[ext_resource path="res://actors/weapons/bullet/BulletSpawner.gd" type="Script" id=24]
[ext_resource path="res://audio/sfx/step_01.wav" type="AudioStream" id=25]
[ext_resource path="res://audio/AudioShuffleStepSounds.gd" type="Script" id=26]
[ext_resource path="res://actors/CoinsCollector.tscn" type="PackedScene" id=27]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 31.3139
[sub_resource type="Animation" id=2]
resource_name = "SETUP"
length = 0.01
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 0, -58.8242 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("BodyPivot/Body:rotation_degrees")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ 0.0 ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("BodyPivot/Body:scale")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ) ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("Shadow:modulate")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ) ]
}
tracks/4/type = "value"
tracks/4/path = NodePath("Shadow:scale")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ) ]
}
tracks/5/type = "value"
tracks/5/path = NodePath("BodyPivot:scale")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ) ]
}
tracks/6/type = "value"
tracks/6/path = NodePath("BodyPivot:modulate")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=3]
resource_name = "bump"
length = 0.2
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.1, 0.2 ),
"transitions": PoolRealArray( 0.466516, 1, 0.466516 ),
"update": 0,
"values": [ Vector2( 0, -58.8242 ), Vector2( 0, -100 ), Vector2( 0, -58.8242 ) ]
}
[sub_resource type="Animation" id=4]
resource_name = "die"
length = 0.6
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.4 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 0, 0, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0, 0, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0, 0, 1 ), Color( 1, 1, 1, 1 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("BodyPivot:scale")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.25, 0.5 ),
"transitions": PoolRealArray( 0.326562, 0.326562, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1, 1 ), Vector2( 0, 0 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("Shadow:scale")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0, 0.25, 0.5 ),
"transitions": PoolRealArray( 0.27991, 0.27991, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1, 1 ), Vector2( 0.275362, 0.275362 ) ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("Shadow:modulate")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0, 0.25, 0.5 ),
"transitions": PoolRealArray( 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
}
[sub_resource type="Animation" id=5]
length = 1.1
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.3, 1.1 ),
"transitions": PoolRealArray( 1, 0, 1 ),
"update": 0,
"values": [ Vector2( 0, -58.8242 ), Vector2( 0, 20 ), Vector2( 0, -58.8242 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("BodyPivot/Body:scale")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.3, 1.1 ),
"transitions": PoolRealArray( 1, 0, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 0.0163307, 0.0163307 ), Vector2( 1, 1 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("Shadow:modulate")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0, 0.15, 1.1 ),
"transitions": PoolRealArray( 1, 0, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("BodyPivot/Body:modulate")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0, 0.3, 1.1 ),
"transitions": PoolRealArray( 1, 0, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 0.175781, 0.175781, 0.175781, 1 ), Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=6]
length = 0.01
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 0.466516 ),
"update": 0,
"values": [ Vector2( 0, -58.8242 ) ]
}
[sub_resource type="Animation" id=7]
length = 0.6
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.4 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 0, 0, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0, 0, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0, 0, 1 ), Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=8]
length = 0.3
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.15 ),
"transitions": PoolRealArray( 0.466516, 1.86089 ),
"update": 0,
"values": [ Vector2( 0, -58.8242 ), Vector2( 0, -75.549 ) ]
}
tracks/1/type = "method"
tracks/1/path = NodePath("Sfx/Steps")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"values": [ {
"args": [ ],
"method": "play_random"
} ]
}
tracks/2/type = "method"
tracks/2/path = NodePath("StateMachine/Move")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0.3 ),
"transitions": PoolRealArray( 1 ),
"values": [ {
"args": [ ],
"method": "spawn_dust"
} ]
}
[sub_resource type="DynamicFont" id=9]
size = 20
use_mipmaps = false
use_filter = true
font_data = ExtResource( 17 )
_sections_unfolded = [ "Font", "Settings" ]
[node name="Player" type="KinematicBody2D" index="0"]
position = Vector2( 960, 550 )
input_pickable = false
collision_layer = 1
collision_mask = 3
collision/safe_margin = 0.08
script = ExtResource( 1 )
_sections_unfolded = [ "Collision", "Transform", "Visibility" ]
__meta__ = {
"_edit_horizontal_guides_": [ ]
}
[node name="ShakingCamera" parent="." index="0" instance=ExtResource( 2 )]
[node name="HitBox" parent="." index="1" instance=ExtResource( 3 )]
monitorable = true
[node name="CollisionShape2D" parent="HitBox" index="0"]
shape = SubResource( 1 )
[node name="StateMachine" type="Node" parent="." index="2"]
script = ExtResource( 4 )
active = false
[node name="Idle" type="Node" parent="StateMachine" index="0"]
script = ExtResource( 5 )
[node name="Move" type="Node" parent="StateMachine" index="1"]
script = ExtResource( 6 )
MAX_WALK_SPEED = 450
MAX_RUN_SPEED = 700
[node name="Bump" type="Node" parent="StateMachine" index="2"]
script = ExtResource( 7 )
SPEED = 240.0
[node name="Fall" type="Node" parent="StateMachine" index="3"]
script = ExtResource( 8 )
[node name="Jump" type="Node" parent="StateMachine" index="4"]
script = ExtResource( 9 )
BASE_MAX_HORIZONTAL_SPEED = 400.0
AIR_ACCELERATION = 1000.0
AIR_DECCELERATION = 2000.0
AIR_STEERING_POWER = 50.0
JUMP_HEIGHT = 120.0
JUMP_DURATION = 0.8
GRAVITY = 1600.0
[node name="Stagger" type="Node" parent="StateMachine" index="5"]
script = ExtResource( 10 )
[node name="Attack" type="Node" parent="StateMachine" index="6"]
script = ExtResource( 11 )
[node name="Die" type="Node" parent="StateMachine" index="7"]
script = ExtResource( 12 )
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="3"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/SETUP = SubResource( 2 )
anims/bump = SubResource( 3 )
anims/die = SubResource( 4 )
anims/fall = SubResource( 5 )
anims/idle = SubResource( 6 )
anims/stagger = SubResource( 7 )
anims/walk = SubResource( 8 )
blend_times = [ ]
[node name="Shadow" type="Sprite" parent="." index="4"]
self_modulate = Color( 1, 1, 1, 0.361098 )
position = Vector2( 0.362319, -4 )
texture = ExtResource( 13 )
_sections_unfolded = [ "Transform", "Visibility" ]
[node name="BodyPivot" type="Position2D" parent="." index="5"]
_sections_unfolded = [ "Material", "Transform", "Visibility" ]
[node name="WeaponPivot" type="Position2D" parent="BodyPivot" index="0"]
position = Vector2( 0, -62 )
script = ExtResource( 14 )
_sections_unfolded = [ "Transform", "Z Index" ]
[node name="Offset" type="Position2D" parent="BodyPivot/WeaponPivot" index="0"]
position = Vector2( 110, 0 )
[node name="Sword" parent="BodyPivot/WeaponPivot/Offset" index="0" instance=ExtResource( 15 )]
[node name="Body" type="Sprite" parent="BodyPivot" index="1"]
position = Vector2( 0, -58.8242 )
texture = ExtResource( 16 )
_sections_unfolded = [ "Visibility" ]
[node name="StateNameDisplayer" type="Label" parent="BodyPivot" index="2"]
editor/display_folded = true
visible = false
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = -109.0
margin_top = -172.0
margin_right = 110.0
margin_bottom = -138.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 9 )
text = "Test"
align = 1
valign = 1
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
script = ExtResource( 18 )
_sections_unfolded = [ "Rect", "custom_fonts" ]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="6"]
build_mode = 0
polygon = PoolVector2Array( -20, 0, -20, -20, 20, -20, 20, 0 )
[node name="Health" parent="." index="7" instance=ExtResource( 19 )]
[node name="Purse" parent="." index="8" instance=ExtResource( 20 )]
coins = 32
MAXIMUM = 1000000
[node name="Inventory" parent="." index="9" instance=ExtResource( 21 )]
[node name="MinorHealthPotion" parent="Inventory" index="0" instance=ExtResource( 22 )]
amount = 4
[node name="StrongHealthPotion" parent="Inventory" index="1" instance=ExtResource( 23 )]
[node name="BulletSpawn" type="Node2D" parent="." index="10"]
position = Vector2( 1.17401, -61.266 )
script = ExtResource( 24 )
_sections_unfolded = [ "Transform" ]
[node name="CooldownTimer" type="Timer" parent="BulletSpawn" index="0"]
process_mode = 1
wait_time = 0.2
one_shot = true
autostart = false
[node name="Sfx" type="Node" parent="." index="11"]
[node name="Steps" type="AudioStreamPlayer" parent="Sfx" index="0"]
stream = ExtResource( 25 )
volume_db = -16.0
pitch_scale = 1.0
autoplay = false
mix_target = 0
bus = "Master"
script = ExtResource( 26 )
[node name="CoinsCollector" parent="." index="12" instance=ExtResource( 27 )]
[connection signal="direction_changed" from="." to="BodyPivot/WeaponPivot" method="_on_Player_direction_changed"]
[connection signal="state_changed" from="StateMachine" to="BodyPivot/StateNameDisplayer" method="_on_StateMachine_state_changed"]
[connection signal="last_moved" from="StateMachine/Move" to="StateMachine/Bump" method="_on_Move_last_moved"]
[connection signal="finished" from="StateMachine/Die" to="." method="_on_Die_finished"]
[connection signal="animation_finished" from="AnimationPlayer" to="StateMachine" method="_on_animation_finished"]
[connection signal="combo_finished" from="BodyPivot/WeaponPivot/Offset/Sword" to="StateMachine/Attack" method="_on_Sword_combo_finished"]
[connection signal="damage_taken" from="Health" to="StateMachine" method="_on_Health_damage_taken"]
[connection signal="health_depleted" from="Health" to="StateMachine" method="_on_Health_health_depleted"]
[connection signal="coins_received" from="CoinsCollector" to="Purse" method="add_coins"]
[editable path="HitBox"]
================================================
FILE: actors/player/PlayerController.gd
================================================
extends "res://actors/Actor.gd"
onready var weapon = $BodyPivot/WeaponPivot/Offset/Sword
onready var camera = $ShakingCamera
onready var state_machine = $StateMachine
onready var anim_player = $AnimationPlayer
onready var body = $BodyPivot/Body
onready var purse = $Purse
func _ready():
anim_player.play('SETUP')
state_machine.start()
func reset(target_global_position):
.reset(target_global_position)
anim_player.play('SETUP')
camera.offset = Vector2()
camera.current = true
func get_body():
return body
func take_damage_from(damage_source):
if state_machine.current_state == $StateMachine/Stagger:
return
.take_damage_from(damage_source)
$StateMachine/Stagger.knockback_direction = (damage_source.global_position - global_position).normalized()
camera.shake = true
func move(velocity):
move_and_slide(velocity, Vector2(), 5, 2)
emit_signal("position_changed", position)
if get_slide_count() == 0:
return
return get_slide_collision(0)
func fall(gap_size):
"""
Interrupts the state machine and goes to the Fall state
"""
state_machine._change_state('fall')
yield(state_machine.current_state, 'finished')
move_and_collide(-look_direction * gap_size * 1.5)
$Health.take_damage(2)
func _on_Die_finished(string):
set_dead(true)
func get_health_node():
return $Health
func get_inventory():
return $Inventory
func get_purse():
return purse
================================================
FILE: actors/player/PlayerStateMachine.gd
================================================
extends "res://utils/state/StateMachine.gd"
func _ready():
states_map = {
'idle': $Idle,
'move': $Move,
'jump': $Jump,
'bump': $Bump,
'fall': $Fall,
'stagger': $Stagger,
'attack': $Attack,
'die': $Die,
}
for state in get_children():
state.connect('finished', self, '_change_state')
func _change_state(state_name):
if current_state == states_map['die']:
set_active(false)
return
# Reset the player's jump height if transitioning away from jump to a state
# that would stop jump's update method
if current_state == states_map['jump'] and state_name in ['fall']:
current_state.height = 0
if not active:
return
if state_name in ['stagger', 'jump', 'attack']:
states_stack.push_front(states_map[state_name])
if state_name == 'jump' and current_state == $Move:
$Jump.initialize($Move.speed, $Move.velocity)
._change_state(state_name)
func _unhandled_input(event):
if event.is_action_pressed('attack'):
if current_state in [$Attack, $Stagger]:
return
_change_state('attack')
get_tree().set_input_as_handled()
return
current_state.handle_input(event)
func _on_Health_damage_taken(new_health):
_change_state('stagger')
func _on_Health_health_depleted():
_change_state('die')
================================================
FILE: actors/player/body.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/body.png-f9a1fa1c6faee90775a5169653a19c8b.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://actors/player/body.png"
dest_files=[ "res://.import/body.png-f9a1fa1c6faee90775a5169653a19c8b.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: actors/player/shadow.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/shadow.png-a76d0d66e7c861fcbe21472ca29df610.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://actors/player/shadow.png"
dest_files=[ "res://.import/shadow.png-a76d0d66e7c861fcbe21472ca29df610.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: actors/player/states/Die.gd
================================================
extends "res://utils/state/State.gd"
func enter():
owner.set_dead(true)
owner.get_node("AnimationPlayer").play("die")
func _on_animation_finished(anim_name):
emit_signal("finished", "none")
================================================
FILE: actors/player/states/Fall.gd
================================================
extends "res://utils/state/State.gd"
func enter():
owner.get_node('AnimationPlayer').play('fall')
func _on_animation_finished(anim_name):
emit_signal('finished', 'idle')
================================================
FILE: actors/player/states/combat/Attack.gd
================================================
"""
The stagger state end with the stagger animation from the AnimationPlayer
The animation only affects the Body Sprite"s modulate property so
it could stack with other animations if we had two AnimationPlayer nodes
"""
extends "res://utils/state/State.gd"
func enter():
owner.get_node("AnimationPlayer").play("idle")
owner.weapon.attack()
func _on_Sword_combo_finished():
emit_signal("finished", "previous")
================================================
FILE: actors/player/states/combat/Stagger.gd
================================================
"""
The stagger state end with the stagger animation from the AnimationPlayer
The animation only affects the Body Sprite"s modulate property so
it could stack with other animations if we had two AnimationPlayer nodes
"""
extends "res://utils/state/State.gd"
var knockback_direction = Vector2()
func enter():
owner.get_node("AnimationPlayer").play("stagger")
func _on_animation_finished(anim_name):
owner.get_body().modulate = Color('#ffffff')
emit_signal("finished", "previous")
================================================
FILE: actors/player/states/debug/StateNameDisplayer.gd
================================================
extends Label
func _on_StateMachine_state_changed(current_state):
text = current_state.name
================================================
FILE: actors/player/states/motion/Motion.gd
================================================
# Collection of important methods to handle direction and animation
extends "res://utils/state/State.gd"
func handle_input(event):
if event.is_action_pressed("discrete_move_left") or Input.is_action_pressed("joy_move_left") \
or event.is_action_pressed("discrete_move_right") or Input.is_action_pressed("joy_move_right") \
or event.is_action_pressed("discrete_move_up") or Input.is_action_pressed("joy_move_up") \
or event.is_action_pressed("discrete_move_down") or Input.is_action_pressed("joy_move_down"):
get_tree().set_input_as_handled()
func get_input_direction():
var input_direction = Vector2()
input_direction.x = \
int(Input.is_action_pressed("discrete_move_right") or Input.is_action_pressed("joy_move_right")) - \
int(Input.is_action_pressed("discrete_move_left") or Input.is_action_pressed("joy_move_left"))
input_direction.y = \
int(Input.is_action_pressed("discrete_move_down") or Input.is_action_pressed("joy_move_down")) - \
int(Input.is_action_pressed("discrete_move_up") or Input.is_action_pressed("joy_move_up"))
return input_direction
func update_look_direction(direction):
if direction and owner.look_direction != direction:
owner.look_direction = direction
================================================
FILE: actors/player/states/motion/in_air/Jump.gd
================================================
extends "../Motion.gd"
export(float) var BASE_MAX_HORIZONTAL_SPEED = 400.0
export(float) var AIR_ACCELERATION = 1000.0
export(float) var AIR_DECCELERATION = 2000.0
export(float) var AIR_STEERING_POWER = 50.0
export(float) var JUMP_HEIGHT = 120.0
export(float) var JUMP_DURATION = 0.8
export(float) var GRAVITY = 1600.0
var enter_velocity = Vector2()
var max_horizontal_speed = 0.0
var horizontal_speed = 0.0
var horizontal_velocity = Vector2()
var vertical_speed = 0.0
var height = 0.0 setget set_height
func initialize(speed, velocity):
horizontal_speed = speed
max_horizontal_speed = speed if speed > 0.0 else BASE_MAX_HORIZONTAL_SPEED
enter_velocity = velocity
func enter():
var input_direction = get_input_direction()
update_look_direction(input_direction)
horizontal_velocity = enter_velocity if input_direction else Vector2()
vertical_speed = 600.0
owner.get_node("AnimationPlayer").play("idle")
func update(delta):
var input_direction = get_input_direction()
update_look_direction(input_direction)
move_horizontally(delta, input_direction)
animate_jump_height(delta)
if height <= 0.0:
emit_signal("finished", "previous")
func move_horizontally(delta, direction):
if direction:
horizontal_speed += AIR_ACCELERATION * delta
else:
horizontal_speed -= AIR_DECCELERATION * delta
horizontal_speed = clamp(horizontal_speed, 0, max_horizontal_speed)
var target_velocity = horizontal_speed * direction.normalized()
var steering_velocity = (target_velocity - horizontal_velocity).normalized() * AIR_STEERING_POWER
horizontal_velocity += steering_velocity
owner.move_and_slide(horizontal_velocity)
owner.emit_signal("position_changed", owner.position)
func set_height(new_height):
height = new_height
owner.get_node("BodyPivot").position.y = -height
func animate_jump_height(delta):
vertical_speed -= GRAVITY * delta
set_height(max(0.0, height + vertical_speed * delta))
================================================
FILE: actors/player/states/motion/on_ground/BumpPlayer.gd
================================================
extends "res://utils/state/State.gd"
export(float) var SPEED = 240.0
var direction = Vector2(-1.0, 0.0)
func _on_Move_last_moved(moved_direction):
direction = -moved_direction
func enter():
owner.get_node('AnimationPlayer').play('bump')
func update(delta):
owner.move_and_slide(direction * SPEED)
func _on_animation_finished(anim_name):
emit_signal('finished', 'idle')
================================================
FILE: actors/player/states/motion/on_ground/Idle.gd
================================================
extends "OnGround.gd"
func enter():
owner.get_node("AnimationPlayer").play("idle")
func handle_input(event):
return .handle_input(event)
func update(delta):
var input_direction = get_input_direction()
if input_direction:
emit_signal("finished", "move")
================================================
FILE: actors/player/states/motion/on_ground/Move.gd
================================================
extends "OnGround.gd"
signal last_moved(direction)
export(float) var MAX_WALK_SPEED = 450
export(float) var MAX_RUN_SPEED = 700
const DustRun = preload("res://vfx/particles/dust_puffs/DustRun.tscn")
const DustWalk = preload("res://vfx/particles/dust_puffs/DustWalk.tscn")
func enter():
speed = 0.0
velocity = Vector2()
var input_direction = get_input_direction()
update_look_direction(input_direction)
owner.get_node("AnimationPlayer").play("walk")
func exit():
owner.get_node("AnimationPlayer").play("idle")
func handle_input(event):
return .handle_input(event)
func update(delta):
var input_direction = get_input_direction()
if not input_direction:
emit_signal("finished", "idle")
update_look_direction(input_direction)
speed = MAX_RUN_SPEED if Input.is_action_pressed("run") else MAX_WALK_SPEED
velocity = input_direction.normalized() * speed
var collision_info = owner.move(velocity)
if not collision_info:
return
if speed == MAX_RUN_SPEED and collision_info.collider.is_in_group("environment"):
emit_signal("last_moved", input_direction)
emit_signal("finished", 'bump')
func spawn_dust():
var dust
match speed:
MAX_RUN_SPEED:
dust = DustRun.instance()
MAX_WALK_SPEED:
dust = DustWalk.instance()
owner.add_child(dust)
dust.start()
================================================
FILE: actors/player/states/motion/on_ground/OnGround.gd
================================================
extends "../Motion.gd"
var speed = 0.0
var velocity = Vector2()
func handle_input(event):
if event.is_action_pressed("jump"):
emit_signal("finished", "jump")
return .handle_input(event)
================================================
FILE: actors/shadow.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/shadow.png-c2c688bd1e688f17d176ab7d3afdad57.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://actors/shadow.png"
dest_files=[ "res://.import/shadow.png-c2c688bd1e688f17d176ab7d3afdad57.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: actors/weapons/bullet/Bullet.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://actors/weapons/bullet/bullet.gd" type="Script" id=1]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 12.0
[node name="Bullet" type="KinematicBody2D" index="0"]
input_pickable = false
collision_layer = 2
collision_mask = 2
collision/safe_margin = 0.08
script = ExtResource( 1 )
_sections_unfolded = [ "Collision", "collision" ]
SPEED = 1000.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="0"]
shape = SubResource( 1 )
================================================
FILE: actors/weapons/bullet/BulletSpawner.gd
================================================
extends Node2D
var bullet = preload("Bullet.tscn")
func _input(event):
if event.is_action_pressed("fire"):
fire(owner.look_direction)
func fire(direction):
if not $CooldownTimer.is_stopped():
return
$CooldownTimer.start()
var new_bullet = bullet.instance()
new_bullet.direction = direction
add_child(new_bullet)
================================================
FILE: actors/weapons/bullet/bullet.gd
================================================
extends KinematicBody2D
var direction = Vector2()
export(float) var SPEED = 1000.0
func _ready():
set_as_toplevel(true)
func _physics_process(delta):
if is_outside_view_bounds():
queue_free()
var motion = direction * SPEED * delta
var collision_info = move_and_collide(motion)
if collision_info:
queue_free()
func is_outside_view_bounds():
return position.x > OS.get_screen_size().x or position.x < 0.0 \
or position.y > OS.get_screen_size().y or position.y < 0.0
func _draw():
draw_circle(Vector2(), $CollisionShape2D.shape.radius, Color('#ffffff'))
================================================
FILE: actors/weapons/sword/Sword.gd
================================================
extends "res://actors/DamageSource.gd"
signal combo_finished()
enum States { IDLE, ATTACK }
var state = null
enum AttackInputStates { WAITING, LISTENING, REGISTERED }
var attack_input_state = AttackInputStates.WAITING
var ready_for_next_attack = false
var attack_id = 0
var combo = [
{
'damage': 1,
'animation': 'attack_fast',
},
{
'damage': 1,
'animation': 'attack_fast',
},
{
'damage': 3,
'animation': 'attack_medium',
}]
func _ready():
$AnimationPlayer.connect('animation_finished', self, "_on_animation_finished")
_change_state(States.IDLE)
func _change_state(new_state):
match state:
States.IDLE:
visible = true
match new_state:
States.IDLE:
attack_id = 0
visible = false
States.ATTACK:
attack_input_state = AttackInputStates.WAITING
ready_for_next_attack = false
var attack = combo[min(attack_id, combo.size() - 1)]
damage = attack['damage']
$AnimationPlayer.play(attack['animation'])
attack_id += 1
state = new_state
func _input(event):
if not state == States.ATTACK:
return
if attack_input_state != AttackInputStates.LISTENING:
return
if event.is_action_pressed('attack'):
attack_input_state = AttackInputStates.REGISTERED
func _physics_process(delta):
if attack_input_state == AttackInputStates.REGISTERED and ready_for_next_attack:
attack()
func attack():
_change_state(States.ATTACK)
# use with AnimationPlayer func track
func set_attack_input_listening():
attack_input_state = AttackInputStates.LISTENING
# use with AnimationPlayer func track
func set_ready_for_next_attack():
ready_for_next_attack = true
func _on_animation_finished(name):
if attack_input_state == AttackInputStates.REGISTERED and attack_id < combo.size():
attack()
else:
_change_state(States.IDLE)
emit_signal("combo_finished")
================================================
FILE: actors/weapons/sword/Sword.tscn
================================================
[gd_scene load_steps=8 format=2]
[ext_resource path="res://actors/weapons/sword/Sword.gd" type="Script" id=1]
[ext_resource path="res://actors/weapons/sword/sword.png" type="Texture" id=2]
[sub_resource type="Animation" id=1]
resource_name = "SETUP"
length = 0.01
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ 0.0 ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:scale")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath(".:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ true ]
}
tracks/3/type = "value"
tracks/3/path = NodePath(".:monitoring")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ true ]
}
tracks/4/type = "value"
tracks/4/path = NodePath(".:monitorable")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ false ]
}
tracks/5/type = "value"
tracks/5/path = NodePath("CollisionPolygon2D:disabled")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ true ]
}
[sub_resource type="Animation" id=2]
resource_name = "attack_circular"
length = 0.3
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.15, 0.2 ),
"transitions": PoolRealArray( 0.439427, 1, 1 ),
"update": 0,
"values": [ -100.0, 100.0, 90.0 ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:scale")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.05, 0.15, 0.2 ),
"transitions": PoolRealArray( 1, 2.50795, 1, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1, 1.3 ), Vector2( 1, 1 ), Vector2( 1, 1 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath(".:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ true ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("CollisionPolygon2D:disabled")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0, 0.2 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ false, true ]
}
[sub_resource type="Animation" id=3]
length = 0.45
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.15, 0.2 ),
"transitions": PoolRealArray( 0.439427, 1, 1 ),
"update": 0,
"values": [ -80.0, 85.0, 75.0 ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:scale")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.05, 0.15, 0.2 ),
"transitions": PoolRealArray( 1, 2.50795, 1, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1, 1.3 ), Vector2( 1, 1 ), Vector2( 1, 1 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath(".:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ true ]
}
tracks/3/type = "method"
tracks/3/path = NodePath(".")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0.1, 0.25 ),
"transitions": PoolRealArray( 1, 1 ),
"values": [ {
"args": [ ],
"method": "set_attack_input_listening"
}, {
"args": [ ],
"method": "set_ready_for_next_attack"
} ]
}
tracks/4/type = "value"
tracks/4/path = NodePath("CollisionPolygon2D:disabled")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/keys = {
"times": PoolRealArray( 0, 0.2 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ false, true ]
}
[sub_resource type="Animation" id=4]
resource_name = "attack_medium"
length = 0.5
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0.05, 0.25, 0.35 ),
"transitions": PoolRealArray( 0.439427, 1, 1 ),
"update": 0,
"values": [ 95.0, -95.0, -90.0 ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:scale")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.1, 0.2, 0.25 ),
"transitions": PoolRealArray( 1, 2.50795, 1, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1, 1.3 ), Vector2( 1, 1 ), Vector2( 1, 1 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath(".:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ true ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("CollisionPolygon2D:disabled")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0, 0.35 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ false, true ]
}
[sub_resource type="Animation" id=5]
length = 0.01
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:visible")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ false ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("CollisionPolygon2D:disabled")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ true ]
}
[node name="Sword" type="Area2D"]
rotation = 1.5708
input_pickable = false
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitoring = false
collision_layer = 16
collision_mask = 8
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Collision", "Transform" ]
damage = 2
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="0"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/SETUP = SubResource( 1 )
anims/attack_circular = SubResource( 2 )
anims/attack_fast = SubResource( 3 )
anims/attack_medium = SubResource( 4 )
anims/idle = SubResource( 5 )
blend_times = [ ]
_sections_unfolded = [ "Playback Options" ]
[node name="sword" type="Sprite" parent="." index="1"]
position = Vector2( 4, 0 )
texture = ExtResource( 2 )
offset = Vector2( 67, 0 )
_sections_unfolded = [ "Offset", "Transform" ]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="2"]
build_mode = 0
polygon = PoolVector2Array( 32, -112, 128, -80, 160, 0, 128, 80, 32, 112 )
disabled = true
================================================
FILE: actors/weapons/sword/WeaponPivot.gd
================================================
extends Position2D
func _on_Player_direction_changed(new_direction):
rotation = new_direction.angle()
show_behind_parent = new_direction == Vector2(0, -1)
================================================
FILE: actors/weapons/sword/sword.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/sword.png-2705643189a083599451044bb61b43fc.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://actors/weapons/sword/sword.png"
dest_files=[ "res://.import/sword.png-2705643189a083599451044bb61b43fc.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: audio/AudioShuffleStepSounds.gd
================================================
extends AudioStreamPlayer
# In Godot 3.1 you can export the Array instead
var samples = [
preload("res://audio/sfx/step_01.wav"),
preload("res://audio/sfx/step_02.wav")
]
func _ready():
randomize()
func play_random():
# In Godot 3.1 you can use Array.shuffle() after going through the sounds
stream = samples[randi() % samples.size()]
play()
================================================
FILE: audio/AudioStreamPlayer.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://audio/AudioShuffleStepSounds.gd" type="Script" id=1]
[node name="AudioStreamPlayer" type="AudioStreamPlayer"]
stream = null
volume_db = 0.0
pitch_scale = 1.0
autoplay = false
mix_target = 0
bus = "Master"
script = ExtResource( 1 )
================================================
FILE: audio/MusicPlayer.gd
================================================
extends AudioStreamPlayer
func _ready():
play()
================================================
FILE: audio/MusicPlayer.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://audio/music/birdy_pong.ogg" type="AudioStream" id=1]
[node name="MusicPlayer" type="AudioStreamPlayer"]
pause_mode = 2
stream = ExtResource( 1 )
volume_db = 0.0
pitch_scale = 1.0
autoplay = false
mix_target = 0
bus = "Music"
_sections_unfolded = [ "Pause" ]
================================================
FILE: audio/music/birdy_pong.ogg.import
================================================
[remap]
importer="ogg_vorbis"
type="AudioStreamOGGVorbis"
path="res://.import/birdy_pong.ogg-25193f4693fd63a5305fa3c526808da0.oggstr"
[deps]
source_file="res://audio/music/birdy_pong.ogg"
dest_files=[ "res://.import/birdy_pong.ogg-25193f4693fd63a5305fa3c526808da0.oggstr" ]
[params]
loop=true
loop_offset=-2.65
================================================
FILE: audio/sfx/menu_confirm.wav.import
================================================
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/menu_confirm.wav-b14347e8ceccbb161b72ec9db2392e19.sample"
[deps]
source_file="res://audio/sfx/menu_confirm.wav"
dest_files=[ "res://.import/menu_confirm.wav-b14347e8ceccbb161b72ec9db2392e19.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=true
edit/normalize=true
edit/loop=false
compress/mode=0
================================================
FILE: audio/sfx/menu_navigate_01.wav.import
================================================
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/menu_navigate_01.wav-773eee8fbe1dd9eb11962e36b57bc664.sample"
[deps]
source_file="res://audio/sfx/menu_navigate_01.wav"
dest_files=[ "res://.import/menu_navigate_01.wav-773eee8fbe1dd9eb11962e36b57bc664.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=true
edit/normalize=true
edit/loop=false
compress/mode=0
================================================
FILE: audio/sfx/menu_navigate_02.wav.import
================================================
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/menu_navigate_02.wav-671622ef2a874b5827dcda32ef1e01ba.sample"
[deps]
source_file="res://audio/sfx/menu_navigate_02.wav"
dest_files=[ "res://.import/menu_navigate_02.wav-671622ef2a874b5827dcda32ef1e01ba.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=true
edit/normalize=true
edit/loop=false
compress/mode=0
================================================
FILE: audio/sfx/menu_popup_open.wav.import
================================================
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/menu_popup_open.wav-51859fa0446f42584709772f4d8e8405.sample"
[deps]
source_file="res://audio/sfx/menu_popup_open.wav"
dest_files=[ "res://.import/menu_popup_open.wav-51859fa0446f42584709772f4d8e8405.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=true
edit/normalize=true
edit/loop=false
compress/mode=0
================================================
FILE: audio/sfx/step_01.wav.import
================================================
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/step_01.wav-daf925df75ada545cb636d177cd40f57.sample"
[deps]
source_file="res://audio/sfx/step_01.wav"
dest_files=[ "res://.import/step_01.wav-daf925df75ada545cb636d177cd40f57.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=true
edit/normalize=true
edit/loop=false
compress/mode=0
================================================
FILE: audio/sfx/step_02.wav.import
================================================
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/step_02.wav-f7737a1e06e1f3d2e9e00fd041d0652d.sample"
[deps]
source_file="res://audio/sfx/step_02.wav"
dest_files=[ "res://.import/step_02.wav-f7737a1e06e1f3d2e9e00fd041d0652d.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=true
edit/normalize=true
edit/loop=false
compress/mode=0
================================================
FILE: core/Game.gd
================================================
extends Node
onready var level_loader = $LevelLoader
onready var transition = $Overlays/TransitionColor
onready var pause_menu = $Interface/PauseMenu
onready var tree = get_tree()
func _ready():
$Interface.initialize($LevelLoader/Player)
level_loader.initialize()
for door in level_loader.get_doors():
door.connect("player_entered", self, "_on_Door_player_entered")
func change_level(scene_path):
tree.paused = true
yield(transition.fade_to_color(), "completed")
level_loader.change_level(scene_path)
for door in level_loader.get_doors():
door.connect("player_entered", self, "_on_Door_player_entered")
yield(transition.fade_from_color(), "completed")
tree.paused = false
func _on_Door_player_entered(target_map):
change_level(target_map)
func _unhandled_input(event):
if event.is_action_pressed("pause"):
pause()
tree.set_input_as_handled()
if event.is_action_pressed("toggle_fullscreen"):
OS.window_fullscreen = not OS.window_fullscreen
func pause():
tree.paused = true
pause_menu.open()
yield(pause_menu, "closed")
tree.paused = false
func _on_ShopMenu_open():
tree.paused = true
func _on_ShopMenu_closed():
tree.paused = false
================================================
FILE: core/LevelLoader.gd
================================================
extends Node
signal loaded(level)
export(String, FILE, "*.tscn") var LEVEL_START
var map
onready var player = $Player
func initialize():
remove_child(player)
change_level(LEVEL_START)
func change_level(scene_path):
if map:
map.get_ysort_node().remove_child(player)
remove_child(map)
map.queue_free()
map = load(scene_path).instance()
add_child(map)
map.get_ysort_node().add_child(player)
var spawn = map.get_node("PlayerSpawningPoint")
player.reset(spawn.global_position)
for monster in get_tree().get_nodes_in_group("monster"):
monster.initialize(player)
map.initialize()
emit_signal("loaded", map)
func get_doors():
var doors = []
for door in get_tree().get_nodes_in_group("doors"):
if not map.is_a_parent_of(door):
continue
doors.append(door)
return doors
================================================
FILE: core/inventory/Inventory.gd
================================================
extends Node
signal content_changed(items_as_string)
signal item_added(item)
signal item_removed(item)
func get_items():
return get_children()
func find_item(reference):
for item in get_items():
if item.name == reference.name:
return item
func has(item):
return true if find_item(item) else false
func get_count(reference):
var item = find_item(reference)
return item.amount if item else 0
func add(reference, amount=1):
var item = find_item(reference)
if not item:
item = _instance_item_from_db(reference)
amount -= item.amount
item.amount += amount
emit_signal("content_changed", get_content_as_string())
func trash(reference, amount=1):
var item = find_item(reference)
if not item:
return
item.amount -= amount
emit_signal("content_changed", get_content_as_string())
func use(item, user):
item.use(user)
emit_signal("content_changed", get_content_as_string())
func get_content_as_string():
var string = ""
for item in get_items():
if item.amount == 0:
continue
string += "%s: %s" % [item.name, item.amount]
string += "\n"
return string
func _instance_item_from_db(reference):
var item = ItemDatabase.get_item(reference)
add_child(item)
item.connect("depleted", self, "_on_Item_depleted", [item])
emit_signal("item_added", item)
return item
func _on_Item_depleted(item):
emit_signal("item_removed", item)
================================================
FILE: core/inventory/Inventory.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://core/inventory/Inventory.gd" type="Script" id=1]
[node name="Inventory" type="Node"]
script = ExtResource( 1 )
================================================
FILE: core/inventory/ItemDatabase.gd
================================================
extends Node
func get_item(reference):
for item in get_children():
if reference.name == item.name:
return item.duplicate()
func get_items():
return get_children()
================================================
FILE: core/inventory/ItemDatabase.tscn
================================================
[gd_scene load_steps=6 format=2]
[ext_resource path="res://core/inventory/ItemDatabase.gd" type="Script" id=1]
[ext_resource path="res://core/inventory/items/equipment/sword/Sword.tscn" type="PackedScene" id=2]
[ext_resource path="res://core/inventory/items/usable/potions/restore_health/MinorHealthPotion.tscn" type="PackedScene" id=3]
[ext_resource path="res://core/inventory/items/usable/potions/restore_health/StrongHealthPotion.tscn" type="PackedScene" id=4]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/FireballScroll.tscn" type="PackedScene" id=5]
[node name="ItemDatabase" type="Node"]
script = ExtResource( 1 )
[node name="Sword" parent="." index="0" instance=ExtResource( 2 )]
[node name="MinorHealthPotion" parent="." index="1" instance=ExtResource( 3 )]
[node name="StrongHealthPotion" parent="." index="2" instance=ExtResource( 4 )]
[node name="FireballScroll" parent="." index="3" instance=ExtResource( 5 )]
================================================
FILE: core/inventory/items/Coins.gd
================================================
tool
extends Area2D
enum CoinAmounts {SMALL=10, MID=30, HIGH=100}
export(CoinAmounts) var amount = CoinAmounts.SMALL setget set_amount
export(float) var MAX_START_VERTICAL_THRUST = 400.0
export(float) var MAX_HORIZONTAL_SPEED = 200.0
export(float) var GRAVITY = 2000.0
export(float) var STOP_THRESHOLD_VERTICAL_SPEED = 4.0
export(float, 0.0, 1.0) var DAMPING_FACTOR = 0.4
onready var sprite = $coins
var direction = Vector2()
var velocity = Vector2()
var speed_horizontal = 0.0
var speed_vertical = 0.0
var height = 0.0 setget set_height
var TEXTURES = {
CoinAmounts.SMALL: preload("res://core/inventory/items/coins/coin_single.png"),
CoinAmounts.MID: preload("res://core/inventory/items/coins/coins_three.png"),
CoinAmounts.HIGH: preload("res://core/inventory/items/coins/coins_stack.png"),
}
func set_amount(value):
amount = value
if not sprite:
return
sprite.texture = TEXTURES[value]
func _ready():
set_process(false)
func throw():
var rand_angle = randf() * 2 * PI
direction = Vector2(
cos(rand_angle),
sin(rand_angle))
speed_vertical = (randf() * 0.5 + 0.5) * MAX_START_VERTICAL_THRUST
speed_horizontal = (randf() * 0.8 + 0.2) * MAX_HORIZONTAL_SPEED
$Timer.wait_time = rand_range(1.0, 2.0)
$Timer.start()
set_process(true)
func _process(delta):
# Move horizontally
var speed_scale = $Timer.time_left / $Timer.wait_time
velocity = speed_horizontal * direction * speed_scale
position += velocity * delta
# Move vertically
speed_vertical -= GRAVITY * delta
var distance_vertical = speed_vertical * delta
self.height += distance_vertical
if height < 0.0:
self.height = 0.0
set_process(false)
func set_height(value):
height = value
if is_processing():
$coins.position.y = -height
func set_random_amount():
var amounts = [CoinAmounts.SMALL, CoinAmounts.MID, CoinAmounts.HIGH]
self.amount = amounts[randi() % amounts.size()]
# TODO: won't work as currently velocity is re-calculated on every process tick
#func steer_towards(target_global_position):
# velocity = Steering.follow(
# velocity,
# global_position,
# target_global_position,
# MAX_HORIZONTAL_SPEED)
================================================
FILE: core/inventory/items/Coins.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://core/inventory/items/Coins.gd" type="Script" id=1]
[ext_resource path="res://core/inventory/items/coins/coin_single.png" type="Texture" id=2]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 25.1241
[node name="Coins" type="Area2D" index="0"]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitoring = false
collision_layer = 64
collision_mask = 0
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Audio Bus", "Collision" ]
amount = 10
MAX_START_VERTICAL_THRUST = 700.0
MAX_HORIZONTAL_SPEED = 200.0
GRAVITY = 1000.0
STOP_THRESHOLD_VERTICAL_SPEED = 3.0
DAMPING_FACTOR = 0.6
[node name="coins" type="Sprite" parent="." index="0"]
texture = ExtResource( 2 )
_sections_unfolded = [ "Transform" ]
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="1"]
shape = SubResource( 1 )
[node name="Timer" type="Timer" parent="." index="2"]
process_mode = 1
wait_time = 1.0
one_shot = true
autostart = false
================================================
FILE: core/inventory/items/Item.gd
================================================
extends Node
signal amount_changed(amount)
signal depleted()
export(Texture) var icon
export(String) var display_name = ""
export(String) var description = ""
export(int) var price = 100
export(int) var amount = 1 setget set_amount
export(bool) var unique = false
export(bool) var usable = true
func use(user):
if (not usable) or unique:
return
if amount == 0:
return
self.amount -= 1
_apply_effect(user)
func set_amount(value):
amount = max(0, value)
emit_signal("amount_changed", amount)
if amount == 0:
queue_free()
emit_signal("depleted")
func _apply_effect(user):
print("Item %s has no apply_effect override" % name)
================================================
FILE: core/inventory/items/Item.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://core/inventory/items/Item.gd" type="Script" id=1]
[ext_resource path="res://icon.png" type="Texture" id=2]
[node name="Item" type="Node" index="0"]
script = ExtResource( 1 )
icon = ExtResource( 2 )
display_name = ""
description = ""
price = 100
amount = 1
unique = false
usable = true
================================================
FILE: core/inventory/items/coins/coin_single.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/coin_single.png-d22b36184b3f7cd2e981df8d72015e0f.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/inventory/items/coins/coin_single.png"
dest_files=[ "res://.import/coin_single.png-d22b36184b3f7cd2e981df8d72015e0f.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/inventory/items/coins/coins_stack.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/coins_stack.png-b4644d39c8e95f1e5c2242620e4272e4.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/inventory/items/coins/coins_stack.png"
dest_files=[ "res://.import/coins_stack.png-b4644d39c8e95f1e5c2242620e4272e4.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/inventory/items/coins/coins_three.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/coins_three.png-29938721d7b59c8b32b7201678affe18.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/inventory/items/coins/coins_three.png"
dest_files=[ "res://.import/coins_three.png-29938721d7b59c8b32b7201678affe18.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/inventory/items/equipment/Equipment.gd
================================================
extends '../Item.gd'
export(int) var STRENGTH = 0
export(int) var MAGIC = 0
export(int) var ARMOR = 0
export(int) var SPEED = 0
================================================
FILE: core/inventory/items/equipment/Equipment.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://core/inventory/items/Item.tscn" type="PackedScene" id=1]
[ext_resource path="res://core/inventory/items/equipment/Equipment.gd" type="Script" id=2]
[node name="Equipment" index="0" instance=ExtResource( 1 )]
script = ExtResource( 2 )
icon = null
STRENGTH = 0
MAGIC = 0
ARMOR = 0
SPEED = 0
================================================
FILE: core/inventory/items/equipment/sword/Sword.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://core/inventory/items/equipment/Equipment.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/theme/icons/sword.png" type="Texture" id=2]
[node name="Sword" index="0" instance=ExtResource( 1 )]
icon = ExtResource( 2 )
display_name = "Sword"
description = "An old, slightly rusted sword. Fairly dull."
price = 25
usable = false
STRENGTH = 20
================================================
FILE: core/inventory/items/usable/potions/BaseHealthPotion.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://core/inventory/items/Item.tscn" type="PackedScene" id=1]
[ext_resource path="res://core/inventory/items/usable/potions/HealthPotion.gd" type="Script" id=2]
[node name="HealthPotion" index="0" instance=ExtResource( 1 )]
script = ExtResource( 2 )
icon = null
price = 20
HEAL_AMOUNT = 20
================================================
FILE: core/inventory/items/usable/potions/HealthPotion.gd
================================================
extends "res://core/inventory/items/Item.gd"
export(int) var HEAL_AMOUNT = 20
func _apply_effect(user):
if not user.has_node("Health"):
return
user.get_node("Health").heal(HEAL_AMOUNT)
user.get_node("AnimationPlayer").play("heal")
================================================
FILE: core/inventory/items/usable/potions/restore_health/MinorHealthPotion.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://core/inventory/items/usable/potions/BaseHealthPotion.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/theme/icons/potion_health.png" type="Texture" id=2]
[node name="MinorHealthPotion" index="0" instance=ExtResource( 1 )]
icon = ExtResource( 2 )
display_name = "Minor health potion"
description = "Heals 10 life points"
amount = 1
HEAL_AMOUNT = 10
================================================
FILE: core/inventory/items/usable/potions/restore_health/StrongHealthPotion.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://core/inventory/items/usable/potions/BaseHealthPotion.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/theme/icons/potion_health.png" type="Texture" id=2]
[node name="StrongHealthPotion" index="0" instance=ExtResource( 1 )]
icon = ExtResource( 2 )
display_name = "Strong health potion"
description = "Heals 50 life points"
price = 100
HEAL_AMOUNT = 50
================================================
FILE: core/inventory/items/usable/scroll_fireball/FireballScroll.gd
================================================
extends "res://core/inventory/items/Item.gd"
export(PackedScene) var Fireball
func _apply_effect(user):
var fireball = Fireball.instance()
user.add_child(fireball)
================================================
FILE: core/inventory/items/usable/scroll_fireball/FireballScroll.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://core/inventory/items/Item.tscn" type="PackedScene" id=1]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/FireballScroll.gd" type="Script" id=2]
[ext_resource path="res://interface/theme/icons/fire_scroll.png" type="Texture" id=3]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/Fireball.tscn" type="PackedScene" id=4]
[node name="FireballScroll" index="0" instance=ExtResource( 1 )]
script = ExtResource( 2 )
icon = ExtResource( 3 )
display_name = "Fire scroll"
description = "Launches a fire ball that sweeps through the air and damages a single target."
Fireball = ExtResource( 4 )
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/Fireball.gd
================================================
extends Area2D
export(PackedScene) var Explosion
export(float) var SPEED = 1000.0
var direction = Vector2(1, 0)
func _physics_process(delta):
position += direction * SPEED * delta
func _on_body_entered(body):
explode()
func _on_area_entered(area):
explode()
func explode():
set_active(false)
var explosion_node = Explosion.instance()
add_child(explosion_node)
get_tree().create_timer(explosion_node.lifetime * 2.0).connect("timeout", self, "queue_free")
func set_active(value):
set_physics_process(value)
$CollisionShape2D.disabled = value
$Fireball.active = value
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/Fireball.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/Fireball.gd" type="Script" id=1]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/explosions/Explosion.tscn" type="PackedScene" id=2]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/FireballParticles.tscn" type="PackedScene" id=3]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 31.9831
[node name="Fireball" type="Area2D"]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
collision_layer = 8
collision_mask = 6
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Collision" ]
Explosion = ExtResource( 2 )
SPEED = 1400.0
[node name="Fireball" parent="." index="0" instance=ExtResource( 3 )]
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="1"]
shape = SubResource( 1 )
[connection signal="area_entered" from="." to="." method="_on_area_entered"]
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/FireballParticles.tscn
================================================
[gd_scene load_steps=13 format=2]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/fireball/fireball.material" type="Material" id=1]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/smoke_clouds.png" type="Texture" id=2]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/ParticlesToggle.gd" type="Script" id=3]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/sparkles_small.tres" type="Gradient" id=4]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/circle.png" type="Texture" id=5]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/sparkles.tres" type="Gradient" id=6]
[sub_resource type="GradientTexture" id=1]
flags = 4
gradient = ExtResource( 4 )
width = 2048
[sub_resource type="Curve" id=2]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.399763 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=3]
flags = 4
width = 2048
curve = SubResource( 2 )
[sub_resource type="ParticlesMaterial" id=4]
render_priority = 0
trail_divisor = 1
emission_shape = 1
emission_sphere_radius = 24.0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 120.0
flatness = 0.0
gravity = Vector3( 0, 500, 0 )
initial_velocity = 200.0
initial_velocity_random = 0.6
angular_velocity = 0.0
angular_velocity_random = 0.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = 0.0
linear_accel_random = 0.0
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 100.0
tangential_accel_random = 0.0
damping = 0.0
damping_random = 0.0
angle = 0.0
angle_random = 0.0
scale = 0.06
scale_random = 0.0
scale_curve = SubResource( 3 )
color_ramp = SubResource( 1 )
hue_variation = 0.0
hue_variation_random = 0.0
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 0.0
anim_offset_random = 0.0
anim_loop = false
_sections_unfolded = [ "Color", "Gravity", "Scale", "Tangential Accel" ]
[sub_resource type="GradientTexture" id=5]
flags = 4
gradient = ExtResource( 6 )
width = 2048
[sub_resource type="ParticlesMaterial" id=6]
render_priority = 0
trail_divisor = 1
emission_shape = 1
emission_sphere_radius = 24.0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 120.0
flatness = 0.0
gravity = Vector3( 0, 450, 0 )
initial_velocity = 200.0
initial_velocity_random = 0.6
angular_velocity = 0.0
angular_velocity_random = 0.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = 0.0
linear_accel_random = 0.0
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 100.0
tangential_accel_random = 0.0
damping = 0.0
damping_random = 0.0
angle = 0.0
angle_random = 0.0
scale = 0.08
scale_random = 0.0
scale_curve = SubResource( 3 )
color_ramp = SubResource( 5 )
hue_variation = 0.0
hue_variation_random = 0.0
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 0.0
anim_offset_random = 0.0
anim_loop = false
_sections_unfolded = [ "Color", "Gravity", "Scale" ]
[node name="FireballParticles" type="Particles2D" index="0"]
emitting = true
amount = 300
lifetime = 0.4
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.0
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 1
process_material = ExtResource( 1 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 2
v_frames = 1
script = ExtResource( 3 )
_sections_unfolded = [ "Process Material", "Time", "Transform" ]
active = true
[node name="SmallSparkles" type="Particles2D" parent="." index="0"]
rotation = -1.61079
emitting = true
amount = 40
lifetime = 0.6
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.2
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 0
process_material = SubResource( 4 )
texture = ExtResource( 5 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time" ]
[node name="TinySparkles" type="Particles2D" parent="." index="1"]
rotation = -1.61079
emitting = true
amount = 60
lifetime = 0.6
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.2
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 0
process_material = SubResource( 6 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 2
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time" ]
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/ParticlesToggle.gd
================================================
tool
extends Particles2D
export(bool) var active = true setget set_active
func set_active(value):
active = value
emitting = value
for child in get_children():
if not child.get_class() == "Particles2D":
continue
child.emitting = value
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/fire_to_black.tres
================================================
[gd_resource type="Gradient" format=2]
[resource]
offsets = PoolRealArray( 0, 0.00682594, 0.0887372, 0.395904, 0.915601, 1 )
colors = PoolColorArray( 1, 0.773438, 0, 0, 1, 0.755566, 0, 0.381278, 1, 0.726563, 0, 1, 1, 0.304688, 0, 1, 0.160156, 0.115112, 0.115112, 1, 0, 0, 0, 0 )
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/sparkles.tres
================================================
[gd_resource type="Gradient" format=2]
[resource]
offsets = PoolRealArray( 0, 0.0613811, 0.84399, 1 )
colors = PoolColorArray( 1, 0.846985, 0.148438, 0, 1, 0.820313, 0, 1, 1, 0.398438, 0, 1, 0.964844, 0, 0, 0 )
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/sparkles_small.tres
================================================
[gd_resource type="Gradient" format=2]
[resource]
offsets = PoolRealArray( 0, 0.0971867, 0.751918, 1 )
colors = PoolColorArray( 0.980469, 0.878616, 0.413635, 0, 1, 0.820313, 0, 1, 1, 0.257813, 0, 1, 0, 0, 0, 0 )
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/explosions/Explosion.gd
================================================
extends Particles2D
func _ready():
one_shot = true
$SmallSparkles.one_shot = true
get_tree().create_timer(lifetime * 2.0).connect('timeout', self, 'queue_free')
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/explosions/Explosion.tscn
================================================
[gd_scene load_steps=16 format=2]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/fire_to_black.tres" type="Gradient" id=1]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/smoke_clouds.png" type="Texture" id=2]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/explosions/Explosion.gd" type="Script" id=3]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/sparkles.tres" type="Gradient" id=4]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/circle.png" type="Texture" id=5]
[sub_resource type="GradientTexture" id=1]
flags = 4
gradient = ExtResource( 1 )
width = 2048
[sub_resource type="Curve" id=2]
min_value = -0.2
max_value = 0.2
bake_resolution = 100
_data = [ Vector2( 0, 0.0277257 ), 0.0, 0.0, 0, 0, Vector2( 1, -0.0310864 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=3]
flags = 4
width = 2048
curve = SubResource( 2 )
[sub_resource type="Curve" id=4]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.166992 ), 0.0, 1.80027, 0, 0, Vector2( 1, 1 ), 0.121391, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=5]
flags = 4
width = 2048
curve = SubResource( 4 )
[sub_resource type="ParticlesMaterial" id=6]
render_priority = 0
trail_divisor = 1
emission_shape = 0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 180.0
flatness = 0.0
gravity = Vector3( 0, 1200, 0 )
initial_velocity = 600.0
initial_velocity_random = 0.6
angular_velocity = 180.0
angular_velocity_random = 0.6
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = 0.0
linear_accel_random = 0.0
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 0.0
tangential_accel_random = 0.0
damping = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 0.4
scale_random = 1.0
scale_curve = SubResource( 5 )
color_ramp = SubResource( 1 )
hue_variation = 0.0
hue_variation_random = 0.0
hue_variation_curve = SubResource( 3 )
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Spread" ]
[sub_resource type="GradientTexture" id=7]
flags = 4
gradient = ExtResource( 4 )
width = 2048
[sub_resource type="Curve" id=8]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.399763 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=9]
flags = 4
width = 2048
curve = SubResource( 8 )
[sub_resource type="ParticlesMaterial" id=10]
render_priority = 0
trail_divisor = 1
emission_shape = 1
emission_sphere_radius = 24.0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 60.0
flatness = 0.0
gravity = Vector3( 0, 1200, 0 )
initial_velocity = 800.0
initial_velocity_random = 0.6
angular_velocity = 0.0
angular_velocity_random = 0.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = 0.0
linear_accel_random = 0.0
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 100.0
tangential_accel_random = 0.0
damping = 0.0
damping_random = 0.0
angle = 0.0
angle_random = 0.0
scale = 0.04
scale_random = 0.04
scale_curve = SubResource( 9 )
color_ramp = SubResource( 7 )
hue_variation = 0.0
hue_variation_random = 0.0
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 0.0
anim_offset_random = 0.0
anim_loop = false
_sections_unfolded = [ "Emission Shape", "Initial Velocity", "Orbit Velocity", "Scale" ]
[node name="Explosion" type="Particles2D"]
rotation = -1.5708
z_index = 20
emitting = true
amount = 80
lifetime = 0.8
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.8
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 0
process_material = SubResource( 6 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 2
v_frames = 1
script = ExtResource( 3 )
_sections_unfolded = [ "Drawing", "Process Material", "Time", "Transform", "Z Index" ]
[node name="SmallSparkles" type="Particles2D" parent="." index="0"]
rotation = 0.00504816
emitting = true
amount = 80
lifetime = 0.8
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.8
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 0
process_material = SubResource( 10 )
texture = ExtResource( 5 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Time" ]
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/circle.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/circle.png-3a0701102b0b6f1dc869953be140b137.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/circle.png"
dest_files=[ "res://.import/circle.png-3a0701102b0b6f1dc869953be140b137.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/smoke_clouds.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/smoke_clouds.png-75a81e90df68496c912ffb2365928e06.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/smoke_clouds.png"
dest_files=[ "res://.import/smoke_clouds.png-75a81e90df68496c912ffb2365928e06.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/save/SaveAndLoad.gd
================================================
extends Node
signal game_saved(id)
signal game_loaded(id)
onready var GAME_VERSION = ProjectSettings.get_setting("application/config/version")
var SAVE_DIRECTORY = "res://save/" if ProjectSettings.get_setting("application/config/debug") else "res://user/"
const SAVE_FILE_EXT = ".game"
func save_game(id):
var save_data = {
"version": GAME_VERSION,
"data": []
}
# Get nodes in group works in tree order, from top to bottom
# So we are guaranteed to get the parent first
for node in get_tree().get_nodes_in_group("save"):
var node_save_data = node.get_save_data()
assert(node_save_data["filename"] != "")
assert(node_save_data["parent"] != "")
save_data["data"].append(node_save_data)
var directory = Directory.new()
if not directory.dir_exists(SAVE_DIRECTORY):
directory.make_dir_recursive(SAVE_DIRECTORY)
var path = get_save_file_path(id)
var file = File.new()
file.open(path, File.WRITE)
file.store_string(to_json(save_data))
file.close()
emit_signal("game_saved", id)
func load_game(id):
var path = get_save_file_path(id)
var file = File.new()
if not file.file_exists(path):
print("Couldn't load: file %s does not exist." % path)
return
file.open(path, File.READ)
var save_data = parse_json(file.get_as_text())
file.close()
for node in get_tree().get_nodes_in_group("save"):
node.queue_free()
for node_data in save_data["data"]:
var node = load(node_data["filename"]).instance()
get_node(node_data["parent"]).add_child(node)
var properties = node_data["properties"]
for property in properties.keys():
var value
if is_vector_2(property, node):
value = parse_vector_2(properties[property])
else:
value = properties[property]
node.set(property, value)
emit_signal("game_loaded", id)
func get_save_file_path(id):
return SAVE_DIRECTORY + str(id) + SAVE_FILE_EXT
func is_vector_2(property_name, node):
return typeof(node.get(property_name)) == typeof(Vector2())
func parse_vector_2(json_string):
var numbers_string = json_string.substr(1, len(json_string) - 2)
var comma_position = numbers_string.find(",")
var value_x = float(numbers_string.left(comma_position))
var value_y = float(numbers_string.right(comma_position + 1))
return Vector2(value_x, value_y)
================================================
FILE: core/save/SaveAndLoad.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://SaveAndLoad.gd" type="Script" id=1]
[node name="SaveAndLoad" type="Node" index="0"]
script = ExtResource( 1 )
================================================
FILE: core/shop/Shop.gd
================================================
extends Node
export(bool) var STOCK_INFINITE = false
export(bool) var MONEY_INFINITE = false
export(int) var MAX_TRANSACTION_COUNT = 100
export(float, 0.0, 1.0) var BUY_MULTIPLIER = 0.25
onready var inventory = $Inventory
onready var purse = $Purse
func _ready():
assert(inventory != null)
func buy_from(actor, item, amount=1):
amount = clamp(amount, 1, MAX_TRANSACTION_COUNT)
var transaction_value = max(get_buy_value(item) * amount, purse.coins)
actor.get_node("Inventory").trash(item, amount)
actor.get_node("Purse").add_coins(transaction_value)
if not STOCK_INFINITE:
inventory.add(item, amount)
if not MONEY_INFINITE:
purse.remove_coins(transaction_value)
func sell_to(actor, item, amount=1):
amount = clamp(amount, 1, MAX_TRANSACTION_COUNT)
var transaction_value = item.price * amount
actor.get_node("Purse").remove_coins(item.price * amount)
actor.get_node("Inventory").add(item, amount)
if not STOCK_INFINITE:
inventory.trash(item, amount)
if MONEY_INFINITE:
return
purse.add_coins(item.price * amount)
func get_buy_value(item):
return round(item.price * BUY_MULTIPLIER)
func get_purse():
return purse
================================================
FILE: core/shop/Shop.tscn
================================================
[gd_scene load_steps=7 format=2]
[ext_resource path="res://core/shop/Shop.gd" type="Script" id=1]
[ext_resource path="res://core/inventory/Inventory.tscn" type="PackedScene" id=2]
[ext_resource path="res://core/inventory/items/equipment/sword/Sword.tscn" type="PackedScene" id=3]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/FireballScroll.tscn" type="PackedScene" id=4]
[ext_resource path="res://core/inventory/items/usable/potions/restore_health/StrongHealthPotion.tscn" type="PackedScene" id=5]
[ext_resource path="res://core/shop/purse/Purse.tscn" type="PackedScene" id=6]
[node name="Shop" type="Node"]
editor/display_folded = true
script = ExtResource( 1 )
STOCK_INFINITE = false
MONEY_INFINITE = false
MAX_TRANSACTION_COUNT = 100
BUY_MULTIPLIER = 0.25
[node name="Inventory" parent="." index="0" instance=ExtResource( 2 )]
[node name="Sword" parent="Inventory" index="0" instance=ExtResource( 3 )]
amount = 6
[node name="FireballScroll" parent="Inventory" index="1" instance=ExtResource( 4 )]
[node name="StrongHealthPotion" parent="Inventory" index="2" instance=ExtResource( 5 )]
[node name="Purse" parent="." index="1" instance=ExtResource( 6 )]
MAXIMUM = 1000000
================================================
FILE: core/shop/purse/Purse.gd
================================================
extends Node
signal coins_changed(coins)
export(int) var coins = 0
export(int) var MAXIMUM = 1000000
func has_coins(amount):
return coins >= amount
func add_coins(amount):
coins = min(coins + amount, MAXIMUM)
emit_signal("coins_changed", coins)
func remove_coins(amount):
if not has_coins(amount):
return
coins = max(0, coins - amount)
emit_signal("coins_changed", coins)
================================================
FILE: core/shop/purse/Purse.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://core/shop/purse/Purse.gd" type="Script" id=1]
[node name="Purse" type="Node" index="0"]
script = ExtResource( 1 )
coins = 0
================================================
FILE: core/world/Door.gd
================================================
extends Area2D
signal player_entered(map_path)
export(String, FILE, "*.tscn") var map_path
var PlayerController = preload("res://actors/player/PlayerController.gd")
export(bool) var ACTIVE_AT_START = true
func _ready():
set_active(ACTIVE_AT_START)
assert(map_path != "")
func _on_body_entered(body):
if not body is PlayerController:
return
emit_signal("player_entered", map_path)
func set_active(value):
visible = value
$CollisionShape2D.disabled = not value
================================================
FILE: core/world/Door.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://core/world/Door.gd" type="Script" id=1]
[ext_resource path="res://core/world/stairs.png" type="Texture" id=2]
[sub_resource type="RectangleShape2D" id=1]
custom_solver_bias = 0.0
extents = Vector2( 66, 58.7724 )
[node name="Door" type="Area2D" index="0" groups=[
"doors",
]]
input_pickable = false
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
collision_layer = 8
collision_mask = 3
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Visibility" ]
map_path = null
[node name="Stairs" type="Sprite" parent="." index="0"]
position = Vector2( 1, -24.0106 )
texture = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="1"]
position = Vector2( -3, -16.2276 )
shape = SubResource( 1 )
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
================================================
FILE: core/world/Gap.gd
================================================
extends Area2D
func _on_body_entered(body):
if not body.has_method('fall'):
return
body.fall($CollisionShape2D.shape.extents)
================================================
FILE: core/world/Gap.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://core/world/Gap.gd" type="Script" id=1]
[ext_resource path="res://core/world/pit.png" type="Texture" id=2]
[sub_resource type="RectangleShape2D" id=1]
custom_solver_bias = 0.0
extents = Vector2( 50, 30 )
[node name="Gap" type="Area2D" groups=[
"environment",
"gap",
]]
input_pickable = false
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitorable = false
collision_layer = 2
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Collision" ]
[node name="Gap" type="Sprite" parent="." index="0"]
position = Vector2( 1, -24.0106 )
texture = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="1"]
position = Vector2( 1, -24.2276 )
shape = SubResource( 1 )
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
================================================
FILE: core/world/PlayerSpawningPoint.tscn
================================================
[gd_scene load_steps=2 format=2]
[sub_resource type="GDScript" id=1]
script/source = "tool
extends Position2D
export(float) var RADIUS = 100.0
export(int) var EDGES = 32
export(Color) var LINE_COLOR = Color(\"#ffffff\")
func _ready():
set_as_toplevel(true)
func _draw():
if not Engine.editor_hint:
return
var points = PoolVector2Array()
var angle_step = PI * 2 / EDGES
for i in range(EDGES + 1):
var point = Vector2(
cos(angle_step * i) * RADIUS,
sin(angle_step * i) * RADIUS
)
points.append(point)
draw_polyline(points, LINE_COLOR, 4.0)
"
[node name="PlayerSpawningPoint" type="Position2D" index="0"]
script = SubResource( 1 )
RADIUS = 100.0
EDGES = 16
LINE_COLOR = Color( 0.921875, 0.154846, 0.766072, 1 )
================================================
FILE: core/world/Rock.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://core/world/rock.png" type="Texture" id=1]
[sub_resource type="RectangleShape2D" id=1]
custom_solver_bias = 0.0
extents = Vector2( 23.4314, 15.2998 )
[sub_resource type="RectangleShape2D" id=2]
custom_solver_bias = 0.0
extents = Vector2( 44.0727, 26.1865 )
[node name="Rock" type="StaticBody2D" groups=[
"environment",
]]
input_pickable = false
collision_layer = 2
collision_mask = 1
constant_linear_velocity = Vector2( 0, 0 )
constant_angular_velocity = 0.0
friction = 1.0
bounce = 0.0
_sections_unfolded = [ "Collision" ]
[node name="rock" type="Sprite" parent="." index="0"]
position = Vector2( 12.0737, 1.98891 )
texture = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="1"]
position = Vector2( 43.7353, 34.2526 )
shape = SubResource( 1 )
[node name="CollisionShape2D2" type="CollisionShape2D" parent="." index="2"]
position = Vector2( -1.99999, -6.48269 )
shape = SubResource( 2 )
================================================
FILE: core/world/pit.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/pit.png-5ec5084f4b0d321ced939a029f9e9f2b.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/world/pit.png"
dest_files=[ "res://.import/pit.png-5ec5084f4b0d321ced939a029f9e9f2b.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/world/rock.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/rock.png-d90c7ea6986b7d7efafc6116d7469b11.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/world/rock.png"
dest_files=[ "res://.import/rock.png-d90c7ea6986b7d7efafc6116d7469b11.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/world/stairs.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/stairs.png-459082f78726e41c4edb789b8d018960.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/world/stairs.png"
dest_files=[ "res://.import/stairs.png-459082f78726e41c4edb789b8d018960.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/world/tilesets/cave/cave.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/cave.png-7421b3ea2eb0cd51e25cb4e00e5ffa5c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/world/tilesets/cave/cave.png"
dest_files=[ "res://.import/cave.png-7421b3ea2eb0cd51e25cb4e00e5ffa5c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/world/tilesets/cave/cave.tres
================================================
[gd_resource type="TileSet" load_steps=14 format=2]
[ext_resource path="res://core/world/tilesets/cave/cave.png" type="Texture" id=1]
[sub_resource type="ConvexPolygonShape2D" id=1]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=2]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=3]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=4]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=5]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=6]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=7]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=8]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=9]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=10]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=11]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=12]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[resource]
0/name = "cave"
0/texture = ExtResource( 1 )
0/tex_offset = Vector2( 0, 0 )
0/modulate = Color( 1, 1, 1, 1 )
0/region = Rect2( 0, 0, 640, 384 )
0/is_autotile = true
0/autotile/bitmask_mode = 0
0/autotile/icon_coordinate = Vector2( 0, 0 )
0/autotile/tile_size = Vector2( 128, 128 )
0/autotile/spacing = 0
0/autotile/bitmask_flags = [ Vector2( 0, 0 ), 256, Vector2( 0, 1 ), 260, Vector2( 0, 2 ), 4, Vector2( 1, 0 ), 320, Vector2( 1, 1 ), 325, Vector2( 1, 2 ), 5, Vector2( 2, 0 ), 64, Vector2( 2, 1 ), 65, Vector2( 2, 2 ), 1, Vector2( 3, 0 ), 69, Vector2( 3, 1 ), 321, Vector2( 4, 0 ), 261, Vector2( 4, 1 ), 324 ]
0/autotile/occluder_map = [ ]
0/autotile/navpoly_map = [ ]
0/autotile/priority_map = [ ]
0/occluder_offset = Vector2( 320, 192 )
0/navigation_offset = Vector2( 320, 192 )
0/shapes = [ {
"autotile_coord": Vector2( 0, 0 ),
"one_way": false,
"shape": SubResource( 1 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 1, 0 ),
"one_way": false,
"shape": SubResource( 2 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 2, 0 ),
"one_way": false,
"shape": SubResource( 3 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 2, 1 ),
"one_way": false,
"shape": SubResource( 4 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 2, 2 ),
"one_way": false,
"shape": SubResource( 5 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 1, 2 ),
"one_way": false,
"shape": SubResource( 6 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 0, 2 ),
"one_way": false,
"shape": SubResource( 7 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 0, 1 ),
"one_way": false,
"shape": SubResource( 8 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 3, 0 ),
"one_way": false,
"shape": SubResource( 9 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 4, 0 ),
"one_way": false,
"shape": SubResource( 10 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 3, 1 ),
"one_way": false,
"shape": SubResource( 11 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 4, 1 ),
"one_way": false,
"shape": SubResource( 12 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
} ]
_sections_unfolded = [ "0" ]
================================================
FILE: core/world/tilesets/cave/cave_tileset_src.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://core/world/tilesets/cave/cave.png" type="Texture" id=1]
[node name="Node2D" type="Node2D" index="0"]
[node name="cave" type="Sprite" parent="." index="0"]
position = Vector2( 322.14, 192 )
texture = ExtResource( 1 )
region_enabled = true
region_rect = Rect2( 0, 0, 640, 384 )
_sections_unfolded = [ "Region" ]
================================================
FILE: core/world/tilesets/outdoor/outdoor.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/outdoor.png-1eb405fc65af37f625e19d928044f95c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/world/tilesets/outdoor/outdoor.png"
dest_files=[ "res://.import/outdoor.png-1eb405fc65af37f625e19d928044f95c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: core/world/tilesets/outdoor/outdoor.tres
================================================
[gd_resource type="TileSet" load_steps=18 format=2]
[ext_resource path="res://core/world/tilesets/outdoor/outdoor.png" type="Texture" id=1]
[ext_resource path="res://core/world/tilesets/outdoor/pit.png" type="Texture" id=2]
[sub_resource type="ConvexPolygonShape2D" id=1]
custom_solver_bias = 0.0
points = PoolVector2Array( -48, 16, -48, -48, 24, -48, 24, 8, 8, 16 )
[sub_resource type="ConvexPolygonShape2D" id=2]
custom_solver_bias = 0.0
points = PoolVector2Array( 24, 8, 48, 8, 48, 40, 8, 40, 8, 16 )
[sub_resource type="ConvexPolygonShape2D" id=3]
custom_solver_bias = 0.0
points = PoolVector2Array( 80, 128, 80, 96, 96, 80, 128, 80, 128, 128 )
[sub_resource type="ConvexPolygonShape2D" id=4]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 80, 32, 80, 48, 96, 48, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=5]
custom_solver_bias = 0.0
points = PoolVector2Array( 48, 0, 48, 128, 0, 128, 0, 0 )
[sub_resource type="ConvexPolygonShape2D" id=6]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 48, 0, 48, 32, 32, 48, 0, 48 )
[sub_resource type="ConvexPolygonShape2D" id=7]
custom_solver_bias = 0.0
points = PoolVector2Array( 128, 0, 128, 48, 0, 48, 0, 0 )
[sub_resource type="ConvexPolygonShape2D" id=8]
custom_solver_bias = 0.0
points = PoolVector2Array( 128, 48, 96, 48, 80, 32, 80, 0, 128, 0 )
[sub_resource type="ConvexPolygonShape2D" id=9]
custom_solver_bias = 0.0
points = PoolVector2Array( 80, 128, 80, 0, 128, 0, 128, 128 )
[sub_resource type="ConvexPolygonShape2D" id=10]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=11]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 80, 128, 80, 128, 128, 0, 128 )
[sub_resource type="ConvexPolygonShape2D" id=12]
custom_solver_bias = 0.0
points = PoolVector2Array( 128, 0, 128, 128, 0, 128, 0, 80, 80, 80, 80, 0 )
[sub_resource type="ConvexPolygonShape2D" id=13]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 128, 0, 112, 0, 0, 128, 0, 128, 48, 48, 48, 48, 128 )
[sub_resource type="ConvexPolygonShape2D" id=14]
custom_solver_bias = 0.0
points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 80, 128, 80, 48, 0, 48 )
[sub_resource type="ConvexPolygonShape2D" id=15]
custom_solver_bias = 0.0
points = PoolVector2Array( 48, 0, 48, 80, 128, 80, 128, 128, 0, 128, 0, 0 )
[resource]
0/name = "grass"
0/texture = ExtResource( 1 )
0/tex_offset = Vector2( 0, 0 )
0/modulate = Color( 1, 1, 1, 1 )
0/region = Rect2( 0, 0, 384, 256 )
0/is_autotile = true
0/autotile/bitmask_mode = 0
0/autotile/icon_coordinate = Vector2( 0, 1 )
0/autotile/tile_size = Vector2( 128, 128 )
0/autotile/spacing = 0
0/autotile/bitmask_flags = [ Vector2( 0, 0 ), 325, Vector2( 0, 1 ), 325, Vector2( 1, 0 ), 325, Vector2( 2, 0 ), 325 ]
0/autotile/occluder_map = [ ]
0/autotile/navpoly_map = [ ]
0/autotile/priority_map = [ Vector3( 0, 1, 35 ) ]
0/occluder_offset = Vector2( 192, 128 )
0/navigation_offset = Vector2( 192, 128 )
0/shapes = [ ]
1/name = "dirt"
1/texture = ExtResource( 1 )
1/tex_offset = Vector2( 0, 0 )
1/modulate = Color( 1, 1, 1, 1 )
1/region = Rect2( 384, 0, 640, 512 )
1/is_autotile = true
1/autotile/bitmask_mode = 0
1/autotile/icon_coordinate = Vector2( 1, 1 )
1/autotile/tile_size = Vector2( 128, 128 )
1/autotile/spacing = 0
1/autotile/bitmask_flags = [ Vector2( 0, 0 ), 256, Vector2( 0, 1 ), 260, Vector2( 0, 2 ), 4, Vector2( 0, 3 ), 325, Vector2( 1, 0 ), 320, Vector2( 1, 1 ), 325, Vector2( 1, 2 ), 5, Vector2( 1, 3 ), 325, Vector2( 2, 0 ), 64, Vector2( 2, 1 ), 65, Vector2( 2, 2 ), 1, Vector2( 2, 3 ), 325, Vector2( 3, 0 ), 69, Vector2( 3, 1 ), 321, Vector2( 3, 2 ), 257, Vector2( 3, 3 ), 68, Vector2( 4, 0 ), 261, Vector2( 4, 1 ), 324, Vector2( 4, 2 ), 68, Vector2( 4, 3 ), 257 ]
1/autotile/occluder_map = [ ]
1/autotile/navpoly_map = [ ]
1/autotile/priority_map = [ Vector3( 0, 3, 2 ), Vector3( 1, 1, 48 ) ]
1/occluder_offset = Vector2( 320, 256 )
1/navigation_offset = Vector2( 320, 256 )
1/shapes = [ ]
2/name = "rock"
2/texture = ExtResource( 1 )
2/tex_offset = Vector2( 0, 0 )
2/modulate = Color( 1, 1, 1, 1 )
2/region = Rect2( 256, 384, 128, 128 )
2/is_autotile = false
2/occluder_offset = Vector2( 64, 64 )
2/navigation_offset = Vector2( 64, 64 )
2/shapes = [ {
"autotile_coord": Vector2( 0, 0 ),
"one_way": false,
"shape": SubResource( 1 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 64, 64 )
}, {
"autotile_coord": Vector2( 0, 0 ),
"one_way": false,
"shape": SubResource( 2 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 64, 64 )
} ]
3/name = "outdoor"
3/texture = ExtResource( 1 )
3/tex_offset = Vector2( 0, 0 )
3/modulate = Color( 1, 1, 1, 1 )
3/region = Rect2( 0, 0, 384, 256 )
3/is_autotile = false
3/occluder_offset = Vector2( 192, 128 )
3/navigation_offset = Vector2( 192, 128 )
3/shapes = [ ]
4/name = "bush"
4/texture = ExtResource( 1 )
4/tex_offset = Vector2( 0, 0 )
4/modulate = Color( 1, 1, 1, 1 )
4/region = Rect2( 0, 512, 1024, 384 )
4/is_autotile = true
4/autotile/bitmask_mode = 1
4/autotile/icon_coordinate = Vector2( 1, 1 )
4/autotile/tile_size = Vector2( 128, 128 )
4/autotile/spacing = 0
4/autotile/bitmask_flags = [ Vector2( 0, 0 ), 176, Vector2( 0, 1 ), 146, Vector2( 0, 2 ), 50, Vector2( 1, 0 ), 56, Vector2( 1, 1 ), 16, Vector2( 1, 2 ), 56, Vector2( 2, 0 ), 152, Vector2( 2, 1 ), 146, Vector2( 2, 2 ), 26, Vector2( 3, 0 ), 144, Vector2( 3, 1 ), 18, Vector2( 3, 2 ), 48, Vector2( 4, 0 ), 178, Vector2( 4, 1 ), 184, Vector2( 4, 2 ), 24, Vector2( 5, 0 ), 154, Vector2( 5, 1 ), 58, Vector2( 5, 2 ), 186, Vector2( 6, 0 ), 176, Vector2( 6, 1 ), 50, Vector2( 7, 0 ), 152, Vector2( 7, 1 ), 26 ]
4/autotile/occluder_map = [ ]
4/autotile/navpoly_map = [ ]
4/autotile/priority_map = [ ]
4/occluder_offset = Vector2( 512, 192 )
4/navigation_offset = Vector2( 512, 192 )
4/shapes = [ ]
5/name = "pit"
5/texture = ExtResource( 2 )
5/tex_offset = Vector2( 0, 0 )
5/modulate = Color( 1, 1, 1, 1 )
5/region = Rect2( 0, 0, 640, 384 )
5/is_autotile = true
5/autotile/bitmask_mode = 0
5/autotile/icon_coordinate = Vector2( 1, 1 )
5/autotile/tile_size = Vector2( 128, 128 )
5/autotile/spacing = 0
5/autotile/bitmask_flags = [ Vector2( 0, 0 ), 256, Vector2( 0, 1 ), 260, Vector2( 0, 2 ), 4, Vector2( 1, 0 ), 320, Vector2( 1, 1 ), 325, Vector2( 1, 2 ), 5, Vector2( 2, 0 ), 64, Vector2( 2, 1 ), 65, Vector2( 2, 2 ), 1, Vector2( 3, 0 ), 69, Vector2( 3, 1 ), 321, Vector2( 4, 0 ), 261, Vector2( 4, 1 ), 324 ]
5/autotile/occluder_map = [ ]
5/autotile/navpoly_map = [ ]
5/autotile/priority_map = [ ]
5/occluder_offset = Vector2( 320, 192 )
5/navigation_offset = Vector2( 320, 192 )
5/shapes = [ {
"autotile_coord": Vector2( 0, 0 ),
"one_way": false,
"shape": SubResource( 3 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 2, 0 ),
"one_way": false,
"shape": SubResource( 4 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 2, 1 ),
"one_way": false,
"shape": SubResource( 5 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 2, 2 ),
"one_way": false,
"shape": SubResource( 6 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 1, 2 ),
"one_way": false,
"shape": SubResource( 7 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 0, 2 ),
"one_way": false,
"shape": SubResource( 8 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 0, 1 ),
"one_way": false,
"shape": SubResource( 9 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 1, 1 ),
"one_way": false,
"shape": SubResource( 10 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 1, 0 ),
"one_way": false,
"shape": SubResource( 11 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 4, 1 ),
"one_way": false,
"shape": SubResource( 12 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 3, 0 ),
"one_way": false,
"shape": SubResource( 13 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 4, 0 ),
"one_way": false,
"shape": SubResource( 14 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 3, 1 ),
"one_way": false,
"shape": SubResource( 15 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
} ]
_sections_unfolded = [ "5", "Resource" ]
================================================
FILE: core/world/tilesets/outdoor/outdoor.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://core/world/tilesets/outdoor/outdoor.png" type="Texture" id=1]
[ext_resource path="res://core/world/tilesets/outdoor/pit.png" type="Texture" id=2]
[node name="Outdoor" type="Node"]
[node name="outdoor" type="Sprite" parent="." index="0"]
position = Vector2( 192, 160 )
texture = ExtResource( 1 )
region_enabled = true
region_rect = Rect2( 0, 0, 384, 256 )
_sections_unfolded = [ "Region" ]
[node name="dirt" type="Sprite" parent="." index="1"]
position = Vector2( 320, 576 )
texture = ExtResource( 1 )
region_enabled = true
region_rect = Rect2( 384, 0, 640, 512 )
_sections_unfolded = [ "Region" ]
[node name="bush" type="Sprite" parent="." index="2"]
position = Vector2( 1200, 592 )
texture = ExtResource( 1 )
region_enabled = true
region_rect = Rect2( 0, 512, 1024, 384 )
_sections_unfolded = [ "Region" ]
[node name="rock" type="Sprite" parent="." index="3"]
position = Vector2( 832, 192 )
texture = ExtResource( 1 )
region_enabled = true
region_rect = Rect2( 256, 384, 128, 128 )
_sections_unfolded = [ "Region" ]
[node name="StaticBody2D" type="StaticBody2D" parent="rock" index="0"]
input_pickable = false
collision_layer = 1
collision_mask = 1
constant_linear_velocity = Vector2( 0, 0 )
constant_angular_velocity = 0.0
friction = 1.0
bounce = 0.0
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="rock/StaticBody2D" index="0"]
build_mode = 0
polygon = PoolVector2Array( 24, -48, 24, 8, 48, 8, 48, 40, 8, 40, 8, 16, -48, 16, -48, -48 )
[node name="pit" type="Sprite" parent="." index="4"]
position = Vector2( 1056, 1024 )
texture = ExtResource( 2 )
================================================
FILE: core/world/tilesets/outdoor/pit.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/pit.png-81c563e22c5b735099e3aed47ef25a25.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://core/world/tilesets/outdoor/pit.png"
dest_files=[ "res://.import/pit.png-81c563e22c5b735099e3aed47ef25a25.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: default_bus_layout.tres
================================================
[gd_resource type="AudioBusLayout" format=2]
[resource]
bus/0/name = "Master"
bus/0/solo = false
bus/0/mute = false
bus/0/bypass_fx = false
bus/0/volume_db = 0.0
bus/0/send = ""
bus/1/name = "Music"
bus/1/solo = false
bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = -4.8
bus/1/send = "Master"
bus/2/name = "Sounds"
bus/2/solo = false
bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = "LowPass"
bus/3/name = "Interface"
bus/3/solo = false
bus/3/mute = false
bus/3/bypass_fx = false
bus/3/volume_db = 0.0
bus/3/send = "Master"
================================================
FILE: default_env.tres
================================================
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
sky_curve = 0.25
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
sun_energy = 16.0
[resource]
background_mode = 2
background_sky = SubResource( 1 )
================================================
FILE: icon.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: interface/Interface.gd
================================================
extends CanvasLayer
onready var shop_menu = $ShopMenu
func _ready():
shop_menu.connect('closed', self, 'remove_child', [shop_menu])
remove_child(shop_menu)
func initialize(player):
$PlayerGUI.initialize(player.get_health_node(), player.get_purse())
$PauseMenu.initialize({'actor': player})
func _on_Level_loaded(level):
var tree = get_tree()
for seller in tree.get_nodes_in_group('seller'):
seller.connect('shop_open_requested', self, 'shop_open')
var monsters = tree.get_nodes_in_group('monster')
var spawners = tree.get_nodes_in_group('monster_spawner')
$LifebarsBuilder.initialize(monsters, spawners)
func shop_open(seller_shop, buyer):
add_child(shop_menu)
shop_menu.open({'shop': seller_shop, 'buyer': buyer})
================================================
FILE: interface/TopLevelUi.gd
================================================
tool
extends Control
func _ready():
set_as_toplevel(true)
================================================
FILE: interface/fonts/montserrat_black_48.tres
================================================
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://interface/fonts/montserrat_black.ttf" type="DynamicFontData" id=1]
[resource]
size = 48
use_mipmaps = true
use_filter = false
font_data = ExtResource( 1 )
_sections_unfolded = [ "Font", "Settings" ]
================================================
FILE: interface/fonts/source_code_pro_explanations.tres
================================================
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://interface/fonts/SourceCodePro-Bold.ttf" type="DynamicFontData" id=1]
[resource]
size = 18
use_mipmaps = false
use_filter = true
font_data = ExtResource( 1 )
_sections_unfolded = [ "Font", "Settings" ]
================================================
FILE: interface/fonts/source_code_pro_explanations_bold.tres
================================================
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://interface/fonts/SourceCodePro-Black.ttf" type="DynamicFontData" id=1]
[resource]
size = 24
use_mipmaps = false
use_filter = true
font_data = ExtResource( 1 )
_sections_unfolded = [ "Font", "Settings" ]
================================================
FILE: interface/gui/boss/BossLifebar.gd
================================================
tool
extends Control
export(String) var boss_name = "Boss Name"
onready var bar = $Bar
onready var anim_player = $AnimationPlayer
func _ready():
set_as_toplevel(true)
$Label.text = boss_name
hide()
func initialize(health_node):
bar.max_value = health_node.max_health
bar.value = health_node.health
print(bar.value)
health_node.connect('health_changed', self, '_on_Health_health_changed')
func appear():
show()
anim_player.play("appear")
func disappear():
anim_player.play("disappear")
yield(anim_player, "animation_finished")
hide()
func _on_Health_health_changed(value):
bar.value = value
================================================
FILE: interface/gui/boss/BossLifebar.tscn
================================================
[gd_scene load_steps=7 format=2]
[ext_resource path="res://interface/gui/boss/BossLifebar.gd" type="Script" id=1]
[ext_resource path="res://interface/default.theme" type="Theme" id=2]
[ext_resource path="res://interface/gui/boss/boss_bar_bg.png" type="Texture" id=3]
[ext_resource path="res://interface/gui/boss/boss_bar_fill.png" type="Texture" id=4]
[sub_resource type="Animation" id=1]
resource_name = "appear"
length = 1.0
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Label:self_modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.5 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Bar:self_modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0.2, 0.7 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("Label:rect_position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0, 0.5 ),
"transitions": PoolRealArray( 0.356926, 1 ),
"update": 0,
"values": [ Vector2( -84, 0 ), Vector2( 0, 0 ) ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("Bar:rect_position")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/keys = {
"times": PoolRealArray( 0.2, 0.7 ),
"transitions": PoolRealArray( 0.407274, 1 ),
"update": 0,
"values": [ Vector2( 104, 27 ), Vector2( 156, 27 ) ]
}
[sub_resource type="Animation" id=2]
resource_name = "disappear"
length = 0.8
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Label:self_modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.7 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Bar:self_modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0.1, 0.8 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
}
[node name="BossLifebar" type="VBoxContainer"]
visible = false
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
margin_left = -780.0
margin_top = -133.0
margin_right = 780.0
margin_bottom = -40.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
alignment = 0
script = ExtResource( 1 )
boss_name = ""
[node name="Label" type="Label" parent="." index="0"]
self_modulate = Color( 1, 1, 1, 0 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1560.0
margin_bottom = 23.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
theme = ExtResource( 2 )
align = 1
valign = 2
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Theme", "Visibility", "custom_fonts" ]
[node name="Bar" type="TextureProgress" parent="." index="1"]
modulate = Color( 1, 0.0195313, 0.272308, 1 )
self_modulate = Color( 1, 1, 1, 5.96046e-008 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 156.0
margin_top = 27.0
margin_right = 1404.0
margin_bottom = 93.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 4
size_flags_vertical = 4
min_value = 0.0
max_value = 100.0
step = 1.0
page = 0.0
value = 100.0
exp_edit = false
rounded = false
texture_under = ExtResource( 3 )
texture_over = null
texture_progress = ExtResource( 4 )
radial_fill_degrees = 360.0
radial_center_offset = Vector2( 0, 0 )
nine_patch_stretch = false
_sections_unfolded = [ "Size Flags", "Textures", "Visibility" ]
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="2"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/appear = SubResource( 1 )
anims/disappear = SubResource( 2 )
blend_times = [ ]
================================================
FILE: interface/gui/boss/boss_bar_bg.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/boss_bar_bg.png-aed3843f4ed3efb0dbc21b2322fd9e56.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/gui/boss/boss_bar_bg.png"
dest_files=[ "res://.import/boss_bar_bg.png-aed3843f4ed3efb0dbc21b2322fd9e56.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: interface/gui/boss/boss_bar_fill.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/boss_bar_fill.png-9d50dc46e3fabfa93c1e17061ffa511b.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/gui/boss/boss_bar_fill.png"
dest_files=[ "res://.import/boss_bar_fill.png-9d50dc46e3fabfa93c1e17061ffa511b.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: interface/gui/lifebar/HookableLifeBar.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://interface/gui/lifebar/Lifebar.gd" type="Script" id=1]
[ext_resource path="res://interface/gui/lifebar/background.png" type="Texture" id=2]
[ext_resource path="res://interface/gui/lifebar/fill.png" type="Texture" id=3]
[node name="HookableLifeBar" type="Node2D" groups=[
"bars",
]]
script = ExtResource( 1 )
[node name="Background" type="TextureRect" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = -95.0
margin_top = -11.0
margin_right = 97.0
margin_bottom = 11.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 2 )
stretch_mode = 0
_sections_unfolded = [ "Rect", "Textures" ]
[node name="TextureProgress" type="TextureProgress" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = -95.0
margin_top = -11.0
margin_right = 97.0
margin_bottom = 11.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
min_value = 0.0
max_value = 100.0
step = 1.0
page = 0.0
value = 60.0
exp_edit = false
rounded = false
texture_under = null
texture_over = null
texture_progress = ExtResource( 3 )
radial_fill_degrees = 360.0
radial_center_offset = Vector2( 0, 0 )
nine_patch_stretch = false
_sections_unfolded = [ "Rect" ]
================================================
FILE: interface/gui/lifebar/InterfaceAnchor.tscn
================================================
[gd_scene format=2]
[node name="InterfaceAnchor" type="RemoteTransform2D"]
position = Vector2( 0, -98.2191 )
remote_path = NodePath("")
use_global_coordinates = true
update_position = true
update_rotation = false
update_scale = false
================================================
FILE: interface/gui/lifebar/Lifebar.gd
================================================
extends Node2D
var max_health = 0 setget set_max_health
var health = 0 setget set_health
func set_max_health(value):
max_health = value
$TextureProgress.max_value = value
func set_health(value):
health = value
$TextureProgress.value = value
func initialize(actor):
var hook = actor.get_node("InterfaceAnchor")
global_position = hook.global_position
hook.remote_path = hook.get_path_to(self)
var health_node = actor.get_node("Stats")
health_node.connect("health_changed", self, "_on_Actor_health_changed")
health_node.connect("health_depleted", self, "_on_Actor_health_depleted")
self.health = health_node.health
self.max_health = health_node.max_health
func _on_Actor_health_changed(new_health):
self.health = new_health
func _on_Actor_health_depleted():
queue_free()
================================================
FILE: interface/gui/lifebar/LifebarsBuilder.gd
================================================
extends Node
const Lifebar = preload("res://interface/gui/lifebar/HookableLifeBar.tscn")
func initialize(monsters, monster_spawners):
for monster in monsters:
create_lifebar(monster)
for spawner in monster_spawners:
monster_spawners.connect('spawned_monster', self, '_on_MonsterSpawner_spawned_monster')
func _on_MonsterSpawner_spawned_monster(monster_node):
create_lifebar(monster_node)
func create_lifebar(actor):
if not actor.has_node('InterfaceAnchor'):
return
var lifebar = Lifebar.instance()
actor.add_child(lifebar)
lifebar.initialize(actor)
================================================
FILE: interface/gui/lifebar/LifebarsBuilder.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://interface/gui/lifebar/LifebarsBuilder.gd" type="Script" id=1]
[node name="LifebarsBuilder" type="Node"]
script = ExtResource( 1 )
================================================
FILE: interface/gui/lifebar/background.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/background.png-62efda1a07fd52ccf13fb5c00abc7e8c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/gui/lifebar/background.png"
dest_files=[ "res://.import/background.png-62efda1a07fd52ccf13fb5c00abc7e8c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: interface/gui/lifebar/fill.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/fill.png-b3e6044072b4f216e075877da6e81969.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/gui/lifebar/fill.png"
dest_files=[ "res://.import/fill.png-b3e6044072b4f216e075877da6e81969.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: interface/gui/player/PlayerGUI.gd
================================================
extends Control
func initialize(health_node, purse):
$LifeBar.initialize(health_node)
$CoinsCounter.initialize(purse)
health_node.connect('health_depleted', self, '_on_Player_Health_health_depleted')
func _on_Player_Health_health_depleted():
$AnimationPlayer.play("fade_out")
================================================
FILE: interface/gui/player/PlayerGUI.tscn
================================================
[gd_scene load_steps=9 format=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=1]
[ext_resource path="res://interface/gui/player/PlayerGUI.gd" type="Script" id=2]
[ext_resource path="res://interface/gui/player/life_bar/LifeBar.tscn" type="PackedScene" id=3]
[ext_resource path="res://core/inventory/items/coins/coin_single.png" type="Texture" id=4]
[ext_resource path="res://interface/fonts/source_code_pro_explanations_bold.tres" type="DynamicFont" id=5]
[sub_resource type="GDScript" id=3]
script/source = "extends Panel
func initialize(purse):
purse.connect('coins_changed', self, '_on_Purse_coins_changed')
update_count(purse.coins)
func _on_Purse_coins_changed(coins):
update_count(coins)
func update_count(value):
$Label.text = str(value)
"
[sub_resource type="Animation" id=1]
resource_name = "SETUP"
length = 0.5
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=2]
length = 0.8
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.8 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
}
tracks/1/type = "method"
tracks/1/path = NodePath(".")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0.8 ),
"transitions": PoolRealArray( 1 ),
"values": [ {
"args": [ ],
"method": "queue_free"
} ]
}
[node name="PlayerGUI" type="HBoxContainer" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 0.0
margin_left = 20.0
margin_top = 20.0
margin_right = -30.0
margin_bottom = 73.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 1 )
custom_constants/separation = 16
alignment = 0
script = ExtResource( 2 )
_sections_unfolded = [ "Anchor", "Theme", "custom_constants" ]
[node name="LifeBar" parent="." index="0" instance=ExtResource( 3 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 396.0
margin_bottom = 53.0
_sections_unfolded = [ "Rect", "Size Flags" ]
[node name="CoinsCounter" type="Panel" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 412.0
margin_right = 532.0
margin_bottom = 53.0
rect_min_size = Vector2( 120, 0 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
script = SubResource( 3 )
_sections_unfolded = [ "Rect" ]
[node name="Coin" type="TextureRect" parent="CoinsCounter" index="0"]
anchor_left = 0.0
anchor_top = 0.5
anchor_right = 0.0
anchor_bottom = 0.5
margin_left = 15.0
margin_top = -16.5
margin_right = 45.0
margin_bottom = 16.5
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 4 )
expand = true
stretch_mode = 0
[node name="Label" type="Label" parent="CoinsCounter" index="1"]
anchor_left = 1.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -72.0
margin_right = -20.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = ExtResource( 5 )
text = "120"
align = 2
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="2"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/SETUP = SubResource( 1 )
anims/fade_out = SubResource( 2 )
blend_times = [ ]
================================================
FILE: interface/gui/player/life_bar/LifeBar.tscn
================================================
[gd_scene load_steps=8 format=2]
[ext_resource path="res://interface/gui/player/life_bar/bg.png" type="Texture" id=1]
[ext_resource path="res://interface/gui/player/life_bar/Lifebar.gd" type="Script" id=2]
[ext_resource path="res://interface/gui/player/life_bar/fill.png" type="Texture" id=3]
[ext_resource path="res://interface/gui/player/life_bar/TextureProgress.gd" type="Script" id=4]
[sub_resource type="Animation" id=1]
resource_name = "SETUP"
length = 0.01
loop = false
step = 0.1
[sub_resource type="Animation" id=2]
resource_name = "heal"
length = 0.4
loop = false
step = 0.1
[sub_resource type="Animation" id=3]
length = 0.4
loop = false
step = 0.1
[node name="LifeBar" type="TextureRect" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_right = -884.0
margin_bottom = -667.0
rect_pivot_offset = Vector2( 196.476, 27.8519 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 1 )
stretch_mode = 0
script = ExtResource( 2 )
_sections_unfolded = [ "Rect" ]
[node name="TextureProgress" type="TextureProgress" parent="." index="0"]
modulate = Color( 0.366329, 0.902344, 0.0951691, 1 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
min_value = 0.0
max_value = 34.0
step = 1.0
page = 0.0
value = 16.0
exp_edit = false
rounded = false
texture_under = null
texture_over = null
texture_progress = ExtResource( 3 )
radial_fill_degrees = 360.0
radial_center_offset = Vector2( 0, 0 )
nine_patch_stretch = false
script = ExtResource( 4 )
_sections_unfolded = [ "Textures", "Visibility" ]
COLOR_FULL = Color( 0.708904, 0.9375, 0.0769043, 1 )
COLOR_NORMAL = Color( 0.366329, 0.902344, 0.0951691, 1 )
COLOR_LOW = Color( 0.910156, 0.62426, 0.131546, 1 )
COLOR_CRITICAL = Color( 0.957031, 0.203889, 0.056076, 1 )
THRESHOLD_LOW = 0.4
THRESHOLD_CRITICAL = 0.2
[node name="Tween" type="Tween" parent="TextureProgress" index="0"]
repeat = false
playback_process_mode = 1
playback_speed = 1.0
playback/active = false
playback/repeat = false
playback/speed = 1.0
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="1"]
root_node = NodePath("..")
autoplay = "SETUP"
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/SETUP = SubResource( 1 )
anims/heal = SubResource( 2 )
anims/shake = SubResource( 3 )
blend_times = [ ]
[connection signal="maximum_changed" from="." to="TextureProgress" method="_on_Bar_maximum_changed"]
================================================
FILE: interface/gui/player/life_bar/Lifebar.gd
================================================
extends Control
signal maximum_changed(maximum)
var maximum = 100
var current_health = 0
func initialize(health_node):
health_node.connect('health_changed', self, '_on_Player_Health_health_changed')
maximum = health_node.max_health
current_health = health_node.health
emit_signal("maximum_changed", maximum)
animate_bar(current_health)
func _on_Player_Health_health_changed(new_health):
animate_bar(new_health)
current_health = new_health
func animate_bar(target_health):
$TextureProgress.animate_value(current_health, target_health)
$TextureProgress.update_color(target_health)
================================================
FILE: interface/gui/player/life_bar/TextureProgress.gd
================================================
tool
extends TextureProgress
export(Color) var COLOR_FULL
export(Color) var COLOR_NORMAL
export(Color) var COLOR_LOW
export(Color) var COLOR_CRITICAL
export(float, 0, 1) var THRESHOLD_LOW = 0.3
export(float, 0, 1) var THRESHOLD_CRITICAL = 0.1
var color_active = COLOR_NORMAL
func _on_Bar_maximum_changed(maximum):
max_value = maximum
func animate_value(start, end):
$Tween.interpolate_property(self, "value", start, end, 0.5, Tween.TRANS_QUART, Tween.EASE_OUT)
$Tween.start()
func update_color(new_value):
var new_color
if new_value > THRESHOLD_LOW * max_value:
if new_value < max_value:
new_color = COLOR_NORMAL
else:
new_color = COLOR_FULL
elif new_value > THRESHOLD_CRITICAL * max_value:
new_color = COLOR_LOW
else:
new_color = COLOR_CRITICAL
if new_color == color_active:
return
color_active = new_color
$Tween.interpolate_property(self, "modulate", modulate, new_color, 0.4, Tween.TRANS_QUART, Tween.EASE_OUT)
$Tween.start()
================================================
FILE: interface/gui/player/life_bar/bg.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/bg.png-4137f69cffc7cfbd089694c7a17196f3.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/gui/player/life_bar/bg.png"
dest_files=[ "res://.import/bg.png-4137f69cffc7cfbd089694c7a17196f3.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: interface/gui/player/life_bar/fill.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/fill.png-6d81f3dffced581fbfcd68a8ff5225b0.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/gui/player/life_bar/fill.png"
dest_files=[ "res://.import/fill.png-6d81f3dffced581fbfcd68a8ff5225b0.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: interface/items/ItemButton.gd
================================================
extends Button
signal amount_changed(value)
var description = ""
var amount = 0
func initialize(item, price, purse):
$Name.text = item.display_name
$Price.text = str(price)
$Icon.texture = item.icon
description = item.description
amount = item.amount
if purse.coins < price:
disabled = true
item.connect("amount_changed", self, "_on_Item_amount_changed")
item.connect("depleted", self, "_on_Item_depleted")
purse.connect("coins_changed", self, "_on_Purse_coins_changed", [price])
func _on_Item_depleted():
disabled = true
func _on_Item_amount_changed(value):
amount = value
emit_signal("amount_changed", value)
func _on_Purse_coins_changed(coins, price):
if price > coins:
disabled = true
================================================
FILE: interface/items/ItemButton.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=1]
[ext_resource path="res://interface/items/ItemButton.gd" type="Script" id=2]
[ext_resource path="res://interface/theme/icons/purse.png" type="Texture" id=3]
[ext_resource path="res://interface/theme/icons/coins.png" type="Texture" id=4]
[node name="ItemButton" type="Button" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 300.0
margin_bottom = 60.0
rect_min_size = Vector2( 300, 60 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 1
theme = ExtResource( 1 )
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
flat = false
align = 1
script = ExtResource( 2 )
_sections_unfolded = [ "Focus", "Rect", "Size Flags", "Theme" ]
[node name="Name" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 1.0
margin_left = 54.0
margin_right = 254.0
rect_min_size = Vector2( 200, 0 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Item Name"
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Rect" ]
[node name="Icon" type="TextureRect" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 1.0
margin_right = 70.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 3 )
stretch_mode = 4
[node name="coins" type="TextureRect" parent="." index="2"]
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -41.0
margin_top = -18.0
margin_right = -9.0
margin_bottom = 14.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 4 )
stretch_mode = 0
[node name="Price" type="Label" parent="." index="3"]
anchor_left = 1.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -127.0
margin_right = -47.0
rect_min_size = Vector2( 80, 0 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "20"
align = 2
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Rect" ]
================================================
FILE: interface/items/ItemGrid.gd
================================================
extends GridContainer
func initialize():
update_focus_neighbours()
get_child(0).grab_focus()
func update_focus_neighbours(ignore=null):
var buttons_to_update = get_children()
# There's a bug with the Node.tree_exited signal so the button is still in the tree
if ignore:
buttons_to_update.remove(ignore.get_index())
var count = buttons_to_update.size()
var index = 0
for button in buttons_to_update:
var index_previous = index - 1
var index_next = (index + 1) % count
var button_previous = button.get_path_to(buttons_to_update[index_previous])
var button_next = button.get_path_to(buttons_to_update[index_next])
button.focus_neighbour_left = button_previous
button.focus_neighbour_right = button_next
button.focus_neighbour_top = button_previous
button.focus_neighbour_bottom = button_next
button.focus_previous = button_previous
button.focus_next = button_next
index += 1
================================================
FILE: interface/items/ItemsList.gd
================================================
extends Control
signal focused_button_changed(button)
signal item_amount_changed(amount)
signal focused_item_changed(item)
export(PackedScene) var ItemButton = preload("res://interface/items/ItemButton.tscn")
onready var _grid = $Grid
func initialize():
_grid.initialize()
func add_item_button(item, price, purse):
var item_button = ItemButton.instance()
item_button.initialize(item, price, purse)
_grid.add_child(item_button)
item_button.connect("focus_entered", self, "_on_ItemButton_focus_entered", [item_button, item])
item_button.connect("amount_changed", self, "_on_ItemButton_amount_changed")
return item_button
func _gui_input(event):
if not get_focus_owner() == self:
return
if event.is_action_pressed('ui_left') or \
event.is_action_pressed('ui_right') or \
event.is_action_pressed('ui_up') or \
event.is_action_pressed('ui_down'):
$MenuSfx/Navigate.play()
accept_event()
func get_item_buttons():
return _grid.get_children()
func _on_ItemButton_focus_entered(button, item):
emit_signal("focused_button_changed", button)
emit_signal("focused_item_changed", item)
func _on_ItemButton_amount_changed(value):
emit_signal("item_amount_changed", value)
================================================
FILE: interface/items/ItemsList.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://interface/items/ItemsList.gd" type="Script" id=1]
[ext_resource path="res://interface/items/ItemButton.tscn" type="PackedScene" id=2]
[ext_resource path="res://interface/items/ItemGrid.gd" type="Script" id=3]
[ext_resource path="res://interface/menus/MenuSfx.tscn" type="PackedScene" id=4]
[node name="ItemsList" type="Panel"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource( 1 )
_sections_unfolded = [ "Size Flags" ]
ItemButton = ExtResource( 2 )
[node name="Grid" type="GridContainer" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 40.0
margin_top = 40.0
margin_right = -40.0
margin_bottom = -40.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 1
custom_constants/vseparation = 16
custom_constants/hseparation = 16
columns = 2
script = ExtResource( 3 )
[node name="MenuSfx" parent="." index="1" instance=ExtResource( 4 )]
================================================
FILE: interface/menus/Menu.gd
================================================
extends Control
class_name Menu
signal open()
signal closed()
export(NodePath) var SUB_MENU_PATH
onready var sound_confirm = $MenuSfx/Confirm
onready var sound_navigate = $MenuSfx/Navigate
onready var sound_open = $MenuSfx/Open
func _ready():
set_process_input(false)
func open(args={}):
set_process_input(true)
show()
sound_open.play()
emit_signal("open")
func close():
sound_confirm.play()
set_process_input(false)
hide()
emit_signal("closed")
func _gui_input(event):
if event.is_action_pressed("ui_cancel"):
accept_event()
close()
# You can streamline opening sub menus with these methods
# The main drawback is you lose the initialize method's signature
# Instead you have to group the arguments in a dictionary
func initialize(args={}):
return
func open_sub_menu(menu, args={}):
var sub_menu = menu.instance() if menu is PackedScene else menu
if SUB_MENU_PATH:
get_node(SUB_MENU_PATH).add_child(sub_menu)
else:
add_child(sub_menu)
sub_menu.initialize(args)
set_process_input(false)
sub_menu.open(args)
yield(sub_menu, "closed")
set_process_input(true)
remove_child(sub_menu)
================================================
FILE: interface/menus/Menu.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=1]
[ext_resource path="res://interface/menus/Menu.gd" type="Script" id=2]
[ext_resource path="res://interface/menus/MenuSfx.tscn" type="PackedScene" id=3]
[node name="Menu" type="Control"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 1 )
script = ExtResource( 2 )
_sections_unfolded = [ "Theme" ]
SUB_MENU_PATH = null
[node name="MenuSfx" parent="." index="0" instance=ExtResource( 3 )]
================================================
FILE: interface/menus/MenuSfx.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://audio/sfx/menu_confirm.wav" type="AudioStream" id=1]
[ext_resource path="res://audio/sfx/menu_navigate_01.wav" type="AudioStream" id=2]
[ext_resource path="res://audio/sfx/menu_popup_open.wav" type="AudioStream" id=3]
[node name="MenuSfx" type="Node" index="0"]
[node name="Confirm" type="AudioStreamPlayer" parent="." index="0"]
stream = ExtResource( 1 )
volume_db = -1.0
pitch_scale = 1.0
autoplay = false
mix_target = 2
bus = "Interface"
[node name="Navigate" type="AudioStreamPlayer" parent="." index="1"]
stream = ExtResource( 2 )
volume_db = -6.0
pitch_scale = 1.0
autoplay = false
mix_target = 2
bus = "Interface"
[node name="Open" type="AudioStreamPlayer" parent="." index="2"]
stream = ExtResource( 3 )
volume_db = -3.0
pitch_scale = 1.0
autoplay = false
mix_target = 2
bus = "Interface"
================================================
FILE: interface/menus/MenuTitle.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://interface/theme/fonts/source_code_pro_26.tres" type="DynamicFont" id=1]
[sub_resource type="GDScript" id=1]
script/source = "tool
extends Control
export(String) var title = \"Title\" setget set_title
onready var label = $Label
func _ready():
set_title(title)
func set_title(string):
title = string
if not label:
return
label.text = string
"
[node name="TitlePanel" type="Panel" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1920.0
margin_bottom = 80.0
rect_min_size = Vector2( 0, 80 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
script = SubResource( 1 )
_sections_unfolded = [ "Rect" ]
title = "Title"
[node name="Label" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 2.0
margin_right = 2.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = ExtResource( 1 )
text = "Title"
align = 1
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
================================================
FILE: interface/menus/inventory/InventoryMenu.gd
================================================
extends Menu
onready var items_list = $Column/ItemsMenu
"""args: {inventory}"""
func initialize(args={}):
items_list.initialize(args['inventory'])
"""args: {inventory}"""
func open(args={}):
assert(args.size() == 1)
var inventory = args['inventory']
.open()
func close():
.close()
queue_free()
================================================
FILE: interface/menus/inventory/InventoryMenu.tscn
================================================
[gd_scene load_steps=6 format=2]
[ext_resource path="res://interface/menus/Menu.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/menus/inventory/InventoryMenu.gd" type="Script" id=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=3]
[ext_resource path="res://interface/menus/MenuTitle.tscn" type="PackedScene" id=4]
[ext_resource path="res://interface/menus/inventory/ItemsMenu.tscn" type="PackedScene" id=5]
[node name="InventoryMenu" instance=ExtResource( 1 )]
script = ExtResource( 2 )
[node name="Column" type="VBoxContainer" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 3 )
custom_constants/separation = 0
alignment = 0
_sections_unfolded = [ "Theme", "custom_constants" ]
[node name="TitlePanel" parent="Column" index="0" instance=ExtResource( 4 )]
title = "Inventory"
[node name="ItemsMenu" parent="Column" index="1" instance=ExtResource( 5 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 80.0
margin_right = 1920.0
margin_bottom = 1080.0
================================================
FILE: interface/menus/inventory/ItemButton.gd
================================================
extends Button
var description = ""
func initialize(item):
$Name.text = item.display_name
$Amount.text = str(item.amount)
$Icon.texture = item.icon
description = item.description
disabled = not item.usable
item.connect("amount_changed", self, "_on_Item_amount_changed")
item.connect("depleted", self, "queue_free")
func _on_Item_amount_changed(amount):
$Amount.text = str(amount)
================================================
FILE: interface/menus/inventory/ItemButton.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://interface/menus/inventory/ItemButton.gd" type="Script" id=1]
[ext_resource path="res://interface/theme/icons/purse.png" type="Texture" id=2]
[node name="ItemButton" type="Button" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 280.0
margin_bottom = 60.0
rect_min_size = Vector2( 300, 60 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
flat = false
align = 1
script = ExtResource( 1 )
_sections_unfolded = [ "Rect", "Size Flags" ]
[node name="Name" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 1.0
margin_left = 70.0
margin_right = 270.0
rect_min_size = Vector2( 200, 0 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Item Name"
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Rect" ]
[node name="Icon" type="TextureRect" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 1.0
margin_right = 70.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 2 )
stretch_mode = 4
[node name="Amount" type="Label" parent="." index="2"]
anchor_left = 1.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -100.0
margin_right = -20.0
rect_min_size = Vector2( 80, 0 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "20"
align = 2
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Rect" ]
================================================
FILE: interface/menus/inventory/ItemGrid.gd
================================================
extends GridContainer
onready var placeholder_button = $Placeholder
func _ready():
remove_child(placeholder_button)
func initialize(item_buttons):
for button in item_buttons:
add_child(button)
update_focus_neighbours()
for button in get_children():
button.connect("tree_exited", self, "_on_ItemButton_tree_exited", [button])
get_child(0).grab_focus()
add_child(placeholder_button)
func _on_ItemButton_tree_exited(button):
var to_focus_path = button.focus_neighbour_left if button.get_index() > 0 else button.focus_neighbour_right
button.get_node(to_focus_path).grab_focus()
update_focus_neighbours(button)
func update_focus_neighbours(ignore=null):
var buttons_to_update = get_children()
# There's a bug with the Node.tree_exited signal so the button is still in the tree
if ignore:
buttons_to_update.remove(ignore.get_index())
var count = buttons_to_update.size()
var index = 0
for button in buttons_to_update:
var index_previous = index - 1
var index_next = (index + 1) % count
button.focus_neighbour_left = button.get_path_to(buttons_to_update[index_previous])
button.focus_neighbour_right = button.get_path_to(buttons_to_update[index_next])
index += 1
================================================
FILE: interface/menus/inventory/ItemsMenu.gd
================================================
extends Control
signal item_use_requested(item, actor)
export(PackedScene) var ItemButton
onready var _item_grid = $Column/ItemsList/Margin/Grid
onready var _description_label = $Column/DescriptionPanel/Margin/Label
func initialize(inventory):
var buttons = []
for item in inventory.get_items():
var item_button = create_item_button(item)
item_button.connect("focus_entered", self, "_on_ItemButton_focus_entered")
item_button.connect("pressed", self, "_on_ItemButton_pressed", [item])
buttons.append(item_button)
_item_grid.initialize(buttons)
inventory.connect("item_added", self, "create_item_button")
connect("item_use_requested", inventory, "use")
func create_item_button(item):
var item_button = ItemButton.instance()
item_button.initialize(item)
return item_button
func _on_ItemButton_focus_entered():
_description_label.text = get_focus_owner().description
func _on_ItemButton_pressed(item):
var button = get_focus_owner()
$UserSelectMenu.open()
var actor = yield($UserSelectMenu, "closed")
button.grab_focus()
if not actor:
return
emit_signal("item_use_requested", item, actor)
================================================
FILE: interface/menus/inventory/ItemsMenu.tscn
================================================
[gd_scene load_steps=6 format=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=1]
[ext_resource path="res://interface/menus/inventory/ItemsMenu.gd" type="Script" id=2]
[ext_resource path="res://interface/menus/inventory/ItemButton.tscn" type="PackedScene" id=3]
[ext_resource path="res://interface/menus/inventory/ItemGrid.gd" type="Script" id=4]
[ext_resource path="res://interface/menus/inventory/user_select/UserSelectMenu.tscn" type="PackedScene" id=5]
[node name="ItemsMenu" type="Control"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 3
theme = ExtResource( 1 )
script = ExtResource( 2 )
_sections_unfolded = [ "Size Flags" ]
ItemButton = ExtResource( 3 )
[node name="Column" type="VBoxContainer" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
custom_constants/separation = 0
alignment = 0
[node name="ItemsList" type="Panel" parent="Column" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1920.0
margin_bottom = 980.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 3
[node name="Margin" type="MarginContainer" parent="Column/ItemsList" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
_sections_unfolded = [ "custom_constants" ]
[node name="Grid" type="GridContainer" parent="Column/ItemsList/Margin" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 16.0
margin_right = 1904.0
margin_bottom = 964.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 1
custom_constants/vseparation = 16
custom_constants/hseparation = 16
columns = 2
script = ExtResource( 4 )
_sections_unfolded = [ "custom_constants" ]
[node name="Placeholder" type="Button" parent="Column/ItemsList/Margin/Grid" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1888.0
margin_bottom = 27.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 1
disabled = true
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
flat = true
align = 1
_sections_unfolded = [ "Size Flags" ]
[node name="DescriptionPanel" type="Panel" parent="Column" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 980.0
margin_right = 1920.0
margin_bottom = 1080.0
rect_min_size = Vector2( 0, 100 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
_sections_unfolded = [ "Rect" ]
[node name="Margin" type="MarginContainer" parent="Column/DescriptionPanel" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
[node name="Label" type="Label" parent="Column/DescriptionPanel/Margin" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0
margin_top = 25.0
margin_right = 1904.0
margin_bottom = 74.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Item descripton here.
"
autowrap = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="UserSelectMenu" parent="." index="1" instance=ExtResource( 5 )]
visible = false
================================================
FILE: interface/menus/inventory/user_select/ActorButton.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://actors/body.png" type="Texture" id=1]
[node name="ActorButton" type="Button"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 310.0
margin_right = 420.0
margin_bottom = 410.0
rect_min_size = Vector2( 300, 100 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
flat = false
align = 1
_sections_unfolded = [ "Rect", "Size Flags" ]
[node name="Name" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 1.0
margin_left = 90.0
margin_right = 290.0
rect_min_size = Vector2( 200, 0 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Actor"
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Rect" ]
[node name="Icon" type="TextureRect" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 1.0
margin_right = 90.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 1 )
stretch_mode = 4
================================================
FILE: interface/menus/inventory/user_select/UserSelectMenu.gd
================================================
extends Control
signal closed(selected_actor)
export(PackedScene) var ActorButton
func _ready():
set_as_toplevel(true)
func initialize(actors):
for actor in actors:
create_actor_button(actor)
func create_actor_button(actor):
var button = ActorButton.instance()
button.get_node("Name").text = actor.name
button.connect("pressed", self, "_on_SelectButton_pressed", [actor])
$ActorsList.add_child(button)
func _input(event):
if event.is_action_pressed("ui_cancel"):
close()
func _on_SelectButton_pressed(actor):
close(actor)
# TODO: Temporarily bypassing the menu,
# see https://github.com/GDquest/make-pro-2d-games-with-godot/issues/66
func open():
close()
return
$ActorsList.get_child(0).grab_focus()
visible = true
set_process_input(true)
func close(selected_actor=null):
visible = false
set_process_input(false)
emit_signal("closed", selected_actor)
================================================
FILE: interface/menus/inventory/user_select/UserSelectMenu.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://interface/menus/inventory/user_select/UserSelectMenu.gd" type="Script" id=1]
[ext_resource path="res://interface/menus/inventory/user_select/ActorButton.tscn" type="PackedScene" id=2]
[node name="UserSelectMenu" type="Control" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
script = ExtResource( 1 )
ActorButton = ExtResource( 2 )
[node name="BlackOverlay" type="ColorRect" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
color = Color( 0, 0, 0, 0.313726 )
[node name="ActorsList" type="VBoxContainer" parent="." index="1"]
anchor_left = 0.5
anchor_top = 0.0
anchor_right = 0.5
anchor_bottom = 1.0
margin_left = -210.0
margin_right = 210.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
alignment = 1
================================================
FILE: interface/menus/pause/OptionsMenu.gd
================================================
extends Menu
const SoundController = preload("res://interface/menus/pause/SoundController.gd")
onready var first_slider = $Column/MusicController/Row/HSlider
func open(args={}):
.open()
first_slider.grab_focus()
set_focus_neighbors()
func set_focus_neighbors():
"""
Loops through the sliders and assign their focus neighbors manually
This fixes keyboard navigation in the options menu
"""
var sliders = get_sound_sliders()
var index = 0
for slider in sliders:
var index_previous = index - 1
if index_previous >= 0:
slider.focus_neighbour_top = slider.
gitextract_59bn93hr/
├── .github/
│ └── CONTRIBUTING.md
├── .gitignore
├── Demo.tscn
├── LICENSE
├── README.md
├── actors/
│ ├── Actor.gd
│ ├── Actor.tscn
│ ├── CoinsAttractor.tscn
│ ├── CoinsCollector.gd
│ ├── CoinsCollector.tscn
│ ├── CoinsFountain.gd
│ ├── CoinsFountain.tscn
│ ├── DamageSource.gd
│ ├── DamageSource.tscn
│ ├── body.png.import
│ ├── camera/
│ │ ├── ShakingCamera.gd
│ │ └── ShakingCamera.tscn
│ ├── characters/
│ │ └── seller/
│ │ ├── Seller.gd
│ │ └── Seller.tscn
│ ├── health/
│ │ ├── Stats.gd
│ │ ├── Stats.tscn
│ │ └── Status.gd
│ ├── hit_box/
│ │ ├── HitBox.gd
│ │ ├── HitBox.tscn
│ │ └── hitbox_default.tres
│ ├── player/
│ │ ├── Player.tscn
│ │ ├── PlayerController.gd
│ │ ├── PlayerStateMachine.gd
│ │ ├── body.png.import
│ │ ├── shadow.png.import
│ │ └── states/
│ │ ├── Die.gd
│ │ ├── Fall.gd
│ │ ├── combat/
│ │ │ ├── Attack.gd
│ │ │ └── Stagger.gd
│ │ ├── debug/
│ │ │ └── StateNameDisplayer.gd
│ │ └── motion/
│ │ ├── Motion.gd
│ │ ├── in_air/
│ │ │ └── Jump.gd
│ │ └── on_ground/
│ │ ├── BumpPlayer.gd
│ │ ├── Idle.gd
│ │ ├── Move.gd
│ │ └── OnGround.gd
│ ├── shadow.png.import
│ └── weapons/
│ ├── bullet/
│ │ ├── Bullet.tscn
│ │ ├── BulletSpawner.gd
│ │ └── bullet.gd
│ └── sword/
│ ├── Sword.gd
│ ├── Sword.tscn
│ ├── WeaponPivot.gd
│ └── sword.png.import
├── audio/
│ ├── AudioShuffleStepSounds.gd
│ ├── AudioStreamPlayer.tscn
│ ├── MusicPlayer.gd
│ ├── MusicPlayer.tscn
│ ├── music/
│ │ ├── birdy_pong.ogg
│ │ └── birdy_pong.ogg.import
│ └── sfx/
│ ├── menu_confirm.wav.import
│ ├── menu_navigate_01.wav.import
│ ├── menu_navigate_02.wav.import
│ ├── menu_popup_open.wav.import
│ ├── step_01.wav.import
│ └── step_02.wav.import
├── core/
│ ├── Game.gd
│ ├── LevelLoader.gd
│ ├── inventory/
│ │ ├── Inventory.gd
│ │ ├── Inventory.tscn
│ │ ├── ItemDatabase.gd
│ │ ├── ItemDatabase.tscn
│ │ └── items/
│ │ ├── Coins.gd
│ │ ├── Coins.tscn
│ │ ├── Item.gd
│ │ ├── Item.tscn
│ │ ├── coins/
│ │ │ ├── coin_single.png.import
│ │ │ ├── coins_stack.png.import
│ │ │ └── coins_three.png.import
│ │ ├── equipment/
│ │ │ ├── Equipment.gd
│ │ │ ├── Equipment.tscn
│ │ │ └── sword/
│ │ │ └── Sword.tscn
│ │ └── usable/
│ │ ├── potions/
│ │ │ ├── BaseHealthPotion.tscn
│ │ │ ├── HealthPotion.gd
│ │ │ └── restore_health/
│ │ │ ├── MinorHealthPotion.tscn
│ │ │ └── StrongHealthPotion.tscn
│ │ └── scroll_fireball/
│ │ ├── FireballScroll.gd
│ │ ├── FireballScroll.tscn
│ │ └── fireball/
│ │ ├── Fireball.gd
│ │ ├── Fireball.tscn
│ │ └── particles/
│ │ ├── FireballParticles.tscn
│ │ ├── ParticlesToggle.gd
│ │ ├── assets/
│ │ │ └── gradient_ramps/
│ │ │ ├── fire_to_black.tres
│ │ │ ├── sparkles.tres
│ │ │ └── sparkles_small.tres
│ │ ├── explosions/
│ │ │ ├── Explosion.gd
│ │ │ └── Explosion.tscn
│ │ ├── fireball/
│ │ │ ├── fireball.material
│ │ │ └── fireball_big.material
│ │ └── sprites/
│ │ ├── circle.png.import
│ │ └── smoke_clouds.png.import
│ ├── save/
│ │ ├── SaveAndLoad.gd
│ │ └── SaveAndLoad.tscn
│ ├── shop/
│ │ ├── Shop.gd
│ │ ├── Shop.tscn
│ │ └── purse/
│ │ ├── Purse.gd
│ │ └── Purse.tscn
│ └── world/
│ ├── Door.gd
│ ├── Door.tscn
│ ├── Gap.gd
│ ├── Gap.tscn
│ ├── PlayerSpawningPoint.tscn
│ ├── Rock.tscn
│ ├── pit.png.import
│ ├── rock.png.import
│ ├── stairs.png.import
│ └── tilesets/
│ ├── cave/
│ │ ├── cave.png.import
│ │ ├── cave.tres
│ │ └── cave_tileset_src.tscn
│ └── outdoor/
│ ├── outdoor.png.import
│ ├── outdoor.tres
│ ├── outdoor.tscn
│ └── pit.png.import
├── default_bus_layout.tres
├── default_env.tres
├── icon.png.import
├── interface/
│ ├── Interface.gd
│ ├── TopLevelUi.gd
│ ├── default.theme
│ ├── fonts/
│ │ ├── montserrat_black_48.tres
│ │ ├── source_code_pro_explanations.tres
│ │ └── source_code_pro_explanations_bold.tres
│ ├── gui/
│ │ ├── boss/
│ │ │ ├── BossLifebar.gd
│ │ │ ├── BossLifebar.tscn
│ │ │ ├── boss_bar_bg.png.import
│ │ │ └── boss_bar_fill.png.import
│ │ ├── lifebar/
│ │ │ ├── HookableLifeBar.tscn
│ │ │ ├── InterfaceAnchor.tscn
│ │ │ ├── Lifebar.gd
│ │ │ ├── LifebarsBuilder.gd
│ │ │ ├── LifebarsBuilder.tscn
│ │ │ ├── background.png.import
│ │ │ └── fill.png.import
│ │ └── player/
│ │ ├── PlayerGUI.gd
│ │ ├── PlayerGUI.tscn
│ │ └── life_bar/
│ │ ├── LifeBar.tscn
│ │ ├── Lifebar.gd
│ │ ├── TextureProgress.gd
│ │ ├── bg.png.import
│ │ └── fill.png.import
│ ├── items/
│ │ ├── ItemButton.gd
│ │ ├── ItemButton.tscn
│ │ ├── ItemGrid.gd
│ │ ├── ItemsList.gd
│ │ └── ItemsList.tscn
│ ├── menus/
│ │ ├── Menu.gd
│ │ ├── Menu.tscn
│ │ ├── MenuSfx.tscn
│ │ ├── MenuTitle.tscn
│ │ ├── inventory/
│ │ │ ├── InventoryMenu.gd
│ │ │ ├── InventoryMenu.tscn
│ │ │ ├── ItemButton.gd
│ │ │ ├── ItemButton.tscn
│ │ │ ├── ItemGrid.gd
│ │ │ ├── ItemsMenu.gd
│ │ │ ├── ItemsMenu.tscn
│ │ │ └── user_select/
│ │ │ ├── ActorButton.tscn
│ │ │ ├── UserSelectMenu.gd
│ │ │ └── UserSelectMenu.tscn
│ │ ├── pause/
│ │ │ ├── OptionsMenu.gd
│ │ │ ├── OptionsMenu.tscn
│ │ │ ├── PauseMenu.gd
│ │ │ ├── PauseMenu.tscn
│ │ │ ├── SoundController.gd
│ │ │ └── SoundController.tscn
│ │ ├── save_and_load/
│ │ │ ├── SaveMenu.gd
│ │ │ └── SaveMenu.tscn
│ │ ├── shared/
│ │ │ ├── Button.gd
│ │ │ └── Button.tscn
│ │ └── shop/
│ │ ├── ShopMenu.gd
│ │ ├── ShopMenu.tscn
│ │ ├── menus/
│ │ │ ├── BuySubMenu.tscn
│ │ │ ├── SellSubMenu.tscn
│ │ │ ├── ShopSubMenu.gd
│ │ │ └── ShopSubMenu.tscn
│ │ ├── panels/
│ │ │ ├── DescriptionPanel.gd
│ │ │ ├── DescriptionPanel.tscn
│ │ │ ├── InfoPanel.gd
│ │ │ ├── InfoPanel.tscn
│ │ │ └── ShopItemsList.tscn
│ │ └── popups/
│ │ ├── AmountLabel.gd
│ │ ├── AmountPopup.gd
│ │ ├── AmountPopup.tscn
│ │ └── HSlider.gd
│ └── theme/
│ ├── button/
│ │ ├── disabled.stylebox
│ │ ├── focused.stylebox
│ │ ├── hover.stylebox
│ │ ├── normal.stylebox
│ │ └── pressed.stylebox
│ ├── empty.stylebox
│ ├── fonts/
│ │ ├── comfortaa_tips.tres
│ │ ├── default_font_comfortaa.tres
│ │ └── source_code_pro_26.tres
│ ├── icons/
│ │ ├── add.png.import
│ │ ├── cancel.png.import
│ │ ├── coins.png.import
│ │ ├── fire_scroll.png.import
│ │ ├── potion_health.png.import
│ │ ├── potion_mana.png.import
│ │ ├── purse.png.import
│ │ ├── remove.png.import
│ │ └── sword.png.import
│ ├── panel/
│ │ └── panel.stylebox
│ └── slider/
│ └── slider.stylebox
├── levels/
│ ├── Cave.tscn
│ ├── Grasslands.tscn
│ ├── Level.gd
│ └── TestLevel.tscn
├── monsters/
│ ├── BossShakingCamera.gd
│ ├── BossShakingCamera.tscn
│ ├── Monster.gd
│ ├── Monster.tscn
│ ├── ObstacleDetector.gd
│ ├── bosses/
│ │ └── wild_boar/
│ │ ├── WildBoar.gd
│ │ ├── WildBoar.tscn
│ │ ├── WildBoarFSM.gd
│ │ ├── debug/
│ │ │ ├── BossStatesDisplayer.gd
│ │ │ ├── StatesStackDiplayer.tscn
│ │ │ ├── StatesStackDisplayer.gd
│ │ │ └── fonts/
│ │ │ └── source-code-pro-bold.otf
│ │ ├── sprites/
│ │ │ ├── front.png.import
│ │ │ ├── wild_boar_stomp_1.png.import
│ │ │ └── wild_boar_stomp_2.png.import
│ │ └── states/
│ │ ├── Die.gd
│ │ ├── Follow.gd
│ │ ├── ReturnToCenter.gd
│ │ ├── Spawn.gd
│ │ ├── charge/
│ │ │ ├── BumpWildBoar.gd
│ │ │ ├── Prepare.gd
│ │ │ └── Sprint.gd
│ │ ├── roam/
│ │ │ ├── MoveToRandomPosition.gd
│ │ │ ├── RoamSequence.gd
│ │ │ └── Wait.gd
│ │ └── stomp/
│ │ ├── GroundExplosion.gd
│ │ ├── GroundExplosion.tscn
│ │ ├── Stomp.gd
│ │ └── Stomp.tscn
│ ├── exclamation-mark.png.import
│ ├── exclamation-mark.svg.import
│ ├── mosquito/
│ │ ├── Mosquito.gd
│ │ ├── Mosquito.tscn
│ │ ├── Nest.gd
│ │ ├── Nest.tscn
│ │ ├── mosquito.png.import
│ │ └── nest.png.import
│ └── porcupine/
│ ├── Porcupine.gd
│ ├── Porcupine.tscn
│ └── porcupine.png.import
├── project.godot
├── utils/
│ ├── autoload/
│ │ └── Steering.gd
│ ├── debug/
│ │ ├── ControlsPanel.tscn
│ │ ├── Explanations.tscn
│ │ ├── StatesStackDiplayer.tscn
│ │ ├── StatesStackDisplayer.gd
│ │ └── TopLevelUI.gd
│ └── state/
│ ├── Sequence.gd
│ ├── Sequence.tscn
│ ├── State.gd
│ ├── StateMachine.gd
│ └── StateMachine.tscn
└── vfx/
├── Fog.gd
├── TransitionColor.gd
├── TransitionColor.tscn
├── fog.shader
├── fog_background.material
├── fog_foreground.material
├── masks/
│ └── curtain.png.import
├── particles/
│ ├── SelfDestructingParticles.gd
│ ├── assets/
│ │ └── gradient_ramps/
│ │ ├── fire_to_black.tres
│ │ ├── sparkles.tres
│ │ └── sparkles_small.tres
│ ├── dust_charge/
│ │ ├── DustCharge.tscn
│ │ ├── DustChargeLarge.tscn
│ │ └── puffs.png.import
│ ├── dust_puffs/
│ │ ├── DustPuffs.tscn
│ │ ├── DustPuffsLarge.tscn
│ │ ├── DustRun.tscn
│ │ ├── DustWalk.tscn
│ │ ├── dust_puffs_particle.tres
│ │ ├── puff_stylized.png.import
│ │ └── puffs.png.import
│ ├── explosions/
│ │ ├── Explosion.gd
│ │ ├── Explosion.tscn
│ │ ├── ExplosionFlash.tscn
│ │ └── circle.png.import
│ ├── fiery_cloud/
│ │ ├── FieryCloud.tscn
│ │ ├── Fireball.tscn
│ │ └── FireryCloud.gd
│ ├── rocks/
│ │ ├── DirectionalRock.tscn
│ │ ├── crumbs.png.import
│ │ ├── crumbs_particle.tres
│ │ ├── rocks.png.import
│ │ └── rocks_particle.tres
│ └── smoke/
│ ├── EnemySmokeScreen.tscn
│ ├── ParticlesPlayer.gd
│ ├── smoke.png.import
│ └── smoke_screen_particle.tres
├── transition.material
└── transition.shader
Condensed preview — 304 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (455K chars).
[
{
"path": ".github/CONTRIBUTING.md",
"chars": 2525,
"preview": "# Contributing Guidelines\n\n<!-- How to contribute -->\n<!-- How to join the community -->\n<!-- How to get support -->\n\n<!"
},
{
"path": ".gitignore",
"chars": 20,
"preview": ".import\n.projectile\n"
},
{
"path": "Demo.tscn",
"chars": 2995,
"preview": "[gd_scene load_steps=14 format=2]\n\n[ext_resource path=\"res://core/Game.gd\" type=\"Script\" id=1]\n[ext_resource path=\"res:/"
},
{
"path": "LICENSE",
"chars": 1064,
"preview": "MIT License\n\nCopyright (c) 2018 GDquest\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
},
{
"path": "README.md",
"chars": 3634,
"preview": "<h1 align=\"center\">\n Make Pro 2d Games with Godot</br>\n <small>Open Source A-RPG Demo</small>\n</h1>\n\n<p align='center'"
},
{
"path": "actors/Actor.gd",
"chars": 611,
"preview": "extends KinematicBody2D\n\nsignal direction_changed(new_direction)\nsignal position_changed(new_position)\nsignal died()\n\non"
},
{
"path": "actors/Actor.tscn",
"chars": 5399,
"preview": "[gd_scene load_steps=11 format=2]\n\n[ext_resource path=\"res://actors/health/Stats.tscn\" type=\"PackedScene\" id=1]\n[ext_res"
},
{
"path": "actors/CoinsAttractor.tscn",
"chars": 504,
"preview": "[gd_scene load_steps=2 format=2]\n\n[sub_resource type=\"CircleShape2D\" id=2]\n\ncustom_solver_bias = 0.0\nradius = 41.2311\n\n["
},
{
"path": "actors/CoinsCollector.gd",
"chars": 246,
"preview": "extends Area2D\n\nsignal coins_received(amount)\n\nconst Coins = preload(\"res://core/inventory/items/Coins.gd\")\n\nfunc _on_ar"
},
{
"path": "actors/CoinsCollector.tscn",
"chars": 711,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://actors/CoinsCollector.gd\" type=\"Script\" id=1]\n\n[sub_resource"
},
{
"path": "actors/CoinsFountain.gd",
"chars": 448,
"preview": "extends Position2D\n\nconst Coins = preload(\"res://core/inventory/items/Coins.tscn\")\n\nonready var timer = $Timer\n\nexport(i"
},
{
"path": "actors/CoinsFountain.tscn",
"chars": 911,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://actors/CoinsFountain.gd\" type=\"Script\" id=1]\n\n[sub_resource "
},
{
"path": "actors/DamageSource.gd",
"chars": 119,
"preview": "extends Area2D\n\nexport(int) var damage = 2\nvar effect\n\nfunc set_active(value):\n\t$CollisionShape2D.disabled = not value\n"
},
{
"path": "actors/DamageSource.tscn",
"chars": 449,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://actors/DamageSource.gd\" type=\"Script\" id=1]\n\n[node name=\"Dam"
},
{
"path": "actors/body.png.import",
"chars": 647,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/body.png-e947538dbfd8a8c2e1335860c186fed8.stex\"\nmet"
},
{
"path": "actors/camera/ShakingCamera.gd",
"chars": 1011,
"preview": "tool\nextends Camera2D\n\nexport(float) var amplitude = 6.0\nexport(float) var duration = 0.8 setget set_duration\nexport(flo"
},
{
"path": "actors/camera/ShakingCamera.tscn",
"chars": 1031,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://actors/camera/ShakingCamera.gd\" type=\"Script\" id=1]\n\n[node n"
},
{
"path": "actors/characters/seller/Seller.gd",
"chars": 356,
"preview": "extends Area2D\n\nsignal shop_open_requested(shop, user)\n\nconst Player = preload(\"res://actors/player/PlayerController.gd\""
},
{
"path": "actors/characters/seller/Seller.tscn",
"chars": 947,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://actors/characters/seller/Seller.gd\" type=\"Script\" id=1]\n[ext"
},
{
"path": "actors/health/Stats.gd",
"chars": 760,
"preview": "extends Node\n\nsignal health_changed(new_health)\nsignal damage_taken(new_health)\nsignal health_depleted()\n\nvar modifiers "
},
{
"path": "actors/health/Stats.tscn",
"chars": 227,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://actors/health/Stats.gd\" type=\"Script\" id=1]\n\n[node name=\"Sta"
},
{
"path": "actors/health/Status.gd",
"chars": 652,
"preview": "extends Node\n\nsignal added(status)\nsignal removed(status)\n\nvar statuses_active = {}\n\n# Example status\nconst POISON = {\n\t"
},
{
"path": "actors/hit_box/HitBox.gd",
"chars": 241,
"preview": "extends Area2D\n\nconst DamageSource = preload(\"res://actors/DamageSource.gd\")\n\nfunc _on_area_entered(area):\n\tif not area "
},
{
"path": "actors/hit_box/HitBox.tscn",
"chars": 746,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://actors/hit_box/HitBox.gd\" type=\"Script\" id=1]\n[ext_resource "
},
{
"path": "actors/hit_box/hitbox_default.tres",
"chars": 99,
"preview": "[gd_resource type=\"CircleShape2D\" format=2]\n\n[resource]\n\ncustom_solver_bias = 0.0\nradius = 99.636\n\n"
},
{
"path": "actors/player/Player.tscn",
"chars": 16344,
"preview": "[gd_scene load_steps=37 format=2]\n\n[ext_resource path=\"res://actors/player/PlayerController.gd\" type=\"Script\" id=1]\n[ext"
},
{
"path": "actors/player/PlayerController.gd",
"chars": 1375,
"preview": "extends \"res://actors/Actor.gd\"\n\nonready var weapon = $BodyPivot/WeaponPivot/Offset/Sword\nonready var camera = $ShakingC"
},
{
"path": "actors/player/PlayerStateMachine.gd",
"chars": 1227,
"preview": "extends \"res://utils/state/StateMachine.gd\"\n\nfunc _ready():\n\tstates_map = {\n\t\t'idle': $Idle,\n\t\t'move': $Move,\n\t\t'jump': "
},
{
"path": "actors/player/body.png.import",
"chars": 654,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/body.png-f9a1fa1c6faee90775a5169653a19c8b.stex\"\nmet"
},
{
"path": "actors/player/shadow.png.import",
"chars": 660,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/shadow.png-a76d0d66e7c861fcbe21472ca29df610.stex\"\nm"
},
{
"path": "actors/player/states/Die.gd",
"chars": 195,
"preview": "extends \"res://utils/state/State.gd\"\n\nfunc enter():\n\towner.set_dead(true)\n\towner.get_node(\"AnimationPlayer\").play(\"die\")"
},
{
"path": "actors/player/states/Fall.gd",
"chars": 174,
"preview": "extends \"res://utils/state/State.gd\"\n\nfunc enter():\n\towner.get_node('AnimationPlayer').play('fall')\n\nfunc _on_animation_"
},
{
"path": "actors/player/states/combat/Attack.gd",
"chars": 416,
"preview": "\"\"\"\nThe stagger state end with the stagger animation from the AnimationPlayer\nThe animation only affects the Body Sprite"
},
{
"path": "actors/player/states/combat/Stagger.gd",
"chars": 486,
"preview": "\"\"\"\nThe stagger state end with the stagger animation from the AnimationPlayer\nThe animation only affects the Body Sprite"
},
{
"path": "actors/player/states/debug/StateNameDisplayer.gd",
"chars": 94,
"preview": "extends Label\n\nfunc _on_StateMachine_state_changed(current_state):\n\ttext = current_state.name\n"
},
{
"path": "actors/player/states/motion/Motion.gd",
"chars": 1207,
"preview": "# Collection of important methods to handle direction and animation\nextends \"res://utils/state/State.gd\"\n\nfunc handle_in"
},
{
"path": "actors/player/states/motion/in_air/Jump.gd",
"chars": 1917,
"preview": "extends \"../Motion.gd\"\n\nexport(float) var BASE_MAX_HORIZONTAL_SPEED = 400.0\n\nexport(float) var AIR_ACCELERATION = 1000.0"
},
{
"path": "actors/player/states/motion/on_ground/BumpPlayer.gd",
"chars": 378,
"preview": "extends \"res://utils/state/State.gd\"\n\nexport(float) var SPEED = 240.0\nvar direction = Vector2(-1.0, 0.0)\n\nfunc _on_Move_"
},
{
"path": "actors/player/states/motion/on_ground/Idle.gd",
"chars": 262,
"preview": "extends \"OnGround.gd\"\n\nfunc enter():\n\towner.get_node(\"AnimationPlayer\").play(\"idle\")\n\nfunc handle_input(event):\n\treturn "
},
{
"path": "actors/player/states/motion/on_ground/Move.gd",
"chars": 1282,
"preview": "extends \"OnGround.gd\"\n\nsignal last_moved(direction)\n\nexport(float) var MAX_WALK_SPEED = 450\nexport(float) var MAX_RUN_SP"
},
{
"path": "actors/player/states/motion/on_ground/OnGround.gd",
"chars": 192,
"preview": "extends \"../Motion.gd\"\n\nvar speed = 0.0\nvar velocity = Vector2()\n\nfunc handle_input(event):\n\tif event.is_action_pressed("
},
{
"path": "actors/shadow.png.import",
"chars": 653,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/shadow.png-c2c688bd1e688f17d176ab7d3afdad57.stex\"\nm"
},
{
"path": "actors/weapons/bullet/Bullet.tscn",
"chars": 538,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://actors/weapons/bullet/bullet.gd\" type=\"Script\" id=1]\n\n[sub_r"
},
{
"path": "actors/weapons/bullet/BulletSpawner.gd",
"chars": 326,
"preview": "extends Node2D\n\nvar bullet = preload(\"Bullet.tscn\")\n\nfunc _input(event):\n\tif event.is_action_pressed(\"fire\"):\n\t\tfire(own"
},
{
"path": "actors/weapons/bullet/bullet.gd",
"chars": 571,
"preview": "extends KinematicBody2D\n\n\nvar direction = Vector2()\nexport(float) var SPEED = 1000.0\n\nfunc _ready():\n\tset_as_toplevel(tr"
},
{
"path": "actors/weapons/sword/Sword.gd",
"chars": 1800,
"preview": "extends \"res://actors/DamageSource.gd\"\n\nsignal combo_finished()\n\nenum States { IDLE, ATTACK }\nvar state = null\n\nenum Att"
},
{
"path": "actors/weapons/sword/Sword.tscn",
"chars": 8279,
"preview": "[gd_scene load_steps=8 format=2]\n\n[ext_resource path=\"res://actors/weapons/sword/Sword.gd\" type=\"Script\" id=1]\n[ext_reso"
},
{
"path": "actors/weapons/sword/WeaponPivot.gd",
"chars": 158,
"preview": "extends Position2D\n\nfunc _on_Player_direction_changed(new_direction):\n\trotation = new_direction.angle()\n\tshow_behind_par"
},
{
"path": "actors/weapons/sword/sword.png.import",
"chars": 664,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/sword.png-2705643189a083599451044bb61b43fc.stex\"\nme"
},
{
"path": "audio/AudioShuffleStepSounds.gd",
"chars": 351,
"preview": "extends AudioStreamPlayer\n\n# In Godot 3.1 you can export the Array instead\nvar samples = [\n\tpreload(\"res://audio/sfx/ste"
},
{
"path": "audio/AudioStreamPlayer.tscn",
"chars": 296,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://audio/AudioShuffleStepSounds.gd\" type=\"Script\" id=1]\n\n\n[node"
},
{
"path": "audio/MusicPlayer.gd",
"chars": 50,
"preview": "extends AudioStreamPlayer\n\nfunc _ready():\n\tplay()\n"
},
{
"path": "audio/MusicPlayer.tscn",
"chars": 322,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://audio/music/birdy_pong.ogg\" type=\"AudioStream\" id=1]\n\n[node "
},
{
"path": "audio/music/birdy_pong.ogg.import",
"chars": 316,
"preview": "[remap]\n\nimporter=\"ogg_vorbis\"\ntype=\"AudioStreamOGGVorbis\"\npath=\"res://.import/birdy_pong.ogg-25193f4693fd63a5305fa3c526"
},
{
"path": "audio/sfx/menu_confirm.wav.import",
"chars": 429,
"preview": "[remap]\n\nimporter=\"wav\"\ntype=\"AudioStreamSample\"\npath=\"res://.import/menu_confirm.wav-b14347e8ceccbb161b72ec9db2392e19.s"
},
{
"path": "audio/sfx/menu_navigate_01.wav.import",
"chars": 441,
"preview": "[remap]\n\nimporter=\"wav\"\ntype=\"AudioStreamSample\"\npath=\"res://.import/menu_navigate_01.wav-773eee8fbe1dd9eb11962e36b57bc6"
},
{
"path": "audio/sfx/menu_navigate_02.wav.import",
"chars": 441,
"preview": "[remap]\n\nimporter=\"wav\"\ntype=\"AudioStreamSample\"\npath=\"res://.import/menu_navigate_02.wav-671622ef2a874b5827dcda32ef1e01"
},
{
"path": "audio/sfx/menu_popup_open.wav.import",
"chars": 438,
"preview": "[remap]\n\nimporter=\"wav\"\ntype=\"AudioStreamSample\"\npath=\"res://.import/menu_popup_open.wav-51859fa0446f42584709772f4d8e840"
},
{
"path": "audio/sfx/step_01.wav.import",
"chars": 414,
"preview": "[remap]\n\nimporter=\"wav\"\ntype=\"AudioStreamSample\"\npath=\"res://.import/step_01.wav-daf925df75ada545cb636d177cd40f57.sample"
},
{
"path": "audio/sfx/step_02.wav.import",
"chars": 414,
"preview": "[remap]\n\nimporter=\"wav\"\ntype=\"AudioStreamSample\"\npath=\"res://.import/step_02.wav-f7737a1e06e1f3d2e9e00fd041d0652d.sample"
},
{
"path": "core/Game.gd",
"chars": 1170,
"preview": "extends Node\n\nonready var level_loader = $LevelLoader\nonready var transition = $Overlays/TransitionColor\nonready var pau"
},
{
"path": "core/LevelLoader.gd",
"chars": 798,
"preview": "extends Node\n\nsignal loaded(level)\n\nexport(String, FILE, \"*.tscn\") var LEVEL_START\n\nvar map\nonready var player = $Player"
},
{
"path": "core/inventory/Inventory.gd",
"chars": 1362,
"preview": "extends Node\n\nsignal content_changed(items_as_string)\nsignal item_added(item)\nsignal item_removed(item)\n\nfunc get_items("
},
{
"path": "core/inventory/Inventory.tscn",
"chars": 176,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://core/inventory/Inventory.gd\" type=\"Script\" id=1]\n\n\n[node nam"
},
{
"path": "core/inventory/ItemDatabase.gd",
"chars": 172,
"preview": "extends Node\n\nfunc get_item(reference):\n\tfor item in get_children():\n\t\tif reference.name == item.name:\n\t\t\treturn item.du"
},
{
"path": "core/inventory/ItemDatabase.tscn",
"chars": 957,
"preview": "[gd_scene load_steps=6 format=2]\n\n[ext_resource path=\"res://core/inventory/ItemDatabase.gd\" type=\"Script\" id=1]\n[ext_res"
},
{
"path": "core/inventory/items/Coins.gd",
"chars": 2119,
"preview": "tool\nextends Area2D\n\nenum CoinAmounts {SMALL=10, MID=30, HIGH=100}\n\nexport(CoinAmounts) var amount = CoinAmounts.SMALL s"
},
{
"path": "core/inventory/items/Coins.tscn",
"chars": 1123,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://core/inventory/items/Coins.gd\" type=\"Script\" id=1]\n[ext_reso"
},
{
"path": "core/inventory/items/Item.gd",
"chars": 645,
"preview": "extends Node\n\nsignal amount_changed(amount)\nsignal depleted()\n\nexport(Texture) var icon\nexport(String) var display_name "
},
{
"path": "core/inventory/items/Item.tscn",
"chars": 350,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://core/inventory/items/Item.gd\" type=\"Script\" id=1]\n[ext_resou"
},
{
"path": "core/inventory/items/coins/coin_single.png.import",
"chars": 688,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/coin_single.png-d22b36184b3f7cd2e981df8d72015e0f.st"
},
{
"path": "core/inventory/items/coins/coins_stack.png.import",
"chars": 688,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/coins_stack.png-b4644d39c8e95f1e5c2242620e4272e4.st"
},
{
"path": "core/inventory/items/coins/coins_three.png.import",
"chars": 688,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/coins_three.png-29938721d7b59c8b32b7201678affe18.st"
},
{
"path": "core/inventory/items/equipment/Equipment.gd",
"chars": 129,
"preview": "extends '../Item.gd'\n\nexport(int) var STRENGTH = 0\nexport(int) var MAGIC = 0\nexport(int) var ARMOR = 0\nexport(int) var S"
},
{
"path": "core/inventory/items/equipment/Equipment.tscn",
"chars": 354,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://core/inventory/items/Item.tscn\" type=\"PackedScene\" id=1]\n[ex"
},
{
"path": "core/inventory/items/equipment/sword/Sword.tscn",
"chars": 420,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://core/inventory/items/equipment/Equipment.tscn\" type=\"PackedS"
},
{
"path": "core/inventory/items/usable/potions/BaseHealthPotion.tscn",
"chars": 350,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://core/inventory/items/Item.tscn\" type=\"PackedScene\" id=1]\n[ex"
},
{
"path": "core/inventory/items/usable/potions/HealthPotion.gd",
"chars": 239,
"preview": "extends \"res://core/inventory/items/Item.gd\"\n\nexport(int) var HEAL_AMOUNT = 20\n\nfunc _apply_effect(user):\n\tif not user.h"
},
{
"path": "core/inventory/items/usable/potions/restore_health/MinorHealthPotion.tscn",
"chars": 430,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://core/inventory/items/usable/potions/BaseHealthPotion.tscn\" t"
},
{
"path": "core/inventory/items/usable/potions/restore_health/StrongHealthPotion.tscn",
"chars": 434,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://core/inventory/items/usable/potions/BaseHealthPotion.tscn\" t"
},
{
"path": "core/inventory/items/usable/scroll_fireball/FireballScroll.gd",
"chars": 168,
"preview": "extends \"res://core/inventory/items/Item.gd\"\n\nexport(PackedScene) var Fireball\n\nfunc _apply_effect(user):\n\tvar fireball "
},
{
"path": "core/inventory/items/usable/scroll_fireball/FireballScroll.tscn",
"chars": 702,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://core/inventory/items/Item.tscn\" type=\"PackedScene\" id=1]\n[ex"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/Fireball.gd",
"chars": 583,
"preview": "extends Area2D\n\nexport(PackedScene) var Explosion\nexport(float) var SPEED = 1000.0\nvar direction = Vector2(1, 0)\n\nfunc _"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/Fireball.tscn",
"chars": 1185,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://core/inventory/items/usable/scroll_fireball/fireball/Firebal"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/FireballParticles.tscn",
"chars": 4770,
"preview": "[gd_scene load_steps=13 format=2]\n\n[ext_resource path=\"res://core/inventory/items/usable/scroll_fireball/fireball/partic"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/ParticlesToggle.gd",
"chars": 246,
"preview": "tool\nextends Particles2D\n\nexport(bool) var active = true setget set_active\n\nfunc set_active(value):\n\tactive = value\n\temi"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/fire_to_black.tres",
"chars": 282,
"preview": "[gd_resource type=\"Gradient\" format=2]\n\n[resource]\n\noffsets = PoolRealArray( 0, 0.00682594, 0.0887372, 0.395904, 0.91560"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/sparkles.tres",
"chars": 214,
"preview": "[gd_resource type=\"Gradient\" format=2]\n\n[resource]\n\noffsets = PoolRealArray( 0, 0.0613811, 0.84399, 1 )\ncolors = PoolCol"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/assets/gradient_ramps/sparkles_small.tres",
"chars": 215,
"preview": "[gd_resource type=\"Gradient\" format=2]\n\n[resource]\n\noffsets = PoolRealArray( 0, 0.0971867, 0.751918, 1 )\ncolors = PoolCo"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/explosions/Explosion.gd",
"chars": 165,
"preview": "extends Particles2D\n\nfunc _ready():\n\tone_shot = true\n\t$SmallSparkles.one_shot = true\n\tget_tree().create_timer(lifetime *"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/explosions/Explosion.tscn",
"chars": 4682,
"preview": "[gd_scene load_steps=16 format=2]\n\n[ext_resource path=\"res://core/inventory/items/usable/scroll_fireball/fireball/partic"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/circle.png.import",
"chars": 717,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/circle.png-3a0701102b0b6f1dc869953be140b137.stex\"\nm"
},
{
"path": "core/inventory/items/usable/scroll_fireball/fireball/particles/sprites/smoke_clouds.png.import",
"chars": 735,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/smoke_clouds.png-75a81e90df68496c912ffb2365928e06.s"
},
{
"path": "core/save/SaveAndLoad.gd",
"chars": 2244,
"preview": "extends Node\n\nsignal game_saved(id)\nsignal game_loaded(id)\n\nonready var GAME_VERSION = ProjectSettings.get_setting(\"appl"
},
{
"path": "core/save/SaveAndLoad.tscn",
"chars": 174,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://SaveAndLoad.gd\" type=\"Script\" id=1]\n\n[node name=\"SaveAndLoad"
},
{
"path": "core/shop/Shop.gd",
"chars": 1146,
"preview": "extends Node\n\nexport(bool) var STOCK_INFINITE = false\nexport(bool) var MONEY_INFINITE = false\n\nexport(int) var MAX_TRANS"
},
{
"path": "core/shop/Shop.tscn",
"chars": 1210,
"preview": "[gd_scene load_steps=7 format=2]\n\n[ext_resource path=\"res://core/shop/Shop.gd\" type=\"Script\" id=1]\n[ext_resource path=\"r"
},
{
"path": "core/shop/purse/Purse.gd",
"chars": 385,
"preview": "extends Node\n\nsignal coins_changed(coins)\n\nexport(int) var coins = 0\nexport(int) var MAXIMUM = 1000000\n\nfunc has_coins(a"
},
{
"path": "core/shop/purse/Purse.tscn",
"chars": 190,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://core/shop/purse/Purse.gd\" type=\"Script\" id=1]\n\n\n\n[node name="
},
{
"path": "core/world/Door.gd",
"chars": 473,
"preview": "extends Area2D\n\nsignal player_entered(map_path)\n\nexport(String, FILE, \"*.tscn\") var map_path\nvar PlayerController = prel"
},
{
"path": "core/world/Door.tscn",
"chars": 954,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://core/world/Door.gd\" type=\"Script\" id=1]\n[ext_resource path=\""
},
{
"path": "core/world/Gap.gd",
"chars": 131,
"preview": "extends Area2D\n\nfunc _on_body_entered(body):\n\tif not body.has_method('fall'):\n\t\treturn\n\tbody.fall($CollisionShape2D.shap"
},
{
"path": "core/world/Gap.tscn",
"chars": 927,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://core/world/Gap.gd\" type=\"Script\" id=1]\n[ext_resource path=\"r"
},
{
"path": "core/world/PlayerSpawningPoint.tscn",
"chars": 737,
"preview": "[gd_scene load_steps=2 format=2]\n\n[sub_resource type=\"GDScript\" id=1]\n\nscript/source = \"tool\nextends Position2D\n\nexport("
},
{
"path": "core/world/Rock.tscn",
"chars": 1001,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://core/world/rock.png\" type=\"Texture\" id=1]\n\n\n[sub_resource ty"
},
{
"path": "core/world/pit.png.import",
"chars": 648,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/pit.png-5ec5084f4b0d321ced939a029f9e9f2b.stex\"\nmeta"
},
{
"path": "core/world/rock.png.import",
"chars": 651,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/rock.png-d90c7ea6986b7d7efafc6116d7469b11.stex\"\nmet"
},
{
"path": "core/world/stairs.png.import",
"chars": 657,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/stairs.png-459082f78726e41c4edb789b8d018960.stex\"\nm"
},
{
"path": "core/world/tilesets/cave/cave.png.import",
"chars": 665,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/cave.png-7421b3ea2eb0cd51e25cb4e00e5ffa5c.stex\"\nmet"
},
{
"path": "core/world/tilesets/cave/cave.tres",
"chars": 4248,
"preview": "[gd_resource type=\"TileSet\" load_steps=14 format=2]\n\n[ext_resource path=\"res://core/world/tilesets/cave/cave.png\" type=\""
},
{
"path": "core/world/tilesets/cave/cave_tileset_src.tscn",
"chars": 378,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://core/world/tilesets/cave/cave.png\" type=\"Texture\" id=1]\n\n\n\n\n"
},
{
"path": "core/world/tilesets/outdoor/outdoor.png.import",
"chars": 677,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/outdoor.png-1eb405fc65af37f625e19d928044f95c.stex\"\n"
},
{
"path": "core/world/tilesets/outdoor/outdoor.tres",
"chars": 8436,
"preview": "[gd_resource type=\"TileSet\" load_steps=18 format=2]\n\n[ext_resource path=\"res://core/world/tilesets/outdoor/outdoor.png\" "
},
{
"path": "core/world/tilesets/outdoor/outdoor.tscn",
"chars": 1657,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://core/world/tilesets/outdoor/outdoor.png\" type=\"Texture\" id=1"
},
{
"path": "core/world/tilesets/outdoor/pit.png.import",
"chars": 665,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/pit.png-81c563e22c5b735099e3aed47ef25a25.stex\"\nmeta"
},
{
"path": "default_bus_layout.tres",
"chars": 569,
"preview": "[gd_resource type=\"AudioBusLayout\" format=2]\n\n[resource]\n\nbus/0/name = \"Master\"\nbus/0/solo = false\nbus/0/mute = false\nbu"
},
{
"path": "default_env.tres",
"chars": 465,
"preview": "[gd_resource type=\"Environment\" load_steps=2 format=2]\n\n[sub_resource type=\"ProceduralSky\" id=1]\nsky_top_color = Color( "
},
{
"path": "icon.png.import",
"chars": 640,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex\"\nmet"
},
{
"path": "interface/Interface.gd",
"chars": 734,
"preview": "extends CanvasLayer\n\nonready var shop_menu = $ShopMenu\n\nfunc _ready():\n\tshop_menu.connect('closed', self, 'remove_child'"
},
{
"path": "interface/TopLevelUi.gd",
"chars": 60,
"preview": "tool\nextends Control\n\nfunc _ready():\n\tset_as_toplevel(true)\n"
},
{
"path": "interface/fonts/montserrat_black_48.tres",
"chars": 284,
"preview": "[gd_resource type=\"DynamicFont\" load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/fonts/montserrat_black.ttf\" "
},
{
"path": "interface/fonts/source_code_pro_explanations.tres",
"chars": 286,
"preview": "[gd_resource type=\"DynamicFont\" load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/fonts/SourceCodePro-Bold.ttf"
},
{
"path": "interface/fonts/source_code_pro_explanations_bold.tres",
"chars": 288,
"preview": "[gd_resource type=\"DynamicFont\" load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/fonts/SourceCodePro-Black.tt"
},
{
"path": "interface/gui/boss/BossLifebar.gd",
"chars": 610,
"preview": "tool\nextends Control\n\nexport(String) var boss_name = \"Boss Name\"\n\nonready var bar = $Bar\nonready var anim_player = $Anim"
},
{
"path": "interface/gui/boss/BossLifebar.tscn",
"chars": 4619,
"preview": "[gd_scene load_steps=7 format=2]\n\n[ext_resource path=\"res://interface/gui/boss/BossLifebar.gd\" type=\"Script\" id=1]\n[ext_"
},
{
"path": "interface/gui/boss/boss_bar_bg.png.import",
"chars": 680,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/boss_bar_bg.png-aed3843f4ed3efb0dbc21b2322fd9e56.st"
},
{
"path": "interface/gui/boss/boss_bar_fill.png.import",
"chars": 686,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/boss_bar_fill.png-9d50dc46e3fabfa93c1e17061ffa511b."
},
{
"path": "interface/gui/lifebar/HookableLifeBar.tscn",
"chars": 1535,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://interface/gui/lifebar/Lifebar.gd\" type=\"Script\" id=1]\n[ext_r"
},
{
"path": "interface/gui/lifebar/InterfaceAnchor.tscn",
"chars": 238,
"preview": "[gd_scene format=2]\n\n[node name=\"InterfaceAnchor\" type=\"RemoteTransform2D\"]\n\nposition = Vector2( 0, -98.2191 )\nremote_pa"
},
{
"path": "interface/gui/lifebar/Lifebar.gd",
"chars": 793,
"preview": "extends Node2D\n\nvar max_health = 0 setget set_max_health\nvar health = 0 setget set_health\n\nfunc set_max_health(value):\n\t"
},
{
"path": "interface/gui/lifebar/LifebarsBuilder.gd",
"chars": 566,
"preview": "extends Node\n\nconst Lifebar = preload(\"res://interface/gui/lifebar/HookableLifeBar.tscn\")\n\nfunc initialize(monsters, mon"
},
{
"path": "interface/gui/lifebar/LifebarsBuilder.tscn",
"chars": 194,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/gui/lifebar/LifebarsBuilder.gd\" type=\"Script\" id=1"
},
{
"path": "interface/gui/lifebar/background.png.import",
"chars": 680,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/background.png-62efda1a07fd52ccf13fb5c00abc7e8c.ste"
},
{
"path": "interface/gui/lifebar/fill.png.import",
"chars": 662,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/fill.png-b3e6044072b4f216e075877da6e81969.stex\"\nmet"
},
{
"path": "interface/gui/player/PlayerGUI.gd",
"chars": 282,
"preview": "extends Control\n\nfunc initialize(health_node, purse):\n\t$LifeBar.initialize(health_node)\n\t$CoinsCounter.initialize(purse)"
},
{
"path": "interface/gui/player/PlayerGUI.tscn",
"chars": 4279,
"preview": "[gd_scene load_steps=9 format=2]\n\n[ext_resource path=\"res://interface/default.theme\" type=\"Theme\" id=1]\n[ext_resource pa"
},
{
"path": "interface/gui/player/life_bar/LifeBar.tscn",
"chars": 2711,
"preview": "[gd_scene load_steps=8 format=2]\n\n[ext_resource path=\"res://interface/gui/player/life_bar/bg.png\" type=\"Texture\" id=1]\n["
},
{
"path": "interface/gui/player/life_bar/Lifebar.gd",
"chars": 593,
"preview": "extends Control\n\nsignal maximum_changed(maximum)\n\nvar maximum = 100\nvar current_health = 0\n\nfunc initialize(health_node)"
},
{
"path": "interface/gui/player/life_bar/TextureProgress.gd",
"chars": 964,
"preview": "tool\nextends TextureProgress\n\nexport(Color) var COLOR_FULL\nexport(Color) var COLOR_NORMAL\nexport(Color) var COLOR_LOW\nex"
},
{
"path": "interface/gui/player/life_bar/bg.png.import",
"chars": 664,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/bg.png-4137f69cffc7cfbd089694c7a17196f3.stex\"\nmetad"
},
{
"path": "interface/gui/player/life_bar/fill.png.import",
"chars": 670,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/fill.png-6d81f3dffced581fbfcd68a8ff5225b0.stex\"\nmet"
},
{
"path": "interface/items/ItemButton.gd",
"chars": 717,
"preview": "extends Button\n\nsignal amount_changed(value)\n\nvar description = \"\"\nvar amount = 0\n\nfunc initialize(item, price, purse):\n"
},
{
"path": "interface/items/ItemButton.tscn",
"chars": 2690,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://interface/default.theme\" type=\"Theme\" id=1]\n[ext_resource pa"
},
{
"path": "interface/items/ItemGrid.gd",
"chars": 906,
"preview": "extends GridContainer\n\nfunc initialize():\n\tupdate_focus_neighbours()\n\tget_child(0).grab_focus()\n\nfunc update_focus_neigh"
},
{
"path": "interface/items/ItemsList.gd",
"chars": 1190,
"preview": "extends Control\n\nsignal focused_button_changed(button)\nsignal item_amount_changed(amount)\nsignal focused_item_changed(it"
},
{
"path": "interface/items/ItemsList.tscn",
"chars": 1272,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://interface/items/ItemsList.gd\" type=\"Script\" id=1]\n[ext_resou"
},
{
"path": "interface/menus/Menu.gd",
"chars": 1118,
"preview": "extends Control\nclass_name Menu\n\nsignal open()\nsignal closed()\n\nexport(NodePath) var SUB_MENU_PATH\n\nonready var sound_co"
},
{
"path": "interface/menus/Menu.tscn",
"chars": 703,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://interface/default.theme\" type=\"Theme\" id=1]\n[ext_resource pa"
},
{
"path": "interface/menus/MenuSfx.tscn",
"chars": 866,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://audio/sfx/menu_confirm.wav\" type=\"AudioStream\" id=1]\n[ext_re"
},
{
"path": "interface/menus/MenuTitle.tscn",
"chars": 1351,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://interface/theme/fonts/source_code_pro_26.tres\" type=\"Dynamic"
},
{
"path": "interface/menus/inventory/InventoryMenu.gd",
"chars": 304,
"preview": "extends Menu\n\nonready var items_list = $Column/ItemsMenu\n\n\"\"\"args: {inventory}\"\"\"\nfunc initialize(args={}):\n\titems_list."
},
{
"path": "interface/menus/inventory/InventoryMenu.tscn",
"chars": 1234,
"preview": "[gd_scene load_steps=6 format=2]\n\n[ext_resource path=\"res://interface/menus/Menu.tscn\" type=\"PackedScene\" id=1]\n[ext_res"
},
{
"path": "interface/menus/inventory/ItemButton.gd",
"chars": 397,
"preview": "extends Button\n\nvar description = \"\"\n\nfunc initialize(item):\n\t$Name.text = item.display_name\n\t$Amount.text = str(item.am"
},
{
"path": "interface/menus/inventory/ItemButton.tscn",
"chars": 2090,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://interface/menus/inventory/ItemButton.gd\" type=\"Script\" id=1]"
},
{
"path": "interface/menus/inventory/ItemGrid.gd",
"chars": 1191,
"preview": "extends GridContainer\n\nonready var placeholder_button = $Placeholder\nfunc _ready():\n\tremove_child(placeholder_button)\n\nf"
},
{
"path": "interface/menus/inventory/ItemsMenu.gd",
"chars": 1119,
"preview": "extends Control\n\nsignal item_use_requested(item, actor)\n\nexport(PackedScene) var ItemButton\n\nonready var _item_grid = $C"
},
{
"path": "interface/menus/inventory/ItemsMenu.tscn",
"chars": 4366,
"preview": "[gd_scene load_steps=6 format=2]\n\n[ext_resource path=\"res://interface/default.theme\" type=\"Theme\" id=1]\n[ext_resource pa"
},
{
"path": "interface/menus/inventory/user_select/ActorButton.tscn",
"chars": 1473,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://actors/body.png\" type=\"Texture\" id=1]\n\n[node name=\"ActorButt"
},
{
"path": "interface/menus/inventory/user_select/UserSelectMenu.gd",
"chars": 881,
"preview": "extends Control\n\nsignal closed(selected_actor)\n\nexport(PackedScene) var ActorButton\n\nfunc _ready():\n\tset_as_toplevel(tru"
},
{
"path": "interface/menus/inventory/user_select/UserSelectMenu.tscn",
"chars": 1289,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://interface/menus/inventory/user_select/UserSelectMenu.gd\" typ"
},
{
"path": "interface/menus/pause/OptionsMenu.gd",
"chars": 1163,
"preview": "extends Menu\n\nconst SoundController = preload(\"res://interface/menus/pause/SoundController.gd\")\n\nonready var first_slide"
},
{
"path": "interface/menus/pause/OptionsMenu.tscn",
"chars": 4036,
"preview": "[gd_scene load_steps=6 format=2]\n\n[ext_resource path=\"res://interface/default.theme\" type=\"Theme\" id=1]\n[ext_resource pa"
},
{
"path": "interface/menus/pause/PauseMenu.gd",
"chars": 1391,
"preview": "extends Menu\n\nsignal unpause()\n\nconst InventoryMenu = preload(\"res://interface/menus/inventory/InventoryMenu.tscn\")\ncons"
},
{
"path": "interface/menus/pause/PauseMenu.tscn",
"chars": 4074,
"preview": "[gd_scene load_steps=7 format=2]\n\n[ext_resource path=\"res://interface/menus/Menu.tscn\" type=\"PackedScene\" id=1]\n[ext_res"
},
{
"path": "interface/menus/pause/SoundController.gd",
"chars": 602,
"preview": "tool\nextends Panel\n\nonready var audio_bus_label = $Row/Label\nonready var amount_label = $Row/Amount\nonready var slider ="
},
{
"path": "interface/menus/pause/SoundController.tscn",
"chars": 3391,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://interface/default.theme\" type=\"Theme\" id=1]\n[ext_resource pa"
},
{
"path": "interface/menus/save_and_load/SaveMenu.gd",
"chars": 172,
"preview": "extends Menu\n\nonready var save_button = $Panel/Column/SaveButton\nonready var load_button = $Panel/Column/LoadButton\n\nfun"
},
{
"path": "interface/menus/save_and_load/SaveMenu.tscn",
"chars": 4432,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://interface/menus/Menu.tscn\" type=\"PackedScene\" id=1]\n[ext_res"
},
{
"path": "interface/menus/shared/Button.gd",
"chars": 99,
"preview": "extends Button\n\nfunc _gui_input(event):\n\tif event.is_action_pressed('ui_accept'):\n\t\taccept_event()\n"
},
{
"path": "interface/menus/shared/Button.tscn",
"chars": 566,
"preview": "[gd_scene format=2]\n\n[node name=\"Button\" type=\"Button\"]\n\neditor/display_folded = true\nanchor_left = 0.0\nanchor_top = 0.0"
},
{
"path": "interface/menus/shop/ShopMenu.gd",
"chars": 1497,
"preview": "extends Menu\n\nexport(PackedScene) var BuyMenu = preload(\"menus/BuySubMenu.tscn\")\nexport(PackedScene) var SellMenu = prel"
},
{
"path": "interface/menus/shop/ShopMenu.tscn",
"chars": 3806,
"preview": "[gd_scene load_steps=6 format=2]\n\n[ext_resource path=\"res://interface/menus/Menu.tscn\" type=\"PackedScene\" id=1]\n[ext_res"
},
{
"path": "interface/menus/shop/menus/BuySubMenu.tscn",
"chars": 1044,
"preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://interface/menus/shop/menus/ShopSubMenu.tscn\" type=\"PackedSce"
},
{
"path": "interface/menus/shop/menus/SellSubMenu.tscn",
"chars": 206,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/menus/shop/menus/ShopSubMenu.tscn\" type=\"PackedSce"
},
{
"path": "interface/menus/shop/menus/ShopSubMenu.gd",
"chars": 1817,
"preview": "extends Menu\n\nexport(String, \"sell_to\", \"buy_from\") var ACTION = \"\"\n\nonready var items_list = $Column/Row/ShopItemsList\n"
},
{
"path": "interface/menus/shop/menus/ShopSubMenu.tscn",
"chars": 2206,
"preview": "[gd_scene load_steps=7 format=2]\n\n[ext_resource path=\"res://interface/menus/Menu.tscn\" type=\"PackedScene\" id=1]\n[ext_res"
},
{
"path": "interface/menus/shop/panels/DescriptionPanel.gd",
"chars": 67,
"preview": "extends Panel\n\nfunc display(message):\n\t$Description.text = message\n"
},
{
"path": "interface/menus/shop/panels/DescriptionPanel.tscn",
"chars": 1055,
"preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/menus/shop/panels/DescriptionPanel.gd\" type=\"Scrip"
},
{
"path": "interface/menus/shop/panels/InfoPanel.gd",
"chars": 633,
"preview": "extends Control\n\nonready var _money_label = $MoneyPanel/Count\nonready var _owned_label = $OwnedPanel/Count\n\nfunc initial"
},
{
"path": "interface/menus/shop/panels/InfoPanel.tscn",
"chars": 4162,
"preview": "[gd_scene load_steps=4 format=2]\n\n[ext_resource path=\"res://interface/menus/shop/panels/InfoPanel.gd\" type=\"Script\" id=1"
},
{
"path": "interface/menus/shop/panels/ShopItemsList.tscn",
"chars": 363,
"preview": "[gd_scene load_steps=3 format=2]\n\n[ext_resource path=\"res://interface/items/ItemsList.tscn\" type=\"PackedScene\" id=1]\n[ex"
},
{
"path": "interface/menus/shop/popups/AmountLabel.gd",
"chars": 234,
"preview": "extends Label\n\nvar _max_value\n\nfunc initialize(value, max_value):\n\t_max_value = max_value\n\tupdate_text(value)\n\nfunc upda"
},
{
"path": "interface/menus/shop/popups/AmountPopup.gd",
"chars": 776,
"preview": "extends Menu\n\nsignal amount_confirmed(value)\n\nonready var popup = $Popup\nonready var slider = $Popup/VBoxContainer/Slide"
},
{
"path": "interface/menus/shop/popups/AmountPopup.tscn",
"chars": 2386,
"preview": "[gd_scene load_steps=6 format=2]\n\n[ext_resource path=\"res://interface/menus/shop/popups/AmountPopup.gd\" type=\"Script\" id"
},
{
"path": "interface/menus/shop/popups/HSlider.gd",
"chars": 90,
"preview": "extends HSlider\n\nfunc initialize(current, maximum):\n\tmax_value = maximum\n\tvalue = current\n"
},
{
"path": "interface/theme/fonts/comfortaa_tips.tres",
"chars": 306,
"preview": "[gd_resource type=\"DynamicFont\" load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/theme/fonts/Comfortaa-Bold.t"
},
{
"path": "interface/theme/fonts/default_font_comfortaa.tres",
"chars": 245,
"preview": "[gd_resource type=\"DynamicFont\" load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/theme/fonts/Comfortaa-Bold.t"
},
{
"path": "interface/theme/fonts/source_code_pro_26.tres",
"chars": 295,
"preview": "[gd_resource type=\"DynamicFont\" load_steps=2 format=2]\n\n[ext_resource path=\"res://interface/theme/fonts/SourceCodePro-Re"
},
{
"path": "interface/theme/icons/add.png.import",
"chars": 659,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/add.png-a2d973072fa729536972b5d9b7b2035f.stex\"\nmeta"
},
{
"path": "interface/theme/icons/cancel.png.import",
"chars": 668,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/cancel.png-037fe98dac59e9a85d5be364d636db68.stex\"\nm"
},
{
"path": "interface/theme/icons/coins.png.import",
"chars": 665,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/coins.png-d3cc02b051752e916d567a271598e8e8.stex\"\nme"
},
{
"path": "interface/theme/icons/fire_scroll.png.import",
"chars": 683,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/fire_scroll.png-ea84ffcfb65793b96e965f4d5bd34780.st"
},
{
"path": "interface/theme/icons/potion_health.png.import",
"chars": 689,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/potion_health.png-e775c0060582f7b89180f1d376299720."
},
{
"path": "interface/theme/icons/potion_mana.png.import",
"chars": 683,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/potion_mana.png-7aa82fe7a278054b00e2e350eab56c9c.st"
},
{
"path": "interface/theme/icons/purse.png.import",
"chars": 665,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/purse.png-98ac931d0e1f2927c25fc95f9b1cc6af.stex\"\nme"
},
{
"path": "interface/theme/icons/remove.png.import",
"chars": 668,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/remove.png-0d204696e7aa93085028f1e68e1459d2.stex\"\nm"
},
{
"path": "interface/theme/icons/sword.png.import",
"chars": 665,
"preview": "[remap]\n\nimporter=\"texture\"\ntype=\"StreamTexture\"\npath=\"res://.import/sword.png-217a5d3b34aaecc05313ecaf68a75610.stex\"\nme"
},
{
"path": "levels/Cave.tscn",
"chars": 6863,
"preview": "[gd_scene load_steps=10 format=2]\n\n[ext_resource path=\"res://core/world/tilesets/cave/cave.tres\" type=\"TileSet\" id=1]\n[e"
},
{
"path": "levels/Grasslands.tscn",
"chars": 32510,
"preview": "[gd_scene load_steps=9 format=2]\n\n[ext_resource path=\"res://levels/Level.gd\" type=\"Script\" id=1]\n[ext_resource path=\"res"
},
{
"path": "levels/Level.gd",
"chars": 110,
"preview": "extends Node\n\nexport(bool) var fog = false\n\nfunc get_ysort_node():\n\treturn $YSort\n\nfunc initialize():\n\treturn\n"
}
]
// ... and 104 more files (download for full content)
About this extraction
This page contains the full source code of the GDquest/make-pro-2d-games-with-godot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 304 files (399.0 KB), approximately 153.6k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.