├── cgf-version.txt ├── icon.png ├── src ├── cc │ ├── cards │ │ ├── StrikeFront.gd │ │ ├── SFX.gd │ │ ├── Strike.tscn │ │ ├── sets │ │ │ ├── SetDefinition_Core.gd │ │ │ └── SetScripts_Core.gd │ │ ├── StrikeFront.tscn │ │ ├── DuplicateCoreTargetingArrow.tscn │ │ ├── InheritedCoreCardTemplate.tscn │ │ └── DuplicateCustomCGFCardBack.tscn │ ├── decks │ │ └── SampleDeck.gd │ ├── DuplicateCustomCGFHand.gd │ ├── DetailsFont.tres │ ├── DuplicateCustomCGFDiscard.gd │ ├── DuplicateCustomCGFCardManipulationButton.tscn │ ├── DuplicateCustomCGFInfoPanel.tscn │ ├── DuplicateCustomCGFDeck.gd │ ├── InheritedCoreMain.tscn │ ├── Main.gd │ ├── SP.gd │ ├── DuplicateCustomCGFManipulationButtons.gd │ └── DuplicateCustomCGFCardFront.gd ├── battle │ ├── ui │ │ ├── battler_hud │ │ │ ├── hud-bg.png │ │ │ ├── energy_bar │ │ │ │ ├── stub.png │ │ │ │ ├── stub_bg.png │ │ │ │ ├── UIEnergyBar.tscn │ │ │ │ ├── stub.png.import │ │ │ │ ├── stub_bg.png.import │ │ │ │ ├── UIEnergyPoint.tscn │ │ │ │ └── UIEnergyPoint.gd │ │ │ ├── UIBattlerHUDList.gd │ │ │ ├── hud-bg.png.import │ │ │ ├── UIBattlerHUD.tscn │ │ │ └── UIBattlerHUDList.tscn │ │ ├── damage_labels │ │ │ ├── UIDamageLabelBuilder.tscn │ │ │ ├── UIDamageLabel.tscn │ │ │ └── UIDamageLabelBuilder.gd │ │ ├── BattlerUIData.gd │ │ ├── action_menu │ │ │ ├── UIActionMenu.tscn │ │ │ ├── UIActionList.tscn │ │ │ ├── UIMenuSelectArrow.gd │ │ │ ├── UIMenuSelectArrow.tscn │ │ │ ├── UIActionButton.gd │ │ │ ├── UIActionMenu.gd │ │ │ └── UIActionButton.tscn │ │ ├── UICombatResultPanel.gd │ │ └── turn_bar │ │ │ └── UIBattlerIcon.tscn │ ├── ai │ │ ├── AggressiveBattlerAI.tscn │ │ └── AggressiveBattlerAI.gd │ ├── battlers │ │ ├── antagonist.tres │ │ ├── protagonist.tres │ │ ├── enemy_stats.tres │ │ ├── player_stats.tres │ │ ├── BattlerProtagonist.tscn │ │ └── BattlerAntagonist.tscn │ ├── statuseffects │ │ ├── effects │ │ │ └── bug.tres │ │ ├── impl │ │ │ ├── StatusEffectBug.gd │ │ │ ├── StatusEffectSlow.gd │ │ │ └── StatusEffectHaste.gd │ │ ├── StatusEffectData.gd │ │ └── StatusEffectBuilder.gd │ ├── command │ │ ├── basic_attack.tres │ │ ├── Types.gd │ │ ├── Hit.gd │ │ └── AttackActionData.gd │ ├── Arena.gd │ ├── UI.gd │ ├── anim │ │ └── SFX.gd │ ├── Battler.tscn │ └── Arena.tscn ├── custom │ ├── CGFHand.gd │ ├── cards │ │ ├── Token.tscn │ │ ├── Red.tscn │ │ ├── Green.tscn │ │ ├── Blue.tscn │ │ ├── RedFront.tscn │ │ ├── BlueFront.tscn │ │ ├── sets │ │ │ ├── SetDefinition_Demo2.gd │ │ │ ├── SetDefinition_Demo1.gd │ │ │ └── SetScripts_Demo1.gd │ │ ├── GreenFront.tscn │ │ └── CustomScripts.gd │ ├── DetailsFont.tres │ ├── CGFDiscard.gd │ ├── CGFDeckBuilder.gd │ ├── CGFDeckBuilder.tscn │ ├── CGFCardManipulationButton.tscn │ ├── CGFMain.tscn │ ├── CGFCounters.tscn │ ├── CGFInfoPanel.tscn │ ├── CGFModifiedLabelGrid.tscn │ ├── CGFDeck.gd │ ├── CGFHand.tscn │ ├── CGFCardBack.gd │ ├── CGFCardTemplate.tscn │ ├── CGFCounter.tscn │ ├── CGFPlacementGridDemo.tscn │ ├── CGFCounters.gd │ ├── CGFCardTemplate.gd │ ├── SP.gd │ ├── CGFManipulationButtons.gd │ ├── PlayingCardBack.tscn │ └── CGFCardFront.gd ├── shaders │ ├── scroll_bg.shader │ ├── squiggle_vision.shader │ └── film_grain.shader ├── core │ ├── DeckBuilder │ │ ├── DBCardObjectFont.tres │ │ ├── CBCardListHeadersFont.tres │ │ ├── DBDeckSummaries.gd │ │ ├── SaveButtonStyle.tres │ │ ├── FilterButtonStyle.tres │ │ ├── CardLabel.gd │ │ ├── DBPreviewPopup.tscn │ │ ├── CategoryContainer.gd │ │ ├── DBFilterButton.gd │ │ ├── QuantityNumberButton.gd │ │ ├── DBFilterButton.tscn │ │ ├── DBDeckSummaries.tscn │ │ ├── DBGridCardObject.tscn │ │ ├── CategoryContainer.tscn │ │ ├── CardLabel.tscn │ │ ├── DBGridCardObject.gd │ │ ├── DBDeckCardObject.gd │ │ └── DBDeckCardObject.tscn │ ├── Card │ │ ├── CardBackTexture.gd │ │ ├── TargetingArrow.tscn │ │ ├── CardBackGlow.gd │ │ └── CardBack.gd │ ├── DetailPanels.tscn │ ├── perMessage.gd │ ├── OverridableUtils.gd │ ├── OptionalConfirmation.gd │ ├── OptionalConfirmation.tscn │ ├── IntegerLineEdit.gd │ ├── BoardPlacementSlot.gd │ ├── MousePointer.tscn │ ├── CardChoices.gd │ ├── Highlight.tscn │ ├── VBoxContainer.tscn │ ├── ScriptAlter.gd │ ├── CardChoices.tscn │ └── BoardPlacementGrid.tscn ├── game │ ├── StoryKidnap.gd │ ├── MainMenu.gd │ ├── Splash.gd │ ├── FilmGrain.tscn │ └── StoryKidnap.tscn ├── Game.gd └── Events.gd ├── assets ├── characters │ ├── npc.png │ ├── bruli.png │ ├── fenyx.png │ ├── avatar.png │ ├── fenyx-paperbg.png │ ├── icons │ │ ├── bruli.png │ │ ├── fenyx.png │ │ ├── bruli.png.import │ │ └── fenyx.png.import │ ├── proto-character.png │ ├── npc.png.import │ ├── bruli.png.import │ ├── fenyx.png.import │ ├── avatar.png.import │ ├── fenyx-paperbg.png.import │ └── proto-character.png.import ├── font │ ├── timr45w.ttf │ └── DelaGothicOne-Regular.ttf ├── art │ ├── fx │ │ ├── filmgrain.png │ │ ├── vignette.png │ │ ├── filmgrain-1080.png │ │ ├── vignette.png.import │ │ ├── filmgrain.png.import │ │ └── filmgrain-1080.png.import │ ├── ui │ │ └── menu │ │ │ ├── menu_bg.png │ │ │ ├── buttons │ │ │ ├── hover.png │ │ │ ├── normal.png │ │ │ ├── pressed.png │ │ │ ├── hover.png.import │ │ │ ├── normal.png.import │ │ │ └── pressed.png.import │ │ │ └── menu_bg.png.import │ ├── splash │ │ ├── splash_bg.png │ │ ├── splash_hills.png │ │ ├── splash_bg.png.import │ │ └── splash_hills.png.import │ └── normal_maps │ │ ├── squigglevission.jpg │ │ └── squigglevission.jpg.import ├── audio │ ├── music │ │ ├── CC3.ogg │ │ └── CC3.ogg.import │ └── sfx │ │ ├── cards │ │ ├── card1.wav │ │ ├── card2.wav │ │ ├── card3.wav │ │ ├── card4.wav │ │ ├── card1.wav.import │ │ ├── card2.wav.import │ │ ├── card3.wav.import │ │ └── card4.wav.import │ │ ├── attacks │ │ ├── punch1.wav │ │ ├── punch2.wav │ │ ├── punch1.wav.import │ │ └── punch2.wav.import │ │ └── train │ │ ├── train_stop_1.ogg │ │ ├── train_ambience_loop_1.ogg │ │ ├── train_stop_1.ogg.import │ │ └── train_ambience_loop_1.ogg.import ├── cards │ ├── Elbow Bump.png │ ├── Knee Knock.png │ ├── Newspaper.png │ ├── front-placeholder.png │ ├── Newspaper.png.import │ ├── Elbow Bump.png.import │ ├── Knee Knock.png.import │ └── front-placeholder.png.import ├── icons │ ├── icon_frame.png │ ├── contumacious_commuter_icon.ico │ ├── view.svg.import │ └── icon_frame.png.import ├── backgrounds │ ├── hills.png │ ├── kidnap.png │ ├── trees.png │ ├── train-interior.png │ ├── hills.png.import │ ├── trees.png.import │ ├── kidnap.png.import │ └── train-interior.png.import ├── card_backs │ ├── card-back.png │ ├── godot_back.png │ ├── CGFBackDots.png │ ├── CGFBackLines.png │ ├── card-back.png.import │ ├── godot_back.png.import │ ├── CGFBackDots.png.import │ └── CGFBackLines.png.import ├── ui │ ├── turn_bar │ │ ├── turn_bar.png │ │ └── turn_bar.png.import │ ├── life_bar │ │ ├── life_bar_bg.png │ │ ├── life_bar_fill.png │ │ ├── life_bar_bg.png.import │ │ └── life_bar_fill.png.import │ ├── action_menu │ │ ├── menu_action_bg.png │ │ ├── menu_selection_arrow.png │ │ ├── menu_action_bg_disabled.png │ │ ├── menu_action_bg_focused.png │ │ ├── menu_action_bg_pressed.png │ │ ├── icon_punch.svg.import │ │ ├── menu_action_bg.png.import │ │ ├── menu_selection_arrow.png.import │ │ ├── menu_action_bg_focused.png.import │ │ ├── menu_action_bg_pressed.png.import │ │ └── menu_action_bg_disabled.png.import │ └── theme │ │ ├── cc_font_large.tres │ │ ├── cc_font_medium.tres │ │ └── combat_ui_theme.tres └── tokens │ ├── red.svg.import │ ├── black.svg.import │ ├── blue.svg.import │ ├── green.svg.import │ ├── grey.svg.import │ ├── orange.svg.import │ ├── purple.svg.import │ └── yellow.svg.import ├── fonts ├── Comfortaa-Bold.ttf └── Xolonium-Regular.ttf ├── contumacious_commuter_icon.ico ├── default_env.tres ├── .gitignore ├── README.md ├── icon.png.import ├── update-card-game-framework.sh ├── .github └── workflows │ └── godot-ci.yml └── notes.md /cgf-version.txt: -------------------------------------------------------------------------------- 1 | b8f8277d3f0391fb4b4b7cf0a9ab295b49e791e4 2 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/icon.png -------------------------------------------------------------------------------- /src/cc/cards/StrikeFront.gd: -------------------------------------------------------------------------------- 1 | extends "res://src/cc/DuplicateCustomCGFCardFront.gd" 2 | -------------------------------------------------------------------------------- /assets/characters/npc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/npc.png -------------------------------------------------------------------------------- /assets/font/timr45w.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/font/timr45w.ttf -------------------------------------------------------------------------------- /fonts/Comfortaa-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/fonts/Comfortaa-Bold.ttf -------------------------------------------------------------------------------- /assets/art/fx/filmgrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/fx/filmgrain.png -------------------------------------------------------------------------------- /assets/art/fx/vignette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/fx/vignette.png -------------------------------------------------------------------------------- /assets/audio/music/CC3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/music/CC3.ogg -------------------------------------------------------------------------------- /assets/cards/Elbow Bump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/cards/Elbow Bump.png -------------------------------------------------------------------------------- /assets/cards/Knee Knock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/cards/Knee Knock.png -------------------------------------------------------------------------------- /assets/cards/Newspaper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/cards/Newspaper.png -------------------------------------------------------------------------------- /assets/characters/bruli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/bruli.png -------------------------------------------------------------------------------- /assets/characters/fenyx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/fenyx.png -------------------------------------------------------------------------------- /assets/icons/icon_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/icons/icon_frame.png -------------------------------------------------------------------------------- /fonts/Xolonium-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/fonts/Xolonium-Regular.ttf -------------------------------------------------------------------------------- /assets/art/ui/menu/menu_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/ui/menu/menu_bg.png -------------------------------------------------------------------------------- /assets/backgrounds/hills.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/backgrounds/hills.png -------------------------------------------------------------------------------- /assets/backgrounds/kidnap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/backgrounds/kidnap.png -------------------------------------------------------------------------------- /assets/backgrounds/trees.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/backgrounds/trees.png -------------------------------------------------------------------------------- /assets/characters/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/avatar.png -------------------------------------------------------------------------------- /contumacious_commuter_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/contumacious_commuter_icon.ico -------------------------------------------------------------------------------- /assets/art/fx/filmgrain-1080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/fx/filmgrain-1080.png -------------------------------------------------------------------------------- /assets/art/splash/splash_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/splash/splash_bg.png -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/cards/card1.wav -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/cards/card2.wav -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/cards/card3.wav -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/cards/card4.wav -------------------------------------------------------------------------------- /assets/card_backs/card-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/card_backs/card-back.png -------------------------------------------------------------------------------- /assets/card_backs/godot_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/card_backs/godot_back.png -------------------------------------------------------------------------------- /assets/ui/turn_bar/turn_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/turn_bar/turn_bar.png -------------------------------------------------------------------------------- /assets/art/splash/splash_hills.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/splash/splash_hills.png -------------------------------------------------------------------------------- /assets/audio/sfx/attacks/punch1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/attacks/punch1.wav -------------------------------------------------------------------------------- /assets/audio/sfx/attacks/punch2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/attacks/punch2.wav -------------------------------------------------------------------------------- /assets/card_backs/CGFBackDots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/card_backs/CGFBackDots.png -------------------------------------------------------------------------------- /assets/card_backs/CGFBackLines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/card_backs/CGFBackLines.png -------------------------------------------------------------------------------- /assets/cards/front-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/cards/front-placeholder.png -------------------------------------------------------------------------------- /assets/characters/fenyx-paperbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/fenyx-paperbg.png -------------------------------------------------------------------------------- /assets/characters/icons/bruli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/icons/bruli.png -------------------------------------------------------------------------------- /assets/characters/icons/fenyx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/icons/fenyx.png -------------------------------------------------------------------------------- /assets/ui/life_bar/life_bar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/life_bar/life_bar_bg.png -------------------------------------------------------------------------------- /assets/art/ui/menu/buttons/hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/ui/menu/buttons/hover.png -------------------------------------------------------------------------------- /assets/art/ui/menu/buttons/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/ui/menu/buttons/normal.png -------------------------------------------------------------------------------- /assets/backgrounds/train-interior.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/backgrounds/train-interior.png -------------------------------------------------------------------------------- /assets/characters/proto-character.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/characters/proto-character.png -------------------------------------------------------------------------------- /assets/font/DelaGothicOne-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/font/DelaGothicOne-Regular.ttf -------------------------------------------------------------------------------- /assets/ui/life_bar/life_bar_fill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/life_bar/life_bar_fill.png -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/hud-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/src/battle/ui/battler_hud/hud-bg.png -------------------------------------------------------------------------------- /assets/art/ui/menu/buttons/pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/ui/menu/buttons/pressed.png -------------------------------------------------------------------------------- /assets/audio/sfx/train/train_stop_1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/train/train_stop_1.ogg -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/action_menu/menu_action_bg.png -------------------------------------------------------------------------------- /assets/art/normal_maps/squigglevission.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/art/normal_maps/squigglevission.jpg -------------------------------------------------------------------------------- /assets/icons/contumacious_commuter_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/icons/contumacious_commuter_icon.ico -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/energy_bar/stub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/src/battle/ui/battler_hud/energy_bar/stub.png -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_selection_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/action_menu/menu_selection_arrow.png -------------------------------------------------------------------------------- /assets/audio/sfx/train/train_ambience_loop_1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/audio/sfx/train/train_ambience_loop_1.ogg -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/action_menu/menu_action_bg_disabled.png -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg_focused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/action_menu/menu_action_bg_focused.png -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/assets/ui/action_menu/menu_action_bg_pressed.png -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/energy_bar/stub_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanuys/contumacious/master/src/battle/ui/battler_hud/energy_bar/stub_bg.png -------------------------------------------------------------------------------- /default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | 5 | [resource] 6 | background_mode = 2 7 | background_sky = SubResource( 1 ) 8 | -------------------------------------------------------------------------------- /src/cc/decks/SampleDeck.gd: -------------------------------------------------------------------------------- 1 | extends Reference 2 | 3 | const decks = [ 4 | { 5 | "name": "Sample Deck", 6 | "cards": { 7 | "Knee Knock": 5, 8 | "Elbow Bump": 3, 9 | "Newspaper": 2, 10 | }, 11 | }, 12 | ] 13 | -------------------------------------------------------------------------------- /src/custom/CGFHand.gd: -------------------------------------------------------------------------------- 1 | extends Hand 2 | 3 | 4 | func _ready() -> void: 5 | # warning-ignore:return_value_discarded 6 | $Control/ManipulationButtons/DiscardRandom.connect("pressed",self,'_on_DiscardRandom_Button_pressed') 7 | 8 | -------------------------------------------------------------------------------- /src/cc/DuplicateCustomCGFHand.gd: -------------------------------------------------------------------------------- 1 | extends Hand 2 | 3 | 4 | func _ready() -> void: 5 | # warning-ignore:return_value_discarded 6 | $Control/ManipulationButtons/DiscardRandom.connect("pressed",self,'_on_DiscardRandom_Button_pressed') 7 | 8 | -------------------------------------------------------------------------------- /src/shaders/scroll_bg.shader: -------------------------------------------------------------------------------- 1 | shader_type canvas_item; 2 | uniform float scroll_speed; 3 | void fragment() { 4 | vec2 shifted_uv = UV; 5 | shifted_uv.x += TIME * scroll_speed; 6 | vec4 colour = texture(TEXTURE, shifted_uv); 7 | COLOR = colour; 8 | } -------------------------------------------------------------------------------- /src/battle/ai/AggressiveBattlerAI.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/ai/AggressiveBattlerAI.gd" type="Script" id=1] 4 | 5 | [node name="AggresiveBattlerAI" type="Node2D"] 6 | script = ExtResource( 1 ) 7 | -------------------------------------------------------------------------------- /src/custom/cards/Token.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCardTemplate.tscn" type="PackedScene" id=1] 4 | 5 | [node name="Card" instance=ExtResource( 1 )] 6 | disable_dropping_to_cardcontainers = true 7 | -------------------------------------------------------------------------------- /src/cc/DetailsFont.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 12 7 | use_filter = true 8 | font_data = ExtResource( 1 ) 9 | -------------------------------------------------------------------------------- /src/custom/DetailsFont.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 12 7 | use_filter = true 8 | font_data = ExtResource( 1 ) 9 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBCardObjectFont.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 15 7 | use_filter = true 8 | font_data = ExtResource( 1 ) 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot-specific ignores 2 | .import/ 3 | export.cfg 4 | 5 | # Imported translations (automatically generated from CSV files) 6 | *.translation 7 | 8 | # Mono-specific ignores 9 | .mono/ 10 | data_*/ 11 | 12 | # opyate: custom ignores 13 | bin/ 14 | tmp-cgf/ 15 | -------------------------------------------------------------------------------- /src/battle/ui/damage_labels/UIDamageLabelBuilder.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/damage_labels/UIDamageLabelBuilder.gd" type="Script" id=1] 4 | 5 | [node name="UIDamageLabelBuilder" type="Node2D"] 6 | script = ExtResource( 1 ) 7 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/CBCardListHeadersFont.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | outline_color = Color( 0, 0, 0, 1 ) 7 | use_filter = true 8 | font_data = ExtResource( 1 ) 9 | -------------------------------------------------------------------------------- /src/custom/cards/Red.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCardTemplate.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/custom/cards/RedFront.tscn" type="PackedScene" id=2] 5 | 6 | [node name="Card" instance=ExtResource( 1 )] 7 | card_front_design = ExtResource( 2 ) 8 | -------------------------------------------------------------------------------- /src/custom/cards/Green.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCardTemplate.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/custom/cards/GreenFront.tscn" type="PackedScene" id=2] 5 | 6 | [node name="Card" instance=ExtResource( 1 )] 7 | card_front_design = ExtResource( 2 ) 8 | -------------------------------------------------------------------------------- /assets/ui/theme/cc_font_large.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Theme" load_steps=3 format=2] 2 | 3 | [ext_resource path="res://assets/font/DelaGothicOne-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | size = 80 7 | font_data = ExtResource( 1 ) 8 | 9 | [resource] 10 | default_font = SubResource( 1 ) 11 | -------------------------------------------------------------------------------- /assets/ui/theme/cc_font_medium.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Theme" load_steps=3 format=2] 2 | 3 | [ext_resource path="res://assets/font/DelaGothicOne-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | size = 40 7 | font_data = ExtResource( 1 ) 8 | 9 | [resource] 10 | default_font = SubResource( 1 ) 11 | -------------------------------------------------------------------------------- /src/game/StoryKidnap.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | onready var tween = $Tween 4 | 5 | func _ready(): 6 | tween.interpolate_property($kidnap, "modulate:a", 1.0, 0.0, 2.0, Tween.TRANS_LINEAR, Tween.EASE_IN, 3.0) 7 | tween.start() 8 | yield(tween, "tween_completed") 9 | 10 | get_tree().change_scene("res://src/cc/InheritedCoreMain.tscn") 11 | -------------------------------------------------------------------------------- /assets/ui/theme/combat_ui_theme.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Theme" load_steps=3 format=2] 2 | 3 | [ext_resource path="res://assets/font/DelaGothicOne-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | size = 27 7 | font_data = ExtResource( 1 ) 8 | 9 | [resource] 10 | default_font = SubResource( 1 ) 11 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBDeckSummaries.gd: -------------------------------------------------------------------------------- 1 | class_name DBDeckSummaries 2 | extends HBoxContainer 3 | 4 | # Stores the location of the deck-minimun label 5 | var deck_min_label : Label 6 | 7 | # We use this function instead of _ready() 8 | # In order to make it overridable by customized scenes 9 | func setup() -> void: 10 | deck_min_label = $CardCount 11 | -------------------------------------------------------------------------------- /src/core/Card/CardBackTexture.gd: -------------------------------------------------------------------------------- 1 | # This script should be attached to a card back which is using a simple 2 | # texture as a card back and doesn't have any special animations 3 | class_name CardBackTexture 4 | extends CardBack 5 | 6 | 7 | func _ready() -> void: 8 | # warning-ignore:return_value_discarded 9 | viewed_node = $VBoxContainer/CenterContainer/Viewed 10 | 11 | -------------------------------------------------------------------------------- /src/battle/battlers/antagonist.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/BattlerUIData.gd" type="Script" id=1] 4 | [ext_resource path="res://assets/characters/bruli.png" type="Texture" id=2] 5 | 6 | [resource] 7 | script = ExtResource( 1 ) 8 | display_name = "Brüli" 9 | texture = ExtResource( 2 ) 10 | flip = true 11 | -------------------------------------------------------------------------------- /src/core/DetailPanels.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/core/DetailPanels.gd" type="Script" id=2] 4 | 5 | [node name="DetailPanels" type="VBoxContainer"] 6 | margin_left = 7.0 7 | margin_top = 7.0 8 | margin_right = 257.0 9 | margin_bottom = 21.0 10 | script = ExtResource( 2 ) 11 | __meta__ = { 12 | "_edit_use_anchors_": false 13 | } 14 | -------------------------------------------------------------------------------- /src/battle/battlers/protagonist.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/BattlerUIData.gd" type="Script" id=1] 4 | [ext_resource path="res://assets/characters/fenyx.png" type="Texture" id=2] 5 | 6 | [resource] 7 | script = ExtResource( 1 ) 8 | display_name = "Fenyx" 9 | texture = ExtResource( 2 ) 10 | flip = false 11 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/energy_bar/UIEnergyBar.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/battler_hud/energy_bar/UIEnergyBar.gd" type="Script" id=1] 4 | 5 | [node name="UIEnergyBar" type="HBoxContainer"] 6 | margin_right = 40.0 7 | margin_bottom = 40.0 8 | script = ExtResource( 1 ) 9 | __meta__ = { 10 | "_edit_use_anchors_": false 11 | } 12 | -------------------------------------------------------------------------------- /assets/audio/music/CC3.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="ogg_vorbis" 4 | type="AudioStreamOGGVorbis" 5 | path="res://.import/CC3.ogg-b71e9fd57ecdbea425c92e06dc90b9cd.oggstr" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/music/CC3.ogg" 10 | dest_files=[ "res://.import/CC3.ogg-b71e9fd57ecdbea425c92e06dc90b9cd.oggstr" ] 11 | 12 | [params] 13 | 14 | loop=true 15 | loop_offset=0 16 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/SaveButtonStyle.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StyleBoxFlat" format=2] 2 | 3 | [resource] 4 | content_margin_left = 3.0 5 | content_margin_right = 3.0 6 | content_margin_top = 2.0 7 | content_margin_bottom = 2.0 8 | bg_color = Color( 1, 0.4, 0, 1 ) 9 | corner_radius_top_left = 2 10 | corner_radius_top_right = 2 11 | corner_radius_bottom_right = 2 12 | corner_radius_bottom_left = 2 13 | -------------------------------------------------------------------------------- /src/custom/CGFDiscard.gd: -------------------------------------------------------------------------------- 1 | extends Pile 2 | 3 | 4 | # Declare member variables here. Examples: 5 | # var a = 2 6 | # var b = "text" 7 | 8 | 9 | # Called when the node enters the scene tree for the first time. 10 | func _ready(): 11 | pass # Replace with function body. 12 | 13 | 14 | # Called every frame. 'delta' is the elapsed time since the previous frame. 15 | #func _process(delta): 16 | # pass 17 | -------------------------------------------------------------------------------- /src/battle/ui/BattlerUIData.gd: -------------------------------------------------------------------------------- 1 | # Stores the properties required by UI widgets that represent this battler. 2 | class_name BattlerUIData 3 | extends Resource 4 | 5 | # The battler's name to display, for example, in the HUD or in a menu. 6 | export var display_name := "" 7 | # An icon representing the battler. We'll use it in the turn bar 8 | export var texture: Texture 9 | 10 | export var flip := false 11 | -------------------------------------------------------------------------------- /src/battle/statuseffects/effects/bug.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/statuseffects/StatusEffectData.gd" type="Script" id=1] 4 | 5 | [resource] 6 | script = ExtResource( 1 ) 7 | effect = "bug" 8 | duration_seconds = 20.0 9 | effect_power = 0 10 | effect_rate = 0.0 11 | is_ticking = true 12 | ticking_interval = 4.0 13 | ticking_damage = 3 14 | -------------------------------------------------------------------------------- /src/game/MainMenu.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | func _on_New_Game_pressed(): 4 | # warning-ignore:return_value_discarded 5 | get_tree().change_scene("res://src/game/StoryKidnap.tscn") 6 | 7 | 8 | func _on_LeaveFeedback_pressed(): 9 | # warning-ignore:return_value_discarded 10 | OS.shell_open("https://juanuys.com/games/contumacious#feedback") 11 | 12 | 13 | func _on_Exit_pressed(): 14 | get_tree().quit() 15 | -------------------------------------------------------------------------------- /src/cc/DuplicateCustomCGFDiscard.gd: -------------------------------------------------------------------------------- 1 | extends Pile 2 | 3 | 4 | # Declare member variables here. Examples: 5 | # var a = 2 6 | # var b = "text" 7 | 8 | 9 | # Called when the node enters the scene tree for the first time. 10 | func _ready(): 11 | pass # Replace with function body. 12 | 13 | 14 | # Called every frame. 'delta' is the elapsed time since the previous frame. 15 | #func _process(delta): 16 | # pass 17 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/FilterButtonStyle.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StyleBoxFlat" format=2] 2 | 3 | [resource] 4 | content_margin_left = 3.0 5 | content_margin_right = 3.0 6 | content_margin_top = 2.0 7 | content_margin_bottom = 2.0 8 | bg_color = Color( 0.392157, 0.364706, 0.364706, 1 ) 9 | corner_radius_top_left = 2 10 | corner_radius_top_right = 2 11 | corner_radius_bottom_right = 2 12 | corner_radius_bottom_left = 2 13 | -------------------------------------------------------------------------------- /src/battle/battlers/enemy_stats.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/BattlerStats.gd" type="Script" id=1] 4 | 5 | [resource] 6 | script = ExtResource( 1 ) 7 | max_health = 50.0 8 | max_energy = 6 9 | base_attack = 1.0 10 | base_defense = 0.0 11 | base_speed = 16.0 12 | base_hit_chance = 100.0 13 | base_evasion = 0.0 14 | weaknesses = [ ] 15 | affinity = 3 16 | -------------------------------------------------------------------------------- /src/battle/battlers/player_stats.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/BattlerStats.gd" type="Script" id=1] 4 | 5 | [resource] 6 | script = ExtResource( 1 ) 7 | max_health = 100.0 8 | max_energy = 6 9 | base_attack = 1.0 10 | base_defense = 0.0 11 | base_speed = 20.0 12 | base_hit_chance = 100.0 13 | base_evasion = 0.0 14 | weaknesses = [ ] 15 | affinity = 0 16 | -------------------------------------------------------------------------------- /assets/audio/sfx/train/train_stop_1.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="ogg_vorbis" 4 | type="AudioStreamOGGVorbis" 5 | path="res://.import/train_stop_1.ogg-93b1eb89a4be64ae692451049a2ea313.oggstr" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/train/train_stop_1.ogg" 10 | dest_files=[ "res://.import/train_stop_1.ogg-93b1eb89a4be64ae692451049a2ea313.oggstr" ] 11 | 12 | [params] 13 | 14 | loop=true 15 | loop_offset=0 16 | -------------------------------------------------------------------------------- /src/battle/ui/action_menu/UIActionMenu.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/action_menu/UIActionMenu.gd" type="Script" id=1] 4 | 5 | [node name="UIActionMenu" type="Control"] 6 | margin_left = 290.0 7 | margin_top = 492.0 8 | margin_right = 330.0 9 | margin_bottom = 532.0 10 | script = ExtResource( 1 ) 11 | __meta__ = { 12 | "_edit_use_anchors_": false, 13 | "_editor_description_": "" 14 | } 15 | -------------------------------------------------------------------------------- /src/custom/CGFDeckBuilder.gd: -------------------------------------------------------------------------------- 1 | extends DeckBuilder 2 | 3 | 4 | # Declare member variables here. Examples: 5 | # var a: int = 2 6 | # var b: String = "text" 7 | 8 | 9 | # Called when the node enters the scene tree for the first time. 10 | func _ready() -> void: 11 | pass # Replace with function body. 12 | 13 | 14 | # Called every frame. 'delta' is the elapsed time since the previous frame. 15 | #func _process(delta: float) -> void: 16 | # pass 17 | -------------------------------------------------------------------------------- /src/battle/command/basic_attack.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/battle/command/AttackActionData.gd" type="Script" id=1] 4 | 5 | [resource] 6 | script = ExtResource( 1 ) 7 | label = "Basic attack" 8 | energy_cost = 1 9 | damage = 5.0 10 | element = 0 11 | is_targeting_self = false 12 | is_targeting_all = false 13 | readiness_saved = 20.0 14 | damage_multiplier = 1.0 15 | hit_chance = 100.0 16 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/CardLabel.gd: -------------------------------------------------------------------------------- 1 | class_name CardLabel 2 | extends Label 3 | 4 | onready var preview_popup := $PreviewPopup 5 | 6 | func _ready() -> void: 7 | text = "Test Card 1" # debug 8 | 9 | func setup(card_name) -> void: 10 | text = card_name 11 | 12 | 13 | func _on_CardLabel_mouse_entered() -> void: 14 | preview_popup.show_preview_card(text) 15 | 16 | 17 | func _on_CardLabel_mouse_exited() -> void: 18 | preview_popup.hide_preview_card() 19 | -------------------------------------------------------------------------------- /src/custom/CGFDeckBuilder.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/core/DeckBuilder/DeckBuilder.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/custom/CGFInfoPanel.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/custom/CGFDeckBuilder.gd" type="Script" id=3] 6 | 7 | [node name="DeckBuilder" instance=ExtResource( 1 )] 8 | script = ExtResource( 3 ) 9 | info_panel_scene = ExtResource( 2 ) 10 | -------------------------------------------------------------------------------- /src/custom/cards/Blue.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCardTemplate.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/custom/PlayingCardBack.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/custom/cards/BlueFront.tscn" type="PackedScene" id=3] 6 | 7 | [node name="Card" instance=ExtResource( 1 )] 8 | card_back_design = ExtResource( 2 ) 9 | card_front_design = ExtResource( 3 ) 10 | -------------------------------------------------------------------------------- /assets/audio/sfx/train/train_ambience_loop_1.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="ogg_vorbis" 4 | type="AudioStreamOGGVorbis" 5 | path="res://.import/train_ambience_loop_1.ogg-f318aa02691fa5135c945a5121aba45b.oggstr" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/train/train_ambience_loop_1.ogg" 10 | dest_files=[ "res://.import/train_ambience_loop_1.ogg-f318aa02691fa5135c945a5121aba45b.oggstr" ] 11 | 12 | [params] 13 | 14 | loop=true 15 | loop_offset=0 16 | -------------------------------------------------------------------------------- /src/custom/cards/RedFront.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCardFront.tscn" type="PackedScene" id=1] 4 | 5 | [sub_resource type="StyleBoxFlat" id=1] 6 | bg_color = Color( 0.317647, 0, 0, 1 ) 7 | corner_radius_top_left = 10 8 | corner_radius_top_right = 10 9 | corner_radius_bottom_right = 10 10 | corner_radius_bottom_left = 10 11 | 12 | [node name="RedFront" instance=ExtResource( 1 )] 13 | custom_styles/panel = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /src/custom/CGFCardManipulationButton.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | font_data = ExtResource( 1 ) 7 | 8 | [node name="ManipulationButton" type="Button"] 9 | margin_right = 29.0 10 | margin_bottom = 26.0 11 | mouse_filter = 1 12 | custom_fonts/font = SubResource( 1 ) 13 | text = "T" 14 | __meta__ = { 15 | "_edit_use_anchors_": false 16 | } 17 | -------------------------------------------------------------------------------- /src/custom/cards/BlueFront.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCardFront.tscn" type="PackedScene" id=1] 4 | 5 | [sub_resource type="StyleBoxFlat" id=1] 6 | bg_color = Color( 0, 0.0313726, 0.486275, 1 ) 7 | corner_radius_top_left = 10 8 | corner_radius_top_right = 10 9 | corner_radius_bottom_right = 10 10 | corner_radius_bottom_left = 10 11 | 12 | [node name="BlueFront" instance=ExtResource( 1 )] 13 | custom_styles/panel = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /src/cc/DuplicateCustomCGFCardManipulationButton.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | font_data = ExtResource( 1 ) 7 | 8 | [node name="ManipulationButton" type="Button"] 9 | margin_right = 29.0 10 | margin_bottom = 26.0 11 | mouse_filter = 1 12 | custom_fonts/font = SubResource( 1 ) 13 | text = "T" 14 | __meta__ = { 15 | "_edit_use_anchors_": false 16 | } 17 | -------------------------------------------------------------------------------- /src/game/Splash.gd: -------------------------------------------------------------------------------- 1 | # Arena script only concerns itself with the "look" of the scene: 2 | # - which sprites to load 3 | # - sprite position, orientation 4 | 5 | extends Node2D 6 | 7 | onready var hills = $Hills 8 | onready var trees = $Trees 9 | 10 | export(float) var hills_scroll_speed = 0.01 11 | export(float) var trees_scroll_speed = 0.07 12 | 13 | func _ready(): 14 | hills.material.set_shader_param("scroll_speed", hills_scroll_speed) 15 | trees.material.set_shader_param("scroll_speed", trees_scroll_speed) 16 | -------------------------------------------------------------------------------- /src/Game.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const game_mode := "card" 4 | 5 | func _ready(): 6 | var fade_in = Tween.new() 7 | add_child(fade_in) 8 | var music = AudioStreamPlayer.new() 9 | add_child(music) 10 | var stream = load("res://assets/audio/music/CC3.ogg") 11 | music.set_stream(stream) 12 | music.pitch_scale = 1 13 | fade_in.interpolate_property(music, "volume_db", -80, -10, 2.0, Tween.TRANS_LINEAR, Tween.EASE_IN, 0) 14 | fade_in.start() 15 | yield(get_tree().create_timer(0.1), "timeout") 16 | music.play() 17 | -------------------------------------------------------------------------------- /src/custom/CGFMain.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/core/Main.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/custom/CGFBoard.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/custom/CGFInfoPanel.tscn" type="PackedScene" id=3] 6 | 7 | [node name="Main" instance=ExtResource( 1 )] 8 | board_scene = ExtResource( 2 ) 9 | info_panel_scene = ExtResource( 3 ) 10 | 11 | [node name="FocusInfo" parent="VBC" index="1"] 12 | custom_constants/separation = -1 13 | -------------------------------------------------------------------------------- /src/battle/Arena.gd: -------------------------------------------------------------------------------- 1 | # Arena script only concerns itself with the "look" of the scene: 2 | # - which sprites to load 3 | # - sprite position, orientation 4 | 5 | extends Node2D 6 | 7 | onready var hills = $Train/Hills 8 | onready var trees = $Train/Trees 9 | 10 | export(float) var hills_scroll_speed = 0.01 11 | export(float) var trees_scroll_speed = 0.07 12 | 13 | func _ready(): 14 | hills.material.set_shader_param("scroll_speed", hills_scroll_speed) 15 | trees.material.set_shader_param("scroll_speed", trees_scroll_speed) 16 | -------------------------------------------------------------------------------- /src/battle/ai/AggressiveBattlerAI.gd: -------------------------------------------------------------------------------- 1 | class_name AggressiveBattlerAI 2 | extends BattlerAI 3 | 4 | 5 | func _choose_action(info: Dictionary) -> ActionData: 6 | # aggressive AI always pick the strongest action. 7 | print("AggressiveBattlerAI.choose ", info) 8 | return info.strongest_action 9 | 10 | 11 | func _choose_targets(_action: ActionData, info: Dictionary) -> Array: 12 | # arrays of targets to support targeting multiple targets. 13 | # aggresive AI always picks on the weakest targets 14 | return [info.weakest_target] 15 | -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card1.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/card1.wav-3ebb87e40c7516f2557d837ce2c6b083.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/cards/card1.wav" 10 | dest_files=[ "res://.import/card1.wav-3ebb87e40c7516f2557d837ce2c6b083.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card2.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/card2.wav-b8443a233c83c57fc255125e2b1ad185.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/cards/card2.wav" 10 | dest_files=[ "res://.import/card2.wav-b8443a233c83c57fc255125e2b1ad185.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card3.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/card3.wav-5b6a1afa4fbbbb97a1b72523433d6ab3.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/cards/card3.wav" 10 | dest_files=[ "res://.import/card3.wav-5b6a1afa4fbbbb97a1b72523433d6ab3.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /assets/audio/sfx/cards/card4.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/card4.wav-5d232886d3e6f975c71fce1ed9d31bb0.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/cards/card4.wav" 10 | dest_files=[ "res://.import/card4.wav-5d232886d3e6f975c71fce1ed9d31bb0.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /src/battle/ui/action_menu/UIActionList.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/action_menu/UIActionList.gd" type="Script" id=1] 4 | [ext_resource path="res://src/battle/ui/action_menu/UIMenuSelectArrow.tscn" type="PackedScene" id=2] 5 | 6 | [node name="UIActionList" type="VBoxContainer"] 7 | margin_right = 40.0 8 | margin_bottom = 40.0 9 | script = ExtResource( 1 ) 10 | __meta__ = { 11 | "_edit_use_anchors_": false 12 | } 13 | 14 | [node name="UIMenuSelectArrow" parent="." instance=ExtResource( 2 )] 15 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBPreviewPopup.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/core/DeckBuilder/DBPreviewPopup.gd" type="Script" id=1] 4 | [ext_resource path="res://src/core/DetailPanels.gd" type="Script" id=2] 5 | 6 | [node name="PreviewPopup" type="Popup"] 7 | margin_right = 40.0 8 | margin_bottom = 40.0 9 | script = ExtResource( 1 ) 10 | 11 | [node name="FocusInfo" type="VBoxContainer" parent="."] 12 | margin_right = 40.0 13 | margin_bottom = 40.0 14 | custom_constants/separation = -1 15 | script = ExtResource( 2 ) 16 | -------------------------------------------------------------------------------- /assets/audio/sfx/attacks/punch1.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/punch1.wav-5c57edcfd5b20ded4c6d59b7778a795b.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/attacks/punch1.wav" 10 | dest_files=[ "res://.import/punch1.wav-5c57edcfd5b20ded4c6d59b7778a795b.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /assets/audio/sfx/attacks/punch2.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/punch2.wav-16342f9e0b258c9b692cf22d214f5cf3.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/audio/sfx/attacks/punch2.wav" 10 | dest_files=[ "res://.import/punch2.wav-16342f9e0b258c9b692cf22d214f5cf3.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/CategoryContainer.gd: -------------------------------------------------------------------------------- 1 | extends VBoxContainer 2 | 3 | func _process(_delta: float) -> void: 4 | # We count how many cards of this type we have 5 | # and adjust the number in the label 6 | # If there are ever no more cards in this category 7 | # we deinstance it. 8 | var category_card_count = 0 9 | for deck_card_object in $CategoryCards.get_children(): 10 | category_card_count += deck_card_object.quantity 11 | if category_card_count == 0: 12 | queue_free() 13 | else: 14 | $CategoryLabel.text = name + ' (' + str(category_card_count) + ')' 15 | -------------------------------------------------------------------------------- /src/battle/statuseffects/impl/StatusEffectBug.gd: -------------------------------------------------------------------------------- 1 | # e.g. poison 2 | class_name StatusEffectBug 3 | extends StatusEffect 4 | 5 | var damage := 3 6 | 7 | 8 | # The parent class's constructor takes care of initializing ticking-related properties. 9 | func _init(target, data).(target, data) -> void: 10 | id = "bug" 11 | damage = data.ticking_damage 12 | # We set `_can_stack` to `true` so this effect can stack up to N times. 13 | _can_stack = true 14 | 15 | 16 | # On every tick, we deal damage to the target battler. 17 | func _apply() -> void: 18 | _target.take_hit(Hit.new(damage)) 19 | -------------------------------------------------------------------------------- /src/custom/CGFCounters.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCounters.gd" type="Script" id=1] 4 | [ext_resource path="res://src/custom/CGFCounter.tscn" type="PackedScene" id=2] 5 | 6 | [node name="Counters" type="PanelContainer"] 7 | margin_right = 14.0 8 | margin_bottom = 14.0 9 | script = ExtResource( 1 ) 10 | __meta__ = { 11 | "_edit_use_anchors_": false 12 | } 13 | counter_scene = ExtResource( 2 ) 14 | 15 | [node name="VBC" type="VBoxContainer" parent="."] 16 | margin_left = 7.0 17 | margin_top = 7.0 18 | margin_right = 7.0 19 | margin_bottom = 7.0 20 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBFilterButton.gd: -------------------------------------------------------------------------------- 1 | class_name DBFilterButton 2 | extends Button 3 | 4 | # warning-ignore:unused_signal 5 | signal filter_toggled() 6 | 7 | var property : String 8 | var value: String 9 | 10 | func setup(_property: String, _value: String) -> void: 11 | property = _property 12 | value = _value 13 | text = _value 14 | name = _value 15 | 16 | func _ready() -> void: 17 | pass 18 | # warning-ignore:return_value_discarded 19 | # connect("pressed", self, "_on_pressed") 20 | 21 | #func _on_toggle(button_pressed) -> void: 22 | # emit_signal("filter_toggled", filter, button_pressed) 23 | # 24 | -------------------------------------------------------------------------------- /src/custom/CGFInfoPanel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/custom/DetailsFont.tres" type="DynamicFont" id=1] 4 | 5 | [node name="InfoPanel" type="PanelContainer"] 6 | margin_right = 264.0 7 | margin_bottom = 28.0 8 | mouse_filter = 2 9 | __meta__ = { 10 | "_edit_use_anchors_": false 11 | } 12 | 13 | [node name="Details" type="Label" parent="."] 14 | margin_left = 7.0 15 | margin_top = 7.0 16 | margin_right = 257.0 17 | margin_bottom = 21.0 18 | rect_min_size = Vector2( 250, 13 ) 19 | custom_fonts/font = ExtResource( 1 ) 20 | text = "Illustration by: " 21 | autowrap = true 22 | -------------------------------------------------------------------------------- /src/cc/DuplicateCustomCGFInfoPanel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://src/cc/DetailsFont.tres" type="DynamicFont" id=1] 4 | 5 | [node name="InfoPanel" type="PanelContainer"] 6 | margin_right = 264.0 7 | margin_bottom = 28.0 8 | mouse_filter = 2 9 | __meta__ = { 10 | "_edit_use_anchors_": false 11 | } 12 | 13 | [node name="Details" type="Label" parent="."] 14 | margin_left = 7.0 15 | margin_top = 7.0 16 | margin_right = 257.0 17 | margin_bottom = 21.0 18 | rect_min_size = Vector2( 250, 13 ) 19 | custom_fonts/font = ExtResource( 1 ) 20 | text = "Illustration by: " 21 | autowrap = true 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | Contumacious Commuter is a commuter-themed real-time card game inspired by Slay The Spire, and my daily commute. 4 | 5 | ![screenshot](assets/screenshots/contumacious-commuter-demo.gif) 6 | 7 | # Design Documents 8 | 9 | Design documents and throw-away prototypes and experiments live in a [separate repo](https://github.com/juanuys/ccgdd). 10 | 11 | # Acknowledgements 12 | 13 | Built on [godot-card-game-framework](https://github.com/db0/godot-card-game-framework). 14 | 15 | # Build 16 | 17 | ``` 18 | mkdir tmp 19 | godot --export HTML5 tmp/index.html 20 | cd tmp 21 | python3 -m http.server 22 | ``` 23 | -------------------------------------------------------------------------------- /src/battle/UI.gd: -------------------------------------------------------------------------------- 1 | extends CanvasLayer 2 | 3 | # We preload the `UICombatResultPanel` scene. 4 | const UICombatResultPanel: PackedScene = preload("ui/UICombatResultPanel.tscn") 5 | 6 | const UIAlertPanel: PackedScene = preload("ui/UIAlertPanel.tscn") 7 | 8 | # And when the combat ends, we create an instance of it. 9 | func _on_Combat_combat_ended(message) -> void: 10 | var widget: Control = UICombatResultPanel.instance() 11 | widget.text = message 12 | add_child(widget) 13 | 14 | func _on_ActiveTurnQueue_player_turn_started(message) -> void: 15 | var widget: Control = UIAlertPanel.instance() 16 | widget.text = message 17 | add_child(widget) 18 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/QuantityNumberButton.gd: -------------------------------------------------------------------------------- 1 | # A button with a special signal, which uses the button name 2 | # as the value sent. 3 | class_name QuantityNumberButton 4 | extends Button 5 | 6 | # Send when this button is pressed. It also sents the quantity 7 | signal quantity_set(value) 8 | 9 | # The amount of a singly card, this button marks as being in the deck 10 | var quantity_number: int 11 | 12 | func _ready() -> void: 13 | quantity_number = int(name) 14 | # warning-ignore:return_value_discarded 15 | connect("pressed",self,"_on_button_pressed") 16 | 17 | 18 | func _on_button_pressed() -> void: 19 | emit_signal("quantity_set",quantity_number) 20 | -------------------------------------------------------------------------------- /src/battle/ui/damage_labels/UIDamageLabel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://assets/ui/theme/combat_ui_theme.tres" type="Theme" id=1] 4 | [ext_resource path="res://src/battle/ui/damage_labels/UIDamageLabel.gd" type="Script" id=2] 5 | 6 | [node name="UIDamageLabel" type="Position2D"] 7 | script = ExtResource( 2 ) 8 | 9 | [node name="Label" type="Label" parent="."] 10 | margin_left = -38.1407 11 | margin_top = -49.7948 12 | margin_right = 38.8593 13 | margin_bottom = -9.79477 14 | theme = ExtResource( 1 ) 15 | text = "999" 16 | __meta__ = { 17 | "_edit_use_anchors_": false 18 | } 19 | 20 | [node name="Tween" type="Tween" parent="."] 21 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBFilterButton.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/core/DeckBuilder/DBFilterButton.gd" type="Script" id=1] 4 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=2] 5 | 6 | [sub_resource type="DynamicFont" id=1] 7 | use_filter = true 8 | font_data = ExtResource( 2 ) 9 | 10 | [node name="DBFilterButton" type="Button"] 11 | margin_left = 308.0 12 | margin_right = 320.0 13 | margin_bottom = 20.0 14 | custom_fonts/font = SubResource( 1 ) 15 | toggle_mode = true 16 | pressed = true 17 | text = "Filter" 18 | script = ExtResource( 1 ) 19 | __meta__ = { 20 | "_edit_use_anchors_": false 21 | } 22 | -------------------------------------------------------------------------------- /src/cc/cards/SFX.gd: -------------------------------------------------------------------------------- 1 | extends AudioStreamPlayer 2 | 3 | var assets = [] 4 | func _ready(): 5 | var path = "res://assets/audio/sfx/cards" 6 | var dir = Directory.new() 7 | dir.open(path) 8 | dir.list_dir_begin() 9 | while true: 10 | var file_name = dir.get_next() 11 | if file_name == "": 12 | #break the while loop when get_next() returns "" 13 | break 14 | elif !file_name.begins_with(".") and !file_name.ends_with(".import"): 15 | assets.append(load(path + "/" + file_name)) 16 | dir.list_dir_end() 17 | 18 | func play_sound(): 19 | if not assets.empty(): 20 | var asset = assets[randi() % assets.size()] 21 | self.stream.audio_stream = asset 22 | self.play() 23 | -------------------------------------------------------------------------------- /src/battle/anim/SFX.gd: -------------------------------------------------------------------------------- 1 | extends AudioStreamPlayer 2 | 3 | var assets = [] 4 | func _ready(): 5 | var path = "res://assets/audio/sfx/attacks" 6 | var dir = Directory.new() 7 | dir.open(path) 8 | dir.list_dir_begin() 9 | while true: 10 | var file_name = dir.get_next() 11 | if file_name == "": 12 | #break the while loop when get_next() returns "" 13 | break 14 | elif !file_name.begins_with(".") and !file_name.ends_with(".import"): 15 | assets.append(load(path + "/" + file_name)) 16 | dir.list_dir_end() 17 | 18 | func play_sound(): 19 | if not assets.empty(): 20 | var asset = assets[randi() % assets.size()] 21 | self.stream.audio_stream = asset 22 | self.play() 23 | -------------------------------------------------------------------------------- /src/battle/command/Types.gd: -------------------------------------------------------------------------------- 1 | # Using `class_name` allows us to access the constants from any other file. 2 | class_name Types 3 | extends Reference 4 | 5 | # This is the same enum we wrote in the ActionData classes. 6 | enum Elements { NONE, ROCK, PAPER, SCISSORS, BUG } 7 | 8 | # Mapping between an element and the element against which it's strong. 9 | const WEAKNESS_MAPPING = { 10 | # A value of -1 makes the element strong or weak against nothing. 11 | Elements.NONE: -1, 12 | # For example, the line below means that scissors is strong against paper. 13 | Elements.SCISSORS: Elements.PAPER, 14 | Elements.PAPER: Elements.ROCK, 15 | Elements.ROCK: Elements.SCISSORS, 16 | Elements.BUG: -1, 17 | } 18 | -------------------------------------------------------------------------------- /src/custom/CGFModifiedLabelGrid.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/core/BoardPlacementSlot.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/core/BoardPlacementGrid.tscn" type="PackedScene" id=2] 5 | 6 | [node name="ModifiedLabelGrid" instance=ExtResource( 2 )] 7 | 8 | [node name="GridContainer" parent="." index="0"] 9 | margin_right = 247.0 10 | 11 | [node name="BoardPlacementSlot2" parent="GridContainer" index="1" instance=ExtResource( 1 )] 12 | margin_left = 125.0 13 | margin_right = 245.0 14 | 15 | [node name="Control" parent="." index="1"] 16 | margin_right = 247.0 17 | 18 | [node name="Label" parent="Control" index="0"] 19 | text = "This Grid has a modified label" 20 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBDeckSummaries.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1] 4 | [ext_resource path="res://src/core/DeckBuilder/DBDeckSummaries.gd" type="Script" id=2] 5 | 6 | [sub_resource type="DynamicFont" id=1] 7 | size = 15 8 | use_filter = true 9 | font_data = ExtResource( 1 ) 10 | 11 | [node name="Summaries" type="HBoxContainer"] 12 | margin_right = 633.0 13 | margin_bottom = 18.0 14 | script = ExtResource( 2 ) 15 | __meta__ = { 16 | "_edit_use_anchors_": false 17 | } 18 | 19 | [node name="CardCount" type="Label" parent="."] 20 | margin_right = 124.0 21 | margin_bottom = 18.0 22 | custom_fonts/font = SubResource( 1 ) 23 | text = "0 Cards (min 52)" 24 | -------------------------------------------------------------------------------- /src/custom/CGFDeck.gd: -------------------------------------------------------------------------------- 1 | # Code for a sample deck, you're expected to provide your own ;) 2 | extends Pile 3 | 4 | signal draw_card(deck) 5 | # Called when the node enters the scene tree for the first time. 6 | func _ready() -> void: 7 | if not cfc.are_all_nodes_mapped: 8 | yield(cfc, "all_nodes_mapped") 9 | # warning-ignore:return_value_discarded 10 | $Control.connect("gui_input", self, "_on_Deck_input_event") 11 | # warning-ignore:return_value_discarded 12 | connect("draw_card", cfc.NMAP.hand, "draw_card") 13 | #print(get_signal_connection_list("input_event")[0]['target'].name) 14 | 15 | func _on_Deck_input_event(event) -> void: 16 | if event.is_pressed()\ 17 | and not cfc.game_paused\ 18 | and event.get_button_index() == 1: 19 | emit_signal("draw_card", self) 20 | -------------------------------------------------------------------------------- /src/Events.gd: -------------------------------------------------------------------------------- 1 | # warning-ignore-all:unused_signal 2 | 3 | # Event bus for distant nodes to communicate using signals. 4 | # This is intended for cases where connecting the nodes directly creates more coupling 5 | # or substantially increases code complexity. 6 | extends Node 7 | 8 | # Emitted when the player hovers a card or action button, to preview the corresponding action's energy cost. 9 | # We will use the display name to identify the HUD that corresponds to a given battler. 10 | signal combat_action_hovered(display_name, energy_cost) 11 | 12 | # Emitted during a player's turn, when they chose an action and validated their target. 13 | signal player_target_selection_done 14 | 15 | # Emitted from CustomScripts and yielded on in ActiveTurnQueue 16 | signal action_selected(action_data) 17 | -------------------------------------------------------------------------------- /icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://icon.png" 13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/action_menu/UIMenuSelectArrow.gd: -------------------------------------------------------------------------------- 1 | # Arrow to select actions in a [UIActionList]. 2 | extends Position2D 3 | 4 | onready var _tween: Tween = $Tween 5 | 6 | 7 | # The arrow needs to move indepedently from its parent. 8 | func _init() -> void: 9 | set_as_toplevel(true) 10 | 11 | 12 | # The UIActionList can use this function to move the arrow. 13 | func move_to(target: Vector2) -> void: 14 | # If it's already moving, we stop and re-create the tween. 15 | if _tween.is_active(): 16 | _tween.stop(self, "position") 17 | 18 | # To move the arrow, we tween its position, which is global, for 0.1 seconds. 19 | # This short duration makes the menu feel responsive. 20 | _tween.interpolate_property( 21 | self, "position", position, target, 0.1, Tween.TRANS_CUBIC, Tween.EASE_OUT 22 | ) 23 | _tween.start() 24 | -------------------------------------------------------------------------------- /assets/icons/view.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/view.svg-b2db9bcb5ef2f1d25945e28acd1c0e4b.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/icons/view.svg" 13 | dest_files=[ "res://.import/view.svg-b2db9bcb5ef2f1d25945e28acd1c0e4b.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/red.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/red.svg-4b7f564f2a02e7407695b27e20b4f3a9.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/red.svg" 13 | dest_files=[ "res://.import/red.svg-4b7f564f2a02e7407695b27e20b4f3a9.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/Battler.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://src/battle/Battler.gd" type="Script" id=1] 4 | [ext_resource path="res://src/battle/anim/BattlerAnim.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/battle/battlers/player_stats.tres" type="Resource" id=3] 6 | [ext_resource path="res://src/battle/statuseffects/StatusEffectContainer.gd" type="Script" id=4] 7 | 8 | [node name="Battler" type="Node2D"] 9 | z_index = 49 10 | script = ExtResource( 1 ) 11 | stats = ExtResource( 3 ) 12 | 13 | [node name="BattlerAnim" parent="." instance=ExtResource( 2 )] 14 | 15 | [node name="StatusEffectContainer" type="Node" parent="."] 16 | script = ExtResource( 4 ) 17 | 18 | [connection signal="animation_finished" from="BattlerAnim" to="." method="_on_BattlerAnim_animation_finished"] 19 | -------------------------------------------------------------------------------- /assets/characters/npc.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/npc.png-6f9d69da0d3c2406d39b7add7f33cdce.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/npc.png" 13 | dest_files=[ "res://.import/npc.png-6f9d69da0d3c2406d39b7add7f33cdce.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/black.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/black.svg-a3bcf6dc8b634e52482acc1a0b6c70c5.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/black.svg" 13 | dest_files=[ "res://.import/black.svg-a3bcf6dc8b634e52482acc1a0b6c70c5.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/blue.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/blue.svg-2002d6f67720e8b00526db92e2e3abd9.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/blue.svg" 13 | dest_files=[ "res://.import/blue.svg-2002d6f67720e8b00526db92e2e3abd9.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/green.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/green.svg-8d5703ef1262efac1511d7f865110910.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/green.svg" 13 | dest_files=[ "res://.import/green.svg-8d5703ef1262efac1511d7f865110910.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/grey.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/grey.svg-f2f8fcf0dae8a141b6ec00a44938ef39.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/grey.svg" 13 | dest_files=[ "res://.import/grey.svg-f2f8fcf0dae8a141b6ec00a44938ef39.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/orange.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/orange.svg-d029f71372c1102fa63c0bd383e706b4.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/orange.svg" 13 | dest_files=[ "res://.import/orange.svg-d029f71372c1102fa63c0bd383e706b4.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/purple.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/purple.svg-10ccaa0b031868ad0b28444aa8cbb92d.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/purple.svg" 13 | dest_files=[ "res://.import/purple.svg-10ccaa0b031868ad0b28444aa8cbb92d.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/tokens/yellow.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/yellow.svg-97ae07eff1332cbd758ed2269eb4a1d6.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/tokens/yellow.svg" 13 | dest_files=[ "res://.import/yellow.svg-97ae07eff1332cbd758ed2269eb4a1d6.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/custom/CGFHand.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://src/core/Hand.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=2] 5 | [ext_resource path="res://src/custom/CGFHand.gd" type="Script" id=3] 6 | 7 | [sub_resource type="DynamicFont" id=1] 8 | font_data = ExtResource( 2 ) 9 | 10 | [node name="Hand" instance=ExtResource( 1 )] 11 | script = ExtResource( 3 ) 12 | placement = 7 13 | excess_discard_pile_name = "discard" 14 | excess_cards = 2 15 | 16 | [node name="DiscardRandom" type="Button" parent="Control/ManipulationButtons" index="2" groups=[ 17 | "manipulation_button", 18 | ]] 19 | margin_left = 28.0 20 | margin_right = 52.0 21 | margin_bottom = 26.0 22 | mouse_filter = 1 23 | custom_fonts/font = SubResource( 1 ) 24 | text = "R" 25 | -------------------------------------------------------------------------------- /assets/backgrounds/hills.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/hills.png-9e8a68b5d948be00b7e490843ae82144.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/backgrounds/hills.png" 13 | dest_files=[ "res://.import/hills.png-9e8a68b5d948be00b7e490843ae82144.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/backgrounds/trees.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/trees.png-3a455c3e253d2931740b6989365bec6d.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/backgrounds/trees.png" 13 | dest_files=[ "res://.import/trees.png-3a455c3e253d2931740b6989365bec6d.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/characters/bruli.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/bruli.png-01559a0bc0ce038c7a417f8b0a4d6258.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/bruli.png" 13 | dest_files=[ "res://.import/bruli.png-01559a0bc0ce038c7a417f8b0a4d6258.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/characters/fenyx.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/fenyx.png-adf98b2eb8dbbff85e9e1679b86f3967.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/fenyx.png" 13 | dest_files=[ "res://.import/fenyx.png-adf98b2eb8dbbff85e9e1679b86f3967.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/UIBattlerHUDList.gd: -------------------------------------------------------------------------------- 1 | # Displays a list of UIBattlerHUDs, one for each battler. 2 | extends Node2D 3 | 4 | const UIBattlerHUD: PackedScene = preload("UIBattlerHUD.tscn") 5 | 6 | onready var _anim_player: AnimationPlayer = $AnimationPlayer 7 | 8 | 9 | # Creates a battler HUD for each battler. 10 | func setup(battlers: Array) -> void: 11 | for battler in battlers: 12 | var battler_hud: UIBattlerHUD = UIBattlerHUD.instance() 13 | add_child(battler_hud) 14 | battler_hud.setup(battler) 15 | battler_hud.global_position = battler.battler_anim.get_top_anchor_global_position() 16 | 17 | 18 | # The two functions below respectively play the fade in and fade out animations. 19 | func fade_in() -> void: 20 | _anim_player.play("fade_in") 21 | 22 | 23 | func fade_out() -> void: 24 | _anim_player.play("fade_out") 25 | -------------------------------------------------------------------------------- /assets/art/fx/vignette.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/vignette.png-5e8169229a4981a6dc083481aeba8818.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/fx/vignette.png" 13 | dest_files=[ "res://.import/vignette.png-5e8169229a4981a6dc083481aeba8818.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/backgrounds/kidnap.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/kidnap.png-07adf613e84eaa9958f3939778627d9d.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/backgrounds/kidnap.png" 13 | dest_files=[ "res://.import/kidnap.png-07adf613e84eaa9958f3939778627d9d.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/cards/Newspaper.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/Newspaper.png-4954bbc20124bdc2101e12fb0184dd87.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/cards/Newspaper.png" 13 | dest_files=[ "res://.import/Newspaper.png-4954bbc20124bdc2101e12fb0184dd87.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/characters/avatar.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/avatar.png-14275a7315ec89e33651966e48fdc9dd.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/avatar.png" 13 | dest_files=[ "res://.import/avatar.png-14275a7315ec89e33651966e48fdc9dd.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/UICombatResultPanel.gd: -------------------------------------------------------------------------------- 1 | # The tool mode allows us to update the label's text without directly accessing the node. 2 | tool 3 | class_name UICombatResultPanel 4 | extends Panel 5 | 6 | # We expose a text property to encapsulate the label in the scene. 7 | export var text := "" setget set_text 8 | 9 | onready var _label: Label = $Label 10 | onready var _anim_player: AnimationPlayer = $AnimationPlayer 11 | 12 | 13 | func set_text(value: String) -> void: 14 | text = value 15 | # As usual, we have to wait for the node to be ready before we update the label. 16 | if not is_inside_tree(): 17 | yield(self, "ready") 18 | _label.text = text 19 | 20 | 21 | # And here are our fade animations. 22 | func fade_in() -> void: 23 | _anim_player.play("fade_in") 24 | 25 | 26 | func fade_out() -> void: 27 | _anim_player.play("fade_out") 28 | -------------------------------------------------------------------------------- /assets/art/fx/filmgrain.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/filmgrain.png-97699d8396f8fd96a67499b78ed48280.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/fx/filmgrain.png" 13 | dest_files=[ "res://.import/filmgrain.png-97699d8396f8fd96a67499b78ed48280.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/art/ui/menu/menu_bg.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/menu_bg.png-46ee5a87d332be7c3012f2851ccbae81.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/ui/menu/menu_bg.png" 13 | dest_files=[ "res://.import/menu_bg.png-46ee5a87d332be7c3012f2851ccbae81.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/cards/Elbow Bump.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/Elbow Bump.png-d8fc9bcd3db181f69df77c257949ce59.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/cards/Elbow Bump.png" 13 | dest_files=[ "res://.import/Elbow Bump.png-d8fc9bcd3db181f69df77c257949ce59.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/cards/Knee Knock.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/Knee Knock.png-5a8ad8e7717e846c314a8e16cc20457c.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/cards/Knee Knock.png" 13 | dest_files=[ "res://.import/Knee Knock.png-5a8ad8e7717e846c314a8e16cc20457c.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/characters/icons/bruli.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/bruli.png-24d4a023fb9bb8c0d8308880066734a6.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/icons/bruli.png" 13 | dest_files=[ "res://.import/bruli.png-24d4a023fb9bb8c0d8308880066734a6.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/characters/icons/fenyx.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/fenyx.png-3ee07a11182a0ea275d3bf23b1e2497b.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/icons/fenyx.png" 13 | dest_files=[ "res://.import/fenyx.png-3ee07a11182a0ea275d3bf23b1e2497b.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/icons/icon_frame.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon_frame.png-0c8d8f5be4654075e6ee4d9a99f427c0.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/icons/icon_frame.png" 13 | dest_files=[ "res://.import/icon_frame.png-0c8d8f5be4654075e6ee4d9a99f427c0.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/art/splash/splash_bg.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/splash_bg.png-8e1185d9ea6c2724ab3523d650b6fed9.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/splash/splash_bg.png" 13 | dest_files=[ "res://.import/splash_bg.png-8e1185d9ea6c2724ab3523d650b6fed9.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/card_backs/card-back.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/card-back.png-a52ab740e3db2a940c4c2d110bbab7a8.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/card_backs/card-back.png" 13 | dest_files=[ "res://.import/card-back.png-a52ab740e3db2a940c4c2d110bbab7a8.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/ui/turn_bar/turn_bar.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/turn_bar.png-4ca487ee967b754c798f21fd3ce1489e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/turn_bar/turn_bar.png" 13 | dest_files=[ "res://.import/turn_bar.png-4ca487ee967b754c798f21fd3ce1489e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/art/ui/menu/buttons/hover.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/hover.png-5c800670b426effce027fb11d901b0ef.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/ui/menu/buttons/hover.png" 13 | dest_files=[ "res://.import/hover.png-5c800670b426effce027fb11d901b0ef.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/art/ui/menu/buttons/normal.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/normal.png-562a63ad541824755b3a2bc5767f560e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/ui/menu/buttons/normal.png" 13 | dest_files=[ "res://.import/normal.png-562a63ad541824755b3a2bc5767f560e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/card_backs/godot_back.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/godot_back.png-d96d2d6fc38eec92e0541f54797d7292.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/card_backs/godot_back.png" 13 | dest_files=[ "res://.import/godot_back.png-d96d2d6fc38eec92e0541f54797d7292.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/hud-bg.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/hud-bg.png-1ce97759cf830c1ca9be279e25660a7d.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://src/battle/ui/battler_hud/hud-bg.png" 13 | dest_files=[ "res://.import/hud-bg.png-1ce97759cf830c1ca9be279e25660a7d.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/custom/CGFCardBack.gd: -------------------------------------------------------------------------------- 1 | extends CardBackGlow 2 | 3 | var font_scaled : float = 1 4 | 5 | # Since we have a label on top of our image, we use this to scale the label 6 | # as well 7 | # We don't care about the viewed icon, since it will never be visible 8 | # in the viewport focus. 9 | func scale_to(scale_multiplier: float) -> void: 10 | if font_scaled != scale_multiplier: 11 | var label : Label = $"VBoxContainer/Label" 12 | label.rect_min_size *= scale_multiplier 13 | # We need to adjust the Viewed Container 14 | # a bit more to make the text land in the middle 15 | $"VBoxContainer/CenterContainer".rect_min_size *= scale_multiplier * 1.5 16 | var label_font : Font = label.get("custom_fonts/font").duplicate() 17 | label_font.size *= scale_multiplier 18 | label.set("custom_fonts/font", label_font) 19 | font_scaled = scale_multiplier 20 | 21 | -------------------------------------------------------------------------------- /assets/art/ui/menu/buttons/pressed.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/pressed.png-4c1be30278965cf948b0a8e62df6e8b1.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/ui/menu/buttons/pressed.png" 13 | dest_files=[ "res://.import/pressed.png-4c1be30278965cf948b0a8e62df6e8b1.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/card_backs/CGFBackDots.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/CGFBackDots.png-2c051a48afef3d47d30a8adb1182524b.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/card_backs/CGFBackDots.png" 13 | dest_files=[ "res://.import/CGFBackDots.png-2c051a48afef3d47d30a8adb1182524b.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/ui/life_bar/life_bar_bg.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/life_bar_bg.png-c60e185ad8385341accf06e406e6bf23.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/life_bar/life_bar_bg.png" 13 | dest_files=[ "res://.import/life_bar_bg.png-c60e185ad8385341accf06e406e6bf23.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/cc/DuplicateCustomCGFDeck.gd: -------------------------------------------------------------------------------- 1 | # Code for a sample deck, you're expected to provide your own ;) 2 | extends Pile 3 | 4 | signal draw_card(deck) 5 | 6 | var disabled_deck = false 7 | 8 | # Called when the node enters the scene tree for the first time. 9 | func _ready() -> void: 10 | if not cfc.are_all_nodes_mapped: 11 | yield(cfc, "all_nodes_mapped") 12 | # warning-ignore:return_value_discarded 13 | $Control.connect("gui_input", self, "_on_Deck_input_event") 14 | # warning-ignore:return_value_discarded 15 | connect("draw_card", cfc.NMAP.hand, "draw_card") 16 | #print(get_signal_connection_list("input_event")[0]['target'].name) 17 | 18 | func _on_Deck_input_event(event) -> void: 19 | if disabled_deck: 20 | return 21 | if event.is_pressed()\ 22 | and not cfc.game_paused\ 23 | and event.get_button_index() == 1: 24 | emit_signal("draw_card", self) 25 | -------------------------------------------------------------------------------- /src/cc/cards/Strike.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/cc/cards/InheritedCoreCardTemplate.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/cc/cards/StrikeFront.tscn" type="PackedScene" id=2] 5 | 6 | [node name="Strike" instance=ExtResource( 1 )] 7 | card_front_design = ExtResource( 2 ) 8 | 9 | [node name="Control" parent="." index="1"] 10 | anchor_right = 0.0 11 | anchor_bottom = 0.0 12 | rect_min_size = Vector2( 150, 240 ) 13 | 14 | [node name="Debug" parent="." index="3"] 15 | visible = false 16 | 17 | [node name="state" parent="Debug" index="1"] 18 | margin_top = 0.0 19 | margin_bottom = 14.0 20 | 21 | [node name="index" parent="Debug" index="2"] 22 | margin_top = 18.0 23 | margin_bottom = 32.0 24 | 25 | [node name="parent" parent="Debug" index="3"] 26 | margin_top = 36.0 27 | margin_bottom = 50.0 28 | -------------------------------------------------------------------------------- /assets/art/fx/filmgrain-1080.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/filmgrain-1080.png-a33e9da6f3160480a054be490a125e00.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/fx/filmgrain-1080.png" 13 | dest_files=[ "res://.import/filmgrain-1080.png-a33e9da6f3160480a054be490a125e00.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/art/splash/splash_hills.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/splash_hills.png-78b33a732b067e3095fca60c6707fed1.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/splash/splash_hills.png" 13 | dest_files=[ "res://.import/splash_hills.png-78b33a732b067e3095fca60c6707fed1.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/card_backs/CGFBackLines.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/CGFBackLines.png-7cb5627e25ea3e805d1fd7b99fafb7cd.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/card_backs/CGFBackLines.png" 13 | dest_files=[ "res://.import/CGFBackLines.png-7cb5627e25ea3e805d1fd7b99fafb7cd.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/characters/fenyx-paperbg.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/fenyx-paperbg.png-ea36b9a18e5b724a81134e7d9bda58ec.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/fenyx-paperbg.png" 13 | dest_files=[ "res://.import/fenyx-paperbg.png-ea36b9a18e5b724a81134e7d9bda58ec.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/ui/action_menu/icon_punch.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon_punch.svg-7219d88dceda38aaa51493a5cbc5d7ad.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/action_menu/icon_punch.svg" 13 | dest_files=[ "res://.import/icon_punch.svg-7219d88dceda38aaa51493a5cbc5d7ad.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/ui/life_bar/life_bar_fill.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/life_bar_fill.png-f9a14370451d685198830ab12e71a0c9.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/life_bar/life_bar_fill.png" 13 | dest_files=[ "res://.import/life_bar_fill.png-f9a14370451d685198830ab12e71a0c9.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/energy_bar/stub.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/stub.png-521bfc1b5fba2e1940a9cbbc72d91483.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://src/battle/ui/battler_hud/energy_bar/stub.png" 13 | dest_files=[ "res://.import/stub.png-521bfc1b5fba2e1940a9cbbc72d91483.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/backgrounds/train-interior.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/train-interior.png-1b9876429d1e2cdf79c3aab422f0f6b2.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/backgrounds/train-interior.png" 13 | dest_files=[ "res://.import/train-interior.png-1b9876429d1e2cdf79c3aab422f0f6b2.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/cards/front-placeholder.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/front-placeholder.png-ccca791123b873ac7fb6cce996a8b40b.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/cards/front-placeholder.png" 13 | dest_files=[ "res://.import/front-placeholder.png-ccca791123b873ac7fb6cce996a8b40b.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/characters/proto-character.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/proto-character.png-61a626a637ffb44a234e2e095927855d.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/characters/proto-character.png" 13 | dest_files=[ "res://.import/proto-character.png-61a626a637ffb44a234e2e095927855d.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/menu_action_bg.png-f41500062b3c8c594112940f91f273f9.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/action_menu/menu_action_bg.png" 13 | dest_files=[ "res://.import/menu_action_bg.png-f41500062b3c8c594112940f91f273f9.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/energy_bar/stub_bg.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/stub_bg.png-74c6f94de94fe6bdf3b04d8d09658654.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://src/battle/ui/battler_hud/energy_bar/stub_bg.png" 13 | dest_files=[ "res://.import/stub_bg.png-74c6f94de94fe6bdf3b04d8d09658654.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/cc/cards/sets/SetDefinition_Core.gd: -------------------------------------------------------------------------------- 1 | # This file contains just card definitions. See also `CardConfig.gd` 2 | 3 | extends Reference 4 | 5 | const SET = "Demo Set 1" 6 | const CARDS := { 7 | "Elbow Bump": { 8 | "Type": CardConfig.CardTypes.card_type_strike, 9 | "Tags": ["‎"], 10 | "Requirements": "‎", 11 | "Abilities": "Bump your foe's elbow off the armrest", 12 | "Cost": 2, 13 | "Power": 5, 14 | }, 15 | "Knee Knock": { 16 | "Type": CardConfig.CardTypes.card_type_strike, 17 | "Tags": ["‎"], 18 | "Requirements": "‎", 19 | "Abilities": "Reclaim your leg room, and then some", 20 | "Cost": 3, 21 | "Power": 8, 22 | }, 23 | "Newspaper": { 24 | "Type": CardConfig.CardTypes.card_type_strike, 25 | "Tags": ["‎"], 26 | "Requirements": "‎", 27 | "Abilities": "Open a newspaper in your neighbour's face", 28 | "Cost": 4, 29 | "Power": 12, 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBGridCardObject.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/core/DeckBuilder/DBGridCardObject.gd" type="Script" id=1] 4 | [ext_resource path="res://src/core/DeckBuilder/DBPreviewPopup.tscn" type="PackedScene" id=2] 5 | 6 | [node name="DBGridCardObject" type="CenterContainer"] 7 | margin_right = 150.0 8 | margin_bottom = 240.0 9 | rect_min_size = Vector2( 150, 240 ) 10 | size_flags_horizontal = 3 11 | size_flags_vertical = 3 12 | script = ExtResource( 1 ) 13 | 14 | [node name="PreviewPopup" parent="." instance=ExtResource( 2 )] 15 | margin_left = 75.0 16 | margin_top = 120.0 17 | margin_right = 75.0 18 | margin_bottom = 120.0 19 | 20 | [connection signal="mouse_entered" from="." to="." method="_on_DBGridCardObject_mouse_entered"] 21 | [connection signal="mouse_exited" from="." to="." method="_on_DBGridCardObject_mouse_exited"] 22 | -------------------------------------------------------------------------------- /assets/art/normal_maps/squigglevission.jpg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/squigglevission.jpg-261ec59251ebedbbf7cf4f7b2d88d076.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/art/normal_maps/squigglevission.jpg" 13 | dest_files=[ "res://.import/squigglevission.jpg-261ec59251ebedbbf7cf4f7b2d88d076.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/custom/CGFCardTemplate.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://src/core/CardTemplate.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/custom/CGFCardTemplate.gd" type="Script" id=2] 5 | [ext_resource path="res://src/custom/CGFCardFront.tscn" type="PackedScene" id=3] 6 | [ext_resource path="res://src/custom/CGFManipulationButtons.gd" type="Script" id=4] 7 | [ext_resource path="res://src/custom/CGFCardManipulationButton.tscn" type="PackedScene" id=5] 8 | [ext_resource path="res://src/custom/CGFCardBack.tscn" type="PackedScene" id=6] 9 | 10 | [node name="Card" instance=ExtResource( 1 )] 11 | script = ExtResource( 2 ) 12 | card_back_design = ExtResource( 6 ) 13 | card_front_design = ExtResource( 3 ) 14 | 15 | [node name="ManipulationButtons" parent="Control" index="4"] 16 | script = ExtResource( 4 ) 17 | manipulation_button = ExtResource( 5 ) 18 | -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_selection_arrow.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/menu_selection_arrow.png-35febeb9f1d9c0e262a8925a23cc26d2.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/action_menu/menu_selection_arrow.png" 13 | dest_files=[ "res://.import/menu_selection_arrow.png-35febeb9f1d9c0e262a8925a23cc26d2.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/custom/CGFCounter.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | outline_size = 2 7 | outline_color = Color( 0, 0, 0, 1 ) 8 | use_filter = true 9 | font_data = ExtResource( 1 ) 10 | 11 | [node name="Counter" type="HBoxContainer"] 12 | margin_right = 139.0 13 | margin_bottom = 20.0 14 | mouse_filter = 2 15 | __meta__ = { 16 | "_edit_use_anchors_": false 17 | } 18 | 19 | [node name="CounterTitle" type="Label" parent="."] 20 | margin_right = 112.0 21 | margin_bottom = 20.0 22 | custom_fonts/font = SubResource( 1 ) 23 | text = "Counter Title:" 24 | 25 | [node name="Value" type="Label" parent="."] 26 | margin_left = 116.0 27 | margin_right = 139.0 28 | margin_bottom = 20.0 29 | size_flags_horizontal = 3 30 | custom_fonts/font = SubResource( 1 ) 31 | text = "0" 32 | align = 2 33 | -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg_focused.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/menu_action_bg_focused.png-0880bfcc0051f22db097c1e617d19004.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/action_menu/menu_action_bg_focused.png" 13 | dest_files=[ "res://.import/menu_action_bg_focused.png-0880bfcc0051f22db097c1e617d19004.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg_pressed.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/menu_action_bg_pressed.png-77ca186555b9024dbe12a0a26f83ab65.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/action_menu/menu_action_bg_pressed.png" 13 | dest_files=[ "res://.import/menu_action_bg_pressed.png-77ca186555b9024dbe12a0a26f83ab65.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/turn_bar/UIBattlerIcon.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://assets/icons/icon_frame.png" type="Texture" id=1] 4 | [ext_resource path="res://src/battle/ui/turn_bar/UIBattlerIcon.gd" type="Script" id=3] 5 | [ext_resource path="res://assets/characters/icons/bruli.png" type="Texture" id=4] 6 | 7 | [node name="UIBattlerIcon" type="TextureRect"] 8 | margin_right = 40.0 9 | margin_bottom = 40.0 10 | rect_scale = Vector2( 0.1, 0.1 ) 11 | texture = ExtResource( 1 ) 12 | script = ExtResource( 3 ) 13 | __meta__ = { 14 | "_edit_use_anchors_": false 15 | } 16 | icon = ExtResource( 4 ) 17 | type = 1 18 | 19 | [node name="Icon" type="TextureRect" parent="."] 20 | anchor_right = 1.0 21 | anchor_bottom = 1.0 22 | margin_left = 54.0 23 | margin_top = 47.0 24 | margin_right = -54.0 25 | margin_bottom = -46.0 26 | texture = ExtResource( 4 ) 27 | expand = true 28 | stretch_mode = 6 29 | -------------------------------------------------------------------------------- /assets/ui/action_menu/menu_action_bg_disabled.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/menu_action_bg_disabled.png-cb08278726ad9113215d61763a711b05.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://assets/ui/action_menu/menu_action_bg_disabled.png" 13 | dest_files=[ "res://.import/menu_action_bg_disabled.png-cb08278726ad9113215d61763a711b05.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/energy_bar/UIEnergyPoint.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/battler_hud/energy_bar/stub.png" type="Texture" id=1] 4 | [ext_resource path="res://src/battle/ui/battler_hud/energy_bar/UIEnergyPoint.gd" type="Script" id=2] 5 | [ext_resource path="res://src/battle/ui/battler_hud/energy_bar/stub_bg.png" type="Texture" id=3] 6 | 7 | [node name="UIEnergyPoint" type="TextureRect"] 8 | margin_right = 40.0 9 | margin_bottom = 40.0 10 | rect_rotation = 45.0 11 | rect_scale = Vector2( 0.2, 0.2 ) 12 | texture = ExtResource( 1 ) 13 | stretch_mode = 4 14 | script = ExtResource( 2 ) 15 | __meta__ = { 16 | "_edit_use_anchors_": false 17 | } 18 | 19 | [node name="Fill" type="TextureRect" parent="."] 20 | modulate = Color( 1, 1, 1, 0.470588 ) 21 | margin_right = 40.0 22 | margin_bottom = 40.0 23 | texture = ExtResource( 3 ) 24 | 25 | [node name="Tween" type="Tween" parent="."] 26 | -------------------------------------------------------------------------------- /src/battle/statuseffects/impl/StatusEffectSlow.gd: -------------------------------------------------------------------------------- 1 | class_name StatusEffectSlow 2 | extends StatusEffect 3 | 4 | var speed_reduction := 0.0 setget set_speed_rate 5 | 6 | var _stat_modifier_id := -1 7 | 8 | 9 | # Similar to `StatusEffectHaste`. 10 | func _init(target, data: StatusEffectData).(target, data) -> void: 11 | id = "slow" 12 | speed_reduction = data.effect_rate 13 | 14 | 15 | func _start() -> void: 16 | _stat_modifier_id = _target.stats.add_modifier( 17 | # We can calculate the modifier's value from the `speed_reduction` ratio. 18 | "speed", -1.0 * speed_reduction * _target.stats.speed 19 | ) 20 | 21 | 22 | # Same as `StatusEffectHaste`. 23 | func _expire() -> void: 24 | _target.stats.remove_modifier("speed", _stat_modifier_id) 25 | queue_free() 26 | 27 | 28 | # We ensure the speed reduction is neither 0% nor greater than 99%. 29 | func set_speed_rate(value: float) -> void: 30 | speed_reduction = clamp(value, 0.01, 0.99) 31 | -------------------------------------------------------------------------------- /src/custom/CGFPlacementGridDemo.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/core/BoardPlacementSlot.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/core/BoardPlacementGrid.tscn" type="PackedScene" id=2] 5 | 6 | [node name="PlacementGridDemo" instance=ExtResource( 2 )] 7 | 8 | [node name="GridContainer" parent="." index="0"] 9 | margin_right = 497.0 10 | columns = 4 11 | 12 | [node name="BoardPlacementSlot2" parent="GridContainer" index="1" instance=ExtResource( 1 )] 13 | margin_left = 125.0 14 | margin_right = 245.0 15 | 16 | [node name="BoardPlacementSlot3" parent="GridContainer" index="2" instance=ExtResource( 1 )] 17 | margin_left = 250.0 18 | margin_right = 370.0 19 | 20 | [node name="BoardPlacementSlot4" parent="GridContainer" index="3" instance=ExtResource( 1 )] 21 | margin_left = 375.0 22 | margin_right = 495.0 23 | 24 | [node name="Control" parent="." index="1"] 25 | margin_right = 497.0 26 | -------------------------------------------------------------------------------- /src/battle/command/Hit.gd: -------------------------------------------------------------------------------- 1 | # Represents a damage-dealing hit to be applied to a target Battler. 2 | # Encapsulates calculations for how hits are applied based on some properties. 3 | 4 | # There are two main reasons to bother using a class like Hit: 5 | # - It allows and forces you to pass a single value to the battler when it should take damage. 6 | # - It encapsulates only the information the battler needs to know about the attack’s effect. 7 | class_name Hit 8 | extends Reference 9 | 10 | # The damage dealt by the hit. 11 | var damage := 0 12 | # Chance to hit in base 100. 13 | var hit_chance: float 14 | var effect: StatusEffect 15 | 16 | 17 | func _init(_damage: int, _hit_chance := 100.0, _effect: StatusEffect = null) -> void: 18 | damage = _damage 19 | hit_chance = _hit_chance 20 | effect = _effect 21 | 22 | 23 | # Returns true if the hit isn't missing. To use when consuming the hit. 24 | func does_hit() -> bool: 25 | return randf() * 100.0 < hit_chance 26 | -------------------------------------------------------------------------------- /src/battle/battlers/BattlerProtagonist.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://src/battle/Battler.gd" type="Script" id=1] 4 | [ext_resource path="res://src/battle/anim/BattlerAnim.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/battle/statuseffects/StatusEffectContainer.gd" type="Script" id=3] 6 | [ext_resource path="res://src/battle/battlers/player_stats.tres" type="Resource" id=4] 7 | [ext_resource path="res://src/battle/battlers/protagonist.tres" type="Resource" id=5] 8 | 9 | [node name="BattlerProtagonist" type="Node2D"] 10 | z_index = 49 11 | script = ExtResource( 1 ) 12 | stats = ExtResource( 4 ) 13 | ui_data = ExtResource( 5 ) 14 | 15 | [node name="BattlerAnim" parent="." instance=ExtResource( 2 )] 16 | 17 | [node name="StatusEffectContainer" type="Node" parent="."] 18 | script = ExtResource( 3 ) 19 | 20 | [connection signal="animation_finished" from="BattlerAnim" to="." method="_on_BattlerAnim_animation_finished"] 21 | -------------------------------------------------------------------------------- /src/battle/statuseffects/impl/StatusEffectHaste.gd: -------------------------------------------------------------------------------- 1 | class_name StatusEffectHaste 2 | extends StatusEffect 3 | 4 | # We give an explicit name to the value `StatusEffectData.effect_power` for this effect. 5 | var speed_bonus := 0 6 | 7 | # We're going to use our stats' class to add and remove a modifier. 8 | var _stat_modifier_id := -1 9 | 10 | 11 | # Below, target is of type `Battler`. 12 | func _init(target, data: StatusEffectData).(target, data) -> void: 13 | # All haste effects should have the same `id` so we can later find and remove them. 14 | id = "haste" 15 | speed_bonus = data.effect_power 16 | 17 | 18 | func _start() -> void: 19 | # We initialize the effect by adding a stat modifier to the target battler. 20 | _stat_modifier_id = _target.stats.add_modifier("speed", speed_bonus) 21 | 22 | 23 | func _expire() -> void: 24 | # And we remove the stat modifier when the effect expires. 25 | _target.stats.remove_modifier("speed", _stat_modifier_id) 26 | queue_free() 27 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/CategoryContainer.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1] 4 | [ext_resource path="res://src/core/DeckBuilder/CategoryContainer.gd" type="Script" id=2] 5 | 6 | [sub_resource type="DynamicFont" id=1] 7 | size = 15 8 | use_filter = true 9 | font_data = ExtResource( 1 ) 10 | 11 | [node name="CategoryContainer" type="VBoxContainer"] 12 | margin_right = 633.0 13 | margin_bottom = 46.0 14 | script = ExtResource( 2 ) 15 | __meta__ = { 16 | "_edit_use_anchors_": false 17 | } 18 | 19 | [node name="CategoryLabel" type="Label" parent="."] 20 | margin_right = 633.0 21 | margin_bottom = 18.0 22 | custom_fonts/font = SubResource( 1 ) 23 | text = "Blue (1)" 24 | __meta__ = { 25 | "_edit_use_anchors_": false 26 | } 27 | 28 | [node name="CategoryCards" type="VBoxContainer" parent="."] 29 | margin_top = 22.0 30 | margin_right = 633.0 31 | margin_bottom = 22.0 32 | __meta__ = { 33 | "_edit_use_anchors_": false 34 | } 35 | -------------------------------------------------------------------------------- /update-card-game-framework.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TMP=tmp-cgf 4 | rm -rf $TMP 5 | git clone --depth 1 https://github.com/db0/godot-card-game-framework.git $TMP 6 | SHA=$(git --git-dir=$TMP/.git rev-parse HEAD) 7 | 8 | 9 | rm -rf src/core 10 | cp -R $TMP/src/core src/ 11 | 12 | rm -rf src/custom 13 | cp -R $TMP/src/custom src 14 | 15 | # these are scripts that are supposed to be "moved" from custom to cc, 16 | # i.e. they shouldn't exist in custom anymore after the move. 17 | rm src/custom/CFConst.gd 18 | rm src/custom/cards/CardConfig.gd 19 | 20 | VERSION=cgf-version.txt 21 | rm -f $VERSION 22 | touch $VERSION 23 | echo $SHA > $VERSION 24 | 25 | echo "Updated godot-card-game-framework to sha $SHA" 26 | echo "tmp left in-tact at $TMP" 27 | echo 28 | echo "Remember to look at the history for:" 29 | echo 30 | echo "https://github.com/db0/godot-card-game-framework/blob/main/src/custom/CFConst.gd" 31 | echo "https://github.com/db0/godot-card-game-framework/blob/main/src/custom/cards/CardConfig.gd" 32 | -------------------------------------------------------------------------------- /src/core/Card/TargetingArrow.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/core/Card/TargetingArrow.gd" type="Script" id=1] 4 | 5 | [sub_resource type="Curve" id=1] 6 | _data = [ Vector2( 0, 0.463636 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 1.4, 0.0, 0, 0 ] 7 | 8 | [node name="TargetLine" type="Line2D"] 9 | z_index = 50 10 | points = PoolVector2Array( 384, 112 ) 11 | width = 15.0 12 | width_curve = SubResource( 1 ) 13 | default_color = Color( 1, 1, 1, 1 ) 14 | antialiased = true 15 | script = ExtResource( 1 ) 16 | 17 | [node name="ArrowHead" type="Polygon2D" parent="."] 18 | visible = false 19 | offset = Vector2( -32, -8 ) 20 | polygon = PoolVector2Array( 16, 24, 32, 8, 16, -8 ) 21 | 22 | [node name="Area2D" type="Area2D" parent="ArrowHead"] 23 | monitoring = false 24 | collision_layer = 2 25 | collision_mask = 2 26 | 27 | [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="ArrowHead/Area2D"] 28 | position = Vector2( -32, -8 ) 29 | polygon = PoolVector2Array( 16, 24, 32, 8, 16, -8 ) 30 | -------------------------------------------------------------------------------- /src/custom/cards/sets/SetDefinition_Demo2.gd: -------------------------------------------------------------------------------- 1 | # This file contains just card definitions. See also `CardConfig.gd` 2 | 3 | extends Reference 4 | 5 | const SET = "Demo Set 2" 6 | const CARDS := { 7 | "Test Card 3": { 8 | "Type": "Green", 9 | "Tags": ["Tag 1","Tag 2"], 10 | "Requirements": "", 11 | "Abilities": "While on board, this card will flip face-down " \ 12 | + "and rotate 180 degrees a target." \ 13 | + "\n\nWhile on the hand, this card will remove " \ 14 | + "a target card from the game" \ 15 | + "\n\nAfter another card is rotated, gain a blood token.", 16 | "Cost": 0, 17 | "Power": 9001, 18 | "_keywords": ["Keyword 1","Clarification A"] 19 | }, 20 | "Multiple Choices Test Card": { 21 | "Type": "Blue", 22 | "Tags": ["Tag 2","Tag 3"], 23 | "Requirements": "", 24 | "Abilities": "While on board, either rotate 90, or flip face-down." \ 25 | + "\n\nWhile on hand, discard up to 5 cards " \ 26 | + "from the top of the deck", 27 | "Cost": 0, 28 | "Power": 0, 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /src/game/FilmGrain.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://assets/art/fx/vignette.png" type="Texture" id=1] 4 | [ext_resource path="res://assets/art/fx/filmgrain-1080.png" type="Texture" id=2] 5 | [ext_resource path="res://src/shaders/film_grain.shader" type="Shader" id=3] 6 | 7 | [sub_resource type="ShaderMaterial" id=1] 8 | shader = ExtResource( 3 ) 9 | shader_param/base = Color( 1, 1, 1, 0 ) 10 | shader_param/grain_strength = 0.4 11 | shader_param/fps = 12.0 12 | shader_param/stretch = 0.5 13 | shader_param/flashing = 0.01 14 | shader_param/grain = ExtResource( 2 ) 15 | shader_param/vignette = ExtResource( 1 ) 16 | 17 | [node name="Camera2D" type="Camera2D"] 18 | anchor_mode = 0 19 | current = true 20 | 21 | [node name="CanvasLayer" type="CanvasLayer" parent="."] 22 | 23 | [node name="ColorRect" type="ColorRect" parent="CanvasLayer"] 24 | material = SubResource( 1 ) 25 | anchor_right = 1.0 26 | anchor_bottom = 1.0 27 | mouse_filter = 2 28 | __meta__ = { 29 | "_edit_use_anchors_": false 30 | } 31 | -------------------------------------------------------------------------------- /src/cc/cards/StrikeFront.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/cc/DuplicateCustomCGFCardFront.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/cc/cards/StrikeFront.gd" type="Script" id=2] 5 | 6 | [sub_resource type="StyleBoxFlat" id=1] 7 | bg_color = Color( 1, 0.984314, 0.733333, 1 ) 8 | corner_radius_top_left = 10 9 | corner_radius_top_right = 10 10 | corner_radius_bottom_right = 10 11 | corner_radius_bottom_left = 10 12 | 13 | [node name="StrikeFront" instance=ExtResource( 1 )] 14 | custom_styles/panel = SubResource( 1 ) 15 | script = ExtResource( 2 ) 16 | 17 | [node name="Name" parent="Margin/CardText" index="0"] 18 | text = "Generic Strike" 19 | 20 | [node name="Type" parent="Margin/CardText" index="1"] 21 | text = "‎" 22 | 23 | [node name="Tags" parent="Margin/CardText" index="2"] 24 | text = "‎" 25 | 26 | [node name="Requirements" parent="Margin/CardText" index="3"] 27 | text = "‎" 28 | 29 | [node name="Abilities" parent="Margin/CardText" index="4"] 30 | text = "Whammo!" 31 | -------------------------------------------------------------------------------- /src/cc/cards/DuplicateCoreTargetingArrow.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/cc/cards/MyTargetingArrow.gd" type="Script" id=1] 4 | 5 | [sub_resource type="Curve" id=1] 6 | _data = [ Vector2( 0, 0.463636 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 1.4, 0.0, 0, 0 ] 7 | 8 | [node name="TargetLine" type="Line2D"] 9 | z_index = 50 10 | points = PoolVector2Array( 384, 112 ) 11 | width = 15.0 12 | width_curve = SubResource( 1 ) 13 | default_color = Color( 1, 1, 1, 1 ) 14 | antialiased = true 15 | script = ExtResource( 1 ) 16 | 17 | [node name="ArrowHead" type="Polygon2D" parent="."] 18 | visible = false 19 | offset = Vector2( -32, -8 ) 20 | polygon = PoolVector2Array( 16, 24, 32, 8, 16, -8 ) 21 | 22 | [node name="Area2D" type="Area2D" parent="ArrowHead"] 23 | monitoring = false 24 | collision_layer = 2 25 | collision_mask = 2 26 | 27 | [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="ArrowHead/Area2D"] 28 | position = Vector2( -32, -8 ) 29 | polygon = PoolVector2Array( 16, 24, 32, 8, 16, -8 ) 30 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/CardLabel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=1] 4 | [ext_resource path="res://src/core/DeckBuilder/CardLabel.gd" type="Script" id=2] 5 | [ext_resource path="res://src/core/DeckBuilder/DBPreviewPopup.tscn" type="PackedScene" id=3] 6 | 7 | [sub_resource type="DynamicFont" id=1] 8 | size = 15 9 | use_filter = true 10 | font_data = ExtResource( 1 ) 11 | 12 | [node name="CardLabel" type="Label"] 13 | margin_left = 18.0 14 | margin_right = 105.0 15 | margin_bottom = 18.0 16 | mouse_filter = 1 17 | size_flags_horizontal = 3 18 | custom_fonts/font = SubResource( 1 ) 19 | text = "Test Card 1" 20 | script = ExtResource( 2 ) 21 | __meta__ = { 22 | "_edit_use_anchors_": false 23 | } 24 | 25 | [node name="PreviewPopup" parent="." instance=ExtResource( 3 )] 26 | 27 | [connection signal="mouse_entered" from="." to="." method="_on_CardLabel_mouse_entered"] 28 | [connection signal="mouse_exited" from="." to="." method="_on_CardLabel_mouse_exited"] 29 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBGridCardObject.gd: -------------------------------------------------------------------------------- 1 | 2 | class_name DBGridCardObject 3 | extends CenterContainer 4 | 5 | var display_card: Card 6 | var card_list_object 7 | 8 | onready var preview_popup := $PreviewPopup 9 | 10 | func _ready() -> void: 11 | connect("gui_input",self,"on_gui_input") 12 | rect_min_size = CFConst.CARD_SIZE 13 | 14 | func on_gui_input(event) -> void: 15 | if event is InputEventMouseButton and event.is_pressed(): 16 | if event.get_button_index() == 1: 17 | card_list_object._on_Plus_pressed() 18 | elif event.get_button_index() == 2: 19 | card_list_object._on_Minus_pressed() 20 | elif event.get_button_index() == 3: 21 | card_list_object.set_quantity(0) 22 | 23 | func setup(card_name) -> void: 24 | display_card = cfc.instance_card(card_name) 25 | add_child(display_card) 26 | display_card.state = Card.CardState.DECKBUILDER_GRID 27 | 28 | 29 | func _on_DBGridCardObject_mouse_entered() -> void: 30 | preview_popup.show_preview_card(display_card.canonical_name) 31 | 32 | 33 | func _on_DBGridCardObject_mouse_exited() -> void: 34 | preview_popup.hide_preview_card() 35 | -------------------------------------------------------------------------------- /.github/workflows/godot-ci.yml: -------------------------------------------------------------------------------- 1 | name: Build and deploy to itch.io 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | publish-godot-game-to-itchio: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: checkout 13 | id: checkout 14 | uses: actions/checkout@v2 15 | - name: build 16 | id: build 17 | uses: josephbmanley/build-godot-action@master 18 | with: 19 | name: index.html 20 | preset: HTML5 21 | - run: ls -la build 22 | - run: echo "${GITHUB_RUN_ID}-${GITHUB_RUN_NUMBER}-${GITHUB_SHA}" > VERSION_FILE 23 | - uses: montudor/action-zip@v0.1.1 24 | with: 25 | args: zip -qq -r -j build.zip build 26 | - name: publish 27 | id: publish 28 | uses: josephbmanley/butler-publish-itchio-action@master 29 | env: 30 | BUTLER_CREDENTIALS: ${{ secrets.BUTLER_CREDENTIALS }} 31 | CHANNEL: web 32 | ITCH_GAME: contumacious-commuter 33 | ITCH_USER: opyate 34 | PACKAGE: build.zip 35 | VERSION_FILE: VERSION_FILE 36 | -------------------------------------------------------------------------------- /src/battle/battlers/BattlerAntagonist.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://src/battle/Battler.gd" type="Script" id=1] 4 | [ext_resource path="res://src/battle/ai/AggressiveBattlerAI.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/battle/battlers/antagonist.tres" type="Resource" id=3] 6 | [ext_resource path="res://src/battle/anim/BattlerAnim.tscn" type="PackedScene" id=4] 7 | [ext_resource path="res://src/battle/statuseffects/StatusEffectContainer.gd" type="Script" id=5] 8 | [ext_resource path="res://src/battle/battlers/enemy_stats.tres" type="Resource" id=6] 9 | 10 | [node name="BattlerAntagonist" type="Node2D"] 11 | z_index = 49 12 | script = ExtResource( 1 ) 13 | stats = ExtResource( 6 ) 14 | ai_scene = ExtResource( 2 ) 15 | ui_data = ExtResource( 3 ) 16 | 17 | [node name="BattlerAnim" parent="." instance=ExtResource( 4 )] 18 | scale = Vector2( -1, 1 ) 19 | 20 | [node name="StatusEffectContainer" type="Node" parent="."] 21 | script = ExtResource( 5 ) 22 | 23 | [connection signal="animation_finished" from="BattlerAnim" to="." method="_on_BattlerAnim_animation_finished"] 24 | -------------------------------------------------------------------------------- /src/custom/CGFCounters.gd: -------------------------------------------------------------------------------- 1 | extends Counters 2 | 3 | # * The `counters_container` has to point to the scene path, relative to your 4 | # counters scene, where each counter will be placed. 5 | # * value_node specified the name of the label which holds 6 | # the value of the counter as displayed to the player 7 | # * The needed_counters dictionary has one key per counter used in your game 8 | # Each value hold a dictionary with details about this counter. 9 | # * The key matching `value_node` will be used to set the starting 10 | # value of this counter 11 | # * All other keys specified have to match a label node name in the counter scene 12 | # and their value will be set as that label's text. 13 | # * spawn_needed_counters() has to be called at the end, to actually 14 | # add the specified counters to your counters scene. 15 | func _ready() -> void: 16 | counters_container = $VBC 17 | value_node = "Value" 18 | needed_counters = { 19 | "credits": { 20 | "CounterTitle": "Available Credits: ", 21 | "Value": 100}, 22 | "research":{ 23 | "CounterTitle": "Research: ", 24 | "Value": 0}, 25 | } 26 | spawn_needed_counters() 27 | -------------------------------------------------------------------------------- /src/battle/ui/action_menu/UIMenuSelectArrow.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://assets/ui/action_menu/menu_selection_arrow.png" type="Texture" id=1] 4 | [ext_resource path="res://src/battle/ui/action_menu/UIMenuSelectArrow.gd" type="Script" id=2] 5 | 6 | [sub_resource type="Animation" id=1] 7 | length = 0.6 8 | loop = true 9 | tracks/0/type = "value" 10 | tracks/0/path = NodePath("Sprite:position") 11 | tracks/0/interp = 1 12 | tracks/0/loop_wrap = true 13 | tracks/0/imported = false 14 | tracks/0/enabled = true 15 | tracks/0/keys = { 16 | "times": PoolRealArray( 0, 0.3 ), 17 | "transitions": PoolRealArray( 0.353553, 1 ), 18 | "update": 0, 19 | "values": [ Vector2( -68, 0 ), Vector2( 0, 0 ) ] 20 | } 21 | 22 | [node name="UIMenuSelectArrow" type="Position2D"] 23 | script = ExtResource( 2 ) 24 | 25 | [node name="Sprite" type="Sprite" parent="."] 26 | texture = ExtResource( 1 ) 27 | offset = Vector2( -67.9673, 0.25444 ) 28 | 29 | [node name="Tween" type="Tween" parent="."] 30 | 31 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 32 | autoplay = "wiggle" 33 | anims/wiggle = SubResource( 1 ) 34 | -------------------------------------------------------------------------------- /src/core/perMessage.gd: -------------------------------------------------------------------------------- 1 | # Contains details about the way to seek through the game for the 2 | # Requested things to count. This is sent to ScriptPer to initiate it. 3 | class_name perMessage 4 | extends Reference 5 | 6 | var per_seek: String 7 | var script_owner # Card type, but cannot type to avoid cyclic dependency 8 | var per_definitions: Dictionary 9 | var trigger_card = null 10 | var subjects := [] 11 | var found_things := 0 setget ,count_found_things 12 | 13 | func _init( 14 | _per_seek: String, 15 | _script_owner, 16 | _per_definitions: Dictionary, 17 | _trigger_card = null, 18 | _subjects := []) -> void: 19 | per_seek = _per_seek 20 | script_owner = _script_owner 21 | per_definitions = _per_definitions 22 | trigger_card = _trigger_card 23 | subjects = _subjects 24 | 25 | # Returns the amount of things the calling script is trying to count. 26 | func count_found_things() -> int: 27 | var found_count := 0 28 | var per_discovery = cfc.script_per.new(self) 29 | # if not per_discovery.has_init_completed: 30 | # yield(per_discovery,"primed") 31 | found_count = per_discovery.return_per_count() 32 | return(found_count) 33 | 34 | -------------------------------------------------------------------------------- /src/shaders/squiggle_vision.shader: -------------------------------------------------------------------------------- 1 | // squiggle vision 2 | 3 | shader_type canvas_item; 4 | 5 | uniform sampler2D flowMap; //Displacement map 6 | uniform float strength = 0.05; //Force of the effect 7 | uniform float speed = 5; //Speed of the effect 8 | uniform int frames : hint_range(1, 10) = 4; //Frames of the effect 9 | 10 | //Returns a value between 0 and 1 depending of the frames -> exemple: frames = 4, frame 1 = 0.25 11 | float clock(float time){ 12 | float fframes = float(frames); 13 | return floor(mod(time * speed, fframes)) / fframes; 14 | } 15 | 16 | void fragment(){ 17 | float c = clock(TIME); //Get clock frame 18 | vec4 offset = texture(flowMap, vec2(UV.x + c, UV.y + c)) * strength; //Get offset 19 | //COLOR = texture(TEXTURE, vec2(UV.x,UV.y) + normal.xy); //Apply offset 20 | COLOR = texture(TEXTURE, vec2(UV.x,UV.y) + offset.xy - vec2(0.5,0.5)*strength, 0.0); //We need to remove the displacement 21 | 22 | // disable shader: 23 | // COLOR = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0); 24 | } 25 | 26 | 27 | // TEST CLOCK 28 | /* 29 | void fragment(){ 30 | float c = clock(TIME); 31 | COLOR = vec4( c, c, c, 1); 32 | } 33 | /* -------------------------------------------------------------------------------- /src/custom/CGFCardTemplate.gd: -------------------------------------------------------------------------------- 1 | extends Card 2 | 3 | 4 | func _ready() -> void: 5 | pass 6 | 7 | # Sample code on how to ensure costs are paid when a card 8 | # is dragged from hand to the table 9 | func common_move_scripts(new_container: Node, old_container: Node) -> void: 10 | if new_container == cfc.NMAP.board and old_container == cfc.NMAP.hand: 11 | pay_play_costs() 12 | 13 | 14 | # Sample code on how to figure out costs of a card 15 | func get_modified_credits_cost() -> int: 16 | var modified_cost : int = properties.get("Cost", 0) 17 | return(modified_cost) 18 | 19 | 20 | # This sample function ensures all costs defined by a card are paid. 21 | func pay_play_costs() -> void: 22 | cfc.NMAP.board.counters.mod_counter("credits", -get_modified_credits_cost()) 23 | 24 | # A signal for whenever the player clicks on a card 25 | func _on_Card_gui_input(event) -> void: 26 | ._on_Card_gui_input(event) 27 | if event is InputEventMouseButton: 28 | if event.is_pressed() and event.get_button_index() == 2: 29 | targeting_arrow.initiate_targeting() 30 | elif not event.is_pressed() and event.get_button_index() == 2: 31 | targeting_arrow.complete_targeting() 32 | -------------------------------------------------------------------------------- /src/core/OverridableUtils.gd: -------------------------------------------------------------------------------- 1 | # This class is not instanced via its name. 2 | # Rather it is instanced using its path from cfc 3 | # This allows a game to extend it by extending this class 4 | # and then replacing the path in CFConst.PATH_OVERRIDABLE_UTILS 5 | # with the location of their extended script. 6 | class_name OVUtils 7 | extends Reference 8 | 9 | 10 | # Populates the info panels under the card, when it is shown in the 11 | # viewport focus or deckbuilder 12 | func populate_info_panels(card: Card, focus_info: DetailPanels) -> void: 13 | focus_info.hide_all_info() 14 | var card_illustration = card.get_property("_illustration") 15 | if card_illustration: 16 | focus_info.show_illustration("Illustration by: " + card_illustration) 17 | else: 18 | focus_info.hide_illustration() 19 | for tag in card.get_property("Tags"): 20 | if CardConfig.EXPLANATIONS.has(tag): 21 | focus_info.add_info(tag, CardConfig.EXPLANATIONS[tag]) 22 | var card_keywords = card.get_property("_keywords") 23 | if card_keywords: 24 | for keyword in card_keywords: 25 | if CardConfig.EXPLANATIONS.has(keyword): 26 | focus_info.add_info(keyword, CardConfig.EXPLANATIONS[keyword]) 27 | -------------------------------------------------------------------------------- /src/custom/cards/sets/SetDefinition_Demo1.gd: -------------------------------------------------------------------------------- 1 | # This file contains just card definitions. See also `CardConfig.gd` 2 | 3 | extends Reference 4 | 5 | const SET = "Demo Set 1" 6 | const CARDS := { 7 | "Test Card 1": { 8 | "Type": "Blue", 9 | "Tags": ["Tag 1","Tag 2"], 10 | "Requirements": "Demo Requirements", 11 | "Abilities": "While on board, this will rotate itself." \ 12 | + "\n\nWhile in hand, this will spawn a test card on the board.", 13 | "Cost": 0, 14 | "Power": 0, 15 | "_max_allowed": 1, 16 | "_illustration": "Nobody", 17 | "_keywords": ["Keyword 1"] 18 | }, 19 | "Test Card 2": { 20 | "Type": "Red", 21 | "Tags": ["Tag 1","Tag 2"], 22 | "Requirements": "", 23 | "Abilities": "While on board, this card will discard itself " \ 24 | + "and another target."\ 25 | + "\n\nWhile on the hand, this card will remove itself " \ 26 | + "from the game", 27 | "Cost": 2, 28 | "Power": 5, 29 | "_max_allowed": 10, 30 | "_illustration": "Nobody", 31 | }, 32 | "Spawn Card": { 33 | "Type": "Token", 34 | "Tags": [], 35 | "Requirements": "", 36 | "Abilities": " ", 37 | "Cost": 0, 38 | "Power": 1, 39 | "_hide_in_deckbuilder": true, 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /src/battle/statuseffects/StatusEffectData.gd: -------------------------------------------------------------------------------- 1 | # Data container to define new status effects. 2 | # The status effect abstract base class StatusEffect is initialised from this data, 3 | # by way of the StatusEffectBuilder 4 | class_name StatusEffectData 5 | extends Resource 6 | 7 | # Text id for the effect type. See StatusEffectBuilder for more information. 8 | export var effect := "" 9 | # Duration of the effect in seconds. 10 | export var duration_seconds := 20.0 11 | # Modifier amount that the effect applies or removes to a character's stat. 12 | export var effect_power := 20 13 | # Rate of the effect, if, for instance, it is percentage-based. 14 | export var effect_rate := 0.5 15 | 16 | # If `true`, the effect applies once every `ticking_interval` 17 | export var is_ticking := false 18 | # Duration between ticks in seconds. 19 | export var ticking_interval := 4.0 20 | # Damage inflicted by the effect every tick. 21 | export var ticking_damage := 3 22 | 23 | 24 | # Returns the total theoretical damage the effect will inflict over time. For ticking effects. 25 | func calculate_total_damage() -> int: 26 | var damage := 0 27 | if is_ticking: 28 | damage += int(duration_seconds / ticking_interval * ticking_damage) 29 | return damage 30 | -------------------------------------------------------------------------------- /src/cc/InheritedCoreMain.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://src/cc/DuplicateCustomCGFBoard.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/cc/Main.gd" type="Script" id=2] 5 | [ext_resource path="res://src/cc/DuplicateCustomCGFInfoPanel.tscn" type="PackedScene" id=3] 6 | [ext_resource path="res://src/core/Main.tscn" type="PackedScene" id=4] 7 | [ext_resource path="res://src/game/FilmGrain.tscn" type="PackedScene" id=5] 8 | 9 | [node name="Main" instance=ExtResource( 4 )] 10 | script = ExtResource( 2 ) 11 | board_scene = ExtResource( 1 ) 12 | info_panel_scene = ExtResource( 3 ) 13 | 14 | [node name="ViewportContainer" parent="." index="1"] 15 | margin_left = 9.5874 16 | margin_top = 5.76221 17 | margin_right = 1289.59 18 | margin_bottom = 725.762 19 | 20 | [node name="Viewport" parent="ViewportContainer" index="0"] 21 | size = Vector2( 1920, 1080 ) 22 | 23 | [node name="Focus" parent="VBC" index="0"] 24 | visible = false 25 | 26 | [node name="Viewport" parent="VBC/Focus" index="0"] 27 | render_target_update_mode = 0 28 | 29 | [node name="FocusInfo" parent="VBC" index="1"] 30 | margin_top = 0.0 31 | margin_bottom = 0.0 32 | 33 | [node name="FilmGrain" parent="." index="3" instance=ExtResource( 5 )] 34 | -------------------------------------------------------------------------------- /src/battle/statuseffects/StatusEffectBuilder.gd: -------------------------------------------------------------------------------- 1 | # Creates concrete [StatusEffect] instances from [StatusEffectData] resources. 2 | class_name StatusEffectBuilder 3 | extends Reference 4 | 5 | # We register the valid ID strings for `StatusEffectData.id` in this constant. 6 | # This allows us to not have to reference the class names directly and create new effect resources 7 | # in the inspector. 8 | # Note the convention in the GDScript style guide is to use PascalCase for types. I used that 9 | # because our content is a map of types, but you may want to use constant case instead: 10 | # `STATUS_EFFECTS`. 11 | const StatusEffects := { 12 | haste = StatusEffectHaste, 13 | slow = StatusEffectSlow, 14 | bug = StatusEffectBug, 15 | } 16 | 17 | # The class only exposes a function that creates and returns a new status effect based on the data 18 | # we provide. 19 | static func create_status_effect(target, data): 20 | # We can use the function to run through some `assert()` or return early if the input parameters 21 | # are incorrect. 22 | if not data: 23 | return null 24 | # You can store a reference to a class in a variable! 25 | var effect_class = StatusEffects[data.effect] 26 | var effect: StatusEffect = effect_class.new(target, data) 27 | return effect 28 | -------------------------------------------------------------------------------- /src/battle/ui/action_menu/UIActionButton.gd: -------------------------------------------------------------------------------- 1 | # Individual button representing one combat action. 2 | extends TextureButton 3 | 4 | # We store references to the nodes we access in the class, as usual. 5 | onready var _icon_node: TextureRect = $HBoxContainer/Icon 6 | onready var _label_node: Label = $HBoxContainer/Label 7 | 8 | 9 | # To call from a parent UI widget. Initializes the button. 10 | func setup(action: ActionData, can_be_used: bool) -> void: 11 | # In a parent node you may call `setup()` before adding the button as a child. 12 | # If that is the case, we need to pause execution until the button is ready. 13 | if not is_inside_tree(): 14 | yield(self, "ready") 15 | # Only update the icon's texture if the action data inlcudes an icon. 16 | if action.icon: 17 | _icon_node.texture = action.icon 18 | _label_node.text = action.label 19 | # The button has no notion of the battler's energy and the action's cost. 20 | # We will tell it if the player can use the action or not. If not, the button should be disabled. 21 | disabled = not can_be_used 22 | 23 | 24 | # When pressing the button, we release its focus. Doing so prevents the player from 25 | # pressing two action buttons or from pressing one twice. 26 | func _on_pressed() -> void: 27 | release_focus() 28 | -------------------------------------------------------------------------------- /src/custom/cards/sets/SetScripts_Demo1.gd: -------------------------------------------------------------------------------- 1 | # See README.md 2 | extends Reference 3 | 4 | # This fuction returns all the scripts of the specified card name. 5 | # 6 | # if no scripts have been defined, an empty dictionary is returned instead. 7 | func get_scripts(card_name: String) -> Dictionary: 8 | var scripts := { 9 | "Test Card 1": { 10 | "manual": { 11 | "board": [ 12 | { 13 | "name": "rotate_card", 14 | "subject": "self", 15 | "degrees": 90, 16 | } 17 | ], 18 | "hand": [ 19 | { 20 | "name": "spawn_card", 21 | "card_name": "Spawn Card", 22 | "board_position": Vector2(500,200), 23 | } 24 | ] 25 | }, 26 | }, 27 | "Test Card 2": { 28 | "manual": { 29 | "board": [ 30 | { 31 | "name": "move_card_to_container", 32 | "subject": "target", 33 | "dest_container": cfc.NMAP.discard, 34 | }, 35 | { 36 | "name": "move_card_to_container", 37 | "subject": "self", 38 | "dest_container": cfc.NMAP.discard, 39 | } 40 | ], 41 | "hand": [ 42 | { 43 | "name": "custom_script", 44 | } 45 | ] 46 | }, 47 | }, 48 | } 49 | # We return only the scripts that match the card name and trigger 50 | return(scripts.get(card_name,{})) 51 | -------------------------------------------------------------------------------- /src/core/OptionalConfirmation.gd: -------------------------------------------------------------------------------- 1 | # This scene creates a popup confirmation dialogue 2 | # Which confirms with the player to execute a card script. 3 | extends ConfirmationDialog 4 | 5 | signal selected 6 | 7 | var is_accepted := false 8 | 9 | func _ready() -> void: 10 | get_cancel().text = "No" 11 | get_ok().text = "Yes" 12 | # warning-ignore:return_value_discarded 13 | get_cancel().connect("pressed", self, "_on_OptionalConfirmation_cancelled") 14 | 15 | 16 | func prep(card_name: String, task_name: String) -> void: 17 | dialog_text = card_name + ": Do you want to activate " + task_name + "?" 18 | cfc.NMAP.board.add_child(self) 19 | # We spawn the dialogue at the middle of the screen. 20 | popup_centered() 21 | # One again we need two different Panels due to 22 | # https://github.com/godotengine/godot/issues/32030 23 | $HorizontalHighlights.rect_size = rect_size 24 | $HorizontalHighlights.rect_position = Vector2(0,0) 25 | $VecticalHighlights.rect_size = rect_size 26 | $VecticalHighlights.rect_position = Vector2(0,0) 27 | 28 | 29 | func _on_OptionalConfirmation_confirmed() -> void: 30 | is_accepted = true 31 | emit_signal("selected") 32 | 33 | 34 | func _on_OptionalConfirmation_cancelled() -> void: 35 | is_accepted = false 36 | emit_signal("selected") 37 | 38 | -------------------------------------------------------------------------------- /src/game/StoryKidnap.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://src/shaders/squiggle_vision.shader" type="Shader" id=1] 4 | [ext_resource path="res://src/game/FilmGrain.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://assets/backgrounds/kidnap.png" type="Texture" id=3] 6 | [ext_resource path="res://assets/art/normal_maps/squigglevission.jpg" type="Texture" id=4] 7 | [ext_resource path="res://src/game/StoryKidnap.gd" type="Script" id=5] 8 | 9 | [sub_resource type="ShaderMaterial" id=1] 10 | shader = ExtResource( 1 ) 11 | shader_param/strength = 0.002 12 | shader_param/speed = 5.0 13 | shader_param/frames = 4 14 | shader_param/flowMap = ExtResource( 4 ) 15 | 16 | [node name="Node2D" type="Node2D"] 17 | script = ExtResource( 5 ) 18 | 19 | [node name="ColorRect" type="ColorRect" parent="."] 20 | anchor_right = 1.0 21 | anchor_bottom = 1.0 22 | margin_right = 1920.0 23 | margin_bottom = 1080.0 24 | color = Color( 1, 0.984314, 0.733333, 1 ) 25 | __meta__ = { 26 | "_edit_use_anchors_": false 27 | } 28 | 29 | [node name="kidnap" type="Sprite" parent="."] 30 | material = SubResource( 1 ) 31 | position = Vector2( 1072.32, 523.825 ) 32 | texture = ExtResource( 3 ) 33 | 34 | [node name="FilmGrain" parent="." instance=ExtResource( 2 )] 35 | 36 | [node name="Tween" type="Tween" parent="."] 37 | -------------------------------------------------------------------------------- /src/shaders/film_grain.shader: -------------------------------------------------------------------------------- 1 | shader_type canvas_item; 2 | 3 | uniform vec4 base: hint_color; 4 | uniform sampler2D grain; 5 | uniform float grain_strength = 0.3; 6 | uniform sampler2D vignette; 7 | uniform float fps = 12.0; 8 | uniform float stretch = 0.5; 9 | uniform float flashing = 0.01; 10 | 11 | float make_grain(float time, vec2 uv) { 12 | vec2 ofs = vec2(sin(41.0 * time * sin(time * 123.0)), sin(27.0 * time * sin(time * 312.0))); 13 | return texture(grain, (uv + mod(ofs, vec2(1.0, 1.0))) * stretch).r; 14 | } 15 | 16 | void fragment() { 17 | 18 | vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb; 19 | 20 | //float v = max(c.r, max(c.g, c.b)); 21 | float v = dot(c, vec3(0.66666, 0.33333, 0.33333)); 22 | v = sqrt(v); 23 | //v *= v; 24 | 25 | float f = 1.0 / fps; 26 | float g = make_grain(TIME - mod(TIME, f), UV); 27 | g = max(g, make_grain(TIME - mod(TIME, f) + f, UV) * 0.5); 28 | g = max(g, make_grain(TIME - mod(TIME, f) + f * 2.0, UV) * 0.25); 29 | 30 | // COLOR.rgb = base.rgb * v - vec3(g) * grain_strength; 31 | COLOR.rgb = c - vec3(g) * 0.1; 32 | // COLOR.rgb *= texture(vignette, UV).r; 33 | float ft = TIME * 0.002; 34 | COLOR.rgb += vec3(sin(75.0 * ft * sin(ft * 123.0))) * flashing; 35 | 36 | // disable shader: 37 | // COLOR = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0); 38 | } 39 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBDeckCardObject.gd: -------------------------------------------------------------------------------- 1 | # An object displaying a card summary in the Deckbuilder's deck cards area 2 | # and providing controls to adjust their quantity.. 3 | class_name DBDeckCardObject 4 | extends HBoxContainer 5 | 6 | # Sent when the user changes a card quantity directly from the deck area. 7 | signal quantity_changed(value) 8 | 9 | # The quantity of a specific card in the deck. 10 | # Placed in a label 11 | var quantity: int 12 | # The card name which is displayed in the summary 13 | var card_name: String 14 | 15 | onready var _card_label:= $CardLabel 16 | 17 | func _ready() -> void: 18 | pass 19 | 20 | 21 | # This is used to prepare the values of this object 22 | func setup(_card_name: String, count: int) -> void: 23 | card_name = _card_name 24 | set_quantity(count) 25 | _card_label.text = _card_name 26 | 27 | 28 | # Updates the Quantity label and variable 29 | func set_quantity(value) -> void: 30 | quantity = value 31 | $CardCount.text = str(value) + 'x' 32 | 33 | 34 | # Signals the linked ListCardObject to increase quantity by 1 35 | func _on_Plus_pressed() -> void: 36 | emit_signal("quantity_changed", quantity + 1) 37 | 38 | 39 | # Signals the linked ListCardObject to decrease quantity by 1 40 | func _on_Minus_pressed() -> void: 41 | emit_signal("quantity_changed", quantity - 1) 42 | -------------------------------------------------------------------------------- /src/cc/Main.gd: -------------------------------------------------------------------------------- 1 | extends ViewportCardFocus 2 | 3 | # load the arena, and add it on top of the board 4 | var arena_scene = preload("res://src/battle/Arena.tscn") 5 | 6 | func _ready(): 7 | 8 | # first, disable some things on the board_scene 9 | # (Whenever CGF upgrades, it's easier to run the quickstart again, 10 | # which breaks any changes I might have made, so rather make 11 | # changes externally like this.) 12 | $ViewportContainer/Viewport/Board/FancyMovementToggle.hide() 13 | $ViewportContainer/Viewport/Board/OvalHandToggle.hide() 14 | $ViewportContainer/Viewport/Board/ScalingFocusOptions.hide() 15 | $ViewportContainer/Viewport/Board/DeckBuilder.hide() 16 | $ViewportContainer/Viewport/Board/PlacementGridDemo.hide() 17 | $ViewportContainer/Viewport/Board/ModifiedLabelGrid.hide() 18 | $ViewportContainer/Viewport/Board/SeedLabel.hide() 19 | $ViewportContainer/Viewport/Board/EnableAttach.hide() 20 | $ViewportContainer/Viewport/Board/Debug.hide() 21 | $ViewportContainer/Viewport/Board/ReshuffleAllDeck.hide() 22 | $ViewportContainer/Viewport/Board/ReshuffleAllDiscard.hide() 23 | $ViewportContainer/Viewport/Board/Counters.hide() 24 | 25 | # add the arena scene on top of the board scene 26 | var Arena = arena_scene.instance() 27 | $ViewportContainer/Viewport.add_child(Arena) 28 | $ViewportContainer/Viewport.move_child(Arena, 0) 29 | -------------------------------------------------------------------------------- /src/custom/cards/GreenFront.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://src/custom/CGFCardFront.tscn" type="PackedScene" id=1] 4 | 5 | [sub_resource type="StyleBoxFlat" id=1] 6 | bg_color = Color( 0.027451, 0.223529, 0, 1 ) 7 | corner_radius_top_left = 10 8 | corner_radius_top_right = 10 9 | corner_radius_bottom_right = 10 10 | corner_radius_bottom_left = 10 11 | 12 | [node name="GreenFront" instance=ExtResource( 1 )] 13 | margin_right = -1130.0 14 | margin_bottom = -480.0 15 | custom_styles/panel = SubResource( 1 ) 16 | 17 | [node name="CardText" parent="Margin" index="0"] 18 | margin_right = 148.0 19 | margin_bottom = 240.0 20 | 21 | [node name="Name" parent="Margin/CardText" index="0"] 22 | margin_right = 146.0 23 | 24 | [node name="Type" parent="Margin/CardText" index="1"] 25 | margin_right = 146.0 26 | 27 | [node name="Tags" parent="Margin/CardText" index="2"] 28 | margin_right = 146.0 29 | 30 | [node name="Requirements" parent="Margin/CardText" index="3"] 31 | margin_right = 146.0 32 | 33 | [node name="Abilities" parent="Margin/CardText" index="4"] 34 | margin_right = 146.0 35 | margin_bottom = 223.0 36 | 37 | [node name="HB" parent="Margin/CardText" index="5"] 38 | margin_top = 227.0 39 | margin_right = 146.0 40 | margin_bottom = 240.0 41 | 42 | [node name="Power" parent="Margin/CardText/HB" index="1"] 43 | margin_right = 146.0 44 | -------------------------------------------------------------------------------- /src/cc/SP.gd: -------------------------------------------------------------------------------- 1 | # SP stands for "ScriptProperties". 2 | # 3 | # This dummy class exists to allow games to extend 4 | # the core [ScriptProperties] class provided by CGF, with their own requirements. 5 | # 6 | # This is particularly useful when needing to adjust filters for the game's needs. 7 | class_name SP 8 | extends ScriptProperties 9 | 10 | # A demonstration filter setup. If you specify this value in your 11 | # card script definition for a filter, then it will look for the same key 12 | # in the trigger dictionary. If it does not, or the value does not match 13 | # then it will consider this trigger invalid for execution. 14 | const FILTER_DEMONSTRATION = "is_demonstration" 15 | 16 | # This call has been setup to call the original, and allow futher extension 17 | # simply create new filter 18 | static func filter_trigger( 19 | card_scripts, 20 | trigger_card, 21 | owner_card, 22 | trigger_details) -> bool: 23 | var is_valid := .filter_trigger(card_scripts, 24 | trigger_card, 25 | owner_card, 26 | trigger_details) 27 | # This is a sample setup of how you would setup a new filter. 28 | # See ScriptProperties for more advanced filters 29 | if is_valid and card_scripts.get("filter" + FILTER_DEMONSTRATION) \ 30 | and card_scripts.get("filter" + FILTER_DEMONSTRATION) != \ 31 | trigger_details.get(FILTER_DEMONSTRATION): 32 | is_valid = false 33 | return(is_valid) 34 | -------------------------------------------------------------------------------- /src/custom/SP.gd: -------------------------------------------------------------------------------- 1 | # SP stands for "ScriptProperties". 2 | # 3 | # This dummy class exists to allow games to extend 4 | # the core [ScriptProperties] class provided by CGF, with their own requirements. 5 | # 6 | # This is particularly useful when needing to adjust filters for the game's needs. 7 | class_name IGNORED_SP 8 | extends ScriptProperties 9 | 10 | # A demonstration filter setup. If you specify this value in your 11 | # card script definition for a filter, then it will look for the same key 12 | # in the trigger dictionary. If it does not, or the value does not match 13 | # then it will consider this trigger invalid for execution. 14 | const FILTER_DEMONSTRATION = "is_demonstration" 15 | 16 | # This call has been setup to call the original, and allow futher extension 17 | # simply create new filter 18 | static func filter_trigger( 19 | card_scripts, 20 | trigger_card, 21 | owner_card, 22 | trigger_details) -> bool: 23 | var is_valid := .filter_trigger(card_scripts, 24 | trigger_card, 25 | owner_card, 26 | trigger_details) 27 | # This is a sample setup of how you would setup a new filter. 28 | # See ScriptProperties for more advanced filters 29 | if is_valid and card_scripts.get("filter" + FILTER_DEMONSTRATION) \ 30 | and card_scripts.get("filter" + FILTER_DEMONSTRATION) != \ 31 | trigger_details.get(FILTER_DEMONSTRATION): 32 | is_valid = false 33 | return(is_valid) 34 | -------------------------------------------------------------------------------- /src/core/OptionalConfirmation.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/core/OptionalConfirmation.gd" type="Script" id=1] 4 | 5 | [sub_resource type="StyleBoxFlat" id=1] 6 | bg_color = Color( 1, 1, 1, 1 ) 7 | draw_center = false 8 | border_width_left = 3 9 | border_width_right = 3 10 | border_color = Color( 2.2, 1.6, 3, 1 ) 11 | corner_radius_top_left = 3 12 | corner_radius_bottom_right = 3 13 | 14 | [sub_resource type="StyleBoxFlat" id=2] 15 | bg_color = Color( 1, 1, 1, 1 ) 16 | draw_center = false 17 | border_width_top = 3 18 | border_width_bottom = 3 19 | border_color = Color( 1.5, 1.1, 2, 1 ) 20 | corner_radius_top_left = 3 21 | corner_radius_bottom_right = 3 22 | 23 | [node name="OptionalConfirmation" type="ConfirmationDialog"] 24 | margin_right = 20.0 25 | margin_bottom = 20.0 26 | popup_exclusive = true 27 | resizable = true 28 | script = ExtResource( 1 ) 29 | __meta__ = { 30 | "_edit_use_anchors_": false 31 | } 32 | 33 | [node name="HorizontalHighlights" type="Panel" parent="."] 34 | margin_right = 40.0 35 | margin_bottom = 40.0 36 | mouse_filter = 2 37 | custom_styles/panel = SubResource( 1 ) 38 | 39 | [node name="VecticalHighlights" type="Panel" parent="."] 40 | margin_right = 40.0 41 | margin_bottom = 40.0 42 | mouse_filter = 2 43 | custom_styles/panel = SubResource( 2 ) 44 | [connection signal="confirmed" from="." to="." method="_on_OptionalConfirmation_confirmed"] 45 | -------------------------------------------------------------------------------- /src/core/IntegerLineEdit.gd: -------------------------------------------------------------------------------- 1 | class_name IntegerLineEdit 2 | extends LineEdit 3 | 4 | signal int_changed_nok 5 | signal int_changed_ok 6 | signal int_entered(value) 7 | 8 | var previous_text: String 9 | var minimum: int 10 | var maximum: int 11 | var leading_zeroes_regex := RegEx.new() 12 | export var prevent_invalid_text: bool 13 | 14 | func _ready() -> void: 15 | # warning-ignore:return_value_discarded 16 | leading_zeroes_regex.compile("^0+([1-9]+)") 17 | # warning-ignore:return_value_discarded 18 | connect("text_changed", self, "_on_IntegerLineEdit_text_changed") 19 | # warning-ignore:return_value_discarded 20 | connect("text_entered", self, "_on_IntegerLineEdit_text_entered") 21 | 22 | func _on_IntegerLineEdit_text_entered(new_text: String) -> void: 23 | if new_text.is_valid_integer() and \ 24 | int(new_text) >= minimum \ 25 | and int(new_text) <= maximum: 26 | emit_signal("int_entered", int(new_text)) 27 | 28 | 29 | func _on_IntegerLineEdit_text_changed(new_text: String) -> void: 30 | var leading_zeroes = leading_zeroes_regex.search(new_text) 31 | if leading_zeroes: 32 | text = leading_zeroes.get_string(1) 33 | if not new_text.is_valid_integer() or \ 34 | int(new_text) < minimum \ 35 | or int(new_text) > maximum: 36 | emit_signal("int_changed_nok") 37 | if prevent_invalid_text: 38 | text = previous_text 39 | else: 40 | emit_signal("int_changed_ok") 41 | previous_text = text 42 | -------------------------------------------------------------------------------- /src/battle/ui/action_menu/UIActionMenu.gd: -------------------------------------------------------------------------------- 1 | # Menu displaying lists of actions the player can select. 2 | class_name UIActionMenu 3 | extends Control 4 | 5 | # Emitted when the player selected an action. 6 | signal action_selected 7 | 8 | # We preload our UIActionList scene to instantiate it from the code. 9 | # The file UIActionList.tscn must be in the same directory for this to work. 10 | const UIActionList := preload("UIActionList.tscn") 11 | 12 | 13 | func _ready() -> void: 14 | hide() 15 | 16 | 17 | # This function is a bit like the previous nodes' `setup()`, but I decided to call it open 18 | # instead because it feels more natural for a menu. Also, it toggles the node's visibility on. 19 | func open(battler: Battler) -> void: 20 | var list = UIActionList.instance() 21 | add_child(list) 22 | # We listen to the UIActionList's action_selected signal to automatically close the menu and 23 | # forward the signal when the player selects an action. 24 | list.connect("action_selected", self, "_on_UIActionsList_action_selected") 25 | list.setup(battler) 26 | show() 27 | # Calling the list's `focus()` method allows the first button to grab focus. 28 | list.focus() 29 | 30 | 31 | # We free the menu upon closing it. 32 | func close() -> void: 33 | hide() 34 | queue_free() 35 | 36 | 37 | func _on_UIActionsList_action_selected(action: ActionData) -> void: 38 | emit_signal("action_selected", action) 39 | close() 40 | -------------------------------------------------------------------------------- /src/cc/cards/InheritedCoreCardTemplate.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=2] 2 | 3 | [ext_resource path="res://src/core/CardTemplate.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://src/cc/DuplicateCustomCGFCardManipulationButton.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/cc/MyCardTemplate.gd" type="Script" id=3] 6 | [ext_resource path="res://src/cc/cards/DuplicateCoreTargetingArrow.tscn" type="PackedScene" id=4] 7 | [ext_resource path="res://src/cc/DuplicateCustomCGFCardFront.tscn" type="PackedScene" id=5] 8 | [ext_resource path="res://src/cc/cards/DuplicateCustomCGFCardBack.tscn" type="PackedScene" id=6] 9 | [ext_resource path="res://src/cc/cards/SFX.gd" type="Script" id=7] 10 | 11 | [sub_resource type="AudioStreamRandomPitch" id=1] 12 | 13 | [node name="Card" instance=ExtResource( 1 )] 14 | script = ExtResource( 3 ) 15 | card_back_design = ExtResource( 6 ) 16 | card_front_design = ExtResource( 5 ) 17 | targeting_arrow_scene = ExtResource( 4 ) 18 | 19 | [node name="ManipulationButtons" parent="Control" index="4"] 20 | manipulation_button = ExtResource( 2 ) 21 | 22 | [node name="SFX" type="AudioStreamPlayer" parent="." index="4"] 23 | stream = SubResource( 1 ) 24 | script = ExtResource( 7 ) 25 | 26 | [connection signal="card_moved_to_hand" from="." to="." method="_on_Card_card_moved_to_hand"] 27 | [connection signal="card_moved_to_pile" from="." to="." method="_on_Card_card_moved_to_pile"] 28 | -------------------------------------------------------------------------------- /src/custom/CGFManipulationButtons.gd: -------------------------------------------------------------------------------- 1 | extends ManipulationButtons 2 | 3 | 4 | func _ready() -> void: 5 | # The methods to use each of these should be defined in this script 6 | needed_buttons = { 7 | "Rot90": "T", 8 | "Rot180": "@", 9 | "Flip": "F", 10 | "AddToken": "O", 11 | "View": "V", 12 | } 13 | spawn_manipulation_buttons() 14 | 15 | # Hover button which rotates the card 90 degrees 16 | func _on_Rot90_pressed() -> void: 17 | # warning-ignore:return_value_discarded 18 | owner_node.set_card_rotation(90, true) 19 | 20 | 21 | # Hover button which rotates the card 180 degrees 22 | func _on_Rot180_pressed() -> void: 23 | # warning-ignore:return_value_discarded 24 | owner_node.set_card_rotation(180, true) 25 | 26 | 27 | # Hover button which flips the card facedown/faceup 28 | func _on_Flip_pressed() -> void: 29 | # warning-ignore:return_value_discarded 30 | owner_node.set_is_faceup(not owner_node.is_faceup) 31 | 32 | 33 | # Demo hover button which adds a selection of random tokens 34 | func _on_AddToken_pressed() -> void: 35 | var valid_tokens := ['tech','gold coin','blood','plasma'] 36 | # warning-ignore:return_value_discarded 37 | owner_node.tokens.mod_token(valid_tokens[CFUtils.randi() % len(valid_tokens)], 1) 38 | 39 | 40 | # Hover button which allows the player to view a facedown card 41 | func _on_View_pressed() -> void: 42 | # warning-ignore:return_value_discarded 43 | owner_node.set_is_viewed(true) 44 | 45 | -------------------------------------------------------------------------------- /src/cc/DuplicateCustomCGFManipulationButtons.gd: -------------------------------------------------------------------------------- 1 | extends ManipulationButtons 2 | 3 | 4 | func _ready() -> void: 5 | # The methods to use each of these should be defined in this script 6 | needed_buttons = { 7 | "Rot90": "T", 8 | "Rot180": "@", 9 | "Flip": "F", 10 | "AddToken": "O", 11 | "View": "V", 12 | } 13 | spawn_manipulation_buttons() 14 | 15 | # Hover button which rotates the card 90 degrees 16 | func _on_Rot90_pressed() -> void: 17 | # warning-ignore:return_value_discarded 18 | owner_node.set_card_rotation(90, true) 19 | 20 | 21 | # Hover button which rotates the card 180 degrees 22 | func _on_Rot180_pressed() -> void: 23 | # warning-ignore:return_value_discarded 24 | owner_node.set_card_rotation(180, true) 25 | 26 | 27 | # Hover button which flips the card facedown/faceup 28 | func _on_Flip_pressed() -> void: 29 | # warning-ignore:return_value_discarded 30 | owner_node.set_is_faceup(not owner_node.is_faceup) 31 | 32 | 33 | # Demo hover button which adds a selection of random tokens 34 | func _on_AddToken_pressed() -> void: 35 | var valid_tokens := ['tech','gold coin','blood','plasma'] 36 | # warning-ignore:return_value_discarded 37 | owner_node.tokens.mod_token(valid_tokens[CFUtils.randi() % len(valid_tokens)], 1) 38 | 39 | 40 | # Hover button which allows the player to view a facedown card 41 | func _on_View_pressed() -> void: 42 | # warning-ignore:return_value_discarded 43 | owner_node.set_is_viewed(true) 44 | 45 | -------------------------------------------------------------------------------- /src/core/BoardPlacementSlot.gd: -------------------------------------------------------------------------------- 1 | # Represents a spot on the placement grid that is used to organize 2 | # cards on the board. 3 | class_name BoardPlacementSlot 4 | extends Control 5 | 6 | # If a card is placed on this spot, this variable will hold a reference 7 | # to the Card object 8 | # and no other card can be placed in this slot 9 | var occupying_card = null 10 | 11 | # Stores a reference to the owning BoardPlacementGrid object 12 | onready var owner_grid = get_parent().get_parent() 13 | 14 | func _ready() -> void: 15 | # We set the initial size of our highlight and area, to 16 | # fit the size of the cards on the board. 17 | rect_min_size = CFConst.CARD_SIZE * CFConst.PLAY_AREA_SCALE 18 | $Highlight.rect_min_size = rect_min_size 19 | $Area2D/CollisionShape2D.shape.extents = rect_min_size / 2 20 | $Area2D/CollisionShape2D.position = rect_min_size / 2 21 | 22 | 23 | # Returns true if this slot is highlighted, else false 24 | func is_highlighted() -> bool: 25 | return($Highlight.visible) 26 | 27 | 28 | # Changes card highlight colour. 29 | func set_highlight(requested: bool, 30 | hoverColour = owner_grid.highlight) -> void: 31 | $Highlight.visible = requested 32 | if requested: 33 | $Highlight.modulate = hoverColour 34 | 35 | 36 | # Returns the name of the grid which is hosting this slot. 37 | # This is typically used with CFConst.BoardDropPlacement.SPECIFIC_GRID 38 | func get_grid_name() -> String: 39 | return(owner_grid.name_label.text) 40 | -------------------------------------------------------------------------------- /src/battle/ui/damage_labels/UIDamageLabelBuilder.gd: -------------------------------------------------------------------------------- 1 | # Spawns labels that display damage, healing, or missed hits. 2 | class_name UIDamageLabelBuilder 3 | extends Node2D 4 | 5 | # We preload the labels. 6 | export var damage_label_scene: PackedScene = preload("UIDamageLabel.tscn") 7 | export var miss_label_scene: PackedScene = preload("UIMissedLabel.tscn") 8 | 9 | 10 | # In setup(), we connect to the Battler's `damage_taken` and `hit_missed` signals to instantiate the appropriate labels. 11 | func setup(battlers: Array) -> void: 12 | for battler in battlers: 13 | battler.connect("damage_taken", self, "_on_Battler_damage_taken", [battler]) 14 | battler.connect("hit_missed", self, "_on_Battler_hit_missed", [battler]) 15 | 16 | 17 | # When a battler takes damage, we instantiate a damage label. 18 | func _on_Battler_damage_taken(amount: int, target: Battler) -> void: 19 | var label: UIDamageLabel = damage_label_scene.instance() 20 | # The setup() function takes care of changing the color, setting the text and placing it. 21 | label.setup(UIDamageLabel.Types.DAMAGE, target.battler_anim.get_top_anchor_global_position(), amount) 22 | # Adding the label as a child causes the animation to start. 23 | add_child(label) 24 | 25 | 26 | func _on_Battler_hit_missed(target: Battler) -> void: 27 | var label = miss_label_scene.instance() 28 | add_child(label) 29 | # The miss label doesn't have a setup() function so we set its position by hand. 30 | label.global_position = target.battler_anim.get_top_anchor_global_position() 31 | -------------------------------------------------------------------------------- /src/core/MousePointer.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://src/core/MousePointer.gd" type="Script" id=1] 4 | [ext_resource path="res://fonts/Comfortaa-Bold.ttf" type="DynamicFontData" id=2] 5 | 6 | [sub_resource type="CircleShape2D" id=1] 7 | radius = 2.0 8 | 9 | [sub_resource type="StyleBoxFlat" id=2] 10 | bg_color = Color( 1, 1, 1, 1 ) 11 | draw_center = false 12 | border_width_left = 2 13 | border_width_top = 2 14 | border_width_right = 2 15 | border_width_bottom = 2 16 | border_color = Color( 1, 1, 1, 1 ) 17 | corner_radius_top_left = 5 18 | corner_radius_top_right = 5 19 | corner_radius_bottom_right = 5 20 | corner_radius_bottom_left = 5 21 | 22 | [sub_resource type="DynamicFont" id=3] 23 | size = 20 24 | outline_size = 2 25 | outline_color = Color( 0, 0, 0, 1 ) 26 | font_data = ExtResource( 2 ) 27 | 28 | [node name="MousePointer" type="Area2D"] 29 | z_index = 100 30 | collision_layer = 524801 31 | collision_mask = 524801 32 | script = ExtResource( 1 ) 33 | 34 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 35 | shape = SubResource( 1 ) 36 | 37 | [node name="DebugShape" type="Panel" parent="."] 38 | visible = false 39 | margin_right = 10.0 40 | margin_bottom = 10.0 41 | custom_styles/panel = SubResource( 2 ) 42 | __meta__ = { 43 | "_edit_use_anchors_": false 44 | } 45 | 46 | [node name="current_focused_card" type="Label" parent="DebugShape"] 47 | margin_left = -90.0 48 | margin_top = -45.0 49 | margin_right = -50.0 50 | margin_bottom = -31.0 51 | custom_fonts/font = SubResource( 3 ) 52 | __meta__ = { 53 | "_edit_use_anchors_": false 54 | } 55 | -------------------------------------------------------------------------------- /src/custom/PlayingCardBack.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://assets/icons/view.svg" type="Texture" id=1] 4 | [ext_resource path="res://assets/card_backs/godot_back.png" type="Texture" id=2] 5 | [ext_resource path="res://src/core/Card/CardBackTexture.gd" type="Script" id=3] 6 | 7 | [sub_resource type="StyleBoxTexture" id=1] 8 | texture = ExtResource( 2 ) 9 | region_rect = Rect2( 0, 0, 141, 225 ) 10 | 11 | [node name="PlayingCardBack" type="Panel"] 12 | rect_min_size = Vector2( 150, 240 ) 13 | mouse_filter = 2 14 | custom_styles/panel = SubResource( 1 ) 15 | script = ExtResource( 3 ) 16 | __meta__ = { 17 | "_edit_use_anchors_": false 18 | } 19 | 20 | [node name="Pulse" type="Tween" parent="."] 21 | 22 | [node name="VBoxContainer" type="VBoxContainer" parent="."] 23 | anchor_right = 1.0 24 | anchor_bottom = 1.0 25 | mouse_filter = 2 26 | __meta__ = { 27 | "_edit_use_anchors_": false 28 | } 29 | 30 | [node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"] 31 | margin_right = 150.0 32 | margin_bottom = 95.0 33 | mouse_filter = 2 34 | custom_constants/margin_top = 95 35 | 36 | [node name="CenterContainer" type="CenterContainer" parent="VBoxContainer"] 37 | margin_top = 99.0 38 | margin_right = 150.0 39 | margin_bottom = 139.0 40 | rect_min_size = Vector2( 0, 40 ) 41 | mouse_filter = 2 42 | 43 | [node name="Viewed" type="TextureRect" parent="VBoxContainer/CenterContainer"] 44 | visible = false 45 | margin_left = 55.0 46 | margin_right = 95.0 47 | margin_bottom = 40.0 48 | mouse_filter = 2 49 | texture = ExtResource( 1 ) 50 | __meta__ = { 51 | "_edit_use_anchors_": false 52 | } 53 | -------------------------------------------------------------------------------- /src/core/CardChoices.gd: -------------------------------------------------------------------------------- 1 | # Pops up a menu for the player to choose on of the card 2 | # options 3 | extends PopupMenu 4 | 5 | var id_selected := 0 6 | var selected_key: String 7 | 8 | # Called from Card.execute_scripts() when a card has multiple options. 9 | # 10 | # It prepares the menu items based on the dictionary keys and bring the 11 | # popup to the front. 12 | func prep(title_reference: String, script_with_choices: Dictionary) -> void: 13 | set_item_text(0, "Please choose option for " + title_reference) 14 | # The dictionary passed is a card script which contains 15 | # an extra dictionary before the task definitions 16 | # When that happens, it specifies multiple choice 17 | # and the dictionary keys, are the choices in human-readable text. 18 | for key in script_with_choices.keys(): 19 | add_item(key) 20 | cfc.NMAP.board.add_child(self) 21 | popup_centered() 22 | # One again we need two different Panels due to 23 | # https://github.com/godotengine/godot/issues/32030 24 | $HorizontalHighlights.rect_size = rect_size 25 | $VecticalHighlights.rect_size = rect_size 26 | # We spawn the dialogue at the middle of the screen. 27 | 28 | func _on_CardChoices_id_pressed(id: int) -> void: 29 | id_selected = id 30 | selected_key = get_item_text(id) 31 | 32 | # It ensures the "id_pressed" signal is emited even when no choice has 33 | # been made, to allow the script execution to continue and not 34 | # leave yields waiting 35 | func _on_CardChoices_popup_hide() -> void: 36 | # We also allow Unit Tests to send the signal through this function 37 | if not id_selected or cfc.ut: 38 | emit_signal("id_pressed", id_selected) 39 | -------------------------------------------------------------------------------- /src/battle/command/AttackActionData.gd: -------------------------------------------------------------------------------- 1 | # Data container used to construct [AttackAction] objects. 2 | class_name AttackActionData 3 | extends ActionData 4 | 5 | # Multiplier applied to the calculated attack damage. 6 | export var damage_multiplier := 1.0 7 | # Hit chance rating for this attack. Works as a rate: a value of 90 means the 8 | # action has a 90% chance to hit. 9 | export var hit_chance := 100.0 10 | # Status effect applied by the attack, of type `StatusEffectData`. 11 | export var status_effect: Resource 12 | 13 | # Make sure that every parameter has a default value. 14 | # Otherwise, there will be problems with creating and editing 15 | # your resource via the inspector. 16 | 17 | func _init( 18 | p_damage_multiplier = 1.0, 19 | p_hit_chance = 100.0, 20 | p_status_effect = null, 21 | 22 | p_energy_cost = 0, 23 | p_damage = 1.0, 24 | p_element = Elements.NONE, 25 | p_is_targeting_self = false, 26 | p_is_targeting_all = false, 27 | p_readiness_saved = 0.0, 28 | p_label = "Base combat action" 29 | ).(p_energy_cost, p_damage, p_element, p_is_targeting_self, p_is_targeting_all, p_readiness_saved, p_label): 30 | 31 | damage_multiplier = p_damage_multiplier 32 | hit_chance = p_hit_chance 33 | status_effect = p_status_effect 34 | 35 | 36 | # Returns the total damage for the action, factoring in damage dealt by a status effect. 37 | func calculate_potential_damage_for(battler) -> int: 38 | var total_damage: int = int(Formulas.calculate_potential_damage(self, battler)) 39 | # Adding the effect's damage if applicable. 40 | if status_effect: 41 | total_damage += status_effect.calculate_total_damage() 42 | return total_damage 43 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/UIBattlerHUD.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/battler_hud/energy_bar/UIEnergyBar.tscn" type="PackedScene" id=2] 4 | [ext_resource path="res://assets/ui/theme/combat_ui_theme.tres" type="Theme" id=3] 5 | [ext_resource path="res://src/battle/ui/battler_hud/life_bar/UILifeBar.tscn" type="PackedScene" id=4] 6 | [ext_resource path="res://src/battle/ui/battler_hud/UIBattlerHUD.gd" type="Script" id=5] 7 | 8 | [node name="UIBattlerHUD" type="Position2D"] 9 | script = ExtResource( 5 ) 10 | 11 | [node name="Label" type="Label" parent="."] 12 | visible = false 13 | self_modulate = Color( 0.780392, 0.780392, 0.780392, 1 ) 14 | anchor_left = 0.5 15 | anchor_top = 0.5 16 | anchor_right = 0.5 17 | anchor_bottom = 0.5 18 | margin_left = -91.5 19 | margin_top = -100.0 20 | margin_right = 91.5 21 | margin_bottom = -27.0 22 | theme = ExtResource( 3 ) 23 | custom_colors/font_color = Color( 0.00392157, 0.188235, 0.580392, 1 ) 24 | text = "Fenyx" 25 | align = 1 26 | valign = 1 27 | __meta__ = { 28 | "_edit_use_anchors_": false 29 | } 30 | 31 | [node name="UILifeBar" parent="." instance=ExtResource( 4 )] 32 | anchor_left = 0.5 33 | anchor_top = 0.5 34 | anchor_right = 0.5 35 | anchor_bottom = 0.5 36 | margin_left = -142.5 37 | margin_top = -54.0 38 | margin_right = 142.5 39 | margin_bottom = -5.0 40 | 41 | [node name="UIEnergyBar" parent="." instance=ExtResource( 2 )] 42 | visible = false 43 | anchor_left = 0.5 44 | anchor_top = 1.0 45 | anchor_right = 0.5 46 | anchor_bottom = 1.0 47 | margin_left = -177.736 48 | margin_top = 207.464 49 | margin_right = 6177.26 50 | margin_bottom = 719.464 51 | rect_scale = Vector2( 0.15, 0.15 ) 52 | -------------------------------------------------------------------------------- /src/core/Card/CardBackGlow.gd: -------------------------------------------------------------------------------- 1 | # This script should be attached to a card back which has been 2 | # setup to modulate its colour intensity 3 | # so that it appears to glow and change glow intensity 4 | class_name CardBackGlow 5 | extends CardBack 6 | 7 | # Used for looping between brighness scales for the Cardback glow 8 | # The multipliers have to be small, as even small changes increase 9 | # brightness a lot 10 | var _pulse_values := [Color(1.05,1.05,1.05),Color(0.9,0.9,0.9)] 11 | # A link to the tween which changes the glow intensity 12 | # For this class, a Tween node called Pulse must exist at the root of the scene. 13 | onready var _tween = $Pulse 14 | 15 | 16 | func _ready() -> void: 17 | # warning-ignore:return_value_discarded 18 | _tween.connect("tween_all_completed", self, "_on_Pulse_completed") 19 | viewed_node = $VBoxContainer/CenterContainer/Viewed 20 | 21 | 22 | # Reverses the card back pulse and starts it again 23 | func _on_Pulse_completed() -> void: 24 | # We only pulse the card if it's face-down and on the board 25 | if not card_owner.is_faceup: #and get_parent() == cfc.NMAP.board: 26 | _pulse_values.invert() 27 | start_card_back_animation() 28 | else: 29 | stop_card_back_animation() 30 | 31 | 32 | # Initiates the looping card back pulse 33 | # The pulse increases and decreases the brightness of the glow 34 | func start_card_back_animation(): 35 | _tween.interpolate_property(self,'modulate', 36 | _pulse_values[0], _pulse_values[1], 2, 37 | Tween.TRANS_LINEAR, Tween.EASE_IN_OUT) 38 | _tween.start() 39 | 40 | 41 | # Disables the looping card back pulse 42 | func stop_card_back_animation(): 43 | _tween.remove_all() 44 | modulate = Color(1,1,1) 45 | -------------------------------------------------------------------------------- /src/cc/cards/DuplicateCustomCGFCardBack.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://assets/card_backs/card-back.png" type="Texture" id=1] 4 | [ext_resource path="res://src/core/Card/CardBackTexture.gd" type="Script" id=2] 5 | [ext_resource path="res://assets/icons/view.svg" type="Texture" id=3] 6 | 7 | [sub_resource type="StyleBoxTexture" id=1] 8 | texture = ExtResource( 1 ) 9 | region_rect = Rect2( 0, 0, 822, 1122 ) 10 | 11 | [node name="PlayingCardBack" type="Panel"] 12 | margin_right = 171.0 13 | margin_bottom = 240.0 14 | rect_min_size = Vector2( 171, 240 ) 15 | mouse_filter = 2 16 | custom_styles/panel = SubResource( 1 ) 17 | script = ExtResource( 2 ) 18 | __meta__ = { 19 | "_edit_use_anchors_": false 20 | } 21 | 22 | [node name="Pulse" type="Tween" parent="."] 23 | 24 | [node name="VBoxContainer" type="VBoxContainer" parent="."] 25 | anchor_right = 1.0 26 | anchor_bottom = 1.0 27 | mouse_filter = 2 28 | __meta__ = { 29 | "_edit_use_anchors_": false 30 | } 31 | 32 | [node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"] 33 | margin_right = 171.0 34 | margin_bottom = 95.0 35 | mouse_filter = 2 36 | custom_constants/margin_top = 95 37 | 38 | [node name="CenterContainer" type="CenterContainer" parent="VBoxContainer"] 39 | margin_top = 99.0 40 | margin_right = 171.0 41 | margin_bottom = 139.0 42 | rect_min_size = Vector2( 0, 40 ) 43 | mouse_filter = 2 44 | 45 | [node name="Viewed" type="TextureRect" parent="VBoxContainer/CenterContainer"] 46 | visible = false 47 | margin_left = 65.0 48 | margin_right = 105.0 49 | margin_bottom = 40.0 50 | mouse_filter = 2 51 | texture = ExtResource( 3 ) 52 | __meta__ = { 53 | "_edit_use_anchors_": false 54 | } 55 | -------------------------------------------------------------------------------- /src/custom/cards/CustomScripts.gd: -------------------------------------------------------------------------------- 1 | # This class contains very custom scripts definitionsa for objects that need them 2 | # 3 | # The definition happens via object name 4 | class_name NOTUSEDCustomScripts 5 | extends Reference 6 | 7 | var costs_dry_run := false 8 | 9 | func _init(_dry_run) -> void: 10 | costs_dry_run = _dry_run 11 | # This fuction executes custom scripts 12 | # 13 | # It relies on the definition of each script being based the object's name 14 | # Therefore the only thing we need, is the object itself to grab its name 15 | # And to have a self-reference in case it affects itself 16 | # 17 | # You can pass a predefined subject, but it's optional. 18 | func custom_script(script: ScriptObject) -> void: 19 | var card: Card = script.owner 20 | var subjects: Array = script.subjects 21 | # I don't like the extra indent caused by this if, 22 | # But not all object will be Card 23 | # So I can't be certain the "canonical_name" var will exist 24 | match script.owner.canonical_name: 25 | "Test Card 2": 26 | # No demo cost-based custom scripts 27 | if not costs_dry_run: 28 | print("This is a custom script execution.") 29 | print("Look! I am going to destroy myself now!") 30 | card.queue_free() 31 | print("You can do whatever you want here.") 32 | "Test Card 3": 33 | if not costs_dry_run: 34 | print("This custom script uses the _find_subject()" 35 | + " to find a convenient target") 36 | for subject in subjects: 37 | subjects[0].queue_free() 38 | print("Destroying: " + subjects[0].canonical_name) 39 | 40 | # warning-ignore:unused_argument 41 | func custom_alterants(script: ScriptObject) -> int: 42 | var alteration := 0 43 | return(alteration) 44 | -------------------------------------------------------------------------------- /src/core/Highlight.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://src/core/Highlight.gd" type="Script" id=1] 4 | 5 | [sub_resource type="StyleBoxFlat" id=1] 6 | content_margin_left = 6.0 7 | content_margin_right = 5.0 8 | content_margin_top = 6.0 9 | bg_color = Color( 1, 1, 1, 1 ) 10 | draw_center = false 11 | border_width_left = 3 12 | border_width_right = 3 13 | border_color = Color( 3, 3, 3, 1 ) 14 | corner_radius_top_left = 15 15 | corner_radius_top_right = 15 16 | corner_radius_bottom_right = 15 17 | corner_radius_bottom_left = 15 18 | 19 | [sub_resource type="StyleBoxFlat" id=2] 20 | content_margin_left = 6.0 21 | content_margin_right = 5.0 22 | content_margin_top = 6.0 23 | bg_color = Color( 1, 1, 1, 1 ) 24 | draw_center = false 25 | border_width_top = 2 26 | border_width_bottom = 3 27 | border_color = Color( 1.3, 1.3, 1.3, 1 ) 28 | corner_radius_top_left = 15 29 | corner_radius_top_right = 15 30 | corner_radius_bottom_right = 15 31 | corner_radius_bottom_left = 15 32 | 33 | [node name="Highlight" type="MarginContainer"] 34 | visible = false 35 | anchor_right = 1.0 36 | anchor_bottom = 1.0 37 | margin_left = -3.0 38 | margin_top = -3.0 39 | margin_right = -1283.0 40 | margin_bottom = -723.0 41 | mouse_filter = 2 42 | script = ExtResource( 1 ) 43 | __meta__ = { 44 | "_edit_group_": true 45 | } 46 | 47 | [node name="LeftRight" type="Panel" parent="."] 48 | mouse_filter = 2 49 | custom_styles/panel = SubResource( 1 ) 50 | __meta__ = { 51 | "_edit_use_anchors_": false 52 | } 53 | 54 | [node name="TopBottom" type="Panel" parent="."] 55 | modulate = Color( 1.8, 1.8, 1.8, 1 ) 56 | mouse_filter = 2 57 | custom_styles/panel = SubResource( 2 ) 58 | __meta__ = { 59 | "_edit_use_anchors_": false 60 | } 61 | -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | # ScriptEngine 2 | 3 | Example: 4 | ``` 5 | "Card Name": { 6 | "": { // see "known_card_signals" var, or "alterants" 7 | "": [ // board, hand, pile, or NONE 8 | { \ 9 | "name": "custom_script", \___ a "task" 10 | "subject": "target", / 11 | } / 12 | ] 13 | }, 14 | } 15 | ``` 16 | 17 | ## "manual" 18 | 19 | From: https://github.com/db0/godot-card-game-framework/wiki/ScriptDefinitions 20 | 21 | "manual" is default (when a card is double-clicked) 22 | 23 | var known_card_signals := [ 24 | "card_rotated", 25 | "card_flipped", 26 | "card_viewed", 27 | "card_moved_to_board", 28 | "card_moved_to_pile", 29 | "card_moved_to_hand", 30 | "card_token_modified", 31 | "card_attached", 32 | "card_unattached", 33 | "card_targeted", 34 | "card_properties_modified", 35 | ] 36 | 37 | Can be extended: 38 | - alterants 39 | 40 | # Used in place of a trigger name (e.g. 'manual'). This key allows the card to be marked as 41 | # an "Alterant". I.e. a card which will modify the values of other scripts or 42 | # effects. 43 | 44 | - competition_ended (fragment forge) 45 | 46 | ## "board" 47 | 48 | board, hand, pile, or NONE 49 | 50 | # Targeting signals 51 | 52 | In `MyTargetingArrow`: 53 | 54 | ``` 55 | 56 | tc.emit_signal("card_targeted", tc, "card_targeted", 57 | {"targeting_source": owner_object}) 58 | target_object = tc 59 | emit_signal("target_selected",target_object) 60 | 61 | ``` 62 | 63 | 64 | Is it possible to use either of `card_targeted` or `target_selected` in my battler `scriptables` implementation? -------------------------------------------------------------------------------- /src/core/VBoxContainer.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://assets/icons/view.svg" type="Texture" id=1] 4 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=2] 5 | 6 | [sub_resource type="DynamicFont" id=1] 7 | size = 12 8 | font_data = ExtResource( 2 ) 9 | 10 | [node name="VBoxContainer" type="VBoxContainer"] 11 | anchor_right = 1.0 12 | anchor_bottom = 1.0 13 | mouse_filter = 2 14 | __meta__ = { 15 | "_edit_use_anchors_": false 16 | } 17 | 18 | [node name="MarginContainer" type="MarginContainer" parent="."] 19 | margin_right = 1280.0 20 | margin_bottom = 50.0 21 | mouse_filter = 2 22 | custom_constants/margin_top = 50 23 | 24 | [node name="CenterContainer" type="CenterContainer" parent="."] 25 | margin_top = 54.0 26 | margin_right = 1280.0 27 | margin_bottom = 94.0 28 | rect_min_size = Vector2( 0, 40 ) 29 | mouse_filter = 2 30 | 31 | [node name="Viewed" type="TextureRect" parent="CenterContainer"] 32 | visible = false 33 | modulate = Color( 1.5, 0.2, 0, 1 ) 34 | margin_left = 620.0 35 | margin_right = 660.0 36 | margin_bottom = 40.0 37 | mouse_filter = 2 38 | texture = ExtResource( 1 ) 39 | __meta__ = { 40 | "_edit_use_anchors_": false 41 | } 42 | 43 | [node name="MarginContainer2" type="MarginContainer" parent="."] 44 | margin_top = 98.0 45 | margin_right = 1280.0 46 | margin_bottom = 101.0 47 | mouse_filter = 2 48 | custom_constants/margin_top = 3 49 | 50 | [node name="Label" type="Label" parent="."] 51 | margin_top = 105.0 52 | margin_right = 1280.0 53 | margin_bottom = 121.0 54 | custom_fonts/font = SubResource( 1 ) 55 | custom_colors/font_color = Color( 1, 0.2, 0, 1 ) 56 | text = "Card Game Framework" 57 | __meta__ = { 58 | "_edit_use_anchors_": false 59 | } 60 | -------------------------------------------------------------------------------- /src/core/ScriptAlter.gd: -------------------------------------------------------------------------------- 1 | # This contains information about one specific alteration requested by the card 2 | # automation 3 | class_name ScriptAlter 4 | extends ScriptObject 5 | 6 | # Stores the details arg passed the signal to use for filtering 7 | var trigger_details : Dictionary 8 | # If true if this task has been confirmed to run by the player 9 | # Only relevant for optional tasks (see [SP].KEY_IS_OPTIONAL) 10 | var is_accepted := true 11 | 12 | 13 | # Prepares the script_definition needed by the alteration to function and 14 | # checks the ongoing task and its owner_card against defined filters. 15 | func _init( 16 | alteration_script: Dictionary, 17 | trigger_card: Card, 18 | alterant_object, 19 | task_details: Dictionary).( 20 | alterant_object, 21 | alteration_script, 22 | trigger_card) -> void: 23 | # The alteration name gets its own var 24 | script_name = get_property("filter_task") 25 | trigger_details = task_details 26 | if not SP.filter_trigger( 27 | alteration_script, 28 | trigger_card, 29 | owner, 30 | trigger_details): 31 | is_valid = false 32 | if is_valid: 33 | var confirm_return = CFUtils.confirm( 34 | script_definition, 35 | owner.canonical_name, 36 | script_name) 37 | if confirm_return is GDScriptFunctionState: # Still working. 38 | confirm_return = yield(confirm_return, "completed") 39 | is_valid = confirm_return 40 | if is_valid: 41 | # The script might require counting other cards. 42 | var ret =_find_subjects([], 0) 43 | if ret is GDScriptFunctionState: # Still working. 44 | ret = yield(ret, "completed") 45 | # We emit a signal when done so that our ScriptingEngine 46 | # knows we're ready to continue 47 | emit_signal("primed") 48 | is_primed = true 49 | -------------------------------------------------------------------------------- /src/core/DeckBuilder/DBDeckCardObject.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://src/core/DeckBuilder/DBCardObjectFont.tres" type="DynamicFont" id=1] 4 | [ext_resource path="res://src/core/DeckBuilder/CardLabel.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://src/core/DeckBuilder/DBDeckCardObject.gd" type="Script" id=3] 6 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=4] 7 | 8 | [sub_resource type="DynamicFont" id=1] 9 | size = 14 10 | outline_color = Color( 0, 0, 0, 1 ) 11 | use_filter = true 12 | font_data = ExtResource( 4 ) 13 | 14 | [node name="DBDeckCardObject" type="HBoxContainer"] 15 | margin_right = 623.0 16 | margin_bottom = 18.0 17 | script = ExtResource( 3 ) 18 | __meta__ = { 19 | "_edit_use_anchors_": false 20 | } 21 | 22 | [node name="Plus" type="Button" parent="."] 23 | margin_right = 24.0 24 | margin_bottom = 24.0 25 | rect_min_size = Vector2( 24, 0 ) 26 | custom_fonts/font = SubResource( 1 ) 27 | text = "+" 28 | 29 | [node name="Minus" type="Button" parent="."] 30 | margin_left = 28.0 31 | margin_right = 52.0 32 | margin_bottom = 24.0 33 | rect_min_size = Vector2( 24, 0 ) 34 | custom_fonts/font = SubResource( 1 ) 35 | text = "-" 36 | 37 | [node name="CardCount" type="Label" parent="."] 38 | margin_left = 56.0 39 | margin_top = 3.0 40 | margin_right = 70.0 41 | margin_bottom = 21.0 42 | custom_fonts/font = ExtResource( 1 ) 43 | text = "1x" 44 | 45 | [node name="CardLabel" parent="." instance=ExtResource( 2 )] 46 | margin_left = 74.0 47 | margin_top = 3.0 48 | margin_right = 623.0 49 | margin_bottom = 21.0 50 | 51 | [connection signal="pressed" from="Plus" to="." method="_on_Plus_pressed"] 52 | [connection signal="pressed" from="Minus" to="." method="_on_Minus_pressed"] 53 | -------------------------------------------------------------------------------- /src/core/Card/CardBack.gd: -------------------------------------------------------------------------------- 1 | class_name CardBack 2 | extends Panel 3 | 4 | # This varialbe should hold the path to the node which is handling the way 5 | # the card is viewed. 6 | var viewed_node 7 | # This bool will be set to true when we want to signify that the card is viewed 8 | # while face down. 9 | var is_viewed_visible : bool setget set_is_viewed_visible 10 | 11 | # Stores a reference to the Card that is hosting this node 12 | onready var card_owner = get_parent().get_parent().get_parent() 13 | 14 | 15 | # This function can be overriden by any class extending CardBack 16 | # to implement their own way of signifying a viewed face-down card 17 | # 18 | # If a card back does not include a viewed_node definition,this 19 | # function will just show a warning. 20 | func set_is_viewed_visible(value: bool) -> void: 21 | if viewed_node: 22 | viewed_node.visible = value 23 | else: 24 | print("WARNING: viewed_node has not been defined in the card back: " + name) 25 | 26 | 27 | # Each class which extends this has to overwrite this function 28 | # with the one specific to its needs 29 | # 30 | # This is the generic function that will be called when the card back 31 | # is visible to the player 32 | func start_card_back_animation() -> void: 33 | pass 34 | 35 | # Each class which extends this has to overwrite this function 36 | # with the one specific to its needs 37 | # 38 | # This is the generic function that will be called when the card back 39 | # stops being visible to the player. 40 | func stop_card_back_animation() -> void: 41 | pass 42 | 43 | 44 | # This is used to scale the card back when the card back is shown in the 45 | # focus viewport. 46 | # 47 | # Override it according to the requirements of your card back 48 | func scale_to(scale_multiplier: float) -> void: 49 | pass 50 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/UIBattlerHUDList.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://src/battle/ui/battler_hud/UIBattlerHUDList.gd" type="Script" id=1] 4 | 5 | [sub_resource type="Animation" id=1] 6 | resource_name = "_setup" 7 | tracks/0/type = "value" 8 | tracks/0/path = NodePath(".:modulate") 9 | tracks/0/interp = 1 10 | tracks/0/loop_wrap = true 11 | tracks/0/imported = false 12 | tracks/0/enabled = true 13 | tracks/0/keys = { 14 | "times": PoolRealArray( ), 15 | "transitions": PoolRealArray( ), 16 | "update": 0, 17 | "values": [ ] 18 | } 19 | 20 | [sub_resource type="Animation" id=2] 21 | resource_name = "fade_in" 22 | length = 0.7 23 | tracks/0/type = "value" 24 | tracks/0/path = NodePath(".:modulate") 25 | tracks/0/interp = 1 26 | tracks/0/loop_wrap = true 27 | tracks/0/imported = false 28 | tracks/0/enabled = true 29 | tracks/0/keys = { 30 | "times": PoolRealArray( 0, 0.7 ), 31 | "transitions": PoolRealArray( 1, 1 ), 32 | "update": 0, 33 | "values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ] 34 | } 35 | 36 | [sub_resource type="Animation" id=3] 37 | resource_name = "fade_out" 38 | length = 0.7 39 | tracks/0/type = "value" 40 | tracks/0/path = NodePath(".:modulate") 41 | tracks/0/interp = 1 42 | tracks/0/loop_wrap = true 43 | tracks/0/imported = false 44 | tracks/0/enabled = true 45 | tracks/0/keys = { 46 | "times": PoolRealArray( 0, 0.7 ), 47 | "transitions": PoolRealArray( 1, 1 ), 48 | "update": 0, 49 | "values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ] 50 | } 51 | 52 | [node name="UIBattlerHUDList" type="Node2D"] 53 | script = ExtResource( 1 ) 54 | 55 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 56 | autoplay = "fade_in" 57 | anims/_setup = SubResource( 1 ) 58 | anims/fade_in = SubResource( 2 ) 59 | anims/fade_out = SubResource( 3 ) 60 | -------------------------------------------------------------------------------- /src/battle/ui/action_menu/UIActionButton.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=2] 2 | 3 | [ext_resource path="res://assets/ui/theme/combat_ui_theme.tres" type="Theme" id=1] 4 | [ext_resource path="res://assets/ui/action_menu/menu_action_bg_disabled.png" type="Texture" id=2] 5 | [ext_resource path="res://assets/ui/action_menu/menu_action_bg.png" type="Texture" id=3] 6 | [ext_resource path="res://assets/ui/action_menu/menu_action_bg_pressed.png" type="Texture" id=4] 7 | [ext_resource path="res://assets/ui/action_menu/menu_action_bg_focused.png" type="Texture" id=5] 8 | [ext_resource path="res://src/battle/ui/action_menu/UIActionButton.gd" type="Script" id=6] 9 | [ext_resource path="res://assets/ui/action_menu/icon_punch.svg" type="Texture" id=7] 10 | 11 | [node name="UIActionButton" type="TextureButton"] 12 | margin_right = 40.0 13 | margin_bottom = 40.0 14 | theme = ExtResource( 1 ) 15 | texture_normal = ExtResource( 3 ) 16 | texture_pressed = ExtResource( 4 ) 17 | texture_disabled = ExtResource( 2 ) 18 | texture_focused = ExtResource( 5 ) 19 | script = ExtResource( 6 ) 20 | __meta__ = { 21 | "_edit_use_anchors_": false 22 | } 23 | 24 | [node name="HBoxContainer" type="HBoxContainer" parent="."] 25 | anchor_right = 1.0 26 | anchor_bottom = 1.0 27 | margin_left = 21.0 28 | margin_top = 22.0 29 | margin_right = -21.0 30 | margin_bottom = -25.0 31 | rect_clip_content = true 32 | __meta__ = { 33 | "_edit_use_anchors_": false 34 | } 35 | 36 | [node name="Icon" type="TextureRect" parent="HBoxContainer"] 37 | margin_right = 54.0 38 | margin_bottom = 54.0 39 | texture = ExtResource( 7 ) 40 | 41 | [node name="Label" type="Label" parent="HBoxContainer"] 42 | margin_left = 58.0 43 | margin_top = 7.0 44 | margin_right = 164.0 45 | margin_bottom = 47.0 46 | text = "Action" 47 | 48 | [connection signal="pressed" from="." to="." method="_on_pressed"] 49 | -------------------------------------------------------------------------------- /src/battle/ui/battler_hud/energy_bar/UIEnergyPoint.gd: -------------------------------------------------------------------------------- 1 | # Represents one energy point. This node has two animations and functions to make it appear and 2 | # disappear smoothly. 3 | extends TextureRect 4 | 5 | # This represents a target offset when selecting the point and tweening the node's position. 6 | const POSITION_SELECTED := Vector2(0.0, -6.0) 7 | 8 | # All our animations affect the `Fill` node. 9 | onready var _fill: TextureRect = $Fill 10 | onready var _tween: Tween = $Tween 11 | 12 | # We store the start modulate value of the `Fill` node because it's semi-transparent. 13 | # This way, we can animate the color from and to this value. 14 | onready var _color_transparent := _fill.modulate 15 | 16 | 17 | func appear() -> void: 18 | # We animate the `Fill` node's color from `_color_transparent` to a fully opaque white for `0.3 19 | # seconds`. 20 | _tween.interpolate_property(_fill, "modulate", _color_transparent, Color.white, 0.3) 21 | _tween.start() 22 | 23 | 24 | func disappear() -> void: 25 | # This is the opposite of the appear animation, going from the fill's current `modulate` value 26 | # to `_color_transparent`. 27 | _tween.interpolate_property(_fill, "modulate", _fill.modulate, _color_transparent, 0.3) 28 | _tween.start() 29 | 30 | 31 | func select() -> void: 32 | # This animation offsets the node to `POSITION_SELECTED`. The "out" easing means the animation 33 | # starts at full speed and slows down as it reaches the target position. 34 | _tween.interpolate_property(_fill, "rect_position", Vector2.ZERO, POSITION_SELECTED, 0.2, Tween.TRANS_CUBIC, Tween.EASE_OUT) 35 | _tween.start() 36 | 37 | 38 | func deselect() -> void: 39 | # This is the opposite of the select animation. 40 | _tween.interpolate_property(_fill, "rect_position", POSITION_SELECTED, Vector2.ZERO, 0.2, Tween.TRANS_CUBIC, Tween.EASE_OUT) 41 | _tween.start() 42 | -------------------------------------------------------------------------------- /src/core/CardChoices.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://src/core/CardChoices.gd" type="Script" id=1] 4 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=2] 5 | 6 | [sub_resource type="DynamicFont" id=1] 7 | size = 25 8 | outline_size = 2 9 | outline_color = Color( 0, 0, 0, 1 ) 10 | use_mipmaps = true 11 | use_filter = true 12 | font_data = ExtResource( 2 ) 13 | 14 | [sub_resource type="StyleBoxFlat" id=2] 15 | bg_color = Color( 1, 1, 1, 1 ) 16 | draw_center = false 17 | border_width_left = 3 18 | border_width_right = 3 19 | border_color = Color( 2.2, 1.6, 3, 1 ) 20 | corner_radius_top_left = 3 21 | corner_radius_bottom_right = 3 22 | 23 | [sub_resource type="StyleBoxFlat" id=3] 24 | bg_color = Color( 1, 1, 1, 1 ) 25 | draw_center = false 26 | border_width_top = 3 27 | border_width_bottom = 3 28 | border_color = Color( 1.5, 1.1, 2, 1 ) 29 | corner_radius_top_left = 3 30 | corner_radius_bottom_right = 3 31 | 32 | [node name="CardChoices" type="PopupMenu"] 33 | margin_right = 20.0 34 | margin_bottom = 20.0 35 | custom_fonts/font = SubResource( 1 ) 36 | items = [ "Title", null, 0, false, true, 0, 0, null, "", false, "(Click anywhere else to abort)", null, 0, false, true, 1, 0, null, "", false, "", null, 0, false, true, 2, 0, null, "", true ] 37 | script = ExtResource( 1 ) 38 | 39 | [node name="HorizontalHighlights" type="Panel" parent="."] 40 | margin_right = 40.0 41 | margin_bottom = 40.0 42 | mouse_filter = 2 43 | custom_styles/panel = SubResource( 2 ) 44 | 45 | [node name="VecticalHighlights" type="Panel" parent="."] 46 | margin_right = 40.0 47 | margin_bottom = 40.0 48 | mouse_filter = 2 49 | custom_styles/panel = SubResource( 3 ) 50 | [connection signal="id_pressed" from="." to="." method="_on_CardChoices_id_pressed"] 51 | [connection signal="popup_hide" from="." to="." method="_on_CardChoices_popup_hide"] 52 | -------------------------------------------------------------------------------- /src/cc/cards/sets/SetScripts_Core.gd: -------------------------------------------------------------------------------- 1 | # See README.md 2 | extends Reference 3 | 4 | # This fuction returns all the scripts of the specified card name. 5 | # 6 | # if no scripts have been defined, an empty dictionary is returned instead. 7 | func get_scripts(card_name: String) -> Dictionary: 8 | var scripts := { 9 | "Elbow Bump": { 10 | "manual": { 11 | "hand": [ 12 | { 13 | "name": "custom_script", 14 | "subject": "target", 15 | }, 16 | { 17 | "name": "move_card_to_container", 18 | "dest_container": cfc.NMAP.discard, 19 | "subject": "self", 20 | }, 21 | { 22 | "name": "mod_counter", 23 | "counter_name": "credits", 24 | "is_cost": true, 25 | "modification": -1, 26 | }, 27 | ] 28 | }, 29 | }, 30 | "Knee Knock": { 31 | "manual": { 32 | "hand": [ 33 | { 34 | "name": "custom_script", 35 | "subject": "target", 36 | }, 37 | { 38 | "name": "move_card_to_container", 39 | "dest_container": cfc.NMAP.discard, 40 | "subject": "self", 41 | }, 42 | { 43 | "name": "mod_counter", 44 | "counter_name": "credits", 45 | "is_cost": true, 46 | "modification": -1, 47 | }, 48 | ] 49 | }, 50 | }, 51 | "Newspaper": { 52 | "manual": { 53 | "hand": [ 54 | { 55 | "name": "custom_script", 56 | "subject": "target", 57 | }, 58 | { 59 | "name": "move_card_to_container", 60 | "dest_container": cfc.NMAP.discard, 61 | "subject": "self", 62 | }, 63 | { 64 | "name": "mod_counter", 65 | "counter_name": "credits", 66 | "is_cost": true, 67 | "modification": -1, 68 | }, 69 | ] 70 | }, 71 | }, 72 | } 73 | # We return only the scripts that match the card name and trigger 74 | print("getting script: ", card_name) 75 | return(scripts.get(card_name,{})) 76 | -------------------------------------------------------------------------------- /src/core/BoardPlacementGrid.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://src/core/BoardPlacementSlot.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=2] 5 | [ext_resource path="res://src/core/BoardPlacementGrid.gd" type="Script" id=3] 6 | 7 | [sub_resource type="StyleBoxFlat" id=1] 8 | bg_color = Color( 0, 0, 0, 1 ) 9 | border_width_left = 2 10 | border_width_top = 2 11 | border_width_right = 2 12 | border_width_bottom = 2 13 | border_color = Color( 0.0431373, 0.294118, 0.823529, 1 ) 14 | corner_radius_top_left = 10 15 | corner_radius_top_right = 10 16 | corner_radius_bottom_right = 10 17 | corner_radius_bottom_left = 10 18 | 19 | [sub_resource type="DynamicFont" id=2] 20 | outline_size = 2 21 | outline_color = Color( 0, 0, 0, 1 ) 22 | font_data = ExtResource( 2 ) 23 | 24 | [node name="BoardPlacementGrid" type="PanelContainer" groups=[ 25 | "placement_grid", 26 | ]] 27 | self_modulate = Color( 1, 1, 1, 0.121569 ) 28 | custom_styles/panel = SubResource( 1 ) 29 | script = ExtResource( 3 ) 30 | __meta__ = { 31 | "_edit_use_anchors_": false 32 | } 33 | 34 | [node name="GridContainer" type="GridContainer" parent="."] 35 | margin_left = 2.0 36 | margin_top = 2.0 37 | margin_right = 122.0 38 | margin_bottom = 194.0 39 | custom_constants/vseparation = 5 40 | custom_constants/hseparation = 5 41 | columns = 6 42 | __meta__ = { 43 | "_edit_group_": true, 44 | "_edit_use_anchors_": false 45 | } 46 | 47 | [node name="BoardPlacementSlot" parent="GridContainer" instance=ExtResource( 1 )] 48 | 49 | [node name="Control" type="Control" parent="."] 50 | margin_left = 2.0 51 | margin_top = 2.0 52 | margin_right = 122.0 53 | margin_bottom = 194.0 54 | 55 | [node name="Label" type="Label" parent="Control"] 56 | modulate = Color( 1, 1, 1, 0.627451 ) 57 | margin_left = -20.0 58 | margin_top = -20.0 59 | margin_right = 475.0 60 | custom_fonts/font = SubResource( 2 ) 61 | __meta__ = { 62 | "_edit_use_anchors_": false 63 | } 64 | -------------------------------------------------------------------------------- /src/custom/CGFCardFront.gd: -------------------------------------------------------------------------------- 1 | extends CardFront 2 | 3 | func _ready() -> void: 4 | text_expansion_multiplier = { 5 | "Name": 2, 6 | "Tags": 1.2, 7 | "Cost": 3, 8 | "Power": 3, 9 | } 10 | compensation_label = "Abilities" 11 | _card_text = $Margin/CardText 12 | # Map your card text label layout here. We use this when scaling 13 | # The card or filling up its text 14 | card_labels["Name"] = $Margin/CardText/Name 15 | card_labels["Type"] = $Margin/CardText/Type 16 | card_labels["Tags"] = $Margin/CardText/Tags 17 | card_labels["Requirements"] = $Margin/CardText/Requirements 18 | card_labels["Abilities"] = $Margin/CardText/Abilities 19 | card_labels["Cost"] = $Margin/CardText/HB/Cost 20 | card_labels["Power"] = $Margin/CardText/HB/Power 21 | 22 | # These set te max size of each label. This is used to calculate how much 23 | # To shrink the font when it doesn't fit in the rect. 24 | card_label_min_sizes["Name"] = Vector2(CFConst.CARD_SIZE.x - 4, 19) 25 | card_label_min_sizes["Type"] = Vector2(CFConst.CARD_SIZE.x - 4, 13) 26 | card_label_min_sizes["Tags"] = Vector2(CFConst.CARD_SIZE.x - 4, 17) 27 | card_label_min_sizes["Requirements"] = Vector2(CFConst.CARD_SIZE.x - 4, 11) 28 | card_label_min_sizes["Abilities"] = Vector2(CFConst.CARD_SIZE.x - 4, 144) 29 | card_label_min_sizes["Cost"] = Vector2(40,13) 30 | card_label_min_sizes["Power"] = Vector2(40,13) 31 | 32 | # This is not strictly necessary, but it allows us to change 33 | # the card label sizes without editing the scene 34 | for l in card_label_min_sizes: 35 | card_labels[l].rect_min_size = card_label_min_sizes[l] 36 | 37 | # This stores the maximum size for each label, when the card is at its 38 | # standard size. 39 | # This is multiplied when the card is resized in the viewport. 40 | for label in card_labels: 41 | match label: 42 | "Cost","Power": 43 | original_font_sizes[label] = 10 44 | "Requirements": 45 | original_font_sizes[label] = 11 46 | _: 47 | original_font_sizes[label] = 16 48 | -------------------------------------------------------------------------------- /src/cc/DuplicateCustomCGFCardFront.gd: -------------------------------------------------------------------------------- 1 | extends CardFront 2 | 3 | onready var art := $Art 4 | 5 | func _ready() -> void: 6 | text_expansion_multiplier = { 7 | "Name": 2, 8 | "Tags": 1.2, 9 | "Cost": 3, 10 | "Power": 3, 11 | } 12 | compensation_label = "Abilities" 13 | _card_text = $Margin/CardText 14 | # Map your card text label layout here. We use this when scaling 15 | # The card or filling up its text 16 | card_labels["Name"] = $Margin/CardText/Name 17 | card_labels["Type"] = $Margin/CardText/Type 18 | card_labels["Tags"] = $Margin/CardText/Tags 19 | card_labels["Requirements"] = $Margin/CardText/Requirements 20 | card_labels["Abilities"] = $Margin/CardText/Abilities 21 | card_labels["Cost"] = $Margin/CardText/HB/Cost 22 | card_labels["Power"] = $Margin/CardText/HB/Power 23 | 24 | # These set te max size of each label. This is used to calculate how much 25 | # To shrink the font when it doesn't fit in the rect. 26 | card_label_min_sizes["Name"] = Vector2(CFConst.CARD_SIZE.x - 4, 19) 27 | card_label_min_sizes["Type"] = Vector2(CFConst.CARD_SIZE.x - 4, 13) 28 | card_label_min_sizes["Tags"] = Vector2(CFConst.CARD_SIZE.x - 4, 17) 29 | card_label_min_sizes["Requirements"] = Vector2(CFConst.CARD_SIZE.x - 4, 11) 30 | card_label_min_sizes["Abilities"] = Vector2(CFConst.CARD_SIZE.x - 4, 144) 31 | card_label_min_sizes["Cost"] = Vector2(40,13) 32 | card_label_min_sizes["Power"] = Vector2(40,13) 33 | 34 | # This is not strictly necessary, but it allows us to change 35 | # the card label sizes without editing the scene 36 | for l in card_label_min_sizes: 37 | card_labels[l].rect_min_size = card_label_min_sizes[l] 38 | 39 | # This stores the maximum size for each label, when the card is at its 40 | # standard size. 41 | # This is multiplied when the card is resized in the viewport. 42 | for label in card_labels: 43 | match label: 44 | "Cost","Power": 45 | original_font_sizes[label] = 10 46 | "Requirements": 47 | original_font_sizes[label] = 11 48 | _: 49 | original_font_sizes[label] = 16 50 | -------------------------------------------------------------------------------- /src/battle/Arena.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=10 format=2] 2 | 3 | [ext_resource path="res://src/battle/Combat.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://assets/backgrounds/train-interior.png" type="Texture" id=2] 5 | [ext_resource path="res://src/battle/Arena.gd" type="Script" id=3] 6 | [ext_resource path="res://assets/backgrounds/hills.png" type="Texture" id=4] 7 | [ext_resource path="res://assets/backgrounds/trees.png" type="Texture" id=5] 8 | [ext_resource path="res://assets/audio/sfx/train/train_ambience_loop_1.ogg" type="AudioStream" id=6] 9 | [ext_resource path="res://src/shaders/scroll_bg.shader" type="Shader" id=7] 10 | 11 | [sub_resource type="ShaderMaterial" id=1] 12 | shader = ExtResource( 7 ) 13 | shader_param/scroll_speed = null 14 | 15 | [sub_resource type="ShaderMaterial" id=2] 16 | shader = ExtResource( 7 ) 17 | shader_param/scroll_speed = null 18 | 19 | [node name="Arena" type="Node2D"] 20 | script = ExtResource( 3 ) 21 | 22 | [node name="Train" type="Node2D" parent="."] 23 | 24 | [node name="Hills" type="TextureRect" parent="Train"] 25 | material = SubResource( 1 ) 26 | margin_left = 277.725 27 | margin_top = 228.518 28 | margin_right = 3415.72 29 | margin_bottom = 466.518 30 | texture = ExtResource( 4 ) 31 | expand = true 32 | stretch_mode = 2 33 | __meta__ = { 34 | "_edit_use_anchors_": false 35 | } 36 | 37 | [node name="Trees" type="TextureRect" parent="Train"] 38 | material = SubResource( 2 ) 39 | margin_left = 272.498 40 | margin_top = 169.419 41 | margin_right = 2710.5 42 | margin_bottom = 536.419 43 | texture = ExtResource( 5 ) 44 | expand = true 45 | stretch_mode = 2 46 | __meta__ = { 47 | "_edit_use_anchors_": false 48 | } 49 | 50 | [node name="TrainInterior" type="Sprite" parent="Train"] 51 | texture = ExtResource( 2 ) 52 | centered = false 53 | 54 | [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="Train"] 55 | stream = ExtResource( 6 ) 56 | volume_db = -10.0 57 | autoplay = true 58 | 59 | [node name="Combat" parent="." instance=ExtResource( 1 )] 60 | position = Vector2( 0, 2.99658 ) 61 | --------------------------------------------------------------------------------