From cec0c4593297f0cb6d5267017dfc1bd4c23c5e4d Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Thu, 21 Nov 2019 14:04:33 -0600 Subject: [PATCH] Added last 2 units, added sidebar actions and build queue components, entities can now have their build actions put on the sidebar --- lib/component.rb | 2 +- lib/components/build_queue.rb | 14 +++++++++++ lib/components/sidebar_actions.rb | 27 +++++++++++++++++++++ lib/entities/buildings/barracks.rb | 2 ++ lib/entities/buildings/construction_yard.rb | 4 +++ lib/entities/buildings/helipad.rb | 4 +++ lib/entities/buildings/war_factory.rb | 8 +++++- lib/entities/units/helicopter.rb | 14 +++++++++++ lib/entities/units/jeep.rb | 17 +++++++++++++ lib/entity.rb | 2 +- lib/entity_controller.rb | 11 +++++++++ lib/states/game.rb | 10 ++++---- 12 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 lib/components/build_queue.rb create mode 100644 lib/components/sidebar_actions.rb create mode 100644 lib/entities/units/helicopter.rb create mode 100644 lib/entities/units/jeep.rb diff --git a/lib/component.rb b/lib/component.rb index b788686..d2f68ee 100644 --- a/lib/component.rb +++ b/lib/component.rb @@ -7,7 +7,7 @@ class IMICRTS end def self.inherited(klass) - name = klass.to_s.split("::").last.downcase.to_sym + name = klass.to_s.split("::").last.gsub(/([^A-Z])([A-Z]+)/,'\1_\2').downcase.to_sym if get(name) raise "#{klass.inspect} is already defined!" diff --git a/lib/components/build_queue.rb b/lib/components/build_queue.rb new file mode 100644 index 0000000..7d7ae8d --- /dev/null +++ b/lib/components/build_queue.rb @@ -0,0 +1,14 @@ +class IMICRTS + class BuildQueue < Component + Item = Struct.new(:entity, :progress) + def initialize(parent:) + @parent = parent + + @queue = [] + end + + def add(type) + @queue << Item.new(Entity.get(type), 0.0) + end + end +end \ No newline at end of file diff --git a/lib/components/sidebar_actions.rb b/lib/components/sidebar_actions.rb new file mode 100644 index 0000000..52853e3 --- /dev/null +++ b/lib/components/sidebar_actions.rb @@ -0,0 +1,27 @@ +class IMICRTS + class SidebarActions < Component + Action = Struct.new(:label, :image, :description, :block) + + attr_reader :actions + def initialize(parent:) + @parent = parent + + @actions = [] + end + + def add(action, *args) + case action + when :add_to_build_queue + action = Action.new + ent = IMICRTS::Entity.get(args.first) + action.label = ent.name.to_s + action.description = "Cost: #{ent.cost}\n#{ent.description}" + action.block = proc { @parent.component(:build_queue).add(args.first) } + + @actions << action + else + raise "Unhandled sidebar action: #{action.inspect}" + end + end + end +end \ No newline at end of file diff --git a/lib/entities/buildings/barracks.rb b/lib/entities/buildings/barracks.rb index 240bbb6..c36a94d 100644 --- a/lib/entities/buildings/barracks.rb +++ b/lib/entities/buildings/barracks.rb @@ -1,4 +1,6 @@ IMICRTS::Entity.define_entity(:barracks, :building, 400, "Builds and soldiers") do |entity| + entity.has(:build_queue) + entity.radius = 44 entity.max_health = 100.0 diff --git a/lib/entities/buildings/construction_yard.rb b/lib/entities/buildings/construction_yard.rb index 6c4aa47..357b008 100644 --- a/lib/entities/buildings/construction_yard.rb +++ b/lib/entities/buildings/construction_yard.rb @@ -1,4 +1,8 @@ IMICRTS::Entity.define_entity(:construction_yard, :building, 2_000, "Provides radar and builds construction workers") do |entity| + entity.has(:build_queue) + entity.has(:sidebar_actions) + entity.component(:sidebar_actions).add(:add_to_build_queue, :construction_worker) + entity.radius = 40 entity.max_health = 100.0 diff --git a/lib/entities/buildings/helipad.rb b/lib/entities/buildings/helipad.rb index 0f75e8d..521fded 100644 --- a/lib/entities/buildings/helipad.rb +++ b/lib/entities/buildings/helipad.rb @@ -1,4 +1,8 @@ IMICRTS::Entity.define_entity(:helipad, :building, 1_000, "Builds and rearms helicopters") do |entity| + entity.has(:build_queue) + entity.has(:sidebar_actions) + entity.component(:sidebar_actions).add(:add_to_build_queue, :helicopter) + entity.radius = 26 entity.max_health = 100.0 diff --git a/lib/entities/buildings/war_factory.rb b/lib/entities/buildings/war_factory.rb index f59d6ef..fe861f5 100644 --- a/lib/entities/buildings/war_factory.rb +++ b/lib/entities/buildings/war_factory.rb @@ -1,4 +1,10 @@ -IMICRTS::Entity.define_entity(:war_factory, :building, 2_000, "Generates credits") do |entity| +IMICRTS::Entity.define_entity(:war_factory, :building, 2_000, "Builds units") do |entity| + entity.has(:build_queue) + entity.has(:sidebar_actions) + entity.component(:sidebar_actions).add(:add_to_build_queue, :jeep) + entity.component(:sidebar_actions).add(:add_to_build_queue, :tank) + entity.component(:sidebar_actions).add(:add_to_build_queue, :harvester) + entity.radius = 48 entity.max_health = 100.0 diff --git a/lib/entities/units/helicopter.rb b/lib/entities/units/helicopter.rb new file mode 100644 index 0000000..2788368 --- /dev/null +++ b/lib/entities/units/helicopter.rb @@ -0,0 +1,14 @@ +IMICRTS::Entity.define_entity(:helicopter, :unit, 400, "Attacks ground targets") do |entity| + entity.has(:movement) + + entity.radius = 14 + entity.movement = :air + entity.max_health = 100.0 + + entity.body_image = "vehicles/helicopter/helicopter.png" + entity.shell_image = "vehicles/helicopter/helicopter_shell.png" + entity.overlay_image = "vehicles/helicopter/helicopter_overlay.png" + + entity.on_tick do + end +end diff --git a/lib/entities/units/jeep.rb b/lib/entities/units/jeep.rb new file mode 100644 index 0000000..393b8d0 --- /dev/null +++ b/lib/entities/units/jeep.rb @@ -0,0 +1,17 @@ +IMICRTS::Entity.define_entity(:jeep, :unit, 400, "Attacks ground targets") do |entity| + entity.has(:movement) + entity.has(:turret) + + entity.radius = 14 + entity.movement = :ground + entity.max_health = 100.0 + + entity.body_image = "vehicles/jeep/jeep.png" + entity.shell_image = "vehicles/jeep/tank_shell.png" + + entity.component(:turret).shell_image = "vehicles/jeep/jeep_turret_shell.png" + entity.component(:turret).center.y = 0.3125 + + entity.on_tick do + end +end diff --git a/lib/entity.rb b/lib/entity.rb index 8bf471e..a2d52e8 100644 --- a/lib/entity.rb +++ b/lib/entity.rb @@ -67,7 +67,7 @@ class IMICRTS if component @components[symbol] = component.new(parent: self) else - raise "Unknown component: #{component.inspect}" + raise "Unknown component: #{symbol.inspect}" end end diff --git a/lib/entity_controller.rb b/lib/entity_controller.rb index d730050..0dd434b 100644 --- a/lib/entity_controller.rb +++ b/lib/entity_controller.rb @@ -69,6 +69,17 @@ class IMICRTS @director.schedule_order(Order::SELECTED_UNITS, @player.id, @selected_entities) else pick_entity + if ent = @selected_entities.first + return unless ent.component(:sidebar_actions) + + @game.sidebar_actions.clear do |stack| + ent.component(:sidebar_actions).actions.each do |action| + stack.button action.label, tip: action.description do + action.block.call if action.block + end + end + end + end end end end diff --git a/lib/states/game.rb b/lib/states/game.rb index 6652e77..8099093 100644 --- a/lib/states/game.rb +++ b/lib/states/game.rb @@ -2,7 +2,7 @@ class IMICRTS class Game < CyberarmEngine::GuiState Overlay = Struct.new(:image, :position, :angle, :alpha) - attr_reader :sidebar, :overlays + attr_reader :sidebar, :sidebar_actions, :overlays def setup window.show_cursor = true @options[:networking_mode] ||= :host @@ -21,8 +21,8 @@ class IMICRTS label "SIDEBAR", text_size: 78, margin_bottom: 20 flow(width: 1.0) do - @buttons = stack(width: 0.9) do - @h = button("Harvester", width: 1.0) do + @sidebar_actions = stack(width: 0.9) do + button("Harvester", width: 1.0) do @player.entities << Entity.new( name: :harvester, director: @director, @@ -32,7 +32,7 @@ class IMICRTS angle: rand(360) ) end - @c = button("Construction Worker", width: 1.0) do + button("Construction Worker", width: 1.0) do @player.entities << Entity.new( name: :construction_worker, director: @director, @@ -42,7 +42,7 @@ class IMICRTS angle: rand(360) ) end - @t = button("Tank", width: 1.0) do + button("Tank", width: 1.0) do @player.entities << Entity.new( name: :tank, director: @director,