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
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 Shift PrtScn 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
================================================
Make Pro 2d Games with Godot
Open Source A-RPG Demo
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.get_path_to(sliders[index_previous])
var index_next = index + 1
if index_next < sliders.size():
slider.focus_neighbour_bottom = NodePath(slider.get_path_to(sliders[index_next]))
index += 1
var back_button = $Column/GoBackButton
var last_slider = sliders[-1]
last_slider.focus_neighbour_bottom = last_slider.get_path_to(back_button)
back_button.focus_neighbour_top = back_button.get_path_to(last_slider)
func get_sound_sliders():
var sliders = []
for node in $Column.get_children():
if not node is SoundController:
continue
sliders.append(node.slider)
return sliders
================================================
FILE: interface/menus/pause/OptionsMenu.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/pause/OptionsMenu.gd" type="Script" id=2]
[ext_resource path="res://interface/menus/MenuSfx.tscn" type="PackedScene" id=3]
[ext_resource path="res://interface/theme/fonts/default_font_comfortaa.tres" type="DynamicFont" id=4]
[ext_resource path="res://interface/menus/pause/SoundController.tscn" type="PackedScene" id=5]
[node name="OptionsMenu" 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
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 1 )
script = ExtResource( 2 )
_sections_unfolded = [ "Focus", "Theme" ]
SUB_MENU_PATH = null
[node name="MenuSfx" parent="." index="0" instance=ExtResource( 3 )]
[node name="Column" type="VBoxContainer" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 570.0
margin_top = 147.0
margin_right = -570.0
margin_bottom = -147.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
_sections_unfolded = [ "Focus" ]
[node name="Title" type="Label" parent="Column" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 73.0
margin_right = 780.0
margin_bottom = 108.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( 4 )
text = "Sound Options"
align = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Focus", "custom_fonts" ]
[node name="HSeparator" type="HSeparator" parent="Column" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 124.0
margin_right = 780.0
margin_bottom = 128.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="MusicController" parent="Column" index="2" instance=ExtResource( 5 )]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 0.0
margin_top = 144.0
margin_right = 780.0
margin_bottom = 284.0
[node name="SfxController" parent="Column" index="3" instance=ExtResource( 5 )]
editor/display_folded = true
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 0.0
margin_top = 300.0
margin_right = 780.0
margin_bottom = 440.0
[node name="InterfaceController" parent="Column" index="4" instance=ExtResource( 5 )]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 0.0
margin_top = 456.0
margin_right = 780.0
margin_bottom = 596.0
[node name="HSeparator2" type="HSeparator" parent="Column" index="5"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 612.0
margin_right = 780.0
margin_bottom = 616.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="GoBackButton" type="Button" parent="Column" index="6"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 632.0
margin_right = 780.0
margin_bottom = 712.0
rect_min_size = Vector2( 0, 80 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Go back"
flat = false
align = 1
_sections_unfolded = [ "Focus", "Rect" ]
[connection signal="pressed" from="Column/GoBackButton" to="." method="close"]
================================================
FILE: interface/menus/pause/PauseMenu.gd
================================================
extends Menu
signal unpause()
const InventoryMenu = preload("res://interface/menus/inventory/InventoryMenu.tscn")
const PlayerController = preload("res://actors/player/PlayerController.gd")
onready var continue_button = $Background/Column/ContinueButton
onready var items_button = $Background/Column/ItemsButton
onready var options_button = $Background/Column/OptionsButton
onready var save_button = $Background/Column/SaveButton
onready var buttons_container = $Background/Column
onready var save_menu = $SaveMenu
onready var options_menu = $OptionsMenu
func _ready():
options_button.connect('pressed', self, 'open_sub_menu', [options_menu])
save_button.connect('pressed', self, 'open_sub_menu', [save_menu])
remove_child(save_menu)
remove_child(options_menu)
"""args: {actor}"""
func initialize(args={}):
var actor = args['actor']
assert(actor is PlayerController)
var inventory = actor.get_inventory()
items_button.connect('pressed', self, 'open_sub_menu', [InventoryMenu, {'inventory':inventory}])
actor.connect('died', self, '_on_Player_died')
func _on_Player_died():
items_button.disabled = true
func open(args={}):
.open()
continue_button.grab_focus()
func open_sub_menu(menu, args={}):
var last_focused_item = get_focus_owner()
buttons_container.hide()
yield(.open_sub_menu(menu, args), 'completed')
buttons_container.show()
last_focused_item.grab_focus()
================================================
FILE: interface/menus/pause/PauseMenu.tscn
================================================
[gd_scene load_steps=7 format=2]
[ext_resource path="res://interface/menus/Menu.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/menus/pause/PauseMenu.gd" type="Script" id=2]
[ext_resource path="res://interface/menus/shared/Button.tscn" type="PackedScene" id=3]
[ext_resource path="res://interface/menus/save_and_load/SaveMenu.tscn" type="PackedScene" id=4]
[ext_resource path="res://interface/menus/pause/OptionsMenu.tscn" type="PackedScene" id=5]
[sub_resource type="GDScript" id=1]
script/source = "extends VBoxContainer
var focus_active = true setget set_focus_active
func _ready():
self.focus_active = focus_active
func set_focus_active(value):
focus_active = true
var focus_mode = FOCUS_ALL if focus_active else FOCUS_NONE
for child in get_children():
child.focus_mode = focus_mode
"
[node name="PauseMenu" instance=ExtResource( 1 )]
script = ExtResource( 2 )
[node name="DarkOverlay" type="ColorRect" 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 = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
color = Color( 0, 0, 0, 0.313726 )
_sections_unfolded = [ "Visibility" ]
[node name="Background" type="ColorRect" parent="." index="2"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -300.0
margin_top = -280.0
margin_right = 300.0
margin_bottom = 280.0
rect_min_size = Vector2( 600, 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.136719, 0.136719, 0.136719, 1 )
_sections_unfolded = [ "Rect", "custom_constants" ]
[node name="Column" type="VBoxContainer" parent="Background" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
rect_min_size = Vector2( 600, 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
script = SubResource( 1 )
_sections_unfolded = [ "Focus", "Margin", "Rect", "Theme" ]
[node name="Label" type="Label" parent="Background/Column" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 68.0
margin_right = 600.0
margin_bottom = 91.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 = "Pause Menu"
align = 1
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Focus", "Theme" ]
[node name="ContinueButton" parent="Background/Column" index="1" instance=ExtResource( 3 )]
margin_left = 100.0
margin_top = 107.0
margin_right = 500.0
margin_bottom = 171.0
text = "Continue"
[node name="ItemsButton" parent="Background/Column" index="2" instance=ExtResource( 3 )]
margin_left = 100.0
margin_top = 187.0
margin_right = 500.0
margin_bottom = 251.0
text = "Items"
[node name="SaveButton" parent="Background/Column" index="3" instance=ExtResource( 3 )]
margin_left = 100.0
margin_top = 267.0
margin_right = 500.0
margin_bottom = 331.0
text = "Save"
[node name="OptionsButton" parent="Background/Column" index="4" instance=ExtResource( 3 )]
margin_left = 100.0
margin_top = 347.0
margin_right = 500.0
margin_bottom = 411.0
text = "Options"
[node name="TitleScreenButton" parent="Background/Column" index="5" instance=ExtResource( 3 )]
margin_left = 100.0
margin_top = 427.0
margin_right = 500.0
margin_bottom = 491.0
text = "Title Screen"
[node name="SaveMenu" parent="." index="3" instance=ExtResource( 4 )]
visible = false
[node name="OptionsMenu" parent="." index="4" instance=ExtResource( 5 )]
visible = false
[connection signal="pressed" from="Background/Column/ContinueButton" to="." method="close"]
[connection signal="pressed" from="Background/Column/TitleScreenButton" to="." method="close"]
================================================
FILE: interface/menus/pause/SoundController.gd
================================================
tool
extends Panel
onready var audio_bus_label = $Row/Label
onready var amount_label = $Row/Amount
onready var slider = $Row/HSlider
export(String, "Music", "World", "Interface") var BUS_NAME = "Music"
var audio_bus_index
func _ready():
audio_bus_index = AudioServer.get_bus_index(BUS_NAME)
audio_bus_label.text = BUS_NAME
var volume_db = AudioServer.get_bus_volume_db(audio_bus_index)
slider.value = round(min(db2linear(volume_db) * 100.0, 100.0))
func change_volume(value):
var volume = max(linear2db(value / slider.max_value), -80.0)
AudioServer.set_bus_volume_db(audio_bus_index, volume)
================================================
FILE: interface/menus/pause/SoundController.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=1]
[ext_resource path="res://interface/menus/pause/SoundController.gd" type="Script" id=2]
[ext_resource path="res://interface/theme/fonts/source_code_pro_26.tres" type="DynamicFont" id=3]
[sub_resource type="GDScript" id=2]
resource_local_to_scene = true
script/source = "extends Label
func _on_HSlider_value_changed(value):
text = str(value)
"
_sections_unfolded = [ "Resource" ]
[node name="SoundController" type="Panel" index="0"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -390.0
margin_top = -110.0
margin_right = 390.0
margin_bottom = 110.0
rect_min_size = Vector2( 780, 140 )
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 = [ "Focus", "Rect", "Theme" ]
[node name="Row" type="HBoxContainer" parent="." index="0"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -320.0
margin_top = -80.0
margin_right = 320.0
margin_bottom = 80.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
_sections_unfolded = [ "Focus" ]
[node name="Label" type="Label" parent="Row" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 140.0
margin_bottom = 160.0
rect_min_size = Vector2( 140, 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 = 5
custom_fonts/font = ExtResource( 3 )
text = "Music"
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Focus", "Rect", "custom_colors", "custom_fonts" ]
[node name="HSlider" type="HSlider" parent="Row" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 156.0
margin_right = 576.0
margin_bottom = 160.0
rect_min_size = Vector2( 0, 140 )
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
min_value = 0.0
max_value = 100.0
step = 10.0
page = 0.0
value = 58.0
exp_edit = false
rounded = false
editable = true
tick_count = 0
ticks_on_borders = false
focus_mode = 2
_sections_unfolded = [ "Focus" ]
[node name="Amount" type="Label" parent="Row" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 592.0
margin_top = 63.0
margin_right = 640.0
margin_bottom = 97.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( 3 )
text = "100"
align = 1
valign = 2
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
script = SubResource( 2 )
_sections_unfolded = [ "custom_colors", "custom_fonts" ]
[connection signal="value_changed" from="Row/HSlider" to="." method="change_volume"]
[connection signal="value_changed" from="Row/HSlider" to="Row/Amount" method="_on_HSlider_value_changed"]
================================================
FILE: interface/menus/save_and_load/SaveMenu.gd
================================================
extends Menu
onready var save_button = $Panel/Column/SaveButton
onready var load_button = $Panel/Column/LoadButton
func open(args={}):
.open()
save_button.grab_focus()
================================================
FILE: interface/menus/save_and_load/SaveMenu.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://interface/menus/Menu.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/menus/save_and_load/SaveMenu.gd" type="Script" id=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=3]
[ext_resource path="res://interface/theme/fonts/default_font_comfortaa.tres" type="DynamicFont" id=4]
[node name="SaveMenu" instance=ExtResource( 1 )]
script = ExtResource( 2 )
[node name="Panel" type="Panel" 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
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 3 )
_sections_unfolded = [ "Focus", "Theme" ]
[node name="Column" type="VBoxContainer" parent="Panel" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 570.0
margin_top = 147.0
margin_right = -570.0
margin_bottom = -147.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
_sections_unfolded = [ "Focus" ]
[node name="Title" type="Label" parent="Panel/Column" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 211.0
margin_right = 780.0
margin_bottom = 246.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( 4 )
text = "Save and Load"
align = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Focus", "custom_fonts" ]
[node name="HSeparator" type="HSeparator" parent="Panel/Column" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 262.0
margin_right = 780.0
margin_bottom = 266.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="SaveButton" type="Button" parent="Panel/Column" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 282.0
margin_right = 780.0
margin_bottom = 362.0
rect_min_size = Vector2( 0, 80 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
custom_fonts/font = ExtResource( 4 )
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Save"
flat = false
align = 1
_sections_unfolded = [ "Focus", "custom_fonts" ]
[node name="LoadButton" type="Button" parent="Panel/Column" index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 378.0
margin_right = 780.0
margin_bottom = 458.0
rect_min_size = Vector2( 0, 80 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
custom_fonts/font = ExtResource( 4 )
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Load"
flat = false
align = 1
_sections_unfolded = [ "Focus", "custom_fonts" ]
[node name="HSeparator2" type="HSeparator" parent="Panel/Column" index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 474.0
margin_right = 780.0
margin_bottom = 478.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="GoBackButton" type="Button" parent="Panel/Column" index="5"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 494.0
margin_right = 780.0
margin_bottom = 574.0
rect_min_size = Vector2( 0, 80 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Go back"
flat = false
align = 1
_sections_unfolded = [ "Focus", "Rect" ]
[connection signal="pressed" from="Panel/Column/GoBackButton" to="." method="close"]
================================================
FILE: interface/menus/shared/Button.gd
================================================
extends Button
func _gui_input(event):
if event.is_action_pressed('ui_accept'):
accept_event()
================================================
FILE: interface/menus/shared/Button.tscn
================================================
[gd_scene format=2]
[node name="Button" type="Button"]
editor/display_folded = true
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 400.0
margin_bottom = 64.0
rect_min_size = Vector2( 400, 64 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 4
size_flags_vertical = 4
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Button"
flat = false
align = 1
_sections_unfolded = [ "Rect", "Theme" ]
================================================
FILE: interface/menus/shop/ShopMenu.gd
================================================
extends Menu
export(PackedScene) var BuyMenu = preload("menus/BuySubMenu.tscn")
export(PackedScene) var SellMenu = preload("menus/SellSubMenu.tscn")
onready var buttons = $Column/Buttons
onready var submenu = $Column/Menu
onready var button_buy = $Column/Buttons/BuyButton
onready var button_sell = $Column/Buttons/SellButton
func _ready():
hide()
"""args: {shop, buyer}"""
func open(args={}):
assert(args.size() == 2)
var shop = args['shop']
var buyer = args['buyer']
button_buy.connect("pressed", self, "open_submenu",
[BuyMenu, {
'shop':shop,
'buyer':buyer,
'inventory':shop.inventory}])
button_sell.connect("pressed", self, "open_submenu",
[SellMenu, {
'shop':shop,
'buyer':buyer,
'inventory':buyer.get_node("Inventory")}])
.open()
buttons.get_child(0).grab_focus()
func close():
button_buy.disconnect('pressed', self, 'open_submenu')
button_sell.disconnect('pressed', self, 'open_submenu')
.close()
"""args: shop, buyer, inventory"""
func open_submenu(Menu, args={}):
assert(args.size() == 3)
var shop = args['shop']
var buyer = args['buyer']
var inventory = args['inventory']
var pressed_button = get_focus_owner()
var active_menu = Menu.instance()
submenu.add_child(active_menu)
active_menu.initialize({'shop':shop, 'buyer':buyer, 'items':inventory.get_items()})
set_process_input(false)
active_menu.open()
yield(active_menu, "closed")
set_process_input(true)
pressed_button.grab_focus()
func _on_QuitButton_pressed():
close()
================================================
FILE: interface/menus/shop/ShopMenu.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/shop/ShopMenu.gd" type="Script" id=2]
[ext_resource path="res://interface/menus/shop/menus/BuySubMenu.tscn" type="PackedScene" id=3]
[ext_resource path="res://interface/menus/shop/menus/SellSubMenu.tscn" type="PackedScene" id=4]
[ext_resource path="res://interface/menus/MenuTitle.tscn" type="PackedScene" id=5]
[node name="ShopMenu" instance=ExtResource( 1 )]
script = ExtResource( 2 )
BuyMenu = ExtResource( 3 )
SellMenu = ExtResource( 4 )
[node name="DarkOverlay" type="ColorRect" 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 = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
color = Color( 0, 0, 0, 0.313726 )
[node name="Column" type="VBoxContainer" parent="." index="2"]
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
alignment = 0
_sections_unfolded = [ "custom_constants" ]
[node name="TitlePanel" parent="Column" index="0" instance=ExtResource( 5 )]
title = "Terrence's shop"
[node name="Buttons" type="HBoxContainer" parent="Column" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 96.0
margin_right = 1920.0
margin_bottom = 166.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
[node name="BuyButton" type="Button" parent="Column/Buttons" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 629.0
margin_bottom = 70.0
rect_min_size = Vector2( 0, 70 )
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
text = "Buy"
flat = false
align = 1
[node name="SellButton" type="Button" parent="Column/Buttons" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 645.0
margin_right = 1274.0
margin_bottom = 70.0
rect_min_size = Vector2( 0, 70 )
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
text = "Sell"
flat = false
align = 1
[node name="QuitButton" type="Button" parent="Column/Buttons" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 1290.0
margin_right = 1920.0
margin_bottom = 70.0
rect_min_size = Vector2( 0, 70 )
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
text = "Quit"
flat = false
align = 1
[node name="Menu" type="Control" parent="Column" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 182.0
margin_right = 1920.0
margin_bottom = 1080.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
[connection signal="pressed" from="Column/Buttons/QuitButton" to="." method="_on_QuitButton_pressed"]
================================================
FILE: interface/menus/shop/menus/BuySubMenu.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://interface/menus/shop/menus/ShopSubMenu.tscn" type="PackedScene" id=1]
[ext_resource path="res://audio/sfx/menu_confirm.wav" type="AudioStream" id=2]
[ext_resource path="res://audio/sfx/menu_navigate_01.wav" type="AudioStream" id=3]
[ext_resource path="res://audio/sfx/menu_popup_open.wav" type="AudioStream" id=4]
[node name="BuySubMenu" instance=ExtResource( 1 )]
ACTION = "sell_to"
[node name="Sfx" type="Node" parent="." index="0"]
[node name="Confirm" type="AudioStreamPlayer" parent="Sfx" index="0"]
stream = ExtResource( 2 )
volume_db = 0.0
pitch_scale = 1.0
autoplay = false
mix_target = 0
bus = "Interface"
[node name="Navigate" type="AudioStreamPlayer" parent="Sfx" index="1"]
stream = ExtResource( 3 )
volume_db = 0.0
pitch_scale = 1.0
autoplay = false
mix_target = 0
bus = "Interface"
[node name="Open" type="AudioStreamPlayer" parent="Sfx" index="2"]
stream = ExtResource( 4 )
volume_db = 0.0
pitch_scale = 1.0
autoplay = false
mix_target = 0
bus = "Interface"
================================================
FILE: interface/menus/shop/menus/SellSubMenu.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://interface/menus/shop/menus/ShopSubMenu.tscn" type="PackedScene" id=1]
[node name="SellSubMenu" instance=ExtResource( 1 )]
ACTION = "buy_from"
================================================
FILE: interface/menus/shop/menus/ShopSubMenu.gd
================================================
extends Menu
export(String, "sell_to", "buy_from") var ACTION = ""
onready var items_list = $Column/Row/ShopItemsList
onready var description_panel = $Column/DescriptionPanel
onready var info_panel = $Column/Row/InfoPanel
onready var amount_popup = items_list.get_node("AmountPopup")
func _ready():
assert(ACTION != "")
"""Args: {shop, buyer, items}"""
func initialize(args={}):
assert(args.size() == 3)
# Extract the nodes from the args dict to preserve legacy code below
var shop = args['shop']
var items = args['items']
var buyer = args['buyer']
var purse = buyer.get_purse()
info_panel.initialize(purse)
for item in items:
var price = shop.get_buy_value(item) if ACTION == "buy_from" else item.price
var item_button = items_list.add_item_button(item, price, purse)
item_button.connect("pressed", self, "_on_ItemButton_pressed", [shop, buyer, item])
item_button.connect("pressed", info_panel, "_on_focused_Item_amount_changed", [item])
items_list.connect("focused_button_changed", self, "_on_ItemList_focused_button_changed")
items_list.initialize()
func _on_ItemList_focused_button_changed(item_button):
description_panel.display(item_button.description)
func open(args={}):
.open()
items_list.get_child(0).grab_focus()
func close():
.close()
queue_free()
func _on_ItemButton_pressed(shop, buyer, item):
var price = shop.get_buy_value(item) if ACTION == "buy_from" else item.price
var coins = shop.get_purse().coins if ACTION == "buy_from" else buyer.get_purse().coins
var max_amount = min(item.amount, floor(coins / price))
var focused_item = get_focus_owner()
amount_popup.initialize({'value': 1, 'max_value': max_amount})
var amount = yield(amount_popup.open(), "completed")
focused_item.grab_focus()
if not amount:
return
shop.call(ACTION, buyer, item, amount)
================================================
FILE: interface/menus/shop/menus/ShopSubMenu.tscn
================================================
[gd_scene load_steps=7 format=2]
[ext_resource path="res://interface/menus/Menu.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/menus/shop/menus/ShopSubMenu.gd" type="Script" id=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=3]
[ext_resource path="res://interface/menus/shop/panels/ShopItemsList.tscn" type="PackedScene" id=4]
[ext_resource path="res://interface/menus/shop/panels/InfoPanel.tscn" type="PackedScene" id=5]
[ext_resource path="res://interface/menus/shop/panels/DescriptionPanel.tscn" type="PackedScene" id=6]
[node name="ShopSubMenu" index="0" instance=ExtResource( 1 )]
script = ExtResource( 2 )
ACTION = ""
[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 = 3
theme = ExtResource( 3 )
alignment = 0
_sections_unfolded = [ "Rect", "Theme" ]
[node name="Row" type="HBoxContainer" 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 = 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 = 3
alignment = 0
_sections_unfolded = [ "Size Flags" ]
[node name="ShopItemsList" parent="Column/Row" index="0" instance=ExtResource( 4 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1504.0
margin_bottom = 964.0
[node name="InfoPanel" parent="Column/Row" index="1" instance=ExtResource( 5 )]
margin_left = 1520.0
margin_right = 1920.0
margin_bottom = 964.0
[node name="DescriptionPanel" parent="Column" index="1" instance=ExtResource( 6 )]
margin_top = 980.0
margin_right = 1920.0
margin_bottom = 1080.0
[connection signal="focused_button_changed" from="Column/Row/ShopItemsList" to="Column/Row/InfoPanel" method="_on_ItemsList_focused_button_changed"]
[connection signal="item_amount_changed" from="Column/Row/ShopItemsList" to="Column/Row/InfoPanel" method="_on_ItemsList_item_amount_changed"]
================================================
FILE: interface/menus/shop/panels/DescriptionPanel.gd
================================================
extends Panel
func display(message):
$Description.text = message
================================================
FILE: interface/menus/shop/panels/DescriptionPanel.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://interface/menus/shop/panels/DescriptionPanel.gd" type="Script" id=1]
[node name="DescriptionPanel" type="Panel"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 620.0
margin_right = 1280.0
margin_bottom = 720.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
script = ExtResource( 1 )
_sections_unfolded = [ "Rect" ]
[node name="Description" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 40.0
margin_top = 20.0
margin_right = 1240.0
margin_bottom = 81.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
================================================
FILE: interface/menus/shop/panels/InfoPanel.gd
================================================
extends Control
onready var _money_label = $MoneyPanel/Count
onready var _owned_label = $OwnedPanel/Count
func initialize(purse):
purse.connect("coins_changed", self, "_on_Purse_coins_changed")
update_coins(purse.coins)
func update_coins(amount):
_money_label.text = str(amount)
func update_amount(amount):
_owned_label.text = str(amount)
func _on_Purse_coins_changed(coins):
update_coins(coins)
func _on_focused_Item_amount_changed(item):
update_amount(item.amount)
func _on_ItemsList_focused_button_changed(button):
update_amount(button.amount)
func _on_ItemsList_item_amount_changed(amount):
update_amount(amount)
================================================
FILE: interface/menus/shop/panels/InfoPanel.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://interface/menus/shop/panels/InfoPanel.gd" type="Script" id=1]
[ext_resource path="res://interface/theme/icons/coins.png" type="Texture" id=2]
[ext_resource path="res://interface/theme/icons/purse.png" type="Texture" id=3]
[node name="InfoPanel" type="Panel" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 880.0
margin_right = 1280.0
margin_bottom = 462.0
rect_min_size = Vector2( 400, 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 )
_sections_unfolded = [ "Rect" ]
[node name="MoneyPanel" type="Panel" parent="." index="0"]
anchor_left = 0.5
anchor_top = 0.0
anchor_right = 0.5
anchor_bottom = 0.0
margin_left = -180.0
margin_top = 18.0
margin_right = 180.0
margin_bottom = 78.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="MoneyPanel" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 20.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
text = "Purse"
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Count" type="Label" parent="MoneyPanel" index="1"]
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -240.0
margin_top = -30.0
margin_right = -60.0
margin_bottom = 30.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 = "1600"
align = 2
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="CoinsIcon" type="TextureRect" parent="MoneyPanel" index="2"]
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -52.0
margin_top = -16.0
margin_right = -20.0
margin_bottom = 16.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
[node name="OwnedPanel" type="Panel" parent="." index="1"]
anchor_left = 0.5
anchor_top = 0.0
anchor_right = 0.5
anchor_bottom = 0.0
margin_left = -180.0
margin_top = 98.0
margin_right = 180.0
margin_bottom = 158.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="OwnedPanel" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 20.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
text = "Available"
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Count" type="Label" parent="OwnedPanel" index="1"]
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -240.0
margin_top = -30.0
margin_right = -60.0
margin_bottom = 30.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 = "4"
align = 2
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="PurseIcon" type="TextureRect" parent="OwnedPanel" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 308.0
margin_top = 14.0
margin_right = 340.0
margin_bottom = 46.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 = 0
================================================
FILE: interface/menus/shop/panels/ShopItemsList.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://interface/items/ItemsList.tscn" type="PackedScene" id=1]
[ext_resource path="res://interface/menus/shop/popups/AmountPopup.tscn" type="PackedScene" id=2]
[node name="ShopItemsList" instance=ExtResource( 1 )]
[node name="AmountPopup" parent="." index="1" instance=ExtResource( 2 )]
visible = false
================================================
FILE: interface/menus/shop/popups/AmountLabel.gd
================================================
extends Label
var _max_value
func initialize(value, max_value):
_max_value = max_value
update_text(value)
func update_text(value):
text = "%s/%s" % [value, _max_value]
func _on_HSlider_value_changed(value):
update_text(value)
================================================
FILE: interface/menus/shop/popups/AmountPopup.gd
================================================
extends Menu
signal amount_confirmed(value)
onready var popup = $Popup
onready var slider = $Popup/VBoxContainer/Slider/HSlider
onready var label = $Popup/VBoxContainer/Slider/Amount
"""args: {value, max_value}"""
func initialize(args={}):
assert(args.size() == 2)
var value = args['value']
var max_value = args['max_value']
label.initialize(value, max_value)
slider.initialize(value, max_value)
slider.grab_focus()
func open(args={}):
popup.popup_centered()
.open()
var amount = yield(self, "amount_confirmed")
close()
return amount
func _input(event):
if event.is_action_pressed("ui_cancel"):
emit_signal("amount_confirmed", 0)
accept_event()
elif event.is_action_pressed("ui_accept"):
emit_signal("amount_confirmed", slider.value)
accept_event()
================================================
FILE: interface/menus/shop/popups/AmountPopup.tscn
================================================
[gd_scene load_steps=6 format=2]
[ext_resource path="res://interface/menus/shop/popups/AmountPopup.gd" type="Script" id=1]
[ext_resource path="res://interface/menus/MenuSfx.tscn" type="PackedScene" id=2]
[ext_resource path="res://interface/default.theme" type="Theme" id=3]
[ext_resource path="res://interface/menus/shop/popups/HSlider.gd" type="Script" id=4]
[sub_resource type="GDScript" id=1]
resource_local_to_scene = true
script/source = "extends Label
var _max_value
func initialize(value, max_value):
_max_value = max_value
update_text(value)
func _on_HSlider_value_changed(value):
update_text(value)
func update_text(value):
text = \"%s/%s\" % [value, _max_value]
"
[node name="AmountPopup" type="Control"]
margin_right = 40.0
margin_bottom = 40.0
script = ExtResource( 1 )
[node name="MenuSfx" parent="." instance=ExtResource( 2 )]
[node name="Popup" type="PopupPanel" parent="."]
visible = true
margin_right = 300.0
margin_bottom = 300.0
rect_min_size = Vector2( 300, 120 )
theme = ExtResource( 3 )
popup_exclusive = true
[node name="VBoxContainer" type="VBoxContainer" parent="Popup"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 2.0
margin_top = 2.0
margin_right = -2.0
margin_bottom = -2.0
[node name="Title" type="Label" parent="Popup/VBoxContainer"]
margin_right = 296.0
margin_bottom = 60.0
rect_min_size = Vector2( 0, 60 )
text = "Amount"
align = 1
valign = 1
[node name="Slider" type="Control" parent="Popup/VBoxContainer"]
margin_top = 76.0
margin_right = 296.0
margin_bottom = 216.0
rect_min_size = Vector2( 0, 140 )
[node name="Amount" type="Label" parent="Popup/VBoxContainer/Slider"]
anchor_right = 1.0
margin_top = 34.0
margin_bottom = 57.0
text = "6/8"
align = 1
valign = 1
script = SubResource( 1 )
[node name="HSlider" type="HSlider" parent="Popup/VBoxContainer/Slider"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = 20.0
margin_top = -7.0
margin_right = -20.0
margin_bottom = 9.0
max_value = 8.0
value = 6.0
script = ExtResource( 4 )
[node name="OkButton" type="Button" parent="Popup/VBoxContainer"]
margin_left = 18.0
margin_top = 232.0
margin_right = 278.0
margin_bottom = 272.0
rect_min_size = Vector2( 260, 40 )
size_flags_horizontal = 4
text = "OK"
[connection signal="value_changed" from="Popup/VBoxContainer/Slider/HSlider" to="Popup/VBoxContainer/Slider/Amount" method="_on_HSlider_value_changed"]
================================================
FILE: interface/menus/shop/popups/HSlider.gd
================================================
extends HSlider
func initialize(current, maximum):
max_value = maximum
value = current
================================================
FILE: interface/theme/fonts/comfortaa_tips.tres
================================================
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://interface/theme/fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1]
[resource]
size = 22
use_mipmaps = false
use_filter = true
font_data = ExtResource( 1 )
_sections_unfolded = [ "Extra Spacing", "Font", "Settings" ]
================================================
FILE: interface/theme/fonts/default_font_comfortaa.tres
================================================
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://interface/theme/fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1]
[resource]
size = 30
use_mipmaps = false
use_filter = true
font_data = ExtResource( 1 )
================================================
FILE: interface/theme/fonts/source_code_pro_26.tres
================================================
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://interface/theme/fonts/SourceCodePro-Regular.ttf" type="DynamicFontData" id=1]
[resource]
size = 26
use_mipmaps = false
use_filter = true
font_data = ExtResource( 1 )
_sections_unfolded = [ "Font", "Settings" ]
================================================
FILE: interface/theme/icons/add.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/add.png-a2d973072fa729536972b5d9b7b2035f.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/add.png"
dest_files=[ "res://.import/add.png-a2d973072fa729536972b5d9b7b2035f.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/theme/icons/cancel.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/cancel.png-037fe98dac59e9a85d5be364d636db68.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/cancel.png"
dest_files=[ "res://.import/cancel.png-037fe98dac59e9a85d5be364d636db68.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/theme/icons/coins.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/coins.png-d3cc02b051752e916d567a271598e8e8.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/coins.png"
dest_files=[ "res://.import/coins.png-d3cc02b051752e916d567a271598e8e8.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/theme/icons/fire_scroll.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/fire_scroll.png-ea84ffcfb65793b96e965f4d5bd34780.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/fire_scroll.png"
dest_files=[ "res://.import/fire_scroll.png-ea84ffcfb65793b96e965f4d5bd34780.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/theme/icons/potion_health.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/potion_health.png-e775c0060582f7b89180f1d376299720.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/potion_health.png"
dest_files=[ "res://.import/potion_health.png-e775c0060582f7b89180f1d376299720.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/theme/icons/potion_mana.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/potion_mana.png-7aa82fe7a278054b00e2e350eab56c9c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/potion_mana.png"
dest_files=[ "res://.import/potion_mana.png-7aa82fe7a278054b00e2e350eab56c9c.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/theme/icons/purse.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/purse.png-98ac931d0e1f2927c25fc95f9b1cc6af.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/purse.png"
dest_files=[ "res://.import/purse.png-98ac931d0e1f2927c25fc95f9b1cc6af.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/theme/icons/remove.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/remove.png-0d204696e7aa93085028f1e68e1459d2.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/remove.png"
dest_files=[ "res://.import/remove.png-0d204696e7aa93085028f1e68e1459d2.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/theme/icons/sword.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/sword.png-217a5d3b34aaecc05313ecaf68a75610.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interface/theme/icons/sword.png"
dest_files=[ "res://.import/sword.png-217a5d3b34aaecc05313ecaf68a75610.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: levels/Cave.tscn
================================================
[gd_scene load_steps=10 format=2]
[ext_resource path="res://core/world/tilesets/cave/cave.tres" type="TileSet" id=1]
[ext_resource path="res://monsters/BossShakingCamera.tscn" type="PackedScene" id=2]
[ext_resource path="res://core/world/PlayerSpawningPoint.tscn" type="PackedScene" id=3]
[ext_resource path="res://core/world/Door.tscn" type="PackedScene" id=4]
[ext_resource path="res://core/world/pit.png" type="Texture" id=5]
[ext_resource path="res://monsters/bosses/wild_boar/WildBoar.tscn" type="PackedScene" id=6]
[ext_resource path="res://actors/CoinsFountain.tscn" type="PackedScene" id=7]
[sub_resource type="GDScript" id=1]
script/source = "extends \"res://levels/Level.gd\"
onready var camera = $BossShakingCamera
onready var wild_boar = $YSort/WildBoar
const PlayerController = preload(\"res://actors/player/PlayerController.gd\")
func _ready():
camera.current = true
func _on_CameraTrigger_body_entered(body):
assert(body is PlayerController)
camera.initialize(body)
yield(camera.move_to_room_center(), \"completed\")
wild_boar.start()
func _on_WildBoar_died():
$Door.set_active(true)
"
[sub_resource type="GDScript" id=2]
script/source = "extends Area2D
func _on_body_entered(body):
queue_free()
"
[node name="Cave" type="TileMap" index="0"]
position = Vector2( 0, 32 )
mode = 0
tile_set = ExtResource( 1 )
cell_size = Vector2( 128, 128 )
cell_quadrant_size = 16
cell_custom_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
cell_half_offset = 2
cell_tile_origin = 0
cell_y_sort = false
cell_clip_uv = false
collision_use_kinematic = false
collision_friction = 1.0
collision_bounce = 0.0
collision_layer = 2
collision_mask = 1
occluder_light_mask = 1
format = 1
tile_data = PoolIntArray( 1, 0, 0, 2, 0, 1, 3, 0, 1, 4, 0, 1, 5, 0, 1, 6, 0, 1, 7, 0, 1, 8, 0, 1, 9, 0, 1, 10, 0, 1, 11, 0, 1, 12, 0, 1, 13, 0, 2, 65537, 0, 65536, 65538, 0, 65537, 65539, 0, 65537, 65540, 0, 65537, 65541, 0, 65537, 65542, 0, 65537, 65543, 0, 65537, 65544, 0, 65537, 65545, 0, 65537, 65546, 0, 65537, 65547, 0, 65537, 65548, 0, 65537, 65549, 0, 65538, 131073, 0, 65536, 131074, 0, 65537, 131075, 0, 65537, 131076, 0, 65537, 131077, 0, 65537, 131078, 0, 65537, 131079, 0, 65537, 131080, 0, 65537, 131081, 0, 65537, 131082, 0, 65537, 131083, 0, 65537, 131084, 0, 65537, 131085, 0, 65538, 196609, 0, 65536, 196610, 0, 65537, 196611, 0, 65537, 196612, 0, 65537, 196613, 0, 65537, 196614, 0, 65537, 196615, 0, 65537, 196616, 0, 65537, 196617, 0, 65537, 196618, 0, 65537, 196619, 0, 65537, 196620, 0, 65537, 196621, 0, 65538, 262145, 0, 65536, 262146, 0, 65537, 262147, 0, 65537, 262148, 0, 65537, 262149, 0, 65537, 262150, 0, 65537, 262151, 0, 65537, 262152, 0, 65537, 262153, 0, 65537, 262154, 0, 65537, 262155, 0, 65537, 262156, 0, 65537, 262157, 0, 65538, 327681, 0, 65536, 327682, 0, 65537, 327683, 0, 65537, 327684, 0, 65537, 327685, 0, 65537, 327686, 0, 65537, 327687, 0, 65537, 327688, 0, 65537, 327689, 0, 65537, 327690, 0, 65537, 327691, 0, 65537, 327692, 0, 65537, 327693, 0, 65538, 393217, 0, 65536, 393218, 0, 65537, 393219, 0, 65537, 393220, 0, 65537, 393221, 0, 65537, 393222, 0, 65537, 393223, 0, 65537, 393224, 0, 65537, 393225, 0, 65537, 393226, 0, 65537, 393227, 0, 65537, 393228, 0, 65537, 393229, 0, 65538, 458753, 0, 131072, 458754, 0, 131073, 458755, 0, 131073, 458756, 0, 131073, 458757, 0, 131073, 458758, 0, 4, 458759, 0, 65537, 458760, 0, 3, 458761, 0, 131073, 458762, 0, 131073, 458763, 0, 131073, 458764, 0, 131073, 458765, 0, 131074, 524294, 0, 65536, 524295, 0, 65537, 524296, 0, 65538, 589830, 0, 65536, 589831, 0, 65537, 589832, 0, 65539, 589833, 0, 2, 655366, 0, 65536, 655367, 0, 65537, 655368, 0, 3, 655369, 0, 131074, 720902, 0, 65536, 720903, 0, 65537, 720904, 0, 65538, 786437, 0, 0, 786438, 0, 65540, 786439, 0, 65537, 786440, 0, 65538, 851973, 0, 131072, 851974, 0, 4, 851975, 0, 65537, 851976, 0, 65538, 917510, 0, 65536, 917511, 0, 65537, 917512, 0, 65538, 983046, 0, 65536, 983047, 0, 65537, 983048, 0, 65538, 1048582, 0, 65536, 1048583, 0, 65537, 1048584, 0, 65538, 1114118, 0, 65536, 1114119, 0, 65537, 1114120, 0, 65538, 1179654, 0, 65536, 1179655, 0, 65537, 1179656, 0, 65538, 1245190, 0, 65536, 1245191, 0, 65537, 1245192, 0, 65538, 1310724, 0, 0, 1310725, 0, 1, 1310726, 0, 65540, 1310727, 0, 65537, 1310728, 0, 65539, 1310729, 0, 1, 1310730, 0, 2, 1376260, 0, 65536, 1376261, 0, 65537, 1376262, 0, 65537, 1376263, 0, 65537, 1376264, 0, 65537, 1376265, 0, 65537, 1376266, 0, 65538, 1441796, 0, 65536, 1441797, 0, 65537, 1441798, 0, 65537, 1441799, 0, 65537, 1441800, 0, 65537, 1441801, 0, 65537, 1441802, 0, 65538, 1507332, 0, 65536, 1507333, 0, 65537, 1507334, 0, 65537, 1507335, 0, 65537, 1507336, 0, 65537, 1507337, 0, 65537, 1507338, 0, 65538, 1572868, 0, 131072, 1572869, 0, 131073, 1572870, 0, 131073, 1572871, 0, 131073, 1572872, 0, 131073, 1572873, 0, 131073, 1572874, 0, 131074 )
script = SubResource( 1 )
_sections_unfolded = [ "Cell", "Collision", "Transform" ]
__meta__ = {
"_edit_lock_": true
}
fog = true
[node name="BossShakingCamera" parent="." index="0" instance=ExtResource( 2 )]
position = Vector2( 960, 408 )
current = false
[node name="CameraTrigger" type="Area2D" parent="." index="1"]
editor/display_folded = true
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitorable = false
collision_layer = 0
audio_bus_override = false
audio_bus_name = "Master"
script = SubResource( 2 )
_sections_unfolded = [ "Collision" ]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="CameraTrigger" index="0"]
build_mode = 0
polygon = PoolVector2Array( 768, 896, 1152, 896, 1152, 1024, 768, 1024 )
[node name="PlayerSpawningPoint" parent="." index="2" instance=ExtResource( 3 )]
position = Vector2( 960, 2912 )
[node name="Door" parent="." index="3" instance=ExtResource( 4 )]
editor/display_folded = true
visible = false
position = Vector2( 1570, 208 )
map_path = "res://levels/Grasslands.tscn"
ACTIVE_AT_START = false
[node name="Stairs" parent="Door" index="0"]
texture = ExtResource( 5 )
[node name="YSort" type="YSort" parent="." index="4"]
sort_enabled = true
[node name="WildBoar" parent="YSort" index="0" instance=ExtResource( 6 )]
position = Vector2( 970, 528 )
[node name="CoinsFountain" parent="YSort" index="1" instance=ExtResource( 7 )]
position = Vector2( 970, 528 )
MAX_SPAWN_COUNT = 16
[connection signal="body_entered" from="CameraTrigger" to="." method="_on_CameraTrigger_body_entered"]
[connection signal="body_entered" from="CameraTrigger" to="CameraTrigger" method="_on_body_entered"]
[connection signal="died" from="YSort/WildBoar" to="." method="_on_WildBoar_died"]
[connection signal="died" from="YSort/WildBoar" to="YSort/CoinsFountain" method="start"]
[connection signal="hit_wall" from="YSort/WildBoar" to="BossShakingCamera" method="_on_WildBoar_hit_wall"]
[editable path="Door"]
================================================
FILE: levels/Grasslands.tscn
================================================
[gd_scene load_steps=9 format=2]
[ext_resource path="res://levels/Level.gd" type="Script" id=1]
[ext_resource path="res://core/world/tilesets/outdoor/outdoor.tres" type="TileSet" id=2]
[ext_resource path="res://core/world/Gap.tscn" type="PackedScene" id=3]
[ext_resource path="res://monsters/porcupine/Porcupine.tscn" type="PackedScene" id=4]
[ext_resource path="res://monsters/mosquito/Nest.tscn" type="PackedScene" id=5]
[ext_resource path="res://actors/characters/seller/Seller.tscn" type="PackedScene" id=6]
[ext_resource path="res://core/world/PlayerSpawningPoint.tscn" type="PackedScene" id=7]
[ext_resource path="res://core/world/Door.tscn" type="PackedScene" id=8]
[node name="Grasslands" type="Node2D" index="0"]
script = ExtResource( 1 )
_sections_unfolded = [ "Cell", "Collision" ]
fog = false
[node name="Ground" type="TileMap" parent="." index="0"]
mode = 0
tile_set = ExtResource( 2 )
cell_size = Vector2( 128, 128 )
cell_quadrant_size = 16
cell_custom_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
cell_half_offset = 2
cell_tile_origin = 0
cell_y_sort = false
cell_clip_uv = false
collision_use_kinematic = false
collision_friction = 1.0
collision_bounce = 0.0
collision_layer = 1
collision_mask = 1
occluder_light_mask = 1
format = 1
tile_data = PoolIntArray( 0, 0, 65536, 1, 0, 65536, 2, 0, 65536, 3, 0, 65536, 4, 0, 65536, 5, 0, 65536, 6, 0, 65536, 7, 0, 65536, 8, 0, 65536, 9, 0, 65536, 10, 0, 65536, 11, 0, 65536, 12, 0, 65536, 13, 0, 65536, 14, 0, 65536, 15, 0, 65536, 16, 0, 65536, 17, 0, 65536, 18, 0, 65536, 19, 0, 65536, 20, 0, 65536, 21, 0, 65536, 22, 0, 65536, 23, 0, 65536, 24, 0, 65536, 25, 0, 65536, 26, 0, 65536, 27, 0, 65536, 28, 0, 65536, 29, 0, 65536, 30, 0, 65536, 31, 0, 65536, 32, 0, 65536, 33, 0, 65536, 34, 0, 65536, 35, 0, 65536, 36, 0, 65536, 37, 0, 65536, 38, 0, 65536, 39, 0, 65536, 40, 0, 65536, 41, 0, 65536, 42, 0, 65536, 43, 0, 65536, 44, 0, 65536, 45, 0, 65536, 46, 0, 65536, 65536, 0, 65536, 65537, 0, 65536, 65538, 0, 2, 65539, 0, 65536, 65540, 0, 65536, 65541, 0, 65536, 65542, 0, 65536, 65543, 1, 0, 65544, 1, 1, 65545, 1, 1, 65546, 1, 1, 65547, 1, 1, 65548, 1, 1, 65549, 1, 1, 65550, 1, 1, 65551, 1, 1, 65552, 1, 1, 65553, 1, 1, 65554, 1, 1, 65555, 1, 2, 65556, 0, 65536, 65557, 0, 0, 65558, 0, 65536, 65559, 0, 65536, 65560, 0, 65536, 65561, 0, 0, 65562, 0, 65536, 65563, 0, 65536, 65564, 0, 0, 65565, 0, 65536, 65566, 0, 65536, 65567, 0, 65536, 65568, 0, 0, 65569, 0, 2, 65570, 0, 65536, 65571, 0, 65536, 65572, 0, 65536, 65573, 0, 65536, 65574, 0, 65536, 65575, 0, 65536, 65576, 0, 65536, 65577, 0, 65536, 65578, 0, 65536, 65579, 0, 65536, 65580, 0, 65536, 65581, 0, 65536, 65582, 0, 65536, 131072, 0, 65536, 131073, 0, 65536, 131074, 0, 65536, 131075, 0, 65536, 131076, 1, 0, 131077, 1, 1, 131078, 1, 1, 131079, 1, 65540, 131080, 1, 65537, 131081, 1, 65537, 131082, 1, 65537, 131083, 1, 65537, 131084, 1, 65537, 131085, 1, 65537, 131086, 1, 65537, 131087, 1, 65537, 131088, 1, 65537, 131089, 1, 65537, 131090, 1, 65537, 131091, 1, 65538, 131092, 0, 65536, 131093, 0, 65536, 131094, 0, 0, 131095, 0, 65536, 131096, 0, 65536, 131097, 0, 65536, 131098, 0, 65536, 131099, 0, 65536, 131100, 0, 65536, 131101, 0, 65536, 131102, 0, 65536, 131103, 0, 65536, 131104, 0, 65536, 131105, 0, 65536, 131106, 0, 65536, 131107, 0, 65536, 131108, 0, 65536, 131109, 0, 65536, 131110, 0, 65536, 131111, 0, 65536, 131112, 0, 65536, 131113, 0, 65536, 131114, 0, 65536, 131115, 0, 65536, 131116, 0, 65536, 131117, 0, 65536, 131118, 0, 65536, 196608, 0, 65536, 196609, 0, 65536, 196610, 0, 65536, 196611, 0, 65536, 196612, 1, 65536, 196613, 1, 65537, 196614, 1, 65537, 196615, 1, 65537, 196616, 1, 65537, 196617, 1, 65537, 196618, 1, 65537, 196619, 1, 65537, 196620, 1, 65537, 196621, 1, 65537, 196622, 1, 65537, 196623, 1, 65537, 196624, 1, 65537, 196625, 1, 65537, 196626, 1, 65537, 196627, 1, 65538, 196628, 0, 65536, 196629, 0, 65536, 196630, 0, 2, 196631, 0, 65536, 196632, 0, 65536, 196633, 0, 65536, 196634, 0, 65536, 196635, 0, 65536, 196636, 0, 65536, 196637, 0, 65536, 196638, 0, 65536, 196639, 0, 65536, 196640, 0, 65536, 196641, 0, 65536, 196642, 0, 65536, 196643, 0, 65536, 196644, 0, 65536, 196645, 0, 65536, 196646, 0, 65536, 196647, 0, 65536, 196648, 0, 65536, 196649, 0, 65536, 196650, 0, 65536, 196651, 0, 65536, 196652, 0, 65536, 196653, 0, 65536, 196654, 0, 65536, 262144, 0, 65536, 262145, 0, 65536, 262146, 0, 65536, 262147, 1, 0, 262148, 1, 65540, 262149, 1, 65537, 262150, 1, 65537, 262151, 1, 65537, 262152, 1, 65537, 262153, 1, 65537, 262154, 1, 65537, 262155, 1, 65537, 262156, 1, 65537, 262157, 1, 65537, 262158, 1, 65537, 262159, 1, 65537, 262160, 1, 65537, 262161, 1, 65537, 262162, 1, 65537, 262163, 1, 65538, 262164, 0, 65536, 262165, 0, 65536, 262166, 0, 65536, 262167, 0, 65536, 262168, 0, 65536, 262169, 0, 65536, 262170, 0, 65536, 262171, 0, 65536, 262172, 0, 65536, 262173, 0, 65536, 262174, 0, 65536, 262175, 0, 65536, 262176, 0, 65536, 262177, 0, 65536, 262178, 0, 65536, 262179, 0, 65536, 262180, 0, 65536, 262181, 0, 65536, 262182, 0, 65536, 262183, 0, 65536, 262184, 0, 65536, 262185, 0, 65536, 262186, 0, 0, 262187, 0, 65536, 262188, 0, 65536, 262189, 0, 65536, 262190, 0, 65536, 327680, 0, 65536, 327681, 0, 65536, 327682, 0, 65536, 327683, 1, 65536, 327684, 1, 65537, 327685, 1, 65537, 327686, 1, 65537, 327687, 1, 65537, 327688, 1, 65537, 327689, 1, 196609, 327690, 1, 65537, 327691, 1, 65537, 327692, 1, 65537, 327693, 1, 65537, 327694, 1, 65537, 327695, 1, 65537, 327696, 1, 65537, 327697, 1, 65537, 327698, 1, 65537, 327699, 1, 65538, 327700, 0, 65536, 327701, 0, 0, 327702, 0, 65536, 327703, 0, 0, 327704, 0, 65536, 327705, 0, 65536, 327706, 0, 65536, 327707, 0, 65536, 327708, 0, 65536, 327709, 0, 65536, 327710, 0, 65536, 327711, 0, 65536, 327712, 0, 65536, 327713, 0, 65536, 327714, 0, 65536, 327715, 0, 65536, 327716, 0, 65536, 327717, 0, 65536, 327718, 0, 65536, 327719, 0, 65536, 327720, 0, 65536, 327721, 0, 65536, 327722, 0, 65536, 327723, 0, 65536, 327724, 0, 65536, 327725, 0, 2, 327726, 0, 65536, 393216, 0, 65536, 393217, 0, 65536, 393218, 1, 0, 393219, 1, 65540, 393220, 1, 65537, 393221, 1, 65537, 393222, 1, 65537, 393223, 1, 65537, 393224, 1, 65537, 393225, 1, 65537, 393226, 1, 65537, 393227, 1, 65537, 393228, 1, 65537, 393229, 1, 65537, 393230, 1, 65537, 393231, 1, 65537, 393232, 1, 65537, 393233, 1, 65537, 393234, 1, 65537, 393235, 1, 65538, 393236, 0, 65536, 393237, 0, 65536, 393238, 0, 65536, 393239, 0, 65536, 393240, 0, 65536, 393241, 0, 65536, 393242, 0, 65536, 393243, 0, 65536, 393244, 0, 65536, 393245, 0, 65536, 393246, 0, 65536, 393247, 0, 65536, 393248, 0, 0, 393249, 0, 65536, 393250, 0, 65536, 393251, 0, 65536, 393252, 0, 65536, 393253, 0, 2, 393254, 0, 65536, 393255, 0, 65536, 393256, 0, 65536, 393257, 0, 65536, 393258, 0, 65536, 393259, 0, 65536, 393260, 0, 65536, 393261, 0, 65536, 393262, 0, 65536, 458752, 0, 65536, 458753, 0, 65536, 458754, 1, 65536, 458755, 1, 65537, 458756, 1, 65537, 458757, 1, 65537, 458758, 1, 65537, 458759, 1, 65537, 458760, 1, 65537, 458761, 1, 65537, 458762, 1, 65537, 458763, 1, 65537, 458764, 1, 65537, 458765, 1, 65537, 458766, 1, 65537, 458767, 1, 65537, 458768, 1, 65537, 458769, 1, 65537, 458770, 1, 65537, 458771, 1, 65538, 458772, 0, 65536, 458773, 0, 65536, 458774, 0, 65536, 458775, 0, 65536, 458776, 0, 65536, 458777, 0, 65536, 458778, 0, 65536, 458779, 0, 65536, 458780, 0, 65536, 458781, 0, 65536, 458782, 0, 65536, 458783, 0, 65536, 458784, 0, 65536, 458785, 0, 65536, 458786, 0, 65536, 458787, 0, 65536, 458788, 0, 65536, 458789, 0, 65536, 458790, 0, 65536, 458791, 0, 65536, 458792, 0, 65536, 458793, 0, 65536, 458794, 0, 65536, 458795, 0, 65536, 458796, 0, 65536, 458797, 0, 65536, 458798, 0, 65536, 524288, 0, 65536, 524289, 1, 0, 524290, 1, 65540, 524291, 1, 65537, 524292, 1, 65537, 524293, 1, 65537, 524294, 1, 65537, 524295, 1, 65537, 524296, 1, 65537, 524297, 1, 65537, 524298, 1, 65537, 524299, 1, 65537, 524300, 1, 65537, 524301, 1, 65537, 524302, 1, 65537, 524303, 1, 65537, 524304, 1, 65537, 524305, 1, 65537, 524306, 1, 65537, 524307, 1, 65539, 524308, 1, 1, 524309, 1, 1, 524310, 1, 2, 524311, 0, 65536, 524312, 0, 65536, 524313, 0, 65536, 524314, 0, 2, 524315, 0, 65536, 524316, 0, 65536, 524317, 0, 65536, 524318, 0, 65536, 524319, 0, 65536, 524320, 0, 1, 524321, 0, 65536, 524322, 0, 65536, 524323, 0, 65536, 524324, 0, 65536, 524325, 0, 65536, 524326, 0, 65536, 524327, 0, 65536, 524328, 0, 65536, 524329, 0, 65536, 524330, 0, 65536, 524331, 0, 65536, 524332, 0, 65536, 524333, 0, 65536, 524334, 0, 65536, 589824, 0, 65536, 589825, 1, 65536, 589826, 1, 65537, 589827, 1, 65537, 589828, 1, 65537, 589829, 1, 65537, 589830, 1, 65537, 589831, 1, 65537, 589832, 1, 65537, 589833, 1, 65537, 589834, 1, 65537, 589835, 1, 65537, 589836, 1, 65537, 589837, 1, 65537, 589838, 1, 65537, 589839, 1, 196609, 589840, 1, 65537, 589841, 1, 65537, 589842, 1, 65537, 589843, 1, 65537, 589844, 1, 65537, 589845, 1, 65537, 589846, 1, 65538, 589847, 0, 65536, 589848, 0, 65536, 589849, 0, 65536, 589850, 0, 65536, 589851, 0, 65536, 589852, 0, 65536, 589853, 0, 65536, 589854, 0, 65536, 589855, 0, 65536, 589856, 0, 65536, 589857, 0, 65536, 589858, 5, 0, 589859, 5, 1, 589860, 5, 1, 589861, 5, 1, 589862, 5, 1, 589863, 5, 2, 589864, 0, 65536, 589865, 0, 65536, 589866, 0, 0, 589867, 0, 65536, 589868, 0, 65536, 589869, 0, 65536, 589870, 0, 65536, 655360, 0, 65536, 655361, 1, 65536, 655362, 1, 65537, 655363, 1, 196610, 655364, 1, 65537, 655365, 1, 65537, 655366, 1, 65537, 655367, 1, 65537, 655368, 1, 65537, 655369, 1, 65537, 655370, 1, 65537, 655371, 1, 65537, 655372, 1, 65537, 655373, 1, 65537, 655374, 1, 65537, 655375, 1, 65537, 655376, 1, 65537, 655377, 1, 3, 655378, 1, 131073, 655379, 1, 131073, 655380, 1, 131073, 655381, 1, 131073, 655382, 1, 131074, 655383, 0, 65536, 655384, 0, 0, 655385, 0, 65536, 655386, 0, 65536, 655387, 0, 65536, 655388, 0, 65536, 655389, 0, 65536, 655390, 0, 65536, 655391, 0, 65536, 655392, 0, 65536, 655393, 0, 65536, 655394, 5, 131072, 655395, 5, 4, 655396, 5, 65537, 655397, 5, 65537, 655398, 5, 65537, 655399, 5, 65538, 655400, 0, 65536, 655401, 0, 65536, 655402, 0, 65536, 655403, 0, 65536, 655404, 0, 65536, 655405, 0, 65536, 655406, 0, 65536, 720896, 0, 65536, 720897, 1, 65536, 720898, 1, 65537, 720899, 1, 65537, 720900, 1, 65537, 720901, 1, 65537, 720902, 1, 65537, 720903, 1, 65537, 720904, 1, 65537, 720905, 1, 65537, 720906, 1, 196608, 720907, 1, 65537, 720908, 1, 65537, 720909, 1, 65537, 720910, 1, 65537, 720911, 1, 65537, 720912, 1, 65537, 720913, 1, 65538, 720914, 0, 65536, 720915, 0, 65536, 720916, 0, 65536, 720917, 0, 65536, 720918, 0, 65536, 720919, 0, 65536, 720920, 0, 65536, 720921, 0, 65536, 720922, 0, 65536, 720923, 0, 65536, 720924, 0, 65536, 720925, 0, 65536, 720926, 0, 65536, 720927, 0, 65536, 720928, 0, 65536, 720929, 0, 65536, 720930, 0, 65536, 720931, 5, 65536, 720932, 5, 65537, 720933, 5, 65537, 720934, 5, 65537, 720935, 5, 65539, 720936, 5, 1, 720937, 5, 2, 720938, 0, 65536, 720939, 0, 65536, 720940, 0, 65536, 720941, 0, 2, 720942, 0, 65536, 786432, 0, 65536, 786433, 1, 65536, 786434, 1, 65537, 786435, 1, 65537, 786436, 1, 65537, 786437, 1, 65537, 786438, 1, 196609, 786439, 1, 65537, 786440, 1, 65537, 786441, 1, 65537, 786442, 1, 65537, 786443, 1, 3, 786444, 1, 131073, 786445, 1, 131073, 786446, 1, 131073, 786447, 1, 4, 786448, 1, 65537, 786449, 1, 65538, 786450, 0, 65536, 786451, 0, 65536, 786452, 0, 65536, 786453, 0, 65536, 786454, 0, 65536, 786455, 0, 65536, 786456, 0, 65536, 786457, 0, 65536, 786458, 0, 65536, 786459, 0, 65536, 786460, 0, 65536, 786461, 0, 65536, 786462, 0, 65536, 786463, 0, 65536, 786464, 0, 65536, 786465, 0, 65536, 786466, 0, 65536, 786467, 5, 131072, 786468, 5, 131073, 786469, 5, 131073, 786470, 5, 4, 786471, 5, 65537, 786472, 5, 65537, 786473, 5, 65538, 786474, 0, 65536, 786475, 0, 65536, 786476, 0, 65536, 786477, 0, 65536, 786478, 0, 65536, 851968, 0, 65536, 851969, 1, 65536, 851970, 1, 65537, 851971, 1, 65537, 851972, 1, 65537, 851973, 1, 65537, 851974, 1, 65537, 851975, 1, 65537, 851976, 1, 65537, 851977, 1, 65537, 851978, 1, 65537, 851979, 1, 65538, 851980, 0, 65536, 851981, 0, 65536, 851982, 0, 65536, 851983, 1, 65536, 851984, 1, 65537, 851985, 1, 65538, 851986, 0, 65536, 851987, 0, 65536, 851988, 0, 65536, 851989, 0, 65536, 851990, 0, 65536, 851991, 0, 65536, 851992, 0, 65536, 851993, 0, 65536, 851994, 0, 65536, 851995, 0, 65536, 851996, 0, 65536, 851997, 0, 65536, 851998, 0, 0, 851999, 0, 65536, 852000, 0, 65536, 852001, 0, 65536, 852002, 0, 65536, 852003, 0, 65536, 852004, 0, 65536, 852005, 0, 65536, 852006, 5, 131072, 852007, 5, 131073, 852008, 5, 131073, 852009, 5, 131074, 852010, 0, 65536, 852011, 0, 65536, 852012, 0, 65536, 852013, 0, 65536, 852014, 0, 65536, 917504, 0, 65536, 917505, 1, 131072, 917506, 1, 131073, 917507, 1, 131073, 917508, 1, 131073, 917509, 1, 131073, 917510, 1, 131073, 917511, 1, 131073, 917512, 1, 131073, 917513, 1, 131073, 917514, 1, 131073, 917515, 1, 131074, 917516, 0, 65536, 917517, 0, 65536, 917518, 0, 65536, 917519, 1, 131072, 917520, 1, 131073, 917521, 1, 131074, 917522, 0, 65536, 917523, 0, 65536, 917524, 0, 65536, 917525, 0, 65536, 917526, 0, 65536, 917527, 0, 65536, 917528, 0, 65536, 917529, 0, 65536, 917530, 0, 65536, 917531, 0, 65536, 917532, 0, 0, 917533, 0, 2, 917534, 0, 65536, 917535, 0, 0, 917536, 0, 65536, 917537, 0, 65536, 917538, 0, 65536, 917539, 0, 65536, 917540, 0, 65536, 917541, 0, 65536, 917542, 0, 65536, 917543, 0, 65536, 917544, 0, 65536, 917545, 0, 65536, 917546, 0, 65536, 917547, 0, 65536, 917548, 0, 65536, 917549, 0, 65536, 917550, 0, 65536, 983040, 0, 65536, 983041, 0, 65536, 983042, 0, 65536, 983043, 0, 65536, 983044, 0, 65536, 983045, 0, 65536, 983046, 0, 65536, 983047, 0, 65536, 983048, 0, 65536, 983049, 0, 65536, 983050, 0, 65536, 983051, 0, 65536, 983052, 0, 65536, 983053, 0, 65536, 983054, 0, 65536, 983055, 0, 65536, 983056, 0, 65536, 983057, 0, 65536, 983058, 0, 65536, 983059, 0, 65536, 983060, 0, 65536, 983061, 0, 65536, 983062, 0, 65536, 983063, 0, 65536, 983064, 0, 65536, 983065, 0, 65536, 983066, 0, 65536, 983067, 0, 65536, 983068, 0, 65536, 983069, 0, 65536, 983070, 0, 65536, 983071, 0, 65536, 983072, 0, 65536, 983073, 0, 65536, 983074, 0, 65536, 983075, 0, 65536, 983076, 0, 0, 983077, 0, 65536, 983078, 0, 65536, 983079, 0, 65536, 983080, 0, 65536, 983081, 0, 65536, 983082, 0, 65536, 983083, 0, 65536, 983084, 0, 65536, 983085, 0, 65536, 983086, 0, 65536, 1048576, 0, 65536, 1048577, 0, 65536, 1048578, 0, 2, 1048579, 0, 65536, 1048580, 0, 65536, 1048581, 0, 1, 1048582, 0, 65536, 1048583, 0, 65536, 1048584, 0, 65536, 1048585, 0, 65536, 1048586, 0, 65536, 1048587, 0, 65536, 1048588, 0, 65536, 1048589, 0, 65536, 1048590, 0, 65536, 1048591, 0, 65536, 1048592, 0, 65536, 1048593, 0, 65536, 1048594, 0, 65536, 1048595, 0, 1, 1048596, 0, 1, 1048597, 0, 65536, 1048598, 0, 65536, 1048599, 0, 65536, 1048600, 0, 65536, 1048601, 0, 0, 1048602, 0, 65536, 1048603, 0, 65536, 1048604, 0, 65536, 1048605, 0, 65536, 1048606, 0, 65536, 1048607, 0, 2, 1048608, 0, 65536, 1048609, 0, 65536, 1048610, 0, 65536, 1048611, 0, 65536, 1048612, 0, 65536, 1048613, 0, 65536, 1048614, 0, 65536, 1048615, 0, 65536, 1048616, 0, 65536, 1048617, 0, 65536, 1048618, 0, 65536, 1048619, 0, 65536, 1048620, 0, 65536, 1048621, 0, 65536, 1048622, 0, 65536, 1114112, 0, 65536, 1114113, 0, 65536, 1114114, 0, 65536, 1114115, 0, 65536, 1114116, 0, 65536, 1114117, 0, 65536, 1114118, 0, 65536, 1114119, 0, 65536, 1114120, 0, 65536, 1114121, 0, 65536, 1114122, 0, 65536, 1114123, 0, 65536, 1114124, 0, 65536, 1114125, 0, 65536, 1114126, 0, 65536, 1114127, 0, 65536, 1114128, 0, 0, 1114129, 0, 65536, 1114130, 0, 0, 1114131, 0, 65536, 1114132, 0, 65536, 1114133, 0, 65536, 1114134, 0, 0, 1114135, 0, 65536, 1114136, 0, 0, 1114137, 0, 65536, 1114138, 0, 1, 1114139, 0, 65536, 1114140, 0, 65536, 1114141, 0, 65536, 1114142, 0, 0, 1114143, 0, 65536, 1114144, 0, 65536, 1114145, 0, 65536, 1114146, 0, 65536, 1114147, 0, 65536, 1114148, 0, 65536, 1114149, 0, 65536, 1114150, 0, 65536, 1114151, 0, 65536, 1114152, 0, 65536, 1114153, 0, 65536, 1114154, 0, 65536, 1114155, 0, 65536, 1114156, 0, 65536, 1114157, 0, 65536, 1114158, 0, 65536, 1179648, 0, 65536, 1179649, 0, 65536, 1179650, 0, 65536, 1179651, 0, 65536, 1179652, 0, 65536, 1179653, 0, 65536, 1179654, 0, 65536, 1179655, 0, 65536, 1179656, 0, 65536, 1179657, 0, 65536, 1179658, 0, 65536, 1179659, 0, 65536, 1179660, 0, 65536, 1179661, 0, 65536, 1179662, 0, 65536, 1179663, 0, 65536, 1179664, 0, 65536, 1179665, 0, 65536, 1179666, 0, 65536, 1179667, 0, 65536, 1179668, 0, 65536, 1179669, 0, 65536, 1179670, 0, 65536, 1179671, 0, 65536, 1179672, 0, 65536, 1179673, 0, 65536, 1179674, 0, 65536, 1179675, 0, 65536, 1179676, 0, 65536, 1179677, 0, 65536, 1179678, 0, 65536, 1179679, 0, 65536, 1179680, 0, 65536, 1179681, 0, 65536, 1179682, 0, 65536, 1179683, 0, 65536, 1179684, 0, 65536, 1179685, 0, 65536, 1179686, 0, 65536, 1179687, 0, 65536, 1179688, 0, 65536, 1179689, 0, 0, 1179690, 0, 2, 1179691, 0, 65536, 1179692, 0, 65536, 1179693, 0, 65536, 1179694, 0, 65536, 1245184, 0, 65536, 1245185, 0, 65536, 1245186, 0, 65536, 1245187, 0, 65536, 1245188, 0, 65536, 1245189, 0, 65536, 1245190, 0, 65536, 1245191, 0, 65536, 1245192, 0, 65536, 1245193, 0, 65536, 1245194, 0, 65536, 1245195, 0, 65536, 1245196, 0, 65536, 1245197, 0, 65536, 1245198, 0, 65536, 1245199, 0, 65536, 1245200, 0, 65536, 1245201, 0, 65536, 1245202, 0, 65536, 1245203, 0, 0, 1245204, 0, 65536, 1245205, 0, 65536, 1245206, 0, 65536, 1245207, 0, 65536, 1245208, 0, 65536, 1245209, 0, 65536, 1245210, 0, 65536, 1245211, 0, 65536, 1245212, 0, 65536, 1245213, 0, 65536, 1245214, 0, 65536, 1245215, 0, 1, 1245216, 0, 65536, 1245217, 0, 65536, 1245218, 0, 65536, 1245219, 0, 65536, 1245220, 0, 65536, 1245221, 0, 65536, 1245222, 0, 65536, 1245223, 0, 65536, 1245224, 0, 65536, 1245225, 0, 65536, 1245226, 0, 65536, 1245227, 0, 65536, 1245228, 0, 65536, 1245229, 0, 65536, 1245230, 0, 65536, 1310720, 0, 65536, 1310721, 0, 65536, 1310722, 0, 65536, 1310723, 0, 65536, 1310724, 0, 65536, 1310725, 0, 0, 1310726, 0, 65536, 1310727, 0, 65536, 1310728, 0, 65536, 1310729, 0, 1, 1310730, 0, 65536, 1310731, 0, 65536, 1310732, 0, 65536, 1310733, 0, 65536, 1310734, 0, 2, 1310735, 0, 65536, 1310736, 0, 65536, 1310737, 0, 65536, 1310738, 0, 65536, 1310739, 0, 65536, 1310740, 0, 65536, 1310741, 0, 65536, 1310742, 0, 65536, 1310743, 0, 65536, 1310744, 0, 65536, 1310745, 0, 65536, 1310746, 0, 65536, 1310747, 0, 65536, 1310748, 0, 65536, 1310749, 0, 65536, 1310750, 0, 0, 1310751, 0, 65536, 1310752, 0, 65536, 1310753, 0, 65536, 1310754, 0, 65536, 1310755, 0, 1, 1310756, 0, 65536, 1310757, 0, 65536, 1310758, 0, 0, 1310759, 0, 65536, 1310760, 0, 65536, 1310761, 0, 65536, 1310762, 0, 65536, 1310763, 0, 65536, 1310764, 0, 65536, 1310765, 0, 65536, 1310766, 0, 65536, 1376256, 0, 65536, 1376257, 0, 65536, 1376258, 0, 65536, 1376259, 0, 65536, 1376260, 0, 1, 1376261, 0, 65536, 1376262, 0, 65536, 1376263, 0, 65536, 1376264, 0, 65536, 1376265, 0, 65536, 1376266, 0, 65536, 1376267, 0, 65536, 1376268, 0, 65536, 1376269, 0, 65536, 1376270, 0, 65536, 1376271, 0, 65536, 1376272, 0, 65536, 1376273, 0, 65536, 1376274, 0, 65536, 1376275, 0, 65536, 1376276, 0, 65536, 1376277, 0, 65536, 1376278, 0, 65536, 1376279, 0, 2, 1376280, 0, 65536, 1376281, 0, 65536, 1376282, 0, 65536, 1376283, 0, 65536, 1376284, 0, 65536, 1376285, 0, 65536, 1376286, 0, 65536, 1376287, 0, 65536, 1376288, 0, 65536, 1376289, 0, 65536, 1376290, 0, 65536, 1376291, 0, 0, 1376292, 0, 2, 1376293, 0, 65536, 1376294, 0, 65536, 1376295, 0, 65536, 1376296, 0, 65536, 1376297, 0, 65536, 1376298, 0, 65536, 1376299, 0, 65536, 1376300, 0, 65536, 1376301, 0, 65536, 1376302, 0, 65536, 1441792, 0, 65536, 1441793, 0, 2, 1441794, 0, 65536, 1441795, 0, 65536, 1441796, 0, 65536, 1441797, 0, 65536, 1441798, 0, 65536, 1441799, 0, 65536, 1441800, 0, 65536, 1441801, 0, 65536, 1441802, 0, 65536, 1441803, 0, 0, 1441804, 0, 65536, 1441805, 0, 65536, 1441806, 0, 65536, 1441807, 0, 65536, 1441808, 0, 65536, 1441809, 0, 65536, 1441810, 0, 65536, 1441811, 0, 65536, 1441812, 0, 65536, 1441813, 0, 65536, 1441814, 0, 65536, 1441815, 0, 1, 1441816, 0, 65536, 1441817, 0, 65536, 1441818, 0, 65536, 1441819, 0, 65536, 1441820, 0, 65536, 1441821, 0, 65536, 1441822, 0, 65536, 1441823, 0, 65536, 1441824, 0, 65536, 1441825, 0, 65536, 1441826, 0, 65536, 1441827, 0, 65536, 1441828, 0, 65536, 1441829, 0, 65536, 1441830, 0, 65536, 1441831, 0, 65536, 1441832, 0, 65536, 1441833, 0, 65536, 1441834, 0, 65536, 1441835, 0, 65536, 1441836, 0, 65536, 1441837, 0, 65536, 1441838, 0, 65536, 1507328, 0, 65536, 1507329, 0, 65536, 1507330, 0, 65536, 1507331, 0, 65536, 1507332, 0, 65536, 1507333, 0, 65536, 1507334, 0, 65536, 1507335, 0, 65536, 1507336, 0, 65536, 1507337, 0, 65536, 1507338, 0, 65536, 1507339, 0, 1, 1507340, 0, 65536, 1507341, 0, 65536, 1507342, 0, 65536, 1507343, 0, 65536, 1507344, 0, 65536, 1507345, 0, 65536, 1507346, 0, 65536, 1507347, 0, 65536, 1507348, 0, 65536, 1507349, 0, 65536, 1507350, 0, 65536, 1507351, 0, 65536, 1507352, 0, 65536, 1507353, 0, 65536, 1507354, 0, 65536, 1507355, 0, 65536, 1507356, 0, 65536, 1507357, 0, 65536, 1507358, 0, 1, 1507359, 0, 65536, 1507360, 0, 65536, 1507361, 0, 65536, 1507362, 0, 65536, 1507363, 0, 65536, 1507364, 0, 65536, 1507365, 0, 65536, 1507366, 0, 65536, 1507367, 0, 65536, 1507368, 0, 65536, 1507369, 0, 65536, 1507370, 0, 65536, 1507371, 0, 65536, 1507372, 0, 65536, 1507373, 0, 0, 1507374, 0, 65536, 1572864, 0, 65536, 1572865, 0, 65536, 1572866, 0, 65536, 1572867, 0, 65536, 1572868, 0, 65536, 1572869, 0, 65536, 1572870, 0, 65536, 1572871, 0, 65536, 1572872, 0, 65536, 1572873, 0, 65536, 1572874, 0, 65536, 1572875, 0, 65536, 1572876, 0, 65536, 1572877, 0, 65536, 1572878, 0, 0, 1572879, 0, 65536, 1572880, 0, 65536, 1572881, 0, 65536, 1572882, 0, 65536, 1572883, 0, 65536, 1572884, 0, 65536, 1572885, 0, 65536, 1572886, 0, 0, 1572887, 0, 65536, 1572888, 0, 65536, 1572889, 0, 65536, 1572890, 0, 65536, 1572891, 0, 65536, 1572892, 0, 65536, 1572893, 0, 65536, 1572894, 0, 65536, 1572895, 0, 65536, 1572896, 0, 65536, 1572897, 0, 65536, 1572898, 0, 2, 1572899, 0, 65536, 1572900, 0, 65536, 1572901, 0, 65536, 1572902, 0, 65536, 1572903, 0, 65536, 1572904, 0, 65536, 1572905, 0, 65536, 1572906, 0, 65536, 1572907, 0, 0, 1572908, 0, 65536, 1572909, 0, 65536, 1572910, 0, 65536, 1638400, 0, 65536, 1638401, 0, 65536, 1638402, 0, 65536, 1638403, 0, 65536, 1638404, 0, 65536, 1638405, 0, 65536, 1638406, 0, 65536, 1638407, 0, 65536, 1638408, 0, 65536, 1638409, 0, 65536, 1638410, 0, 65536, 1638411, 0, 65536, 1638412, 0, 65536, 1638413, 0, 65536, 1638414, 0, 65536, 1638415, 0, 65536, 1638416, 0, 65536, 1638417, 0, 65536, 1638418, 0, 65536, 1638419, 0, 65536, 1638420, 0, 65536, 1638421, 0, 65536, 1638422, 0, 65536, 1638423, 0, 65536, 1638424, 0, 65536, 1638425, 0, 65536, 1638426, 0, 65536, 1638427, 0, 65536, 1638428, 0, 65536, 1638429, 0, 65536, 1638430, 0, 65536, 1638431, 0, 65536, 1638432, 0, 65536, 1638433, 0, 65536, 1638434, 0, 65536, 1638435, 0, 65536, 1638436, 0, 65536, 1638437, 0, 65536, 1638438, 0, 65536, 1638439, 0, 65536, 1638440, 0, 65536, 1638441, 0, 65536, 1638442, 0, 65536, 1638443, 0, 65536, 1638444, 0, 65536, 1638445, 0, 65536, 1638446, 0, 65536 )
_sections_unfolded = [ "Cell" ]
[node name="Props" type="TileMap" parent="." index="1"]
mode = 0
tile_set = ExtResource( 2 )
cell_size = Vector2( 128, 128 )
cell_quadrant_size = 16
cell_custom_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
cell_half_offset = 2
cell_tile_origin = 0
cell_y_sort = false
cell_clip_uv = false
collision_use_kinematic = false
collision_friction = 1.0
collision_bounce = 0.0
collision_layer = 1
collision_mask = 1
occluder_light_mask = 1
format = 1
tile_data = PoolIntArray( 0, 4, 6, 1, 4, 131073, 2, 4, 1, 3, 4, 1, 4, 4, 1, 5, 4, 1, 6, 4, 131073, 7, 4, 1, 8, 4, 1, 9, 4, 131073, 10, 4, 1, 11, 4, 131073, 12, 4, 1, 13, 4, 131073, 14, 4, 131073, 15, 4, 1, 16, 4, 1, 17, 4, 131073, 18, 4, 131073, 19, 4, 131073, 20, 4, 65540, 21, 4, 131073, 22, 4, 131073, 23, 4, 1, 24, 4, 131073, 25, 4, 131073, 26, 4, 1, 27, 4, 131073, 28, 4, 131073, 29, 4, 1, 30, 4, 1, 31, 4, 1, 32, 4, 1, 33, 4, 131073, 34, 4, 131073, 35, 4, 1, 36, 4, 131073, 37, 4, 131073, 38, 4, 1, 39, 4, 1, 40, 4, 131073, 41, 4, 131073, 42, 4, 131073, 43, 4, 1, 44, 4, 1, 45, 4, 131073, 46, 4, 2, 65536, 4, 65536, 65556, 4, 65536, 65582, 4, 65536, 131072, 4, 65538, 131092, 4, 65536, 131118, 4, 65538, 196608, 4, 65536, 196628, 4, 65538, 196654, 4, 65536, 262144, 4, 65536, 262164, 4, 65536, 262190, 4, 65538, 327680, 4, 65536, 327700, 4, 131072, 327701, 4, 1, 327702, 4, 7, 327726, 4, 65538, 393216, 4, 65536, 393223, 2, 0, 393238, 4, 65539, 393262, 4, 65536, 458752, 4, 65538, 458798, 4, 65536, 524288, 4, 65536, 524306, 2, 0, 524334, 4, 65536, 589824, 4, 65536, 589870, 4, 65536, 655360, 4, 65536, 655406, 4, 65538, 720896, 4, 65538, 720942, 4, 65536, 786432, 4, 65538, 786454, 4, 3, 786478, 4, 65538, 851968, 4, 65536, 851984, 2, 0, 851988, 4, 0, 851989, 4, 131073, 851990, 4, 131074, 852014, 4, 65538, 917504, 4, 65538, 917524, 4, 65538, 917550, 4, 65538, 983040, 4, 4, 983041, 4, 131073, 983042, 4, 1, 983043, 4, 1, 983044, 4, 131073, 983045, 4, 1, 983046, 4, 131073, 983047, 4, 131073, 983048, 4, 131073, 983049, 4, 131073, 983050, 4, 1, 983051, 4, 1, 983052, 4, 131073, 983053, 4, 131073, 983054, 4, 131073, 983055, 4, 1, 983056, 4, 131073, 983057, 4, 131073, 983058, 4, 1, 983059, 4, 1, 983060, 4, 65543, 983086, 4, 65536, 1048576, 4, 65538, 1048622, 4, 65536, 1114112, 4, 65536, 1114127, 5, 0, 1114128, 5, 1, 1114129, 5, 1, 1114130, 5, 2, 1114158, 4, 65536, 1179648, 4, 65536, 1179663, 5, 65536, 1179664, 5, 65537, 1179665, 5, 65537, 1179666, 5, 65539, 1179667, 5, 2, 1179694, 4, 65538, 1245184, 4, 65536, 1245198, 5, 0, 1245199, 5, 65540, 1245200, 5, 65537, 1245201, 5, 65537, 1245202, 5, 65537, 1245203, 5, 65538, 1245230, 4, 65536, 1310720, 4, 65536, 1310734, 5, 65536, 1310735, 5, 65537, 1310736, 5, 65537, 1310737, 5, 65537, 1310738, 5, 65537, 1310739, 5, 65539, 1310740, 5, 2, 1310766, 4, 65536, 1376256, 4, 65536, 1376270, 5, 65536, 1376271, 5, 65537, 1376272, 5, 65537, 1376273, 5, 65537, 1376274, 5, 65537, 1376275, 5, 3, 1376276, 5, 131074, 1376302, 4, 65536, 1441792, 4, 65536, 1441806, 5, 65536, 1441807, 5, 65537, 1441808, 5, 3, 1441809, 5, 131073, 1441810, 5, 131073, 1441811, 5, 131074, 1441838, 4, 65538, 1507328, 4, 65538, 1507342, 5, 65536, 1507343, 5, 65537, 1507344, 5, 65538, 1507374, 4, 65538, 1572864, 4, 65538, 1572878, 5, 131072, 1572879, 5, 131073, 1572880, 5, 131074, 1572910, 4, 65536, 1638400, 4, 131072, 1638401, 4, 1, 1638402, 4, 1, 1638403, 4, 1, 1638404, 4, 1, 1638405, 4, 1, 1638406, 4, 131073, 1638407, 4, 131073, 1638408, 4, 131073, 1638409, 4, 1, 1638410, 4, 131073, 1638411, 4, 1, 1638412, 4, 131073, 1638413, 4, 131073, 1638414, 4, 131073, 1638415, 4, 1, 1638416, 4, 131073, 1638417, 4, 131073, 1638418, 4, 131073, 1638419, 4, 1, 1638420, 4, 1, 1638421, 4, 131073, 1638422, 4, 131073, 1638423, 4, 131073, 1638424, 4, 131073, 1638425, 4, 131073, 1638426, 4, 131073, 1638427, 4, 131073, 1638428, 4, 1, 1638429, 4, 131073, 1638430, 4, 1, 1638431, 4, 1, 1638432, 4, 1, 1638433, 4, 1, 1638434, 4, 131073, 1638435, 4, 1, 1638436, 4, 131073, 1638437, 4, 131073, 1638438, 4, 1, 1638439, 4, 131073, 1638440, 4, 131073, 1638441, 4, 1, 1638442, 4, 1, 1638443, 4, 131073, 1638444, 4, 1, 1638445, 4, 131073, 1638446, 4, 131074 )
_sections_unfolded = [ "Cell" ]
[node name="Gap" parent="." index="2" instance=ExtResource( 3 )]
position = Vector2( 1744, 944 )
[node name="Gap2" parent="." index="3" instance=ExtResource( 3 )]
position = Vector2( 432, 1440 )
[node name="Gap3" parent="." index="4" instance=ExtResource( 3 )]
position = Vector2( 4624, 2272 )
[node name="Gap4" parent="." index="5" instance=ExtResource( 3 )]
position = Vector2( 5664, 1424 )
[node name="Gap5" parent="." index="6" instance=ExtResource( 3 )]
position = Vector2( 3152, 1696 )
[node name="YSort" type="YSort" parent="." index="7"]
editor/display_folded = true
sort_enabled = true
[node name="Porcupine" parent="YSort" index="0" instance=ExtResource( 4 )]
position = Vector2( 576, 768 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
MAX_ROAM_SPEED = 200.0
MAX_FOLLOW_SPEED = 400.0
MAX_CHARGE_SPEED = 900.0
SPOT_RANGE = 460.0
FOLLOW_RANGE = 700.0
BUMP_RANGE = 90.0
CHARGE_RANGE = 340.0
PREPARE_TO_CHARGE_WAIT_TIME = 0.9
ROAM_RADIUS = 140.0
BUMP_DISTANCE = 60.0
BUMP_DURATION = 0.2
MAX_BUMP_HEIGHT = 50.0
BUMP_COOLDOWN_DURATION = 0.6
[node name="Porcupine2" parent="YSort" index="1" instance=ExtResource( 4 )]
position = Vector2( 2176, 656 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
MAX_ROAM_SPEED = 200.0
MAX_FOLLOW_SPEED = 400.0
MAX_CHARGE_SPEED = 900.0
SPOT_RANGE = 460.0
FOLLOW_RANGE = 700.0
BUMP_RANGE = 90.0
CHARGE_RANGE = 340.0
PREPARE_TO_CHARGE_WAIT_TIME = 0.9
ROAM_RADIUS = 140.0
BUMP_DISTANCE = 60.0
BUMP_DURATION = 0.2
MAX_BUMP_HEIGHT = 50.0
BUMP_COOLDOWN_DURATION = 0.6
[node name="Porcupine3" parent="YSort" index="2" instance=ExtResource( 4 )]
position = Vector2( 816, 1728 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
MAX_ROAM_SPEED = 200.0
MAX_FOLLOW_SPEED = 400.0
MAX_CHARGE_SPEED = 900.0
SPOT_RANGE = 460.0
FOLLOW_RANGE = 700.0
BUMP_RANGE = 90.0
CHARGE_RANGE = 340.0
PREPARE_TO_CHARGE_WAIT_TIME = 0.9
ROAM_RADIUS = 140.0
BUMP_DISTANCE = 60.0
BUMP_DURATION = 0.2
MAX_BUMP_HEIGHT = 50.0
BUMP_COOLDOWN_DURATION = 0.6
[node name="Porcupine4" parent="YSort" index="3" instance=ExtResource( 4 )]
position = Vector2( 464, 2976 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
MAX_ROAM_SPEED = 200.0
MAX_FOLLOW_SPEED = 400.0
MAX_CHARGE_SPEED = 900.0
SPOT_RANGE = 460.0
FOLLOW_RANGE = 700.0
BUMP_RANGE = 90.0
CHARGE_RANGE = 340.0
PREPARE_TO_CHARGE_WAIT_TIME = 0.9
ROAM_RADIUS = 140.0
BUMP_DISTANCE = 60.0
BUMP_DURATION = 0.2
MAX_BUMP_HEIGHT = 50.0
BUMP_COOLDOWN_DURATION = 0.6
[node name="Porcupine5" parent="YSort" index="4" instance=ExtResource( 4 )]
position = Vector2( 4752, 640 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
MAX_ROAM_SPEED = 200.0
MAX_FOLLOW_SPEED = 400.0
MAX_CHARGE_SPEED = 900.0
SPOT_RANGE = 460.0
FOLLOW_RANGE = 700.0
BUMP_RANGE = 90.0
CHARGE_RANGE = 340.0
PREPARE_TO_CHARGE_WAIT_TIME = 0.9
ROAM_RADIUS = 140.0
BUMP_DISTANCE = 60.0
BUMP_DURATION = 0.2
MAX_BUMP_HEIGHT = 50.0
BUMP_COOLDOWN_DURATION = 0.6
[node name="Nest" parent="YSort" index="5" instance=ExtResource( 5 )]
position = Vector2( 1936, 1520 )
[node name="Nest2" parent="YSort" index="6" instance=ExtResource( 5 )]
position = Vector2( 384, 912 )
[node name="Nest3" parent="YSort" index="7" instance=ExtResource( 5 )]
position = Vector2( 1088, 2576 )
[node name="Seller" parent="YSort" index="8" instance=ExtResource( 6 )]
position = Vector2( 3056, 1232 )
[node name="PlayerSpawningPoint" parent="." index="8" instance=ExtResource( 7 )]
position = Vector2( 5440, 2896 )
[node name="Door" parent="." index="9" instance=ExtResource( 8 )]
position = Vector2( 304, 432 )
scale = Vector2( 0.8125, 0.8125 )
map_path = "res://levels/Cave.tscn"
ACTIVE_AT_START = true
[node name="SecretDrop" type="Node2D" parent="." index="10"]
position = Vector2( 448, 2560 )
[node name="Walls" type="StaticBody2D" parent="." index="11"]
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="Walls" index="0"]
build_mode = 1
polygon = PoolVector2Array( 96, 2048, 2592, 2048, 2656, 2048, 2656, 1936, 2656, 1792, 2848, 1792, 2912, 1792, 2912, 1680, 2912, 1552, 2848, 1552, 2848, 1680, 2655.43, 1680, 2592, 1680, 2592, 1792, 2592, 1936, 96, 1936 )
[node name="CollisionPolygon2D2" type="CollisionPolygon2D" parent="Walls" index="1"]
build_mode = 1
polygon = PoolVector2Array( 2912, 896, 2848, 896, 2848, 768, 2656, 768, 2592, 768, 2592, 656, 2592, 128, 96, 128, 96, 16, 2591.58, 16, 2656, 16, 2656, 128, 2656, 656, 2848, 656, 2912, 656, 2912, 768 )
[node name="CollisionPolygon2D3" type="CollisionPolygon2D" parent="Walls" index="2"]
build_mode = 1
polygon = PoolVector2Array( 32, 16, 96, 16, 96, 3216, 5920, 3216, 5920, 3328, 96, 3328, 32, 3328, 32, 3216 )
[node name="CollisionPolygon2D4" type="CollisionPolygon2D" parent="Walls" index="3"]
build_mode = 1
polygon = PoolVector2Array( 5984, 3328, 5920, 3328, 5920, 128, 2656, 128, 2656, 16, 5984, 16 )
================================================
FILE: levels/Level.gd
================================================
extends Node
export(bool) var fog = false
func get_ysort_node():
return $YSort
func initialize():
return
================================================
FILE: levels/TestLevel.tscn
================================================
[gd_scene load_steps=11 format=2]
[ext_resource path="res://core/world/tilesets/outdoor/outdoor.tres" type="TileSet" id=1]
[ext_resource path="res://levels/Level.gd" type="Script" id=2]
[ext_resource path="res://core/world/PlayerSpawningPoint.tscn" type="PackedScene" id=3]
[ext_resource path="res://core/world/Gap.tscn" type="PackedScene" id=4]
[ext_resource path="res://core/world/Door.tscn" type="PackedScene" id=5]
[ext_resource path="res://actors/characters/seller/Seller.tscn" type="PackedScene" id=6]
[ext_resource path="res://monsters/mosquito/Nest.tscn" type="PackedScene" id=7]
[ext_resource path="res://monsters/porcupine/Porcupine.tscn" type="PackedScene" id=8]
[ext_resource path="res://core/world/Rock.tscn" type="PackedScene" id=9]
[ext_resource path="res://core/inventory/items/Coins.tscn" type="PackedScene" id=10]
[node name="TestLevel" type="TileMap"]
mode = 0
tile_set = ExtResource( 1 )
cell_size = Vector2( 128, 128 )
cell_quadrant_size = 16
cell_custom_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
cell_half_offset = 2
cell_tile_origin = 0
cell_y_sort = false
cell_clip_uv = false
collision_use_kinematic = true
collision_friction = 1.0
collision_bounce = 0.0
collision_layer = 1
collision_mask = 1
occluder_light_mask = 1
format = 1
tile_data = PoolIntArray( 0, 0, 65536, 1, 0, 65536, 2, 1, 0, 3, 1, 2, 4, 0, 65536, 5, 0, 65536, 6, 0, 65536, 7, 0, 65536, 8, 0, 65536, 9, 0, 65536, 10, 0, 65536, 11, 0, 65536, 12, 0, 65536, 13, 0, 65536, 14, 0, 65536, 15, 0, 65536, 16, 0, 65536, 17, 0, 65536, 18, 0, 65536, 19, 0, 65536, 20, 0, 65536, 65536, 0, 65536, 65537, 0, 65536, 65538, 1, 65536, 65539, 1, 65538, 65540, 5, 0, 65541, 5, 2, 65542, 0, 65536, 65543, 5, 0, 65544, 5, 1, 65545, 5, 2, 65546, 0, 65536, 65547, 0, 65536, 65548, 0, 65536, 65549, 0, 65536, 65550, 0, 65536, 65551, 0, 65536, 65552, 0, 65536, 65553, 0, 65536, 65554, 0, 65536, 65555, 0, 65536, 65556, 0, 65536, 131072, 0, 65536, 131073, 0, 65536, 131074, 1, 65536, 131075, 1, 65538, 131076, 5, 65536, 131077, 5, 65539, 131078, 5, 1, 131079, 5, 65540, 131080, 5, 3, 131081, 5, 131074, 131082, 0, 65536, 131083, 0, 65536, 131084, 1, 0, 131085, 1, 1, 131086, 1, 2, 131087, 0, 65536, 131088, 0, 65536, 131089, 0, 65536, 131090, 0, 65536, 131091, 0, 65536, 131092, 0, 65536, 196608, 0, 65536, 196609, 0, 65536, 196610, 1, 65536, 196611, 1, 65538, 196612, 5, 65536, 196613, 5, 65537, 196614, 5, 65537, 196615, 5, 65537, 196616, 5, 65538, 196617, 0, 65536, 196618, 1, 0, 196619, 1, 1, 196620, 1, 65540, 196621, 1, 65537, 196622, 1, 65539, 196623, 1, 1, 196624, 1, 1, 196625, 1, 1, 196626, 1, 2, 196627, 0, 65536, 196628, 0, 65536, 262144, 0, 65536, 262145, 0, 65536, 262146, 1, 65536, 262147, 1, 65538, 262148, 5, 131072, 262149, 5, 131073, 262150, 5, 4, 262151, 5, 65537, 262152, 5, 65539, 262153, 5, 2, 262154, 1, 65536, 262155, 1, 65537, 262156, 1, 65537, 262157, 1, 65537, 262158, 1, 65537, 262159, 1, 65537, 262160, 1, 65537, 262161, 1, 65537, 262162, 1, 65538, 262163, 0, 65536, 262164, 0, 65536, 327680, 0, 65536, 327681, 0, 65536, 327682, 1, 65536, 327683, 1, 65539, 327684, 1, 2, 327685, 0, 65536, 327686, 5, 131072, 327687, 5, 131073, 327688, 5, 131073, 327689, 5, 131074, 327690, 1, 65536, 327691, 1, 65537, 327692, 1, 65537, 327693, 1, 65537, 327694, 1, 65537, 327695, 1, 65537, 327696, 1, 65537, 327697, 1, 65537, 327698, 1, 65538, 327699, 0, 65536, 327700, 0, 65536, 393216, 0, 65536, 393217, 0, 65536, 393218, 1, 131072, 393219, 1, 4, 393220, 1, 65539, 393221, 1, 2, 393222, 0, 65536, 393223, 0, 65536, 393224, 0, 65536, 393225, 0, 65536, 393226, 1, 65536, 393227, 1, 65537, 393228, 1, 65537, 393229, 1, 65537, 393230, 1, 65537, 393231, 1, 65537, 393232, 1, 65537, 393233, 1, 65537, 393234, 1, 65538, 393235, 0, 65536, 393236, 0, 65536, 458752, 0, 65536, 458753, 0, 65536, 458754, 0, 65536, 458755, 1, 131072, 458756, 1, 4, 458757, 1, 65539, 458758, 1, 1, 458759, 1, 1, 458760, 1, 1, 458761, 1, 1, 458762, 1, 65540, 458763, 1, 65537, 458764, 1, 65537, 458765, 1, 65537, 458766, 1, 3, 458767, 1, 131073, 458768, 1, 131073, 458769, 1, 4, 458770, 1, 65538, 458771, 0, 65536, 458772, 0, 65536, 524288, 0, 65536, 524289, 0, 65536, 524290, 0, 65536, 524291, 0, 65536, 524292, 1, 131072, 524293, 1, 131073, 524294, 1, 131073, 524295, 1, 131073, 524296, 1, 131073, 524297, 1, 4, 524298, 1, 3, 524299, 1, 131073, 524300, 1, 131073, 524301, 1, 131073, 524302, 1, 131074, 524303, 0, 65536, 524304, 0, 65536, 524305, 1, 131072, 524306, 1, 131074, 524307, 0, 65536, 524308, 0, 65536, 589824, 0, 65536, 589825, 0, 65536, 589826, 0, 65536, 589827, 0, 65536, 589828, 0, 65536, 589829, 0, 65536, 589830, 0, 65536, 589831, 0, 65536, 589832, 0, 65536, 589833, 1, 65536, 589834, 1, 65538, 589835, 0, 65536, 589836, 0, 65536, 589837, 0, 65536, 589838, 0, 65536, 589839, 0, 65536, 589840, 0, 65536, 589841, 0, 65536, 589842, 0, 65536, 589843, 0, 65536, 589844, 0, 65536, 655360, 0, 65536, 655361, 0, 65536, 655362, 0, 65536, 655363, 0, 65536, 655364, 0, 2, 655365, 0, 65536, 655366, 0, 65536, 655367, 0, 65536, 655368, 0, 65536, 655369, 1, 65536, 655370, 1, 65538, 655371, 0, 65536, 655372, 0, 65536, 655373, 0, 65536, 655374, 0, 65536, 655375, 0, 65536, 655376, 0, 1, 655377, 0, 65536, 655378, 0, 65536, 655379, 0, 65536, 655380, 0, 65536, 720896, 0, 65536, 720897, 0, 65536, 720898, 0, 65536, 720899, 0, 65536, 720900, 0, 65536, 720901, 0, 65536, 720902, 0, 65536, 720903, 0, 65536, 720904, 0, 65536, 720905, 1, 131072, 720906, 1, 131074, 720907, 0, 65536, 720908, 0, 65536, 720909, 0, 65536, 720910, 0, 65536, 720911, 0, 65536, 720912, 0, 65536, 720913, 0, 65536, 720914, 0, 65536, 720915, 0, 65536, 720916, 0, 65536 )
script = ExtResource( 2 )
_sections_unfolded = [ "Cell", "Collision" ]
fog = false
[node name="PlayerSpawningPoint" parent="." index="0" instance=ExtResource( 3 )]
position = Vector2( 603.07, 1200 )
[node name="Gap" parent="." index="1" instance=ExtResource( 4 )]
position = Vector2( 1658, 902 )
[node name="Door" parent="." index="2" instance=ExtResource( 5 )]
position = Vector2( 2006, 722 )
scale = Vector2( 0.8125, 0.8125 )
map_path = "res://levels/Cave.tscn"
ACTIVE_AT_START = true
[node name="YSort" type="YSort" parent="." index="3"]
sort_enabled = true
[node name="Seller" parent="YSort" index="0" instance=ExtResource( 6 )]
position = Vector2( 466, 1213 )
[node name="Nest" parent="YSort" index="1" instance=ExtResource( 7 )]
position = Vector2( 1635, 455 )
[node name="Porcupine" parent="YSort" index="2" instance=ExtResource( 8 )]
position = Vector2( 2086.01, 1288.82 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
MAX_ROAM_SPEED = 200.0
MAX_FOLLOW_SPEED = 400.0
MAX_CHARGE_SPEED = 900.0
SPOT_RANGE = 460.0
FOLLOW_RANGE = 700.0
BUMP_RANGE = 90.0
CHARGE_RANGE = 340.0
PREPARE_TO_CHARGE_WAIT_TIME = 0.9
ROAM_RADIUS = 140.0
BUMP_DISTANCE = 60.0
BUMP_DURATION = 0.2
MAX_BUMP_HEIGHT = 50.0
BUMP_COOLDOWN_DURATION = 0.6
[node name="Porcupine2" parent="YSort" index="3" instance=ExtResource( 8 )]
position = Vector2( 2546.01, 728.82 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
MAX_ROAM_SPEED = 200.0
MAX_FOLLOW_SPEED = 400.0
MAX_CHARGE_SPEED = 900.0
SPOT_RANGE = 460.0
FOLLOW_RANGE = 700.0
BUMP_RANGE = 90.0
CHARGE_RANGE = 340.0
PREPARE_TO_CHARGE_WAIT_TIME = 0.9
ROAM_RADIUS = 140.0
BUMP_DISTANCE = 60.0
BUMP_DURATION = 0.2
MAX_BUMP_HEIGHT = 50.0
BUMP_COOLDOWN_DURATION = 0.6
[node name="Rock" parent="YSort" index="4" instance=ExtResource( 9 )]
position = Vector2( 1162, 801 )
[node name="Coins" parent="YSort" index="5" instance=ExtResource( 10 )]
position = Vector2( 472.412, 993.695 )
[node name="Coins2" parent="YSort" index="6" instance=ExtResource( 10 )]
position = Vector2( 781.924, 811.246 )
[node name="Coins3" parent="YSort" index="7" instance=ExtResource( 10 )]
position = Vector2( 1153.34, 1179.4 )
[node name="Coins4" parent="YSort" index="8" instance=ExtResource( 10 )]
position = Vector2( 1062.11, 1485.65 )
================================================
FILE: monsters/BossShakingCamera.gd
================================================
tool
extends "res://actors/camera/ShakingCamera.gd"
onready var tween = $Tween
export(float) var AMPLITUDE_HIT_WALL = 30.0
var start_global_position = Vector2()
onready var _start_amplitude = amplitude
func _ready():
start_global_position = global_position
func initialize(player):
global_position = player.camera.global_position
player.get_health_node().connect('damage_taken', self, '_on_Player_damage_taken')
current = true
func move_to_room_center():
tween.interpolate_property(self, 'global_position', global_position, start_global_position, 1.0, Tween.TRANS_QUART, Tween.EASE_IN)
tween.start()
yield(tween, "tween_completed")
func _on_WildBoar_hit_wall():
amplitude = AMPLITUDE_HIT_WALL
self.shake = true
func _on_Player_damage_taken(new_health):
amplitude = _start_amplitude
self.shake = true
================================================
FILE: monsters/BossShakingCamera.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://actors/camera/ShakingCamera.tscn" type="PackedScene" id=1]
[ext_resource path="res://monsters/BossShakingCamera.gd" type="Script" id=2]
[node name="BossShakingCamera" instance=ExtResource( 1 )]
script = ExtResource( 2 )
amplitude = 10.0
AMPLITUDE_HIT_WALL = 30.0
[node name="Tween" type="Tween" parent="." index="1"]
repeat = false
playback_process_mode = 1
playback_speed = 1.0
playback/active = false
playback/repeat = false
playback/speed = 1.0
================================================
FILE: monsters/Monster.gd
================================================
extends KinematicBody2D
signal died
var state
var active
export(float) var ARRIVE_DISTANCE = 6.0
export(float) var DEFAULT_SLOW_RADIUS = 200.0
export(float) var DEFAULT_MAX_SPEED = 300.0
export(float) var MASS = 8.0
onready var stats = $Stats
const Actor = preload("res://actors/Actor.gd")
var target = null # Actor
var start_position = Vector2()
var velocity = Vector2()
func _ready():
set_as_toplevel(true)
start_position = global_position
func initialize(target_actor):
if not target_actor is Actor:
return
target = target_actor
target.connect('died', self, '_on_target_died')
set_active(true)
func _on_target_died():
target = null
func take_damage_from(damage_source):
stats.take_damage(damage_source.damage)
func set_active(value):
active = value
set_physics_process(value)
$HitBox.set_active(value)
$DamageSource.set_active(value)
================================================
FILE: monsters/Monster.tscn
================================================
[gd_scene load_steps=8 format=2]
[ext_resource path="res://monsters/Monster.gd" type="Script" id=1]
[ext_resource path="res://actors/health/Stats.tscn" type="PackedScene" id=2]
[ext_resource path="res://actors/hit_box/HitBox.tscn" type="PackedScene" id=3]
[ext_resource path="res://interface/gui/lifebar/InterfaceAnchor.tscn" type="PackedScene" id=4]
[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: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, 0 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Skin: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: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("Skin: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("Skin:visible")
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": [ true ]
}
tracks/5/type = "value"
tracks/5/path = NodePath("Skin/BodyPivot:modulate")
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": [ Color( 1, 1, 1, 1 ) ]
}
tracks/6/type = "value"
tracks/6/path = NodePath("Skin/BodyPivot:position")
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": [ Vector2( 0, 0 ) ]
}
tracks/7/type = "value"
tracks/7/path = NodePath("Skin/BodyPivot:rotation_degrees")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/imported = false
tracks/7/enabled = true
tracks/7/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ 0.0 ]
}
tracks/8/type = "value"
tracks/8/path = NodePath("Skin/BodyPivot:scale")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/imported = false
tracks/8/enabled = true
tracks/8/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ) ]
}
[sub_resource type="Animation" id=2]
resource_name = "die"
length = 0.4
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Skin/BodyPivot:scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.4 ),
"transitions": PoolRealArray( 0.27058, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 0.1, 0.1 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Skin/BodyPivot:modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.4 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
}
[sub_resource type="Animation" id=3]
resource_name = "stagger"
length = 0.6
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Skin/BodyPivot: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.5 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ 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("Skin/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 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ Vector2( 1, 1 ) ]
}
[node name="Monster" type="KinematicBody2D" index="0"]
input_pickable = false
collision_layer = 1
collision_mask = 1
collision/safe_margin = 0.08
script = ExtResource( 1 )
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
[node name="Stats" parent="." index="0" instance=ExtResource( 2 )]
[node name="HitBox" parent="." index="1" instance=ExtResource( 3 )]
[node name="Skin" type="Position2D" parent="." index="2"]
_sections_unfolded = [ "Visibility" ]
[node name="BodyPivot" type="Position2D" parent="Skin" index="0"]
_sections_unfolded = [ "Transform", "Visibility" ]
[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( 1 )
anims/die = SubResource( 2 )
anims/stagger = SubResource( 3 )
blend_times = [ ]
[node name="InterfaceAnchor" parent="." index="4" instance=ExtResource( 4 )]
position = Vector2( 0, -150.219 )
================================================
FILE: monsters/ObstacleDetector.gd
================================================
# Detects collisions with the environment using raycasts
# If collisions happen, emits a signal with a list of collision points
extends Node2D
signal rays_collided
var rays = []
const RAYS_COUNT = 12
const RAYS_RADIUS = 100
func _ready():
for i in range(RAYS_COUNT):
var new_ray = RayCast2D.new()
var angle = 2 * PI * i / RAYS_COUNT
new_ray.cast_to = Vector2(cos(angle), sin(angle)) * RAYS_RADIUS
add_child(new_ray)
new_ray.add_exception(get_parent().get_parent())
new_ray.enabled = true
new_ray.collision_mask = 2
func _physics_process(delta):
var collision_points = []
for ray in get_children():
if not ray.is_colliding():
continue
collision_points.append(ray.get_collision_point())
if collision_points == []:
return
emit_signal('rays_collided', collision_points)
================================================
FILE: monsters/bosses/wild_boar/WildBoar.gd
================================================
extends "res://monsters/Monster.gd"
signal hit_wall()
onready var state_machine = $StateMachine
onready var lifebar = $BossLifebar
onready var health_node = $Stats
onready var tween_node = $Tween
var start_global_position
func _ready():
visible = false
set_invincible(true)
start_global_position = global_position
lifebar.initialize(health_node)
func start():
lifebar.appear()
state_machine.start()
func _on_Health_health_depleted():
set_invincible(true)
lifebar.disappear()
func _on_Health_health_changed(new_health):
tween_node.interpolate_property($Pivot, 'scale', Vector2(0.92, 1.12), Vector2(1.0, 1.0), 0.3, Tween.TRANS_ELASTIC, Tween.EASE_IN_OUT)
tween_node.interpolate_property($Pivot/Body, 'modulate', Color('#ff48de'), Color('#ffffff'), 0.2, Tween.TRANS_QUINT, Tween.EASE_IN)
tween_node.start()
match state_machine.phase:
1:
if new_health < 100:
state_machine.phase = 2
2:
if new_health < 50:
state_machine.phase = 3
func set_particles_active(value):
$DustPuffsLarge.emitting = value
func set_invincible(value):
$CollisionPolygon2D.disabled = value
$HitBox/CollisionShape2D.disabled = value
$DamageSource/CollisionShape2D.disabled = value
$DamageSource.monitorable = not value
func take_damage_from(attacker):
health_node.take_damage(attacker.damage)
func _on_Die_finished():
state_machine.set_active(false)
emit_signal('died')
queue_free()
func _on_target_died():
._on_target_died()
state_machine.change_phase(4)
state_machine.go_to_next_state()
func _on_Sprint_hit_wall():
emit_signal('hit_wall')
================================================
FILE: monsters/bosses/wild_boar/WildBoar.tscn
================================================
[gd_scene load_steps=35 format=2]
[ext_resource path="res://monsters/bosses/wild_boar/WildBoar.gd" type="Script" id=1]
[ext_resource path="res://vfx/particles/dust_puffs/DustPuffsLarge.tscn" type="PackedScene" id=2]
[ext_resource path="res://monsters/bosses/wild_boar/sprites/front.png" type="Texture" id=3]
[ext_resource path="res://monsters/bosses/wild_boar/sprites/wild_boar_stomp_2.png" type="Texture" id=4]
[ext_resource path="res://monsters/bosses/wild_boar/sprites/wild_boar_stomp_1.png" type="Texture" id=5]
[ext_resource path="res://actors/health/Stats.tscn" type="PackedScene" id=6]
[ext_resource path="res://monsters/bosses/wild_boar/WildBoarFSM.gd" type="Script" id=7]
[ext_resource path="res://monsters/bosses/wild_boar/states/Spawn.gd" type="Script" id=8]
[ext_resource path="res://monsters/bosses/wild_boar/states/roam/RoamSequence.gd" type="Script" id=9]
[ext_resource path="res://monsters/bosses/wild_boar/states/roam/Wait.gd" type="Script" id=10]
[ext_resource path="res://monsters/bosses/wild_boar/states/roam/MoveToRandomPosition.gd" type="Script" id=11]
[ext_resource path="res://utils/state/Sequence.gd" type="Script" id=12]
[ext_resource path="res://monsters/bosses/wild_boar/states/charge/Prepare.gd" type="Script" id=13]
[ext_resource path="res://monsters/bosses/wild_boar/states/charge/Sprint.gd" type="Script" id=14]
[ext_resource path="res://monsters/bosses/wild_boar/states/charge/BumpWildBoar.gd" type="Script" id=15]
[ext_resource path="res://monsters/bosses/wild_boar/states/ReturnToCenter.gd" type="Script" id=16]
[ext_resource path="res://monsters/bosses/wild_boar/states/stomp/Stomp.gd" type="Script" id=17]
[ext_resource path="res://monsters/bosses/wild_boar/states/Die.gd" type="Script" id=18]
[ext_resource path="res://vfx/particles/explosions/Explosion.tscn" type="PackedScene" id=19]
[ext_resource path="res://actors/DamageSource.tscn" type="PackedScene" id=20]
[ext_resource path="res://actors/hit_box/HitBox.tscn" type="PackedScene" id=21]
[ext_resource path="res://interface/gui/boss/BossLifebar.tscn" type="PackedScene" id=22]
[sub_resource type="Animation" id=1]
resource_name = "SETUP"
length = 0.05
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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( 3.57628e-007, 17.6051 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Pivot/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("Pivot/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("Pivot/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 ) ]
}
tracks/4/type = "value"
tracks/4/path = NodePath("Pivot/Body:modulate")
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": [ Color( 1, 1, 1, 1 ) ]
}
tracks/5/type = "value"
tracks/5/path = NodePath("Pivot/Body:texture")
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": [ ExtResource( 3 ) ]
}
[sub_resource type="Animation" id=2]
resource_name = "bump"
length = 1.4
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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, 0.55, 0.7, 0.85, 0.95, 1.05, 1.1, 1.15 ),
"transitions": PoolRealArray( 0.225072, 1.67946, 0.367583, 1, 0.367583, 1, 0.367583, 1, 0.367583 ),
"update": 0,
"values": [ Vector2( 3.57628e-007, 17.6051 ), Vector2( 0, -37.6635 ), Vector2( 3.57628e-007, 17.6051 ), Vector2( 0, -6.75531 ), Vector2( 3.57628e-007, 17.6051 ), Vector2( 0, 8.69879 ), Vector2( 3.57628e-007, 17.6051 ), Vector2( 0, 17.8458 ), Vector2( 3.57628e-007, 17.6051 ) ]
}
[sub_resource type="Animation" id=3]
length = 3.0
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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.15, 0.3, 1.25, 1.6, 2.05, 2.25, 2.3, 2.35, 2.4, 2.45, 2.6, 2.75, 2.95 ),
"transitions": PoolRealArray( 0.307901, 2.62585, 1, 0.307901, 2.62585, 1, 1, 1, 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 10, 10, 10, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 1 ), Color( 10, 10, 10, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Pivot/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.5, 2.25, 2.6, 2.7, 2.9 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 2.94246, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1, 1 ), Vector2( 1, 1 ), Vector2( 1, 1 ), Vector2( 0.812022, 1.23284 ), Vector2( 2.7717, 0.0452506 ) ]
}
[sub_resource type="Animation" id=4]
length = 0.01
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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( 3.57628e-007, 17.6051 ) ]
}
[sub_resource type="Animation" id=5]
resource_name = "move"
length = 0.3
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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.367583, 1.73627 ),
"update": 0,
"values": [ Vector2( 3.57628e-007, 17.6051 ), Vector2( 0, 0.113144 ) ]
}
[sub_resource type="Animation" id=6]
resource_name = "prepare"
length = 1.3
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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, 0.8 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1.08725, 0.772716 ) ]
}
[sub_resource type="Animation" id=7]
resource_name = "spawn"
length = 3.1
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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.5, 2.9 ),
"transitions": PoolRealArray( 1, 1, 1 ),
"update": 0,
"values": [ Vector2( -477.666, -688.279 ), Vector2( -477.666, -688.279 ), Vector2( 0, 0 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Pivot:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.5, 0.65, 0.8, 0.95, 1.1, 1.25, 1.4, 1.55, 1.7, 1.85, 2, 2.15, 2.3, 2.45, 2.6, 2.75, 2.9 ),
"transitions": PoolRealArray( 1, 0.342967, 2.00422, 0.342967, 2.00422, 0.342967, 2.00422, 0.342967, 2.00422, 0.342967, 2.00422, 0.342967, 2.00422, 0.342967, 2.00422, 0.342967, 2.00422, 0.342967 ),
"update": 0,
"values": [ Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ), Vector2( 0, -45 ), Vector2( 0, 0 ) ]
}
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 ]
}
[sub_resource type="Animation" id=8]
length = 0.9
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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( 3.57628e-007, 17.6051 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Pivot/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 ]
}
[sub_resource type="Animation" id=9]
length = 0.1
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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, 0.05 ),
"transitions": PoolRealArray( 0.550489, 0.550489 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1.08725, 0.772716 ) ]
}
[sub_resource type="Animation" id=10]
length = 0.3
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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.3 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=11]
resource_name = "stomp"
length = 3.0
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Pivot/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.25, 0.3, 1, 1.1, 1.2 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Vector2( 3.57628e-007, 17.6051 ), Vector2( 0, 23.1995 ), Vector2( 3.57628e-007, 17.6051 ), Vector2( 3.57628e-007, 17.6051 ), Vector2( 0.260636, 30.418 ), Vector2( 3.57628e-007, 17.6051 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Pivot/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, 0.3, 0.45, 0.65, 0.85, 1 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ 0.0, 0.0, -4.36329, 1.8451, -4.4684, 0.333169 ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("Pivot/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, 0.25, 0.3, 1, 1.1, 1.2 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1.14791, 0.896572 ), Vector2( 1, 1 ), Vector2( 1, 1 ), Vector2( 1.16872, 0.836578 ), Vector2( 1, 1 ) ]
}
tracks/3/type = "value"
tracks/3/path = NodePath("Pivot/Body:texture")
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, 1.25 ),
"transitions": PoolRealArray( 1, 1, 1, 1 ),
"update": 1,
"values": [ ExtResource( 4 ), ExtResource( 5 ), ExtResource( 4 ), ExtResource( 3 ) ]
}
tracks/4/type = "method"
tracks/4/path = NodePath("StateMachine/Stomp")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/keys = {
"times": PoolRealArray( 1.15 ),
"transitions": PoolRealArray( 1 ),
"values": [ {
"args": [ ],
"method": "stomp"
} ]
}
[sub_resource type="CircleShape2D" id=12]
custom_solver_bias = 0.0
radius = 50.0
[node name="WildBoar" type="KinematicBody2D" index="0" groups=[
"monster",
]]
input_pickable = false
collision_layer = 1
collision_mask = 2
collision/safe_margin = 0.08
script = ExtResource( 1 )
_sections_unfolded = [ "Transform", "Visibility", "Z Index" ]
__meta__ = {
"_edit_group_": true
}
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 1.4
[node name="DustPuffsLarge" parent="." index="0" instance=ExtResource( 2 )]
emitting = false
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="1"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/SETUP = SubResource( 1 )
anims/bump = SubResource( 2 )
anims/die = SubResource( 3 )
anims/idle = SubResource( 4 )
anims/move = SubResource( 5 )
anims/prepare = SubResource( 6 )
anims/spawn = SubResource( 7 )
anims/spot = SubResource( 8 )
anims/sprint = SubResource( 9 )
anims/stagger = SubResource( 10 )
anims/stomp = SubResource( 11 )
blend_times = [ ]
[node name="Tween" type="Tween" parent="." index="2"]
repeat = false
playback_process_mode = 1
playback_speed = 1.0
playback/active = false
playback/repeat = false
playback/speed = 1.0
[node name="Stats" parent="." index="3" instance=ExtResource( 6 )]
max_health = 120
[node name="StateMachine" type="Node" parent="." index="4"]
script = ExtResource( 7 )
active = false
phase = 1
[node name="Spawn" type="Node" parent="StateMachine" index="0"]
script = ExtResource( 8 )
[node name="RoamSequence" type="Node" parent="StateMachine" index="1"]
script = ExtResource( 9 )
[node name="Wait" type="Node" parent="StateMachine/RoamSequence" index="0"]
editor/display_folded = true
script = ExtResource( 10 )
[node name="Timer" type="Timer" parent="StateMachine/RoamSequence/Wait" index="0"]
process_mode = 1
wait_time = 1.0
one_shot = true
autostart = false
[node name="MoveTo" type="Node" parent="StateMachine/RoamSequence" index="1"]
script = ExtResource( 11 )
ARRIVE_DISTANCE = 6.0
SLOW_RADIUS = 200.0
MASS = 4.0
MAX_SPEED = 300.0
ROAM_RADIUS = 150.0
[node name="ChargeSequence" type="Node" parent="StateMachine" index="2"]
script = ExtResource( 12 )
[node name="Prepare" type="Node" parent="StateMachine/ChargeSequence" index="0"]
script = ExtResource( 13 )
[node name="Sprint" type="Node" parent="StateMachine/ChargeSequence" index="1"]
script = ExtResource( 14 )
SPEED = 1000.0
MAX_DISTANCE = 1200.0
[node name="Bump" type="Node" parent="StateMachine/ChargeSequence" index="2"]
script = ExtResource( 15 )
SPEED = 100.0
[node name="ReturnToCenter" type="Node" parent="StateMachine/ChargeSequence" index="3"]
script = ExtResource( 16 )
MASS = 4.0
SLOW_RADIUS = 200.0
MAX_SPEED = 300.0
ARRIVE_DISTANCE = 6.0
[node name="Stomp" type="Node" parent="StateMachine" index="3"]
editor/display_folded = true
script = ExtResource( 17 )
[node name="ExplodeTimer" type="Timer" parent="StateMachine/Stomp" index="0"]
process_mode = 1
wait_time = 0.2
one_shot = false
autostart = false
[node name="Die" type="Node" parent="StateMachine" index="4"]
editor/display_folded = true
script = ExtResource( 18 )
MAX_RADIUS = 180.0
Explosion = ExtResource( 19 )
[node name="ExplodeTimer" type="Timer" parent="StateMachine/Die" index="0"]
process_mode = 1
wait_time = 0.15
one_shot = false
autostart = false
[node name="Pivot" type="Position2D" parent="." index="5"]
_sections_unfolded = [ "Transform", "Visibility", "Z Index" ]
[node name="Body" type="Sprite" parent="Pivot" index="0"]
position = Vector2( -477.666, -688.279 )
rotation = 0.0058149
texture = ExtResource( 3 )
offset = Vector2( -1.98642, -55.6066 )
_sections_unfolded = [ "Offset", "Transform", "Visibility", "Z Index" ]
[node name="DamageSource" parent="." index="6" instance=ExtResource( 20 )]
position = Vector2( 0, -27.075 )
monitorable = false
damage = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageSource" index="0"]
position = Vector2( 0, -17.075 )
shape = SubResource( 12 )
[node name="HitBox" parent="." index="7" instance=ExtResource( 21 )]
collision_layer = 8
collision_mask = 16
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="8"]
position = Vector2( 0, 21.5742 )
build_mode = 0
polygon = PoolVector2Array( -36, -96, 36, -96, 36, -24, -36, -24 )
_sections_unfolded = [ "Visibility" ]
[node name="BossLifebar" parent="." index="9" instance=ExtResource( 22 )]
margin_top = -153.0
margin_bottom = -60.0
boss_name = "Wild Boar"
[connection signal="animation_finished" from="AnimationPlayer" to="StateMachine" method="_on_animation_finished"]
[connection signal="health_changed" from="Stats" to="." method="_on_Health_health_changed"]
[connection signal="health_depleted" from="Stats" to="StateMachine" method="_on_Health_health_depleted"]
[connection signal="health_depleted" from="Stats" to="." method="_on_Health_health_depleted"]
[connection signal="charge_direction_set" from="StateMachine/ChargeSequence/Sprint" to="StateMachine/ChargeSequence/Bump" method="_on_Sprint_charge_direction_set"]
[connection signal="hit_wall" from="StateMachine/ChargeSequence/Sprint" to="." method="_on_Sprint_hit_wall"]
[connection signal="finished" from="StateMachine/Die" to="." method="_on_Die_finished"]
[connection signal="timeout" from="StateMachine/Die/ExplodeTimer" to="StateMachine/Die" method="_on_ExplodeTimer_timeout"]
================================================
FILE: monsters/bosses/wild_boar/WildBoarFSM.gd
================================================
extends "res://utils/state/StateMachine.gd"
signal phase_changed(number)
var sequence_cycles = 0
export(int, 1, 3) var phase = 1
func _ready():
for child in get_children():
child.connect("finished", self, "go_to_next_state")
func initialize():
change_phase(phase)
func _on_active_state_finished():
go_to_next_state()
func go_to_next_state(state_override=null):
if not active:
return
current_state.exit()
current_state = _decide_on_next_state() if state_override == null else state_override
emit_signal("state_changed", current_state)
current_state.enter()
func _decide_on_next_state():
# Battle start
if current_state == null:
return $Spawn
if current_state == $Spawn:
return $RoamSequence
if phase == 1:
if current_state == $RoamSequence:
sequence_cycles += 1
if sequence_cycles < 2:
return $RoamSequence
else:
sequence_cycles = 0
return $Stomp
if current_state == $Stomp:
return $RoamSequence
elif phase == 2:
if current_state == $RoamSequence:
return $Stomp
if current_state == $Stomp:
if sequence_cycles < 2:
sequence_cycles += 1
return $Stomp
else:
sequence_cycles = 0
return $ChargeSequence
if current_state == $ChargeSequence:
return $RoamSequence
elif phase == 3:
if current_state == $RoamSequence:
return $Stomp
if current_state == $Stomp:
if sequence_cycles < 2:
sequence_cycles += 1
return $Stomp
else:
sequence_cycles = 0
return $ChargeSequence
if current_state == $ChargeSequence:
if sequence_cycles < 2:
sequence_cycles += 1
return $ChargeSequence
else:
sequence_cycles = 0
return $Stomp
elif phase == 4:
return $RoamSequence
func change_phase(new_phase):
phase = new_phase
var anim_player = owner.get_node('AnimationPlayer')
match new_phase:
1:
anim_player.playback_speed = 1.0
2:
anim_player.playback_speed = 1.4
3:
anim_player.playback_speed = 1.8
4:
anim_player.playback_speed = 1.0
emit_signal("phase_changed", new_phase)
func _on_Health_health_depleted():
go_to_next_state($Die)
================================================
FILE: monsters/bosses/wild_boar/debug/BossStatesDisplayer.gd
================================================
tool
extends Panel
func _ready():
set_as_toplevel(true)
func _on_WildBoar_state_changed(new_state_name):
$State.text = new_state_name
func _on_WildBoar_phase_changed(new_phase_name):
$Phase.text = "Phase: " + new_phase_name
================================================
FILE: monsters/bosses/wild_boar/debug/StatesStackDiplayer.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://debug/states_stack_displayer.gd" type="Script" id=1]
[ext_resource path="res://debug/fonts/stack_state_displayer_font.tres" type="DynamicFont" id=2]
[node name="StatesStackDiplayer" type="Panel"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 210.0
margin_bottom = 170.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 )
__meta__ = {
"_edit_group_": true
}
[node name="Title" type="Label" parent="." index="0"]
anchor_left = 0.5
anchor_top = 0.0
anchor_right = 0.5
anchor_bottom = 0.0
margin_left = -105.0
margin_right = 105.0
margin_bottom = 40.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( 2 )
text = "Player"
align = 1
valign = 1
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
[node name="States" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 20.0
margin_top = 50.0
margin_right = 190.0
margin_bottom = 170.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( 2 )
text = "Jump
Test"
align = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
[node name="Numbers" type="Label" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 20.0
margin_top = 50.0
margin_right = 190.0
margin_bottom = 170.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( 2 )
text = "1.
2."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
================================================
FILE: monsters/bosses/wild_boar/debug/StatesStackDisplayer.gd
================================================
tool
extends Panel
func _ready():
set_as_toplevel(true)
func _on_Player_state_changed(states_stack):
var states_names = ''
var numbers = ''
var index = 0
for state in states_stack:
states_names += state.get_name() + '\n'
numbers += str(index) + '\n'
index += 1
$States.text = states_names
$Numbers.text = numbers
================================================
FILE: monsters/bosses/wild_boar/sprites/front.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/front.png-057d3dd7010286ac73782a3387387e0a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://monsters/bosses/wild_boar/sprites/front.png"
dest_files=[ "res://.import/front.png-057d3dd7010286ac73782a3387387e0a.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: monsters/bosses/wild_boar/sprites/wild_boar_stomp_1.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/wild_boar_stomp_1.png-d07b8919e74a2c01fc887ee3913e97cc.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://monsters/bosses/wild_boar/sprites/wild_boar_stomp_1.png"
dest_files=[ "res://.import/wild_boar_stomp_1.png-d07b8919e74a2c01fc887ee3913e97cc.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: monsters/bosses/wild_boar/sprites/wild_boar_stomp_2.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/wild_boar_stomp_2.png-17bc22f03cf0802ac3e65515e42132c8.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://monsters/bosses/wild_boar/sprites/wild_boar_stomp_2.png"
dest_files=[ "res://.import/wild_boar_stomp_2.png-17bc22f03cf0802ac3e65515e42132c8.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: monsters/bosses/wild_boar/states/Die.gd
================================================
extends "res://utils/state/State.gd"
export(float) var MAX_RADIUS = 300.0
export(PackedScene) var Explosion
func enter():
owner.get_node('AnimationPlayer').play('die')
$ExplodeTimer.start()
func _on_ExplodeTimer_timeout():
spawn_explosion()
func spawn_explosion():
var explosion_node = Explosion.instance()
explosion_node.position = owner.position + calculate_random_offset()
add_child(explosion_node)
func calculate_random_offset():
randomize()
var random_angle = randf() * 2 * PI
randomize()
var random_radius = (randf() * MAX_RADIUS) / 2 + MAX_RADIUS / 2
return Vector2(cos(random_angle) * random_radius, sin(random_angle) * random_radius)
func _on_animation_finished(anim_name):
$ExplodeTimer.stop()
assert(anim_name == 'die')
get_tree().create_timer(0.6).connect("timeout", self, 'emit_signal', ['finished'])
================================================
FILE: monsters/bosses/wild_boar/states/Follow.gd
================================================
extends "res://utils/state/State.gd"
func enter():
owner.get_node('AnimationPlayer').play('stomp')
func _on_animation_finished(anim_name):
emit_signal('finished')
================================================
FILE: monsters/bosses/wild_boar/states/ReturnToCenter.gd
================================================
extends "res://utils/state/State.gd"
export(float) var MASS = 4.0
export(float) var SLOW_RADIUS = 200.0
export(float) var MAX_SPEED = 300.0
export(float) var ARRIVE_DISTANCE = 6.0
var velocity = Vector2()
func enter():
owner.get_node('AnimationPlayer').play('move')
func update(delta):
velocity = Steering.arrive_to(velocity,
owner.global_position,
owner.start_global_position,
MASS,
SLOW_RADIUS,
MAX_SPEED)
owner.move_and_slide(velocity)
if owner.global_position.distance_to(owner.start_global_position) < ARRIVE_DISTANCE:
emit_signal('finished')
================================================
FILE: monsters/bosses/wild_boar/states/Spawn.gd
================================================
extends "res://utils/state/State.gd"
func enter():
owner.set_invincible(true)
owner.get_node('AnimationPlayer').play('spawn')
func exit():
owner.set_invincible(false)
func _on_animation_finished(anim_name):
assert(anim_name == 'spawn')
emit_signal('finished')
================================================
FILE: monsters/bosses/wild_boar/states/charge/BumpWildBoar.gd
================================================
extends "res://utils/state/State.gd"
export(float) var SPEED = 60.0
var direction = Vector2(-1.0, 0.0)
func enter():
owner.get_node('AnimationPlayer').play('bump')
owner.get_node('Pivot/Body').scale = Vector2(1.0, 1.0)
func update(delta):
owner.move_and_slide(direction * SPEED)
func _on_animation_finished(anim_name):
emit_signal('finished')
func _on_Sprint_charge_direction_set(charge_direction):
direction = -charge_direction
================================================
FILE: monsters/bosses/wild_boar/states/charge/Prepare.gd
================================================
extends "res://utils/state/State.gd"
func enter():
owner.get_node('AnimationPlayer').play('prepare')
func _on_animation_finished(anim_name):
emit_signal('finished')
================================================
FILE: monsters/bosses/wild_boar/states/charge/Sprint.gd
================================================
extends "res://utils/state/State.gd"
signal charge_direction_set(direction)
signal hit_wall()
export(float) var SPEED = 1000.0
export(float) var MAX_DISTANCE = 1200.0
var direction = Vector2()
var distance = 0.0
const DirectionalRock = preload("res://vfx/particles/rocks/DirectionalRock.tscn")
const PlayerController = preload("res://actors/player/PlayerController.gd")
func enter():
distance = 0.0
direction = (owner.target.global_position - owner.global_position).normalized()
owner.get_node('AnimationPlayer').play('sprint')
owner.set_particles_active(true)
func exit():
owner.set_particles_active(false)
func update(delta):
var velocity = SPEED * direction
owner.move_and_slide(velocity)
distance += velocity.length() * delta
if owner.get_slide_count() > 0:
var collision = owner.get_slide_collision(0)
if not collision.collider is PlayerController:
spawn_rock_particles(collision)
emit_signal('hit_wall')
emit_signal('charge_direction_set', direction)
emit_signal('finished')
elif distance > MAX_DISTANCE:
emit_signal('charge_direction_set', Vector2())
func spawn_rock_particles(collision):
var rock_particles = DirectionalRock.instance()
add_child(rock_particles)
rock_particles.initialize(collision.position, collision.normal.angle())
================================================
FILE: monsters/bosses/wild_boar/states/roam/MoveToRandomPosition.gd
================================================
extends "res://utils/state/State.gd"
export(float) var ARRIVE_DISTANCE = 6.0
export(float) var SLOW_RADIUS = 200.0
export(float) var MASS = 4.0
export(float) var MAX_SPEED = 300.0
export(float) var ROAM_RADIUS = 150.0
var target_position = Vector2()
var start_position = Vector2()
var velocity = Vector2()
func enter():
start_position = get_parent().start_position
target_position = calculate_new_target_position()
owner.get_node('AnimationPlayer').play('move')
func update(delta):
velocity = Steering.arrive_to(velocity, owner.global_position, target_position, MASS, SLOW_RADIUS, MAX_SPEED)
owner.move_and_slide(velocity)
if owner.get_slide_count() > 0:
emit_signal('finished')
elif owner.global_position.distance_to(target_position) < ARRIVE_DISTANCE:
emit_signal('finished')
func calculate_new_target_position():
randomize()
var random_angle = randf() * 2 * PI
randomize()
var random_radius = (randf() * ROAM_RADIUS) / 2 + ROAM_RADIUS / 2
return start_position + Vector2(cos(random_angle) * random_radius, sin(random_angle) * random_radius)
================================================
FILE: monsters/bosses/wild_boar/states/roam/RoamSequence.gd
================================================
extends "res://utils/state/Sequence.gd"
var start_position = Vector2()
func enter():
start_position = owner.global_position
.enter()
func exit():
.exit()
func update(delta):
.update(delta)
================================================
FILE: monsters/bosses/wild_boar/states/roam/Wait.gd
================================================
extends "res://utils/state/State.gd"
func enter():
owner.get_node('AnimationPlayer').play('idle')
$Timer.start()
func update(delta):
if $Timer.time_left <= 0.0:
emit_signal('finished')
func exit():
$Timer.stop()
================================================
FILE: monsters/bosses/wild_boar/states/stomp/GroundExplosion.gd
================================================
extends "res://actors/DamageSource.gd"
func _ready():
$AnimationPlayer.play('explode')
func _physics_process(delta):
position = position
================================================
FILE: monsters/bosses/wild_boar/states/stomp/GroundExplosion.tscn
================================================
[gd_scene load_steps=6 format=2]
[ext_resource path="res://actors/DamageSource.tscn" type="PackedScene" id=1]
[ext_resource path="res://monsters/bosses/wild_boar/states/stomp/GroundExplosion.gd" type="Script" id=2]
[ext_resource path="res://core/inventory/items/usable/scroll_fireball/fireball/particles/explosions/Explosion.tscn" type="PackedScene" id=3]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 45.1559
[sub_resource type="Animation" id=2]
resource_name = "explode"
length = 0.5
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("CollisionShape2D:disabled")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.4 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ false, true ]
}
tracks/1/type = "value"
tracks/1/path = NodePath("Explosion: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.4 ),
"transitions": PoolRealArray( 0, 0 ),
"update": 1,
"values": [ true, false ]
}
tracks/2/type = "method"
tracks/2/path = NodePath(".")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0.4 ),
"transitions": PoolRealArray( 1 ),
"values": [ {
"args": [ ],
"method": "queue_free"
} ]
}
[node name="GroundExplosion" instance=ExtResource( 1 )]
script = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="0"]
shape = SubResource( 1 )
disabled = true
[node name="Explosion" parent="." index="1" instance=ExtResource( 3 )]
[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/explode = SubResource( 2 )
blend_times = [ ]
================================================
FILE: monsters/bosses/wild_boar/states/stomp/Stomp.gd
================================================
extends "res://utils/state/State.gd"
var explosion_scene = preload("GroundExplosion.tscn")
var explosion_count = 0
var direction = Vector2()
func _ready():
$ExplodeTimer.connect("timeout", self, "_on_ExplodeTimer_timeout")
func enter():
explosion_count = 0
owner.get_node('AnimationPlayer').play('stomp')
func _on_animation_finished(anim_name):
$ExplodeTimer.stop()
emit_signal('finished')
func stomp():
direction = (owner.target.position - owner.global_position).normalized()
$ExplodeTimer.start()
explode()
func _on_ExplodeTimer_timeout():
explode()
func explode():
explosion_count += 1
var new_explosion = explosion_scene.instance()
new_explosion.position = owner.position + explosion_count * direction * 80.0
self.add_child(new_explosion)
================================================
FILE: monsters/bosses/wild_boar/states/stomp/Stomp.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://monsters/bosses/wild_boar/states/stomp/Stomp.gd" type="Script" id=1]
[node name="Stomp" type="Node"]
script = ExtResource( 1 )
[node name="ExplodeTimer" type="Timer" parent="." index="0"]
process_mode = 1
wait_time = 0.2
one_shot = false
autostart = false
================================================
FILE: monsters/exclamation-mark.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/exclamation-mark.png-71455c01c46e91dfa6565f7fa57a362a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://monsters/exclamation-mark.png"
dest_files=[ "res://.import/exclamation-mark.png-71455c01c46e91dfa6565f7fa57a362a.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: monsters/exclamation-mark.svg.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/exclamation-mark.svg-17d593f918361282d38491dd92cc9311.stex"
[deps]
source_file="res://monsters/exclamation-mark.svg"
source_md5="8148dc8f2a7d33524acc8429e13b1cf5"
dest_files=[ "res://.import/exclamation-mark.svg-17d593f918361282d38491dd92cc9311.stex" ]
dest_md5="3647bb80cc90a5818d62bf39516420e2"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=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
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
================================================
FILE: monsters/mosquito/Mosquito.gd
================================================
extends '../Monster.gd'
enum { IDLE, RETURN, SPOT, FOLLOW, DIE}
export(float) var FOLLOW_RANGE = 300.0
export(float) var MAX_FLY_SPEED = 360.0
func _ready():
_change_state(IDLE)
func _change_state(new_state):
match new_state:
IDLE:
pass
DIE:
queue_free()
emit_signal('died')
state = new_state
func _physics_process(delta):
var current_state = state
match current_state:
IDLE:
if not target:
return
if position.distance_to(target.position) <= FOLLOW_RANGE:
_change_state(FOLLOW)
FOLLOW:
if not target:
return
if position.distance_to(target.position) > FOLLOW_RANGE:
_change_state(RETURN)
return
velocity = Steering.follow(velocity, position, target.position, MAX_FLY_SPEED)
move_and_slide(velocity)
rotation = velocity.angle()
RETURN:
velocity = Steering.arrive_to(velocity, position, start_position)
move_and_slide(velocity)
rotation = velocity.angle()
if position.distance_to(start_position) < ARRIVE_DISTANCE:
_change_state(IDLE)
func _on_DamageSource_area_entered(area):
_change_state(DIE)
func _on_Stats_damage_taken(new_health):
_change_state(DIE)
================================================
FILE: monsters/mosquito/Mosquito.tscn
================================================
[gd_scene load_steps=9 format=2]
[ext_resource path="res://monsters/mosquito/Mosquito.gd" type="Script" id=1]
[ext_resource path="res://actors/health/Stats.tscn" type="PackedScene" id=2]
[ext_resource path="res://actors/hit_box/HitBox.tscn" type="PackedScene" id=3]
[ext_resource path="res://actors/DamageSource.tscn" type="PackedScene" id=4]
[ext_resource path="res://monsters/exclamation-mark.png" type="Texture" id=5]
[ext_resource path="res://monsters/mosquito/mosquito.png" type="Texture" id=6]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 38.4768
[sub_resource type="CircleShape2D" id=2]
custom_solver_bias = 0.0
radius = 24.9469
[node name="Mosquito" type="KinematicBody2D" groups=[
"character",
]]
position = Vector2( -1.98642, 0.817726 )
input_pickable = false
collision_layer = 2
collision_mask = 1
collision/safe_margin = 0.08
script = ExtResource( 1 )
_sections_unfolded = [ "Collision", "Z Index" ]
ARRIVE_DISTANCE = 6.0
DEFAULT_SLOW_RADIUS = 200.0
DEFAULT_MAX_SPEED = 300.0
MASS = 8.0
FOLLOW_RANGE = 300.0
MAX_FLY_SPEED = 360.0
[node name="Stats" parent="." index="0" instance=ExtResource( 2 )]
max_health = 1
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="1"]
position = Vector2( -3.01358, 49.1823 )
build_mode = 0
polygon = PoolVector2Array( -18.0136, -69.4669, -18.0136, -29.4669, 31.9864, -29.4669, 31.9864, -69.4669 )
disabled = true
_sections_unfolded = [ "Transform" ]
[node name="HitBox" parent="." index="2" instance=ExtResource( 3 )]
editor/display_folded = true
collision_layer = 8
collision_mask = 16
[node name="CollisionShape2D" parent="HitBox" index="0"]
position = Vector2( 6, -2.42273 )
shape = SubResource( 1 )
[node name="DamageSource" parent="." index="3" instance=ExtResource( 4 )]
editor/display_folded = true
monitoring = true
_sections_unfolded = [ "Audio Bus", "Collision" ]
damage = 3
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageSource" index="0"]
position = Vector2( 6, 0 )
shape = SubResource( 2 )
[node name="BodyPivot" type="Position2D" parent="." index="4"]
editor/display_folded = true
z_index = 2
_sections_unfolded = [ "Transform", "Visibility", "Z Index" ]
[node name="exclamation-mark" type="Sprite" parent="BodyPivot" index="0"]
self_modulate = Color( 1, 1, 1, 0 )
position = Vector2( 74.8139, -90 )
rotation = 0.253141
texture = ExtResource( 5 )
_sections_unfolded = [ "Visibility" ]
[node name="Sprite" type="Sprite" parent="BodyPivot" index="1"]
position = Vector2( 1.40846, -1.88954 )
texture = ExtResource( 6 )
offset = Vector2( 15.695, 0.889542 )
[node name="Timer" type="Timer" parent="." index="5"]
process_mode = 1
wait_time = 1.0
one_shot = false
autostart = false
[node name="RayCast2D" type="RayCast2D" parent="." index="6"]
visible = false
enabled = false
exclude_parent = true
cast_to = Vector2( 0, 50 )
collision_mask = 1
[connection signal="damage_taken" from="Stats" to="." method="_on_Stats_damage_taken"]
[connection signal="area_entered" from="DamageSource" to="." method="_on_DamageSource_area_entered"]
[editable path="HitBox"]
================================================
FILE: monsters/mosquito/Nest.gd
================================================
extends Node2D
export(int) var MAX_MOSQUITO_COUNT = 2
var Mosquito = preload("Mosquito.tscn")
onready var timer = $SpawnTimer
onready var collider = $SpawnArea/CollisionShape2D
onready var mosquitos = $Mosquitos
var target
func initialize(actor):
target = actor
func _on_SpawnTimer_timeout():
if mosquitos.get_child_count() < MAX_MOSQUITO_COUNT:
spawn_mosquito()
func spawn_mosquito():
var new_mosquito = Mosquito.instance()
new_mosquito.global_position = calculate_random_spawn_position()
new_mosquito.initialize(target)
mosquitos.add_child(new_mosquito)
func calculate_random_spawn_position():
var spawn_radius = collider.shape.radius
var random_angle = randf() * 2 * PI
var random_radius = randf() * spawn_radius / 2 + spawn_radius / 2
return collider.global_position + Vector2(cos(random_angle) * random_radius, sin(random_angle) * random_radius)
================================================
FILE: monsters/mosquito/Nest.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://monsters/mosquito/Nest.gd" type="Script" id=1]
[ext_resource path="res://monsters/mosquito/nest.png" type="Texture" id=2]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 40.0
[sub_resource type="GDScript" id=2]
script/source = "extends Timer
func _ready():
wait_time = randf() *1.5 + 2.0
"
[node name="Nest" type="Node2D" index="0" groups=[
"monster",
]]
position = Vector2( 468, 202 )
script = ExtResource( 1 )
MAX_MOSQUITO_COUNT = 2
[node name="Sprite" type="Sprite" parent="." index="0"]
position = Vector2( 0, 10 )
texture = ExtResource( 2 )
[node name="SpawnArea" type="Area2D" parent="." index="1"]
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitoring = false
monitorable = false
audio_bus_override = false
audio_bus_name = "Master"
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpawnArea" index="0"]
position = Vector2( 0, -6.43921 )
shape = SubResource( 1 )
[node name="SpawnTimer" type="Timer" parent="." index="2"]
process_mode = 1
wait_time = 2.0
one_shot = false
autostart = true
script = SubResource( 2 )
[node name="Mosquitos" type="Node" parent="." index="3"]
[connection signal="timeout" from="SpawnTimer" to="." method="_on_SpawnTimer_timeout"]
================================================
FILE: monsters/mosquito/mosquito.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/mosquito.png-321e9de6070b983093d0eeac1e99b420.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://monsters/mosquito/mosquito.png"
dest_files=[ "res://.import/mosquito.png-321e9de6070b983093d0eeac1e99b420.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: monsters/mosquito/nest.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/nest.png-b3e74c0f42f31be173ab28e91ca5d1a6.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://monsters/mosquito/nest.png"
dest_files=[ "res://.import/nest.png-b3e74c0f42f31be173ab28e91ca5d1a6.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: monsters/porcupine/Porcupine.gd
================================================
extends '../Monster.gd'
enum { IDLE, ROAM, RETURN, SPOT, FOLLOW, STAGGER, PREPARE_TO_CHARGE, CHARGE, BUMP, BUMP_COOLDOWN, HIT_PLAYER_COOLDOWN, DIE, DEAD}
export(float) var MAX_ROAM_SPEED = 200.0
export(float) var MAX_FOLLOW_SPEED = 400.0
export(float) var MAX_CHARGE_SPEED = 900.0
export(float) var SPOT_RANGE = 460.0
export(float) var FOLLOW_RANGE = 700.0
export(float) var BUMP_RANGE = 90.0
export(float) var CHARGE_RANGE = 340.0
export(float) var PREPARE_TO_CHARGE_WAIT_TIME = 0.9
onready var timer = $Timer
onready var body_pivot = $BodyPivot
onready var dust_puffs = $DustPuffs
onready var anim_player = $AnimationPlayer
onready var tween = $Tween
var charge_direction = Vector2()
var charge_distance = 0.0
export(float) var ROAM_RADIUS = 140.0
var roam_target_position = Vector2()
var roam_slow_radius = 0.0
export(float) var BUMP_DISTANCE = 60.0
export(float) var BUMP_DURATION = 0.2
export(float) var MAX_BUMP_HEIGHT = 50.0
export(float) var BUMP_COOLDOWN_DURATION = 0.6
func initialize(target_actor):
.initialize(target_actor)
tween.connect('tween_completed', self, '_on_tween_completed')
anim_player.connect('animation_finished', self, '_on_animation_finished')
timer.connect('timeout', self, '_on_Timer_timeout')
_change_state(IDLE)
func _change_state(new_state):
if not active:
return
match state:
IDLE:
timer.stop()
CHARGE:
dust_puffs.emitting = false
match new_state:
IDLE:
randomize()
timer.wait_time = randf() * 2 + 1.0
timer.start()
ROAM:
randomize()
var random_angle = randf() * 2 * PI
randomize()
var random_radius = (randf() * ROAM_RADIUS) / 2 + ROAM_RADIUS / 2
roam_target_position = start_position + Vector2(cos(random_angle) * random_radius, sin(random_angle) * random_radius)
roam_slow_radius = roam_target_position.distance_to(start_position) / 2
STAGGER:
anim_player.play("stagger")
SPOT:
anim_player.play('spot')
PREPARE_TO_CHARGE:
timer.wait_time = PREPARE_TO_CHARGE_WAIT_TIME
timer.start()
CHARGE:
if not target:
return
charge_direction = (target.position - position).normalized()
charge_distance = 0.0
dust_puffs.emitting = true
BUMP:
anim_player.stop()
var bump_direction = - velocity.normalized()
tween.interpolate_property(self, 'position', position, position + BUMP_DISTANCE * bump_direction, BUMP_DURATION, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.interpolate_method(self, '_animate_bump_height', 0, 1, BUMP_DURATION, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.start()
BUMP_COOLDOWN:
randomize()
get_tree().create_timer(BUMP_COOLDOWN_DURATION).connect('timeout', self, '_change_state', [FOLLOW])
DEAD:
anim_player.play("die")
set_active(false)
yield(anim_player, "animation_finished")
queue_free()
state = new_state
func _physics_process(delta):
var current_state = state
match current_state:
IDLE:
if not target:
return
if position.distance_to(target.position) < SPOT_RANGE:
_change_state(SPOT)
ROAM:
velocity = Steering.arrive_to(velocity, position, roam_target_position, roam_slow_radius, MAX_ROAM_SPEED)
move_and_slide(velocity)
if position.distance_to(roam_target_position) < ARRIVE_DISTANCE:
_change_state(IDLE)
if not target:
return
elif position.distance_to(target.position) < SPOT_RANGE:
_change_state(SPOT)
RETURN:
velocity = Steering.arrive_to(velocity, position, start_position, roam_slow_radius, MAX_ROAM_SPEED)
move_and_slide(velocity)
if position.distance_to(start_position) < ARRIVE_DISTANCE:
_change_state(IDLE)
elif not target:
return
elif position.distance_to(target.position) < SPOT_RANGE:
_change_state(SPOT)
FOLLOW:
if not target:
_change_state(RETURN)
return
velocity = Steering.follow(velocity, position, target.position, MAX_FOLLOW_SPEED)
move_and_slide(velocity)
if position.distance_to(target.position) < CHARGE_RANGE:
_change_state(PREPARE_TO_CHARGE)
if position.distance_to(target.position) > FOLLOW_RANGE:
_change_state(RETURN)
CHARGE:
if charge_distance > 800.0 or not target:
_change_state(BUMP_COOLDOWN)
return
velocity = charge_direction * MAX_CHARGE_SPEED
charge_distance += velocity.length() * delta
move_and_slide(velocity)
if get_slide_count() > 0:
_change_state(BUMP)
func _on_animation_finished(anim_name):
match anim_name:
'spot':
_change_state(FOLLOW)
'stagger':
_change_state(IDLE)
func _animate_bump_height(progress):
body_pivot.position.y = -pow(sin(progress * PI), 0.4) * MAX_BUMP_HEIGHT
func _on_tween_completed(object, key):
_change_state(BUMP_COOLDOWN)
func _on_Timer_timeout():
match state:
IDLE:
_change_state(ROAM)
PREPARE_TO_CHARGE:
_change_state(CHARGE)
func _on_Stats_damage_taken(new_health):
_change_state(STAGGER)
func _on_Stats_health_depleted():
_change_state(DEAD)
================================================
FILE: monsters/porcupine/Porcupine.tscn
================================================
[gd_scene load_steps=16 format=2]
[ext_resource path="res://monsters/porcupine/Porcupine.gd" type="Script" id=1]
[ext_resource path="res://actors/health/Stats.tscn" type="PackedScene" id=2]
[ext_resource path="res://actors/hit_box/HitBox.tscn" type="PackedScene" id=3]
[ext_resource path="res://actors/DamageSource.tscn" type="PackedScene" id=4]
[ext_resource path="res://monsters/porcupine/porcupine.png" type="Texture" id=5]
[ext_resource path="res://monsters/exclamation-mark.png" type="Texture" id=6]
[ext_resource path="res://vfx/particles/dust_puffs/DustPuffs.tscn" type="PackedScene" id=7]
[ext_resource path="res://interface/gui/lifebar/InterfaceAnchor.tscn" type="PackedScene" id=8]
[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("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( 3.57628e-007, 17.6051 ) ]
}
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("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 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ) ]
}
tracks/4/type = "value"
tracks/4/path = NodePath("BodyPivot/Body:modulate")
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": [ Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=2]
resource_name = "die"
length = 0.7
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.35, 0.5, 0.7 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
}
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.35, 0.45, 0.65 ),
"transitions": PoolRealArray( 1, 1, 2.94246, 1 ),
"update": 0,
"values": [ Vector2( 1, 1 ), Vector2( 1, 1 ), Vector2( 0.812022, 1.23284 ), Vector2( 2.7717, 0.0452506 ) ]
}
[sub_resource type="Animation" id=3]
resource_name = "idle"
length = 1.0
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( 3.57628e-007, 17.6051 ) ]
}
[sub_resource type="Animation" id=4]
resource_name = "spot"
length = 0.9
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 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 3.57628e-007, 17.6051 ) ]
}
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/exclamation-mark: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("BodyPivot/exclamation-mark:position")
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, 0.25 ),
"transitions": PoolRealArray( 0.382544, 1, 1 ),
"update": 0,
"values": [ Vector2( 54.0852, -65 ), Vector2( 74.1273, -90 ), Vector2( 74.8139, -90 ) ]
}
tracks/4/type = "value"
tracks/4/path = NodePath("BodyPivot/exclamation-mark:rotation_degrees")
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, 0.25 ),
"transitions": PoolRealArray( 0.382544, 1, 1 ),
"update": 0,
"values": [ 3.97992, 12.3991, 14.5039 ]
}
tracks/5/type = "value"
tracks/5/path = NodePath("BodyPivot/exclamation-mark:scale")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/keys = {
"times": PoolRealArray( 0, 0.2, 0.25 ),
"transitions": PoolRealArray( 0.382544, 1, 1 ),
"update": 0,
"values": [ Vector2( 0.315916, 0.315916 ), Vector2( 1.05264, 1.05264 ), Vector2( 1, 1 ) ]
}
tracks/6/type = "value"
tracks/6/path = NodePath("BodyPivot/exclamation-mark:self_modulate")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/keys = {
"times": PoolRealArray( 0, 0.5, 0.7 ),
"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 = 0.5
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.4 ),
"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1 ),
"update": 0,
"values": [ Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 0.296875, 0.296875, 1 ), Color( 1, 1, 1, 1 ) ]
}
[sub_resource type="Animation" id=6]
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.367583, 1.73627 ),
"update": 0,
"values": [ Vector2( 3.57628e-007, 17.6051 ), Vector2( 0, 0.113144 ) ]
}
[sub_resource type="CircleShape2D" id=7]
custom_solver_bias = 0.0
radius = 35.906
[node name="Porcupine" type="KinematicBody2D" groups=[
"monster",
]]
position = Vector2( -1.98642, 0.817726 )
input_pickable = false
collision_layer = 2
collision_mask = 3
collision/safe_margin = 0.08
script = ExtResource( 1 )
_sections_unfolded = [ "Collision", "Z Index" ]
[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/die = SubResource( 2 )
anims/idle = SubResource( 3 )
anims/spot = SubResource( 4 )
anims/stagger = SubResource( 5 )
anims/walk = SubResource( 6 )
blend_times = [ ]
[node name="Tween" type="Tween" parent="." index="1"]
repeat = false
playback_process_mode = 1
playback_speed = 1.0
playback/active = false
playback/repeat = false
playback/speed = 1.0
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="2"]
position = Vector2( 0, 48.6492 )
build_mode = 0
polygon = PoolVector2Array( -36, -96, 36, -96, 36, -24, -36, -24 )
[node name="Stats" parent="." index="3" instance=ExtResource( 2 )]
max_health = 5
[node name="HitBox" parent="." index="4" instance=ExtResource( 3 )]
collision_layer = 8
collision_mask = 16
[node name="DamageSource" parent="." index="5" instance=ExtResource( 4 )]
editor/display_folded = true
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageSource" index="0"]
position = Vector2( -1.19209e-007, -14 )
shape = SubResource( 7 )
[node name="BodyPivot" type="Position2D" parent="." index="6"]
editor/display_folded = true
z_index = 2
_sections_unfolded = [ "Transform", "Visibility", "Z Index" ]
[node name="Body" type="Sprite" parent="BodyPivot" index="0"]
position = Vector2( 3.57628e-007, 17.6051 )
texture = ExtResource( 5 )
offset = Vector2( 0.0850579, -32.8777 )
_sections_unfolded = [ "Visibility" ]
[node name="exclamation-mark" type="Sprite" parent="BodyPivot" index="1"]
self_modulate = Color( 1, 1, 1, 0 )
position = Vector2( 74.8139, -90 )
rotation = 0.253141
texture = ExtResource( 6 )
_sections_unfolded = [ "Visibility" ]
[node name="Timer" type="Timer" parent="." index="7"]
process_mode = 1
wait_time = 1.0
one_shot = false
autostart = false
[node name="DustPuffs" parent="." index="8" instance=ExtResource( 7 )]
emitting = false
[node name="InterfaceAnchor" parent="." index="9" instance=ExtResource( 8 )]
position = Vector2( 0, -106.219 )
_sections_unfolded = [ "Transform" ]
[connection signal="damage_taken" from="Stats" to="." method="_on_Stats_damage_taken"]
[connection signal="health_depleted" from="Stats" to="." method="_on_Stats_health_depleted"]
================================================
FILE: monsters/porcupine/porcupine.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/porcupine.png-8034b65048f25f0e61302d6bff865dcc.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://monsters/porcupine/porcupine.png"
dest_files=[ "res://.import/porcupine.png-8034b65048f25f0e61302d6bff865dcc.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: project.godot
================================================
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ {
"base": "Control",
"class": "Menu",
"language": "GDScript",
"path": "res://interface/menus/Menu.gd"
} ]
_global_script_class_icons={
"Menu": ""
}
[Colors]
blue="#2196F3"
pink="#C23A61"
purple="#6200EA"
yellow="#FFCA28"
[application]
config/name="Make Pro 2D Games with Godot"
run/main_scene="res://Demo.tscn"
config/icon="res://icon.png"
run/debug=true
[autoload]
Steering="*res://utils/autoload/Steering.gd"
ItemDatabase="*res://core/inventory/ItemDatabase.tscn"
[display]
window/size/width=1920
window/size/height=1080
window/size/fullscreen=true
window/stretch/mode="2d"
window/stretch/aspect="keep"
[input]
fire={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
]
}
run={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
]
}
jump={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
simulate_damage={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":88,"unicode":0,"echo":false,"script":null)
]
}
attack={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"unicode":0,"echo":false,"script":null)
]
}
pause={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
]
}
toggle_fullscreen={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":true,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777254,"unicode":0,"echo":false,"script":null)
]
}
discrete_move_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
]
}
discrete_move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
]
}
discrete_move_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
]
}
discrete_move_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
]
}
joy_move_left={
"deadzone": 0.5,
"events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
]
}
joy_move_right={
"deadzone": 0.5,
"events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
]
}
joy_move_up={
"deadzone": 0.5,
"events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
]
}
joy_move_down={
"deadzone": 0.5,
"events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
]
}
[layer_names]
2d_physics/layer_1="motion"
2d_physics/layer_2="environment"
2d_physics/layer_3="hitbox_characters"
2d_physics/layer_4="hitbox_monsters"
2d_physics/layer_5="weapon"
2d_physics/layer_6="damager_area"
2d_physics/layer_7="collectibles"
2d_physics/layer_8="collector"
[rendering]
quality/2d/use_pixel_snap=true
environment/default_environment="res://default_env.tres"
================================================
FILE: utils/autoload/Steering.gd
================================================
extends Node
const DEFAULT_MASS = 2.0
const DEFAULT_SLOW_RADIUS = 200.0
const DEFAULT_MAX_SPEED = 300.0
func arrive_to(velocity,
position,
target_position,
mass=DEFAULT_MASS,
slow_radius=DEFAULT_SLOW_RADIUS,
max_speed=DEFAULT_MAX_SPEED):
"""
Calculates and returns a new velocity with the arrive steering behavior arrived based on
an existing velocity (Vector2), the object's current and target positions (Vector2)
"""
var distance_to_target = position.distance_to(target_position)
var desired_velocity = (target_position - position).normalized() * max_speed
if distance_to_target < slow_radius:
desired_velocity *= (distance_to_target / slow_radius) * .75 + .25
var steering = (desired_velocity - velocity) / mass
return velocity + steering
func follow(velocity,
position,
target_position,
max_speed,
mass=DEFAULT_MASS):
var desired_velocity = (target_position - position).normalized() * max_speed
# var push = calculate_avoid_force(desired_velocity)
# var steering = (desired_velocity - velocity + push) / mass
var steering = (desired_velocity - velocity) / mass
return velocity + steering
================================================
FILE: utils/debug/ControlsPanel.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://utils/debug/TopLevelUI.gd" type="Script" id=1]
[ext_resource path="res://interface/fonts/source_code_pro_explanations.tres" type="DynamicFont" id=2]
[node name="ControlsPanel" type="Panel" index="0"]
anchor_left = 1.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 0.0
margin_left = -220.0
margin_bottom = 170.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 )
[node name="Keys" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = 10.0
margin_right = -10.0
margin_bottom = -10.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( 2 )
text = "Shoot:
Attack:
Stagger:
Jump:
Sprint:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "BBCode", "custom_fonts" ]
[node name="Keys2" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = 10.0
margin_right = -10.0
margin_bottom = -10.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( 2 )
text = "R
F
X
Space
Shift"
align = 2
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "BBCode", "custom_fonts" ]
================================================
FILE: utils/debug/Explanations.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://interface/fonts/source_code_pro_explanations_bold.tres" type="DynamicFont" id=1]
[ext_resource path="res://interface/fonts/source_code_pro_explanations.tres" type="DynamicFont" id=2]
[ext_resource path="res://utils/debug/TopLevelUI.gd" type="Script" id=3]
[node name="Explanations" type="RichTextLabel"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = -370.0
margin_right = -10.0
margin_bottom = -730.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/bold_font = ExtResource( 1 )
custom_fonts/normal_font = ExtResource( 2 )
bbcode_enabled = true
bbcode_text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
States are common in games. You can use the pattern to:
1. Separate each behavior and transitions between behaviors, thus make scripts shorter and easier to manage
2. Respect the Single Responsibility Principle. Each State object represents [b]one[/b] action
3. Improve your code's structure. Look at the scene tree and FileSystem tab: without looking at the code, you'll know what the Player can or cannot do.
You can read more about States in the excellent [url=http://gameprogrammingpatterns.com/state.html]Game Programming Patterns ebook[/url]."
visible_characters = -1
percent_visible = 1.0
meta_underlined = true
tab_size = 4
text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
States are common in games. You can use the pattern to:
1. Separate each behavior and transitions between behaviors, thus make scripts shorter and easier to manage
2. Respect the Single Responsibility Principle. Each State object represents one action
3. Improve your code's structure. Look at the scene tree and FileSystem tab: without looking at the code, you'll know what the Player can or cannot do.
You can read more about States in the excellent Game Programming Patterns ebook."
scroll_active = true
scroll_following = false
selection_enabled = false
override_selected_font_color = false
script = ExtResource( 3 )
_sections_unfolded = [ "BBCode", "custom_fonts" ]
__meta__ = {
"_edit_lock_": true
}
================================================
FILE: utils/debug/StatesStackDiplayer.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://utils/debug/StatesStackDisplayer.gd" type="Script" id=1]
[ext_resource path="res://interface/fonts/SourceCodePro-Bold.ttf" type="DynamicFontData" id=2]
[sub_resource type="DynamicFont" id=1]
size = 20
use_mipmaps = false
use_filter = true
font_data = ExtResource( 2 )
_sections_unfolded = [ "Font", "Settings" ]
[node name="StatesStackDiplayer" type="Panel"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 210.0
margin_bottom = 170.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 )
__meta__ = {
"_edit_group_": true
}
[node name="Title" type="Label" parent="." index="0"]
anchor_left = 0.5
anchor_top = 0.0
anchor_right = 0.5
anchor_bottom = 0.0
margin_left = -105.0
margin_right = 105.0
margin_bottom = 40.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( 1 )
text = "Pushown"
align = 1
valign = 1
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
[node name="States" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 20.0
margin_top = 50.0
margin_right = 190.0
margin_bottom = 170.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( 1 )
text = "Jump
Test"
align = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
[node name="Numbers" type="Label" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 20.0
margin_top = 50.0
margin_right = 190.0
margin_bottom = 170.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( 1 )
text = "1.
2."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
================================================
FILE: utils/debug/StatesStackDisplayer.gd
================================================
tool
extends Panel
func _ready():
set_as_toplevel(true)
func _on_Player_state_changed(states_stack):
var states_names = ''
var numbers = ''
var index = 0
for state in states_stack:
states_names += state.get_name() + '\n'
numbers += str(index) + '\n'
index += 1
$States.text = states_names
$Numbers.text = numbers
================================================
FILE: utils/debug/TopLevelUI.gd
================================================
tool
extends Control
func _ready():
set_as_toplevel(true)
================================================
FILE: utils/state/Sequence.gd
================================================
"""
Sequence is a State that delegates calls to one of its children
at the time, in the tree order
It automates the creation of new sequences of behaviors,
a bit as in a behavior tree, although in this case each sub-state
has to finish its job
To tell the state machine when a sequence is over
"""
extends 'State.gd'
var state_active = null
func _ready():
for child in get_children():
child.connect('finished', self, '_on_state_active_finished')
if child.owner != owner:
child.set_owner(owner)
func enter():
state_active = get_child(0)
state_active.enter()
func exit():
state_active = null
func update(delta):
state_active.update(delta)
func _on_animation_finished(anim_name):
state_active._on_animation_finished(anim_name)
func _on_state_active_finished():
go_to_next_state_in_sequence()
func go_to_next_state_in_sequence():
state_active.exit()
var new_state_index = (state_active.get_index() + 1) % get_child_count()
if new_state_index == 0:
emit_signal('finished')
return
state_active = get_child(new_state_index)
state_active.enter()
================================================
FILE: utils/state/Sequence.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://utils/state/Sequence.gd" type="Script" id=1]
[node name="Sequence" type="Node" index="0"]
script = ExtResource( 1 )
================================================
FILE: utils/state/State.gd
================================================
"""
Base interface for all states: it doesn't do anything in itself
but forces us to pass the right arguments to the methods below
and makes sure every State object had all of these methods.
"""
extends Node
signal finished(next_state_name)
func enter():
return
func exit():
return
func handle_input(event):
return
func update(delta):
return
func _on_animation_finished(anim_name):
return
================================================
FILE: utils/state/StateMachine.gd
================================================
"""
Base interface for a generic state machine
It handles initializing, setting the machine active or not
delegating _physics_process, _input calls to the State nodes,
and changing the current/active state.
"""
extends Node
signal state_changed(current_state)
var states_map = {}
var states_stack = []
var current_state = null
export(bool) var active = false setget set_active
func _ready():
states_stack.push_front(get_child(0))
current_state = states_stack[0]
if active:
start()
func start():
current_state.enter()
set_active(true)
func set_active(value):
active = value
set_physics_process(value)
set_process_input(value)
if not active:
states_stack = []
current_state = null
func _unhandled_input(event):
current_state.handle_input(event)
func _physics_process(delta):
current_state.update(delta)
func _on_animation_finished(anim_name):
if not active:
return
current_state._on_animation_finished(anim_name)
func _change_state(state_name):
if not active:
return
current_state.exit()
if state_name == "previous":
states_stack.pop_front()
else:
states_stack[0] = states_map[state_name]
current_state = states_stack[0]
emit_signal("state_changed", current_state)
current_state.enter()
================================================
FILE: utils/state/StateMachine.tscn
================================================
[gd_scene load_steps=2 format=2]
[ext_resource path="res://utils/state/StateMachine.gd" type="Script" id=1]
[node name="StateMachine" type="Node" index="0"]
script = ExtResource( 1 )
START_STATE = null
================================================
FILE: vfx/Fog.gd
================================================
extends ColorRect
func _on_LevelLoader_loaded(level):
visible = level.fog
================================================
FILE: vfx/TransitionColor.gd
================================================
extends ColorRect
onready var anim_player = $AnimationPlayer
func fade_to_color():
show()
anim_player.play("to_color")
yield(anim_player, "animation_finished")
hide()
func fade_from_color():
show()
anim_player.play("to_transparent")
yield(anim_player, "animation_finished")
hide()
================================================
FILE: vfx/TransitionColor.tscn
================================================
[gd_scene load_steps=6 format=2]
[ext_resource path="res://vfx/transition.material" type="Material" id=1]
[ext_resource path="res://vfx/TransitionColor.gd" type="Script" 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(".:material:shader_param/cutoff")
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 ]
}
[sub_resource type="Animation" id=3]
resource_name = "to_color"
length = 0.7
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:material:shader_param/cutoff")
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( 0.27058, 0.307901 ),
"update": 0,
"values": [ 1.0, 0.0 ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:material:shader_param/smooth_size")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.7 ),
"transitions": PoolRealArray( 0.27058, 1 ),
"update": 0,
"values": [ 0.941, 0.161 ]
}
[sub_resource type="Animation" id=2]
resource_name = "to_transparent"
length = 0.7
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:material:shader_param/cutoff")
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( 0.307901, 1 ),
"update": 0,
"values": [ 0.0, 1.0 ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:material:shader_param/smooth_size")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.7 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ 0.161, 0.941 ]
}
[node name="TransitionColor" type="ColorRect"]
material = ExtResource( 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 = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
color = Color( 1, 1, 1, 1 )
script = ExtResource( 2 )
_sections_unfolded = [ "Material" ]
[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/to_color = SubResource( 3 )
anims/to_transparent = SubResource( 2 )
blend_times = [ ]
_sections_unfolded = [ "Playback Options" ]
================================================
FILE: vfx/fog.shader
================================================
shader_type canvas_item;
uniform vec4 color : hint_color = vec4(0.35, 0.48, 0.95, 1.0);
uniform float noise_scale = 20.0;
uniform float alpha_power = 2.0;
uniform int OCTAVES = 1;
float rand(vec2 coord){
return fract(sin(dot(coord, vec2(56, 78)) * 1000.0) * 1000.0);
}
float noise(vec2 coord){
vec2 i = floor(coord);
vec2 f = fract(coord);
// 4 corners of a rectangle surrounding our point
float a = rand(i);
float b = rand(i + vec2(1.0, 0.0));
float c = rand(i + vec2(0.0, 1.0));
float d = rand(i + vec2(1.0, 1.0));
vec2 cubic = f * f * (3.0 - 2.0 * f);
return mix(a, b, cubic.x) + (c - a) * cubic.y * (1.0 - cubic.x) + (d - b) * cubic.x * cubic.y;
}
float fbm(vec2 coord){
float value = 0.0;
float scale = 0.5;
for(int i = 0; i < OCTAVES; i++){
value += noise(coord) * scale;
coord *= 2.0;
scale *= 0.5;
}
return value;
}
void fragment() {
vec2 coord = UV * noise_scale;
vec2 motion = vec2( fbm(coord + vec2(TIME * -0.5, TIME * 0.5)) );
float final = fbm(coord + motion);
COLOR = vec4(color.rgb, pow(final, alpha_power) * color.a);
}
================================================
FILE: vfx/masks/curtain.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/curtain.png-3af2c44df15fd54790d255ef204f96fe.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/masks/curtain.png"
dest_files=[ "res://.import/curtain.png-3af2c44df15fd54790d255ef204f96fe.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: vfx/particles/SelfDestructingParticles.gd
================================================
extends Particles2D
func start():
emitting = true
yield(get_tree().create_timer(lifetime * speed_scale * 1.2), "timeout")
queue_free()
================================================
FILE: vfx/particles/assets/gradient_ramps/fire_to_black.tres
================================================
[gd_resource type="Gradient" format=2]
[resource]
offsets = PoolRealArray( 0, 0.0358056, 0.480818, 0.915601, 1 )
colors = PoolColorArray( 1, 0.773438, 0, 0, 1, 0.726563, 0, 1, 1, 0.304688, 0, 1, 0.160156, 0.115112, 0.115112, 1, 0, 0, 0, 0 )
================================================
FILE: vfx/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: vfx/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: vfx/particles/dust_charge/DustCharge.tscn
================================================
[gd_scene load_steps=9 format=2]
[ext_resource path="res://dust_charge/puffs.png" type="Texture" id=1]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.0710059, 0.887574, 1 )
colors = PoolColorArray( 0.834469, 0.650242, 0.192065, 0, 0.84375, 0.699554, 0.316406, 1, 0.824219, 0.595778, 0.0547333, 1, 0.826506, 0.607932, 0.0853797, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 2048
[sub_resource type="Curve" id=3]
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=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[sub_resource type="Curve" id=5]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.166992 ), 0.0, 0.0, 0, 0, Vector2( 0.378064, 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 = 45.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 100.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 = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 0.8
scale_random = 0.2
scale_curve = SubResource( 6 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 1.0
hue_variation_curve = SubResource( 4 )
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Color", "Hue Variation" ]
[node name="DustCharge" type="Particles2D" index="0"]
position = Vector2( 1, 3 )
rotation = -1.5708
emitting = true
amount = 16
lifetime = 1.0
one_shot = false
preprocess = 0.0
speed_scale = 2.0
explosiveness = 0.2
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 1
process_material = SubResource( 7 )
texture = ExtResource( 1 )
normal_map = null
h_frames = 2
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time", "Transform" ]
================================================
FILE: vfx/particles/dust_charge/DustChargeLarge.tscn
================================================
[gd_scene load_steps=9 format=2]
[ext_resource path="res://dust_charge/DustCharge.tscn" type="PackedScene" id=1]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.0710059, 0.887574, 1 )
colors = PoolColorArray( 0.834469, 0.650242, 0.192065, 0, 0.84375, 0.699554, 0.316406, 1, 0.824219, 0.595778, 0.0547333, 1, 0.826506, 0.607932, 0.0853797, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 2048
[sub_resource type="Curve" id=3]
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=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[sub_resource type="Curve" id=5]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.166992 ), 0.0, 0.0, 0, 0, Vector2( 0.378064, 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 = 60.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 160.0
initial_velocity_random = 0.7
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 = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 1.4
scale_random = 0.3
scale_curve = SubResource( 6 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 1.0
hue_variation_curve = SubResource( 4 )
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Color", "Hue Variation", "Initial Velocity", "Scale", "Spread" ]
[node name="DustChargeLarge" index="0" instance=ExtResource( 1 )]
amount = 40
lifetime = 1.4
explosiveness = 0.1
randomness = 0.6
process_material = SubResource( 7 )
================================================
FILE: vfx/particles/dust_charge/puffs.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/puffs.png-5a8f7bae06bf0d22084af1f35563a1df.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/particles/dust_charge/puffs.png"
dest_files=[ "res://.import/puffs.png-5a8f7bae06bf0d22084af1f35563a1df.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: vfx/particles/dust_puffs/DustPuffs.tscn
================================================
[gd_scene load_steps=9 format=2]
[ext_resource path="res://vfx/particles/dust_charge/puffs.png" type="Texture" id=1]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.0710059, 0.887574, 1 )
colors = PoolColorArray( 0.834469, 0.650242, 0.192065, 0, 0.84375, 0.699554, 0.316406, 1, 0.824219, 0.595778, 0.0547333, 1, 0.826506, 0.607932, 0.0853797, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 2048
[sub_resource type="Curve" id=3]
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=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[sub_resource type="Curve" id=5]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.166992 ), 0.0, 0.0, 0, 0, Vector2( 0.378064, 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 = 45.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 100.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 = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 0.8
scale_random = 0.2
scale_curve = SubResource( 6 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 1.0
hue_variation_curve = SubResource( 4 )
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Color", "Hue Variation" ]
[node name="DustPuffs" type="Particles2D" index="0"]
position = Vector2( 1, 3 )
rotation = -1.5708
emitting = true
amount = 16
lifetime = 1.0
one_shot = false
preprocess = 0.0
speed_scale = 2.0
explosiveness = 0.2
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 1
process_material = SubResource( 7 )
texture = ExtResource( 1 )
normal_map = null
h_frames = 2
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time", "Transform" ]
================================================
FILE: vfx/particles/dust_puffs/DustPuffsLarge.tscn
================================================
[gd_scene load_steps=9 format=2]
[ext_resource path="res://vfx/particles/dust_puffs/DustPuffs.tscn" type="PackedScene" id=1]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.0710059, 0.887574, 1 )
colors = PoolColorArray( 0.834469, 0.650242, 0.192065, 0, 0.84375, 0.699554, 0.316406, 1, 0.824219, 0.595778, 0.0547333, 1, 0.826506, 0.607932, 0.0853797, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 2048
[sub_resource type="Curve" id=3]
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=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[sub_resource type="Curve" id=5]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.166992 ), 0.0, 0.0, 0, 0, Vector2( 0.378064, 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 = 60.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 160.0
initial_velocity_random = 0.7
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 = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 1.4
scale_random = 0.3
scale_curve = SubResource( 6 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 1.0
hue_variation_curve = SubResource( 4 )
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Color", "Hue Variation", "Initial Velocity", "Scale", "Spread" ]
[node name="DustPuffsLarge" index="0" instance=ExtResource( 1 )]
amount = 40
lifetime = 1.4
explosiveness = 0.1
randomness = 0.6
process_material = SubResource( 7 )
================================================
FILE: vfx/particles/dust_puffs/DustRun.tscn
================================================
[gd_scene load_steps=8 format=2]
[ext_resource path="res://vfx/particles/dust_puffs/puff_stylized.png" type="Texture" id=1]
[ext_resource path="res://vfx/particles/SelfDestructingParticles.gd" type="Script" id=2]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.0602007, 0.769231, 1 )
colors = PoolColorArray( 0.308594, 0.233027, 0.144653, 0, 0.574219, 0.435676, 0.273651, 1, 0.598236, 0.472648, 0.325774, 1, 0.596078, 0.470588, 0.32549, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 256
[sub_resource type="Curve" id=3]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.349609 ), 0.0, 1.47649, 0, 0, Vector2( 0.908748, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.628906 ), -4.5017, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[sub_resource type="ParticlesMaterial" id=5]
render_priority = 0
trail_divisor = 1
emission_shape = 1
emission_sphere_radius = 10.0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 120.0
flatness = 1.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 30.0
initial_velocity_random = 0.4
angular_velocity = 120.0
angular_velocity_random = 0.7
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = -10.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.6
scale_random = 0.1
scale_curve = SubResource( 4 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 0.0
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Color", "Scale" ]
[node name="DustRun" type="Particles2D" index="0"]
show_behind_parent = true
position = Vector2( 1, 0 )
rotation = -1.5708
emitting = false
amount = 12
lifetime = 1.0
one_shot = true
preprocess = 0.0
speed_scale = 2.0
explosiveness = 0.95
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( 5 )
texture = ExtResource( 1 )
normal_map = null
h_frames = 1
v_frames = 1
script = ExtResource( 2 )
_sections_unfolded = [ "Drawing", "Material", "Process Material", "Textures", "Time", "Transform", "Visibility", "Z Index" ]
================================================
FILE: vfx/particles/dust_puffs/DustWalk.tscn
================================================
[gd_scene load_steps=4 format=2]
[ext_resource path="res://vfx/particles/dust_puffs/dust_puffs_particle.tres" type="Material" id=1]
[ext_resource path="res://vfx/particles/dust_puffs/puff_stylized.png" type="Texture" id=2]
[ext_resource path="res://vfx/particles/SelfDestructingParticles.gd" type="Script" id=3]
[node name="DustWalk" type="Particles2D" index="0"]
show_behind_parent = true
position = Vector2( 1, 0 )
rotation = -1.5708
emitting = false
amount = 8
lifetime = 1.0
one_shot = true
preprocess = 0.0
speed_scale = 1.4
explosiveness = 0.95
randomness = 0.3
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 0
process_material = ExtResource( 1 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 1
v_frames = 1
script = ExtResource( 3 )
_sections_unfolded = [ "Drawing", "Material", "Time", "Transform", "Visibility" ]
================================================
FILE: vfx/particles/dust_puffs/dust_puffs_particle.tres
================================================
[gd_resource type="ParticlesMaterial" load_steps=5 format=2]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.112532, 0.869565, 1 )
colors = PoolColorArray( 0.308594, 0.233027, 0.144653, 0, 0.574219, 0.435676, 0.273651, 1, 0.598236, 0.472648, 0.325774, 1, 0.596078, 0.470588, 0.32549, 0 )
[sub_resource type="GradientTexture" id=2]
gradient = SubResource( 1 )
width = 256
[sub_resource type="Curve" id=3]
_data = [ Vector2( 0, 0.349609 ), 0.0, 1.47649, 0, 0, Vector2( 0.908748, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.628906 ), -4.5017, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=4]
curve = SubResource( 3 )
[resource]
emission_shape = 1
emission_sphere_radius = 5.0
flag_disable_z = true
spread = 120.0
flatness = 1.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 30.0
initial_velocity_random = 0.4
angular_velocity = 120.0
angular_velocity_random = 0.7
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = -10.0
angle = 360.0
angle_random = 1.0
scale = 0.5
scale_curve = SubResource( 4 )
color_ramp = SubResource( 2 )
anim_offset = 1.0
anim_offset_random = 1.0
================================================
FILE: vfx/particles/dust_puffs/puff_stylized.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/puff_stylized.png-76fe5696970602731dcc9616af628ed6.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/particles/dust_puffs/puff_stylized.png"
dest_files=[ "res://.import/puff_stylized.png-76fe5696970602731dcc9616af628ed6.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: vfx/particles/dust_puffs/puffs.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/puffs.png-647a0897f9b56787d9f19dffab574e9f.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/particles/dust_puffs/puffs.png"
dest_files=[ "res://.import/puffs.png-647a0897f9b56787d9f19dffab574e9f.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: vfx/particles/explosions/Explosion.gd
================================================
extends Particles2D
func _ready():
get_tree().create_timer(lifetime).connect('timeout', self, 'stop_emitting')
get_tree().create_timer(lifetime * 2.0).connect('timeout', self, 'queue_free')
func stop_emitting():
emitting = false
================================================
FILE: vfx/particles/explosions/Explosion.tscn
================================================
[gd_scene load_steps=10 format=2]
[ext_resource path="res://vfx/particles/dust_charge/puffs.png" type="Texture" id=1]
[ext_resource path="res://vfx/particles/explosions/Explosion.gd" type="Script" id=2]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0.226293, 0.545259, 0.898707, 1 )
colors = PoolColorArray( 0.953125, 0.907313, 0.785583, 1, 0.953125, 0.850099, 0.0111694, 1, 0.921875, 0.450078, 0.219666, 1, 0.826506, 0.607932, 0.0853797, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 2048
[sub_resource type="Curve" id=3]
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=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[sub_resource type="Curve" id=5]
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=6]
flags = 4
width = 2048
curve = SubResource( 5 )
[sub_resource type="ParticlesMaterial" id=7]
render_priority = 0
trail_divisor = 1
emission_shape = 1
emission_sphere_radius = 20.0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 180.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 160.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 = 0.0
tangential_accel_random = 0.0
damping = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 1.0
scale_random = 0.6
scale_curve = SubResource( 6 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 1.0
hue_variation_curve = SubResource( 4 )
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Color", "Emission Shape", "Gravity", "Initial Velocity", "Scale", "Spread" ]
[node name="Explosion" type="Particles2D" index="0"]
position = Vector2( 13.6701, 0 )
rotation = -1.5708
z_index = 20
emitting = true
amount = 80
lifetime = 0.3
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.4
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 1
process_material = SubResource( 7 )
texture = ExtResource( 1 )
normal_map = null
h_frames = 2
v_frames = 1
script = ExtResource( 2 )
_sections_unfolded = [ "Drawing", "Process Material", "Time", "Transform", "Z Index" ]
================================================
FILE: vfx/particles/explosions/ExplosionFlash.tscn
================================================
[gd_scene load_steps=10 format=2]
[ext_resource path="res://vfx/particles/explosions/circle.png" type="Texture" id=1]
[ext_resource path="res://explosions/explosion.gd" type="Script" id=2]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.0946746, 0.414201, 0.650888, 0.87574, 1 )
colors = PoolColorArray( 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 2048
[sub_resource type="Curve" id=3]
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=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[sub_resource type="Curve" id=5]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.790039 ), 0.0, -0.433343, 0, 0, Vector2( 0.413238, 0.811523 ), 0.775457, 3.68342, 0, 0, Vector2( 1, 1 ), 0.121391, 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 = 1
emission_sphere_radius = 44.04
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 180.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 200.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 = 360.0
angle_random = 1.0
scale = 1.0
scale_random = 0.4
scale_curve = SubResource( 6 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 1.0
hue_variation_curve = SubResource( 4 )
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 1.0
anim_offset_random = 1.0
anim_loop = false
_sections_unfolded = [ "Color", "Damping", "Emission Shape", "Flags", "Initial Velocity", "Scale", "Spread" ]
[node name="ExplosionFlash" type="Particles2D" index="0"]
z_index = 20
emitting = false
amount = 10
lifetime = 0.6
one_shot = true
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.3
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 1
process_material = SubResource( 7 )
texture = ExtResource( 1 )
normal_map = null
h_frames = 1
v_frames = 1
script = ExtResource( 2 )
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time" ]
================================================
FILE: vfx/particles/explosions/circle.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/circle.png-206ef6dbbb41f3edbef77fad323ed599.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/particles/explosions/circle.png"
dest_files=[ "res://.import/circle.png-206ef6dbbb41f3edbef77fad323ed599.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: vfx/particles/fiery_cloud/FieryCloud.tscn
================================================
[gd_scene load_steps=17 format=2]
[ext_resource path="res://assets/gradient_ramps/fire_to_black.tres" type="Gradient" id=1]
[ext_resource path="res://dust_charge/puffs.png" type="Texture" id=2]
[ext_resource path="res://fiery_cloud/fiery_cloud.gd" type="Script" id=3]
[ext_resource path="res://assets/gradient_ramps/sparkles_small.tres" type="Gradient" id=4]
[ext_resource path="res://explosions/circle.png" type="Texture" id=5]
[ext_resource path="res://assets/gradient_ramps/sparkles.tres" type="Gradient" id=6]
[sub_resource type="GradientTexture" id=1]
flags = 4
gradient = ExtResource( 1 )
width = 2048
[sub_resource type="Curve" id=2]
min_value = 0.0
max_value = 1.6
bake_resolution = 100
_data = [ Vector2( 0.00254472, 0.414062 ), 0.0, 0.0, 0, 0, Vector2( 0.195613, 0.650391 ), 1.7438, 1.7438, 0, 0, Vector2( 1, 1.59062 ), 4.80181, 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 = 0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 120.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 120.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 = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 0.4
scale_random = 1.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 = [ "Angle", "Color", "Scale" ]
[sub_resource type="GradientTexture" id=5]
flags = 4
gradient = ExtResource( 4 )
width = 2048
[sub_resource type="Curve" id=6]
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=7]
flags = 4
width = 2048
curve = SubResource( 6 )
[sub_resource type="ParticlesMaterial" id=8]
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, 200, 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.04
scale_random = 0.0
scale_curve = SubResource( 7 )
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", "Emission Shape", "Gravity", "Initial Velocity", "Scale", "Spread", "Tangential Accel" ]
[sub_resource type="GradientTexture" id=9]
flags = 4
gradient = ExtResource( 6 )
width = 2048
[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 = 120.0
flatness = 0.0
gravity = Vector3( 0, 200, 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.04
scale_random = 0.0
scale_curve = SubResource( 7 )
color_ramp = SubResource( 9 )
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" ]
[node name="FieryCloud" type="Particles2D" index="0"]
emitting = false
amount = 40
lifetime = 0.6
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 = SubResource( 4 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 2
v_frames = 1
script = ExtResource( 3 )
_sections_unfolded = [ "Drawing", "Process Material", "Time" ]
TIME_SCALE = 2.0
RADIUS = 160.0
OFFSET = Vector2( 0, 0 )
active = false
[node name="SmallSparkles" type="Particles2D" parent="." index="0"]
visible = false
rotation = -1.61079
emitting = true
amount = 40
lifetime = 1.0
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( 8 )
texture = ExtResource( 5 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures" ]
[node name="TinySparkles" type="Particles2D" parent="." index="1"]
visible = false
rotation = -1.61079
emitting = true
amount = 60
lifetime = 1.0
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( 10 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 2
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures" ]
================================================
FILE: vfx/particles/fiery_cloud/Fireball.tscn
================================================
[gd_scene load_steps=17 format=2]
[ext_resource path="res://assets/gradient_ramps/fire_to_black.tres" type="Gradient" id=1]
[ext_resource path="res://dust_charge/puffs.png" type="Texture" id=2]
[ext_resource path="res://fiery_cloud/fiery_cloud.gd" type="Script" id=3]
[ext_resource path="res://assets/gradient_ramps/sparkles_small.tres" type="Gradient" id=4]
[ext_resource path="res://explosions/circle.png" type="Texture" id=5]
[ext_resource path="res://assets/gradient_ramps/sparkles.tres" type="Gradient" id=6]
[sub_resource type="GradientTexture" id=1]
flags = 4
gradient = ExtResource( 1 )
width = 2048
[sub_resource type="Curve" id=2]
min_value = 0.0
max_value = 3.0
bake_resolution = 100
_data = [ Vector2( 0, 0.645313 ), 0.0, 2.139, 0, 0, Vector2( 1, 2.55371 ), 2.94849, 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 = 10.0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 180.0
flatness = 0.0
gravity = Vector3( 0, 98, 0 )
initial_velocity = 120.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 = 0.0
damping_random = 0.0
angle = 360.0
angle_random = 1.0
scale = 0.4
scale_random = 1.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", "Emission Shape", "Hue Variation", "Scale", "Spread", "Trail" ]
[sub_resource type="GradientTexture" id=5]
flags = 4
gradient = ExtResource( 4 )
width = 2048
[sub_resource type="Curve" id=6]
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=7]
flags = 4
width = 2048
curve = SubResource( 6 )
[sub_resource type="ParticlesMaterial" id=8]
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.04
scale_random = 0.0
scale_curve = SubResource( 7 )
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", "Tangential Accel" ]
[sub_resource type="GradientTexture" id=9]
flags = 4
gradient = ExtResource( 6 )
width = 2048
[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 = 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.04
scale_random = 0.0
scale_curve = SubResource( 7 )
color_ramp = SubResource( 9 )
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" ]
[node name="Fireball" type="Particles2D" index="0"]
position = Vector2( 274.321, -72.4055 )
emitting = true
amount = 120
lifetime = 0.8
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.0
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -400, -400, 800, 800 )
local_coords = false
draw_order = 1
process_material = SubResource( 4 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 2
v_frames = 1
script = ExtResource( 3 )
_sections_unfolded = [ "Process Material", "Textures", "Time", "Transform" ]
TIME_SCALE = 3.0
RADIUS = 300.0
OFFSET = Vector2( 400, 200 )
active = true
[node name="SmallSparkles" type="Particles2D" parent="." index="0"]
rotation = -1.61079
emitting = true
amount = 40
lifetime = 1.0
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( 8 )
texture = ExtResource( 5 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures" ]
[node name="TinySparkles" type="Particles2D" parent="." index="1"]
rotation = -1.61079
emitting = true
amount = 60
lifetime = 1.0
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( 10 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 2
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures" ]
================================================
FILE: vfx/particles/fiery_cloud/FireryCloud.gd
================================================
tool
extends Particles2D
export(float) var TIME_SCALE = 1.0
export(float) var RADIUS = 200.0
export(Vector2) var OFFSET = Vector2()
export(bool) var active = false setget set_active
var time = 0.0
func _process(delta):
time += delta
var time_scaled = TIME_SCALE * time
position = Vector2(
cos(time_scaled) * RADIUS,
sin(time_scaled) * RADIUS
)
position += OFFSET
func set_active(value):
active = value
set_process(active)
if not active:
position = Vector2()
================================================
FILE: vfx/particles/rocks/DirectionalRock.tscn
================================================
[gd_scene load_steps=5 format=2]
[ext_resource path="res://vfx/particles/rocks/rocks_particle.tres" type="Material" id=1]
[ext_resource path="res://vfx/particles/rocks/rocks.png" type="Texture" id=2]
[ext_resource path="res://vfx/particles/rocks/crumbs_particle.tres" type="Material" id=3]
[sub_resource type="GDScript" id=1]
script/source = "extends Particles2D
func initialize(position, angle):
global_position = position
rotation = angle
yield(get_tree().create_timer(lifetime / speed_scale), \"timeout\")
queue_free()
"
[node name="DirectionalRock" type="Particles2D"]
modulate = Color( 0.691406, 0.486124, 0.132339, 1 )
rotation = -1.5708
emitting = false
amount = 20
lifetime = 0.7
one_shot = true
preprocess = 0.0
speed_scale = 1.5
explosiveness = 0.9
randomness = 0.9
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = false
draw_order = 0
process_material = ExtResource( 1 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 1
v_frames = 1
script = SubResource( 1 )
_sections_unfolded = [ "Material", "Process Material", "Time", "Visibility" ]
[node name="Pebbles2" type="Particles2D" parent="." index="0"]
self_modulate = Color( 0.744278, 0.768273, 0.832031, 1 )
show_behind_parent = true
scale = Vector2( 1.3383, 1.50043 )
emitting = true
amount = 20
lifetime = 0.7
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.8
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = false
draw_order = 0
process_material = ExtResource( 3 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Process Material", "Time", "Visibility" ]
[node name="Pebbles" type="Particles2D" parent="." index="1"]
show_behind_parent = true
scale = Vector2( 1.01931, 1.27982 )
emitting = true
amount = 20
lifetime = 0.7
one_shot = false
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.8
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = false
draw_order = 0
process_material = ExtResource( 3 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Process Material", "Time", "Visibility" ]
================================================
FILE: vfx/particles/rocks/crumbs.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/crumbs.png-0cfbcc76d6de4ba75de4c089e6c455de.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/particles/rocks/crumbs.png"
dest_files=[ "res://.import/crumbs.png-0cfbcc76d6de4ba75de4c089e6c455de.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: vfx/particles/rocks/crumbs_particle.tres
================================================
[gd_resource type="ParticlesMaterial" load_steps=3 format=2]
[sub_resource type="Curve" id=1]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 1 ), 0.0, -5.56082, 0, 0, Vector2( 0.502916, 0 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=2]
flags = 4
width = 2048
curve = SubResource( 1 )
[resource]
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, 200, 0 )
initial_velocity = 140.0
initial_velocity_random = 0.4
angular_velocity = 180.0
angular_velocity_random = 1.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = -60.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 = 80.0
damping_random = 0.0
angle = 0.0
angle_random = 1.0
scale = 0.15
scale_random = 0.3
scale_curve = SubResource( 2 )
color = Color( 0.816406, 0.816406, 0.816406, 1 )
hue_variation = 1.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", "Emission Shape", "Trail" ]
================================================
FILE: vfx/particles/rocks/rocks.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/rocks.png-55d7ebb59a35e3e8e667f24e321f9c1b.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/particles/rocks/rocks.png"
dest_files=[ "res://.import/rocks.png-55d7ebb59a35e3e8e667f24e321f9c1b.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: vfx/particles/rocks/rocks_particle.tres
================================================
[gd_resource type="ParticlesMaterial" load_steps=9 format=2]
[sub_resource type="Curve" id=1]
min_value = 0.0
max_value = 200.0
bake_resolution = 100
_data = [ Vector2( 0, 0 ), 0.0, 53.531, 0, 0, Vector2( 0.249193, 0 ), -8.39704, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=2]
flags = 4
width = 2048
curve = SubResource( 1 )
[sub_resource type="Gradient" id=3]
offsets = PoolRealArray( 0.881657, 1 )
colors = PoolColorArray( 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 = -200.0
max_value = 200.0
bake_resolution = 100
_data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, -55.8594 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=6]
flags = 4
width = 2048
curve = SubResource( 5 )
[sub_resource type="Curve" id=7]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.446289 ), 0.0, 8.58244, 0, 0, Vector2( 0.410727, 1 ), -1.18141, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=8]
flags = 4
width = 32
curve = SubResource( 7 )
[resource]
render_priority = 0
trail_divisor = 1
emission_shape = 0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 30.0
flatness = 0.0
gravity = Vector3( 0, 500, 0 )
initial_velocity = 500.0
initial_velocity_random = 0.5
angular_velocity = 360.0
angular_velocity_random = 0.53
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = 0.0
linear_accel_random = 0.0
linear_accel_curve = SubResource( 6 )
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 0.0
tangential_accel_random = 0.0
damping = 100.0
damping_random = 0.0
angle = 0.0
angle_random = 1.0
scale = 0.1
scale_random = 0.7
scale_curve = SubResource( 8 )
color_ramp = SubResource( 4 )
hue_variation = 1.0
hue_variation_random = 0.02
anim_speed = 0.0
anim_speed_random = 0.0
anim_speed_curve = SubResource( 2 )
anim_offset = 0.0
anim_offset_random = 0.0
anim_loop = false
_sections_unfolded = [ "Color", "Scale" ]
================================================
FILE: vfx/particles/smoke/EnemySmokeScreen.tscn
================================================
[gd_scene load_steps=3 format=2]
[ext_resource path="res://vfx/particles/smoke/smoke_screen_particle.tres" type="Material" id=1]
[ext_resource path="res://vfx/particles/smoke/smoke.png" type="Texture" id=2]
[node name="EnemySmokeScreen" type="Particles2D" index="0"]
self_modulate = Color( 0.90831, 0.918911, 0.941406, 1 )
emitting = false
amount = 10
lifetime = 0.9
one_shot = true
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.8
randomness = 1.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = false
draw_order = 0
process_material = ExtResource( 1 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time" ]
[node name="SmokeDarker" type="Particles2D" parent="." index="0"]
self_modulate = Color( 0.632904, 0.671685, 0.726563, 1 )
show_behind_parent = true
scale = Vector2( 1.20092, 1.32186 )
emitting = false
amount = 20
lifetime = 0.7
one_shot = true
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.8
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = true
draw_order = 0
process_material = ExtResource( 1 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Material", "Process Material", "Textures", "Time", "Visibility" ]
[node name="SmokeGrey" type="Particles2D" parent="." index="1"]
self_modulate = Color( 0.789703, 0.828256, 0.882813, 1 )
show_behind_parent = true
scale = Vector2( 1.05668, 1.05668 )
emitting = false
amount = 20
lifetime = 0.8
one_shot = true
preprocess = 0.0
speed_scale = 1.0
explosiveness = 0.8
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = true
draw_order = 0
process_material = ExtResource( 1 )
texture = ExtResource( 2 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Material", "Process Material", "Textures", "Time", "Visibility" ]
================================================
FILE: vfx/particles/smoke/ParticlesPlayer.gd
================================================
extends Particles2D
func play():
emitting = true
for child in get_children():
if not child.get_class() == "Particles2D":
continue
child.emitting = true
================================================
FILE: vfx/particles/smoke/smoke.png.import
================================================
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/smoke.png-510677d7daa804cf41c380a0acf068c5.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://vfx/particles/smoke/smoke.png"
dest_files=[ "res://.import/smoke.png-510677d7daa804cf41c380a0acf068c5.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: vfx/particles/smoke/smoke_screen_particle.tres
================================================
[gd_resource type="ParticlesMaterial" load_steps=5 format=2]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0.912387, 1 )
colors = PoolColorArray( 1, 1, 1, 1, 1, 1, 1, 0 )
[sub_resource type="GradientTexture" id=2]
flags = 4
gradient = SubResource( 1 )
width = 2048
[sub_resource type="Curve" id=3]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.136789 ), 0.0, 3.12433, 0, 0, Vector2( 0.469416, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.998443, 0.728062 ), -0.801458, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=4]
flags = 4
width = 2048
curve = SubResource( 3 )
[resource]
render_priority = 0
trail_divisor = 1
emission_shape = 1
emission_sphere_radius = 12.0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 180.0
flatness = 0.0
gravity = Vector3( 0, -20, 0 )
initial_velocity = 40.0
initial_velocity_random = 0.2
angular_velocity = 80.0
angular_velocity_random = 0.0
orbit_velocity = 0.0
orbit_velocity_random = 1.0
linear_accel = 0.0
linear_accel_random = 0.0
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 20.0
tangential_accel_random = 0.0
damping = 0.0
damping_random = 0.4
angle = 360.0
angle_random = 1.0
scale = 0.4
scale_random = 0.6
scale_curve = SubResource( 4 )
color_ramp = SubResource( 2 )
hue_variation = 0.0
hue_variation_random = 0.0
anim_speed = 1.0
anim_speed_random = 0.5
anim_offset = 0.0
anim_offset_random = 0.0
anim_loop = false
_sections_unfolded = [ "Scale" ]
================================================
FILE: vfx/transition.shader
================================================
shader_type canvas_item;
render_mode unshaded;
uniform float cutoff : hint_range(0.0, 1.0);
uniform float smooth_size : hint_range(0.0, 1.0);
uniform sampler2D mask : hint_albedo;
uniform vec4 color : hint_color;
void fragment()
{
float value = texture(mask, UV).r;
float alpha = smoothstep(cutoff, cutoff + smooth_size, value * (1.0 - smooth_size) + smooth_size);
COLOR = vec4(color.rgb, alpha);
}