commit 1c78677eb3e9ed553bf5f5902202ebd96ce7d011 Author: Larra Emily Van Loon Date: Tue May 12 12:02:30 2026 +0200 initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/3dScene.gd b/3dScene.gd new file mode 100644 index 0000000..5718129 --- /dev/null +++ b/3dScene.gd @@ -0,0 +1,24 @@ +extends Node3D + +var handCards = []; +@export var HandParent: Node3D; + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass + +func make_card_model(card: GameState.Card): + var viewport = load("res://card_render.tscn").instantiate(); + viewport.set_card(card); + viewport.position = Vector3(-3.5 + handCards.size()*1.8, 0,0) + HandParent.add_child(viewport) + handCards.append(viewport); + + +func _on_game_state_card_drawn(card: RefCounted) -> void: + make_card_model(card) diff --git a/3dScene.gd.uid b/3dScene.gd.uid new file mode 100644 index 0000000..fda1c9e --- /dev/null +++ b/3dScene.gd.uid @@ -0,0 +1 @@ +uid://75ywelc4x5ly diff --git a/Game.tscn b/Game.tscn new file mode 100644 index 0000000..e01d8bd --- /dev/null +++ b/Game.tscn @@ -0,0 +1,36 @@ +[gd_scene format=3 uid="uid://bjnuwqt2n1qwo"] + +[ext_resource type="Script" uid="uid://jyebvspa2jud" path="res://game_state.gd" id="1_wbfu4"] +[ext_resource type="Script" uid="uid://75ywelc4x5ly" path="res://3dScene.gd" id="2_u44n3"] + +[node name="Node" type="Node" unique_id=111377658] + +[node name="GameState" type="Node" parent="." unique_id=1610400664] +script = ExtResource("1_wbfu4") + +[node name="Control" type="Control" parent="." unique_id=485009883] +layout_mode = 3 +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="Button" type="Button" parent="Control" unique_id=7224124] +layout_mode = 0 +offset_left = 509.0 +offset_top = 535.0 +offset_right = 639.0 +offset_bottom = 603.0 +text = "test" + +[node name="Node3D" type="Node3D" parent="." unique_id=218155985 node_paths=PackedStringArray("HandParent")] +script = ExtResource("2_u44n3") +HandParent = NodePath("Hand") + +[node name="Camera3D" type="Camera3D" parent="Node3D" unique_id=1715232584] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.1365387) + +[node name="Hand" type="Node3D" parent="Node3D" unique_id=524923868] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, -2) + +[connection signal="card_drawn" from="GameState" to="Node3D" method="_on_game_state_card_drawn"] +[connection signal="button_down" from="Control/Button" to="GameState" method="_on_button_button_down"] diff --git a/MultiplayerController.gd b/MultiplayerController.gd new file mode 100644 index 0000000..f552106 --- /dev/null +++ b/MultiplayerController.gd @@ -0,0 +1,53 @@ +extends Control + +@export var Address = "127.0.0.1"; +@export var port = 8910 + +var peer; + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + multiplayer.peer_connected.connect(PlayerConnected) + multiplayer.peer_disconnected.connect(PlayerDisconnected) + multiplayer.connected_to_server.connect(ConnectedToServer) + multiplayer.connection_failed.connect(ConnectionFailed) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass + +# server and client +func PlayerConnected(id): + print("Player connected " + str(id)); + +func PlayerDisconnected(id): + print("Player disconnected " + str(id)) + +# client only +func ConnectedToServer(): + print("connected to server!") + +func ConnectionFailed(): + print("connection failed"); + +func _on_host_button_down() -> void: + peer = ENetMultiplayerPeer.new() + var error = peer.create_server(port, 2) + if error != OK: + print("cannot host" + error) + return + + multiplayer.set_multiplayer_peer(peer); + print("waiting for players") + + +func _on_join_button_down() -> void: + peer = ENetMultiplayerPeer.new() + peer.create_client(Address, port); + + multiplayer.set_multiplayer_peer(peer) + + +func _on_start_button_down() -> void: + pass # Replace with function body. diff --git a/MultiplayerController.gd.uid b/MultiplayerController.gd.uid new file mode 100644 index 0000000..60b4a00 --- /dev/null +++ b/MultiplayerController.gd.uid @@ -0,0 +1 @@ +uid://ddnryq3tes123 diff --git a/SRCMDALG_Scout.jpg b/SRCMDALG_Scout.jpg new file mode 100644 index 0000000..a0c6b75 Binary files /dev/null and b/SRCMDALG_Scout.jpg differ diff --git a/SRCMDALG_Scout.jpg.import b/SRCMDALG_Scout.jpg.import new file mode 100644 index 0000000..7232b50 --- /dev/null +++ b/SRCMDALG_Scout.jpg.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://btpo7d6bwaj8j" +path="res://.godot/imported/SRCMDALG_Scout.jpg-d976b2a4237d0f4d39a379550f2fcb8d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://SRCMDALG_Scout.jpg" +dest_files=["res://.godot/imported/SRCMDALG_Scout.jpg-d976b2a4237d0f4d39a379550f2fcb8d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/card_render.gd b/card_render.gd new file mode 100644 index 0000000..1a1cd87 --- /dev/null +++ b/card_render.gd @@ -0,0 +1,17 @@ +extends Node + +@export var NameNode:Label; +@export var CostNode:Label; + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass + +func set_card(card: GameState.Card): + NameNode.text = card.name; + CostNode.text = str(card.cost); diff --git a/card_render.gd.uid b/card_render.gd.uid new file mode 100644 index 0000000..ea21ea4 --- /dev/null +++ b/card_render.gd.uid @@ -0,0 +1 @@ +uid://bpbofmi7gvj6p diff --git a/card_render.tscn b/card_render.tscn new file mode 100644 index 0000000..385940c --- /dev/null +++ b/card_render.tscn @@ -0,0 +1,95 @@ +[gd_scene format=3 uid="uid://jsrjasxkd820"] + +[ext_resource type="Script" uid="uid://bpbofmi7gvj6p" path="res://card_render.gd" id="1_3dncl"] + +[sub_resource type="Gradient" id="Gradient_sb48q"] +offsets = PackedFloat32Array(0, 0.5294118, 0.9909502) +colors = PackedColorArray(0, 0, 0, 1, 0.11858138, 0.11858138, 0.11858138, 1, 0, 0, 0, 1) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_t88pq"] +gradient = SubResource("Gradient_sb48q") +repeat = 1 + +[sub_resource type="LabelSettings" id="LabelSettings_r0x5m"] +font_size = 17 + +[sub_resource type="ViewportTexture" id="ViewportTexture_3dncl"] +viewport_path = NodePath("CardRender") + +[sub_resource type="Animation" id="Animation_3dncl"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite3D:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_eaqeq"] +resource_name = "new_animation" +length = 4.0 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite3D:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1.98, 4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0.5235988, 0), Vector3(0, -0.5235988, 0), Vector3(0, 0.5235988, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_ash2r"] +_data = { +&"RESET": SubResource("Animation_3dncl"), +&"new_animation": SubResource("Animation_eaqeq") +} + +[node name="Card" type="Node3D" unique_id=596397715 node_paths=PackedStringArray("NameNode", "CostNode")] +script = ExtResource("1_3dncl") +NameNode = NodePath("CardRender/Node2D/Name") +CostNode = NodePath("CardRender/Node2D/Cost") + +[node name="CardRender" type="SubViewport" parent="." unique_id=1189133253] +size = Vector2i(160, 190) + +[node name="Node2D" type="Node2D" parent="CardRender" unique_id=127198536] + +[node name="BG" type="Sprite2D" parent="CardRender/Node2D" unique_id=545821664] +position = Vector2(80, 96.00001) +scale = Vector2(2.5, 3) +texture = SubResource("GradientTexture2D_t88pq") + +[node name="Name" type="Label" parent="CardRender/Node2D" unique_id=537154871] +offset_left = 24.0 +offset_right = 138.0 +offset_bottom = 25.0 +text = "Test" +label_settings = SubResource("LabelSettings_r0x5m") +horizontal_alignment = 1 +clip_text = true + +[node name="Cost" type="Label" parent="CardRender/Node2D" unique_id=1196428120] +offset_left = 138.0 +offset_right = 160.0 +offset_bottom = 25.0 +text = "-1" +label_settings = SubResource("LabelSettings_r0x5m") +horizontal_alignment = 1 +clip_text = true + +[node name="Sprite3D" type="Sprite3D" parent="." unique_id=1634659694] +texture = SubResource("ViewportTexture_3dncl") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1857926089] +libraries/ = SubResource("AnimationLibrary_ash2r") +autoplay = &"RESET" diff --git a/game_state.gd b/game_state.gd new file mode 100644 index 0000000..c2d1e17 --- /dev/null +++ b/game_state.gd @@ -0,0 +1,100 @@ +extends Node +class_name GameState + +signal card_drawn(card: Card) + +enum Faction {Scavangers, Kingdom, Emporium} + +class Player: + var name: String; + var id: int; + var deck: Array; + var hand: Array; + var discard: Array; + var combat: int; + var trade: int; + +class Card: + var name: String; + var cost: int; + var primaryAbilityEffects: Array; + var allyAbility: Faction; + var allyAbilityEffects: Array; + var acquireAbilityEffects: Array; + var faction: Faction; + + +# effects +class TradeGainEffect: + static func NewTradeGainEffect(amount: int): + return {Type = "TradeGain", Amount = amount} + + static func TradeGainDisplay(): + pass + + static func ProcessTradeGainEffect(effect, state): + state.trade = effect.Amount; + +class CombatGainEffect: + static func NewCombatGainEffect(amount: int): + return {Type = "CombatGain", Amount = amount} + + static func CombatGainDisplay(): + pass + + static func ProcessCombatGainEffect(effect, state): + state.trade = effect.Amount; + +# make cards +static func make_scout(): + var card := Card.new(); + card.name = "Scout" + card.cost = 0; + card.primaryAbilityEffects = [TradeGainEffect.NewTradeGainEffect(1)]; + return card; + +static func make_viper(): + var card := Card.new(); + card.name = "Viper" + card.cost = 0; + card.primaryAbilityEffects = [CombatGainEffect.NewCombatGainEffect(1)]; + return card; + +static func make_starting_deck(): + var deck = []; + for i in range(8): + deck.append(make_scout()) + for i in range(2): + deck.append(make_viper()) + return deck; + + +var player = Player.new() +var rng = RandomNumberGenerator.new() + +func draw_card(): + var cardId = rng.randi_range(0, player.deck.size()-1) + var card = player.deck[cardId] + player.hand.append(card) + player.deck.remove_at(cardId) + card_drawn.emit(card) + + +func draw_cards(n: int): + for i in range(n): + draw_card() + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + player.name = "placeholder" + player.deck = make_starting_deck() + draw_cards(5) + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass + + + +func _on_button_button_down() -> void: + draw_cards(5) diff --git a/game_state.gd.uid b/game_state.gd.uid new file mode 100644 index 0000000..0cf1747 --- /dev/null +++ b/game_state.gd.uid @@ -0,0 +1 @@ +uid://jyebvspa2jud diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..fc4c7cd --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bc8jfct36ppc6" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/multiplayerScene.tscn b/multiplayerScene.tscn new file mode 100644 index 0000000..1beb8aa --- /dev/null +++ b/multiplayerScene.tscn @@ -0,0 +1,41 @@ +[gd_scene format=3 uid="uid://dv0gb47bqfiqr"] + +[ext_resource type="Script" uid="uid://ddnryq3tes123" path="res://MultiplayerController.gd" id="1_ixi2m"] + +[node name="Control" type="Control" unique_id=1661870672] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_ixi2m") + +[node name="Host" type="Button" parent="." unique_id=1368042197] +layout_mode = 0 +offset_left = 84.0 +offset_top = 239.0 +offset_right = 209.0 +offset_bottom = 307.0 +text = "Host +" + +[node name="Join" type="Button" parent="." unique_id=1475030796] +layout_mode = 0 +offset_left = 243.0 +offset_top = 244.0 +offset_right = 368.0 +offset_bottom = 312.0 +text = "Join" + +[node name="Start" type="Button" parent="." unique_id=838367059] +layout_mode = 0 +offset_left = 96.0 +offset_top = 343.0 +offset_right = 355.0 +offset_bottom = 440.0 +text = "start" + +[connection signal="button_down" from="Host" to="." method="_on_host_button_down"] +[connection signal="button_down" from="Join" to="." method="_on_join_button_down"] +[connection signal="button_down" from="Start" to="." method="_on_start_button_down"] diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..8b17828 --- /dev/null +++ b/project.godot @@ -0,0 +1,25 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="TestCardGame" +run/main_scene="uid://dv0gb47bqfiqr" +config/features=PackedStringArray("4.6", "Mobile") +config/icon="res://icon.svg" + +[physics] + +3d/physics_engine="Jolt Physics" + +[rendering] + +rendering_device/driver.windows="d3d12" +renderer/rendering_method="mobile"