mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-13 06:42:35 +00:00
Ran rubocop autocorrect
This commit is contained in:
13
Gemfile
13
Gemfile
@@ -1,14 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
source "https://rubygems.org"
|
||||
gem "rake"
|
||||
gem "opengl-bindings", require: "opengl"
|
||||
gem "cyberarm_engine", git: "https://github.com/cyberarm/cyberarm_engine"
|
||||
gem "nokogiri", ">= 1.11.0.rc1"
|
||||
gem "i18n"
|
||||
gem "nokogiri", ">= 1.11.0.rc1"
|
||||
gem "opengl-bindings", require: "opengl"
|
||||
gem "rake"
|
||||
|
||||
group(:packaging) do
|
||||
gem "releasy", github: "gosu/releasy"
|
||||
gem "ocra"
|
||||
gem "rubyzip"
|
||||
gem "excon"
|
||||
gem "ocra"
|
||||
gem "releasy", github: "gosu/releasy"
|
||||
gem "rubyzip"
|
||||
end
|
||||
|
||||
3
Rakefile
3
Rakefile
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "json"
|
||||
require "tmpdir"
|
||||
require "fileutils"
|
||||
@@ -6,7 +7,7 @@ require "fileutils"
|
||||
require "zip"
|
||||
require "excon"
|
||||
require "releasy"
|
||||
require 'bundler/setup' # Releasy requires that your application uses bundler.
|
||||
require "bundler/setup" # Releasy requires that your application uses bundler.
|
||||
require_relative "lib/version"
|
||||
|
||||
Releasy::Project.new do
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
begin
|
||||
require_relative "../cyberarm_engine/lib/cyberarm_engine"
|
||||
rescue LoadError
|
||||
@@ -13,26 +14,26 @@ class Window < Gosu::Window
|
||||
@slope = 250
|
||||
@color_step = 10
|
||||
@base_color = Gosu::Color.rgb(255, 127, 0)
|
||||
@title = CyberarmEngine::Text.new("I-MIC FPS", color: Gosu::Color.rgb(255,127,0), size: 100, x: 0, y: 15, alignment: :center)
|
||||
@singleplayer = CyberarmEngine::Text.new("Singleplayer", color: Gosu::Color.rgb(0,127,127), size: 50, x: 0, y: 150, alignment: :center)
|
||||
@title = CyberarmEngine::Text.new("I-MIC FPS", color: Gosu::Color.rgb(255, 127, 0), size: 100, x: 0, y: 15, alignment: :center)
|
||||
@singleplayer = CyberarmEngine::Text.new("Singleplayer", color: Gosu::Color.rgb(0, 127, 127), size: 50, x: 0, y: 150, alignment: :center)
|
||||
end
|
||||
|
||||
def draw
|
||||
@background ||= Gosu.record(Gosu.screen_width, Gosu.screen_height) do
|
||||
((Gosu.screen_height+@slope)/@size).times do |i|
|
||||
((Gosu.screen_height + @slope) / @size).times do |i|
|
||||
fill_quad(
|
||||
0, i*@size,
|
||||
0, @slope+(i*@size),
|
||||
Gosu.screen_width/2, (-@slope)+(i*@size),
|
||||
Gosu.screen_width/2, i*@size,
|
||||
Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, 200)
|
||||
0, i * @size,
|
||||
0, @slope + (i * @size),
|
||||
Gosu.screen_width / 2, (-@slope) + (i * @size),
|
||||
Gosu.screen_width / 2, i * @size,
|
||||
Gosu::Color.rgba(@base_color.red - i * @color_step, @base_color.green - i * @color_step, @base_color.blue - i * @color_step, 200)
|
||||
)
|
||||
fill_quad(
|
||||
Gosu.screen_width, i*@size,
|
||||
Gosu.screen_width, @slope+(i*@size),
|
||||
Gosu.screen_width/2, (-@slope)+(i*@size),
|
||||
Gosu.screen_width/2, i*@size,
|
||||
Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, 200)
|
||||
Gosu.screen_width, i * @size,
|
||||
Gosu.screen_width, @slope + (i * @size),
|
||||
Gosu.screen_width / 2, (-@slope) + (i * @size),
|
||||
Gosu.screen_width / 2, i * @size,
|
||||
Gosu::Color.rgba(@base_color.red - i * @color_step, @base_color.green - i * @color_step, @base_color.blue - i * @color_step, 200)
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -41,8 +42,8 @@ class Window < Gosu::Window
|
||||
|
||||
# Box
|
||||
draw_rect(
|
||||
Gosu.screen_width/4, 0,
|
||||
Gosu.screen_width/2, Gosu.screen_height,
|
||||
Gosu.screen_width / 4, 0,
|
||||
Gosu.screen_width / 2, Gosu.screen_height,
|
||||
Gosu::Color.rgba(100, 100, 100, 150)
|
||||
# Gosu::Color.rgba(@base_color.red+@color_step, @base_color.green+@color_step, @base_color.blue+@color_step, 200)
|
||||
)
|
||||
@@ -54,21 +55,21 @@ class Window < Gosu::Window
|
||||
# Cursor
|
||||
fill_quad(
|
||||
mouse_x, mouse_y,
|
||||
mouse_x+16, mouse_y+16,
|
||||
mouse_x, mouse_y+16,
|
||||
mouse_x, mouse_y+16,
|
||||
mouse_x + 16, mouse_y + 16,
|
||||
mouse_x, mouse_y + 16,
|
||||
mouse_x, mouse_y + 16,
|
||||
Gosu::Color::RED, Float::INFINITY
|
||||
)
|
||||
end
|
||||
|
||||
def fill_quad(x1, y1, x2, y2, x3, y3, x4, y4, color = Gosu::Color::WHITE, z = 0, mode = :default)
|
||||
draw_quad(
|
||||
x1,y1, color,
|
||||
x2,y2, color,
|
||||
x3,y3, color,
|
||||
x4,y4, color,
|
||||
x1, y1, color,
|
||||
x2, y2, color,
|
||||
x3, y3, color,
|
||||
x4, y4, color,
|
||||
z, mode
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
origin = entity.position
|
||||
|
||||
on.entity_moved do |event|
|
||||
if origin.distance3d(event.entity.position) <= 3.0
|
||||
entity.position = origin + Vector.up * 2.4
|
||||
else
|
||||
entity.position = origin
|
||||
end
|
||||
entity.position = if origin.distance3d(event.entity.position) <= 3.0
|
||||
origin + Vector.up * 2.4
|
||||
else
|
||||
origin
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
component(:building)
|
||||
|
||||
on.create do |event|
|
||||
map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(-1.5, 1.5, -4.52), Vector.new(0, 20, 0), data: {team: nil})
|
||||
map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(-1.5, 1.5, -4.52), Vector.new(0, 20, 0), data: { team: nil })
|
||||
map.insert_entity("base", "information_panel", event.entity.position + Vector.new(3, 0, 1), Vector.new(0, -90, 0))
|
||||
map.insert_entity("base", "door", event.entity.position + Vector.new(0, 0, 6), Vector.new(0, 0, 0))
|
||||
map.insert_entity("base", "door", event.entity.position + Vector.new(0, 0, 6), Vector.new(0, 180, 0))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
component(:vehicle) # Generic, Weapon
|
||||
|
||||
on.button_down(:interact) do |event|
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
component(:building)
|
||||
|
||||
on.create do |event|
|
||||
map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(6, 1.5, 3), Vector.new(0, -90, 0), data: {team: nil})
|
||||
map.insert_entity("base", "purchase_terminal", event.entity.position + Vector.new(6, 1.5, 3), Vector.new(0, -90, 0), data: { team: nil })
|
||||
map.insert_entity("base", "information_panel", event.entity.position + Vector.new(0.5, 0, 3), Vector.new(0, 90, 0))
|
||||
map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 0, 0))
|
||||
map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 180, 0))
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
IMICFPS_SERVER_MODE = true
|
||||
require_relative "i-mic-fps"
|
||||
|
||||
director = IMICFPS::Networking::Director.new(mode: :server, hostname: "0.0.0.0", port: 56789, interface: IMICFPS::Networking::MemoryServer)
|
||||
director = IMICFPS::Networking::Director.new(mode: :server, hostname: "0.0.0.0", port: 56_789, interface: IMICFPS::Networking::MemoryServer)
|
||||
director.define_singleton_method(:tick) do |dt|
|
||||
puts "Ticked: #{dt}"
|
||||
end
|
||||
|
||||
42
i-mic-fps.rb
42
i-mic-fps.rb
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "fiddle"
|
||||
require "yaml"
|
||||
require "json"
|
||||
@@ -18,8 +19,8 @@ begin
|
||||
require_relative "../cyberarm_engine/lib/cyberarm_engine/opengl"
|
||||
rescue LoadError => e
|
||||
pp e
|
||||
require "cyberarm_engine"
|
||||
require "cyberarm_engine/opengl"
|
||||
require "cyberarm_engine"
|
||||
require "cyberarm_engine/opengl"
|
||||
end
|
||||
|
||||
Dir.chdir(File.dirname(__FILE__))
|
||||
@@ -31,16 +32,16 @@ include GLU
|
||||
def require_all(directory)
|
||||
files = Dir["#{directory}/**/*.rb"].sort!
|
||||
|
||||
begin
|
||||
loop do
|
||||
failed = []
|
||||
first_name_error = nil
|
||||
|
||||
files.each do |file|
|
||||
begin
|
||||
require_relative file
|
||||
rescue NameError => name_error
|
||||
rescue NameError => e
|
||||
failed << file
|
||||
first_name_error ||= name_error
|
||||
first_name_error ||= e
|
||||
end
|
||||
end
|
||||
|
||||
@@ -49,7 +50,8 @@ def require_all(directory)
|
||||
else
|
||||
files = failed
|
||||
end
|
||||
end until( failed.empty? )
|
||||
break if failed.empty?
|
||||
end
|
||||
end
|
||||
|
||||
require_all "lib"
|
||||
@@ -68,24 +70,22 @@ def prevent_launch?
|
||||
return [true, "#{m}: Packaging lockfile is present (#{packaging_lockfile})"]
|
||||
end
|
||||
|
||||
return [false, ""]
|
||||
[false, ""]
|
||||
end
|
||||
|
||||
unless prevent_launch?[0]
|
||||
if ARGV.join.include?("--profile")
|
||||
begin
|
||||
require "ruby-prof"
|
||||
RubyProf.start
|
||||
IMICFPS::Window.new.show
|
||||
result = RubyProf.stop
|
||||
printer = RubyProf::MultiPrinter.new(result)
|
||||
printer.print(path: ".", profile: "profile", min_percent: 2)
|
||||
rescue LoadError
|
||||
puts "ruby-prof not installed!"
|
||||
end
|
||||
else
|
||||
if prevent_launch?[0]
|
||||
puts prevent_launch?[1]
|
||||
elsif ARGV.join.include?("--profile")
|
||||
begin
|
||||
require "ruby-prof"
|
||||
RubyProf.start
|
||||
IMICFPS::Window.new.show
|
||||
result = RubyProf.stop
|
||||
printer = RubyProf::MultiPrinter.new(result)
|
||||
printer.print(path: ".", profile: "profile", min_percent: 2)
|
||||
rescue LoadError
|
||||
puts "ruby-prof not installed!"
|
||||
end
|
||||
else
|
||||
puts prevent_launch?[1]
|
||||
IMICFPS::Window.new.show
|
||||
end
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class CameraController
|
||||
include CommonMethods
|
||||
|
||||
attr_accessor :mode, :camera, :entity, :distance, :origin_distance,
|
||||
:constant_pitch, :mouse_sensitivity, :mouse_captured
|
||||
def initialize(mode: :fpv, camera:, entity:)
|
||||
|
||||
def initialize(camera:, entity:, mode: :fpv)
|
||||
# :fpv - First Person View
|
||||
# :tpv - Third Person View
|
||||
@mode = mode
|
||||
@@ -16,7 +18,8 @@ class IMICFPS
|
||||
@origin_distance = @distance
|
||||
@constant_pitch = 20.0
|
||||
|
||||
window.mouse_x, window.mouse_y = window.width / 2, window.height / 2
|
||||
window.mouse_x = window.width / 2
|
||||
window.mouse_y = window.height / 2
|
||||
|
||||
@true_mouse = Point.new(window.width / 2, window.height / 2)
|
||||
@mouse_sensitivity = 20.0 # Less is faster, more is slower
|
||||
@@ -41,11 +44,11 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def position_camera
|
||||
if first_person_view?
|
||||
@distance = 0
|
||||
else
|
||||
@distance = @origin_distance
|
||||
end
|
||||
@distance = if first_person_view?
|
||||
0
|
||||
else
|
||||
@origin_distance
|
||||
end
|
||||
|
||||
x_offset = horizontal_distance_from_object * Math.sin(@entity.orientation.y.degrees_to_radians)
|
||||
z_offset = horizontal_distance_from_object * Math.cos(@entity.orientation.y.degrees_to_radians)
|
||||
@@ -63,7 +66,7 @@ class IMICFPS
|
||||
position_camera
|
||||
|
||||
if @mouse_captured
|
||||
delta = Float(@true_mouse.x - self.mouse_x) / (@mouse_sensitivity * @camera.field_of_view) * 70
|
||||
delta = Float(@true_mouse.x - mouse_x) / (@mouse_sensitivity * @camera.field_of_view) * 70
|
||||
@camera.orientation.y -= delta
|
||||
@camera.orientation.y %= 360.0
|
||||
|
||||
@@ -73,9 +76,10 @@ class IMICFPS
|
||||
@entity.orientation.y += delta
|
||||
@entity.orientation.y %= 360.0
|
||||
|
||||
window.mouse_x = window.width / 2 if window.mouse_x <= 1 || window.mouse_x >= window.width-1
|
||||
window.mouse_y = window.height / 2 if window.mouse_y <= 1 || window.mouse_y >= window.height-1
|
||||
@true_mouse.x, @true_mouse.y = window.mouse_x, window.mouse_y
|
||||
window.mouse_x = window.width / 2 if window.mouse_x <= 1 || window.mouse_x >= window.width - 1
|
||||
window.mouse_y = window.height / 2 if window.mouse_y <= 1 || window.mouse_y >= window.height - 1
|
||||
@true_mouse.x = window.mouse_x
|
||||
@true_mouse.y = window.mouse_y
|
||||
end
|
||||
end
|
||||
|
||||
@@ -102,6 +106,7 @@ class IMICFPS
|
||||
end
|
||||
end
|
||||
|
||||
def button_up(id); end
|
||||
def button_up(id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,20 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
def self.assets_path
|
||||
File.expand_path("./../../assets", __FILE__)
|
||||
File.expand_path("../assets", __dir__)
|
||||
end
|
||||
|
||||
module CommonMethods
|
||||
def window
|
||||
$window
|
||||
end
|
||||
|
||||
def window; $window; end
|
||||
def delta_time
|
||||
(Gosu.milliseconds - window.delta_time) / 1000.0
|
||||
end
|
||||
|
||||
def delta_time; (Gosu.milliseconds - window.delta_time) / 1000.0; end
|
||||
def button_down?(id); window.button_down?(id); end
|
||||
def button_down?(id)
|
||||
window.button_down?(id)
|
||||
end
|
||||
|
||||
def mouse_x; window.mouse_x; end
|
||||
def mouse_y; window.mouse_y; end
|
||||
def mouse_x=(int); window.mouse_x = int; end
|
||||
def mouse_y=(int); window.mouse_y = int; end
|
||||
def mouse_x
|
||||
window.mouse_x
|
||||
end
|
||||
|
||||
def mouse_y
|
||||
window.mouse_y
|
||||
end
|
||||
|
||||
def mouse_x=(int)
|
||||
window.mouse_x = int
|
||||
end
|
||||
|
||||
def mouse_y=(int)
|
||||
window.mouse_y = int
|
||||
end
|
||||
|
||||
def gl(&block)
|
||||
window.gl do
|
||||
@@ -25,32 +43,43 @@ class IMICFPS
|
||||
def formatted_number(number)
|
||||
string = number.to_s.reverse.scan(/\d{1,3}/).join(",").reverse
|
||||
|
||||
string.insert(0, "-") if number < 0
|
||||
string.insert(0, "-") if number.negative?
|
||||
|
||||
return string
|
||||
string
|
||||
end
|
||||
|
||||
def control_down?; button_down?(Gosu::KbLeftControl) || button_down?(Gosu::KbRightControl); end
|
||||
def shift_down?; button_down?(Gosu::KbLeftShift) || button_down?(Gosu::KbRightShift); end
|
||||
def alt_down?; button_down?(Gosu::KbLeftAlt) || button_down?(Gosu::KbRightAlt); end
|
||||
def control_down?
|
||||
button_down?(Gosu::KbLeftControl) || button_down?(Gosu::KbRightControl)
|
||||
end
|
||||
|
||||
def shift_down?
|
||||
button_down?(Gosu::KbLeftShift) || button_down?(Gosu::KbRightShift)
|
||||
end
|
||||
|
||||
def alt_down?
|
||||
button_down?(Gosu::KbLeftAlt) || button_down?(Gosu::KbRightAlt)
|
||||
end
|
||||
|
||||
def draw_rect(*args)
|
||||
window.draw_rect(*args)
|
||||
end
|
||||
|
||||
def draw_quad(*args)
|
||||
window.draw_quad(*args)
|
||||
end
|
||||
|
||||
def fill(color = Gosu::Color::WHITE, z = 0)
|
||||
draw_rect(0, 0, window.width, window.height, color, z)
|
||||
end
|
||||
|
||||
def fill_quad(x1, y1, x2, y2, x3, y3, x4, y4, color = Gosu::Color::WHITE, z = 0, mode = :default)
|
||||
draw_quad(
|
||||
x1,y1, color,
|
||||
x2,y2, color,
|
||||
x3,y3, color,
|
||||
x4,y4, color,
|
||||
x1, y1, color,
|
||||
x2, y2, color,
|
||||
x3, y3, color,
|
||||
x4, y4, color,
|
||||
z, mode
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def menu_background(primary_color, accent_color, color_step, transparency, bar_size, slope)
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Component
|
||||
COMPONENTS = {}
|
||||
@components = {}
|
||||
|
||||
def self.get(name)
|
||||
COMPONENTS.dig(name)
|
||||
@components[name]
|
||||
end
|
||||
|
||||
def self.inherited(subclass)
|
||||
COMPONENTS["__pending"] ||= []
|
||||
COMPONENTS["__pending"] << subclass
|
||||
@components["__pending"] ||= []
|
||||
@components["__pending"] << subclass
|
||||
end
|
||||
|
||||
def self.initiate
|
||||
return unless COMPONENTS.dig("__pending") # Already setup
|
||||
return unless @components["__pending"] # Already setup
|
||||
|
||||
COMPONENTS["__pending"].each do |klass|
|
||||
@components["__pending"].each do |klass|
|
||||
component = klass.new
|
||||
COMPONENTS[component.name] = component
|
||||
@components[component.name] = component
|
||||
end
|
||||
|
||||
COMPONENTS.delete("__pending")
|
||||
@components.delete("__pending")
|
||||
end
|
||||
|
||||
def initialize
|
||||
@@ -31,9 +32,7 @@ class IMICFPS
|
||||
string = self.class.name.split("::").last
|
||||
split = string.scan(/[A-Z][a-z]*/)
|
||||
|
||||
component_name = "#{split.map { |s| s.downcase }.join("_")}".to_sym
|
||||
|
||||
return component_name
|
||||
split.map(&:downcase).join("_").to_s.to_sym
|
||||
end
|
||||
|
||||
def setup
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Components
|
||||
class Building < Component
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
GAME_ROOT_PATH = File.expand_path("..", File.dirname(__FILE__))
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Crosshair
|
||||
include CommonMethods
|
||||
|
||||
def initialize(color: Gosu::Color.rgb(255,127,0), size: 10, thickness: 3)
|
||||
def initialize(color: Gosu::Color.rgb(255, 127, 0), size: 10, thickness: 3)
|
||||
@color = color
|
||||
@size = size
|
||||
@thickness = thickness
|
||||
end
|
||||
|
||||
def draw
|
||||
draw_rect(window.width/2-@size, (window.height/2-@size)-@thickness/2, @size*2, @thickness, @color, 0, :default)
|
||||
draw_rect((window.width/2)-@thickness/2, window.height/2-(@size*2), @thickness, @size*2, @color, 0, :default)
|
||||
draw_rect(window.width / 2 - @size, (window.height / 2 - @size) - @thickness / 2, @size * 2, @thickness, @color, 0, :default)
|
||||
draw_rect((window.width / 2) - @thickness / 2, window.height / 2 - (@size * 2), @thickness, @size * 2, @color, 0, :default)
|
||||
end
|
||||
end
|
||||
end
|
||||
25
lib/demo.rb
25
lib/demo.rb
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Demo
|
||||
def initialize(camera:, player:, demo:, mode:)
|
||||
@@ -7,7 +8,7 @@ class IMICFPS
|
||||
@demo = demo
|
||||
@mode = mode
|
||||
|
||||
@index= 0
|
||||
@index = 0
|
||||
@tick = 0
|
||||
@changed = false
|
||||
|
||||
@@ -55,33 +56,37 @@ class IMICFPS
|
||||
@tick += 1
|
||||
end
|
||||
|
||||
def playing?; @mode == :play; end
|
||||
def recording?; !playing?; end
|
||||
def playing?
|
||||
@mode == :play
|
||||
end
|
||||
|
||||
def recording?
|
||||
!playing?
|
||||
end
|
||||
|
||||
def play
|
||||
if @data[@index]&.start_with?("tick")
|
||||
if @tick == @data[@index].split(" ").last.to_i
|
||||
@index+=1
|
||||
@index += 1
|
||||
|
||||
until(@data[@index]&.start_with?("tick"))
|
||||
until @data[@index]&.start_with?("tick")
|
||||
break unless @data[@index]
|
||||
|
||||
data = @data[@index].split(" ")
|
||||
if data.first == "up"
|
||||
case data.first
|
||||
when "up"
|
||||
input = InputMapper.get(data.last.to_sym)
|
||||
key = input.is_a?(Array) ? input.first : input
|
||||
$window.current_state.button_up(key) if key
|
||||
|
||||
elsif data.first == "down"
|
||||
when "down"
|
||||
input = InputMapper.get(data.last.to_sym)
|
||||
key = input.is_a?(Array) ? input.first : input
|
||||
$window.current_state.button_down(key) if key
|
||||
|
||||
elsif data.first == "mouse"
|
||||
when "mouse"
|
||||
@camera.orientation.z = data[1].to_f
|
||||
@player.orientation.y = (data[2].to_f * -1) - 180
|
||||
else
|
||||
# hmm
|
||||
end
|
||||
|
||||
@index += 1
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class EventHandler
|
||||
class Event
|
||||
attr_reader :entity, :context
|
||||
|
||||
def initialize(entity:, context: nil)
|
||||
@entity, @context = entity, context
|
||||
@entity = entity
|
||||
@context = context
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class EventHandler
|
||||
@@handlers = {}
|
||||
@@ -23,7 +24,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def self.get(event)
|
||||
@@handlers.dig(event)
|
||||
@@handlers[event]
|
||||
end
|
||||
|
||||
def initialize
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class EventHandler
|
||||
class EntityLifeCycle < EventHandler
|
||||
def handles
|
||||
[:create, :move, :destroy]
|
||||
%i[create move destroy]
|
||||
end
|
||||
|
||||
def handle(subscriber, context, *args)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class EventHandler
|
||||
class EntityMoved < EventHandler
|
||||
@@ -6,7 +7,7 @@ class IMICFPS
|
||||
[:entity_moved]
|
||||
end
|
||||
|
||||
def handle(subscriber, context, *args)
|
||||
def handle(subscriber, _context, *args)
|
||||
event = EventHandler::Event.new(entity: args.first.first)
|
||||
|
||||
subscriber.trigger(event)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class EventHandler
|
||||
class Input < EventHandler
|
||||
def handles
|
||||
[:button_down, :button_up]
|
||||
%i[button_down button_up]
|
||||
end
|
||||
|
||||
def handle(subscriber, context, *args)
|
||||
@@ -14,10 +15,8 @@ class IMICFPS
|
||||
|
||||
if action.is_a?(Numeric) && action == key
|
||||
subscriber.trigger(event)
|
||||
else
|
||||
if InputMapper.get(action) == key
|
||||
subscriber.trigger(event)
|
||||
end
|
||||
elsif InputMapper.get(action) == key
|
||||
subscriber.trigger(event)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
case OpenGL.get_platform
|
||||
when :OPENGL_PLATFORM_WINDOWS
|
||||
OpenGL.load_lib("opengl32.dll", "C:/Windows/System32")
|
||||
@@ -29,8 +30,8 @@ when :OPENGL_PLATFORM_LINUX
|
||||
OpenGL.load_lib("libGL.so", gl_library_path)
|
||||
GLU.load_lib("libGLU.so", gl_library_path)
|
||||
else
|
||||
raise RuntimeError, "Couldn't find GL libraries"
|
||||
raise "Couldn't find GL libraries"
|
||||
end
|
||||
else
|
||||
raise RuntimeError, "Unsupported platform."
|
||||
raise "Unsupported platform."
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
if RUBY_VERSION < "2.5.0"
|
||||
puts "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
|
||||
puts "|NOTICE| Ruby is #{RUBY_VERSION} not 2.5.0+..............................|Notice|"
|
||||
@@ -12,7 +13,7 @@ if RUBY_VERSION < "2.5.0"
|
||||
elsif self > max
|
||||
max
|
||||
else
|
||||
return self
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Editor < Entity
|
||||
|
||||
attr_accessor :speed
|
||||
attr_reader :bound_model, :first_person_view
|
||||
|
||||
@@ -15,7 +15,6 @@ class IMICFPS
|
||||
@first_person_view = true
|
||||
@visible = false
|
||||
@drag = 0.9
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Player < Entity
|
||||
|
||||
attr_accessor :speed
|
||||
attr_reader :name, :bound_model
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Skydome < Entity
|
||||
def setup
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Terrain < Entity
|
||||
end
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
|
||||
|
||||
# A game object is any renderable thing
|
||||
class Entity
|
||||
include CommonMethods
|
||||
|
||||
attr_accessor :visible, :renderable, :backface_culling
|
||||
attr_accessor :position, :orientation, :scale, :velocity
|
||||
attr_reader :name, :debug_color, :bounding_box, :drag, :camera, :manifest, :model
|
||||
attr_accessor :visible, :renderable, :backface_culling, :position, :orientation, :scale, :velocity, :debug_color
|
||||
attr_reader :name, :bounding_box, :drag, :camera, :manifest, :model
|
||||
|
||||
def initialize(manifest:, map_entity: nil, spawnpoint: nil, backface_culling: true, run_scripts: true)
|
||||
@manifest = manifest
|
||||
@@ -54,7 +52,7 @@ class IMICFPS
|
||||
|
||||
@camera = nil
|
||||
|
||||
return self
|
||||
self
|
||||
end
|
||||
|
||||
def load_scripts
|
||||
@@ -94,7 +92,6 @@ class IMICFPS
|
||||
def draw
|
||||
end
|
||||
|
||||
|
||||
def update
|
||||
unless at_same_position?
|
||||
Publisher.instance.publish(:entity_moved, nil, self)
|
||||
@@ -104,10 +101,6 @@ class IMICFPS
|
||||
@last_position = Vector.new(@position.x, @position.y, @position.z)
|
||||
end
|
||||
|
||||
def debug_color=(color)
|
||||
@debug_color = color
|
||||
end
|
||||
|
||||
def at_same_position?
|
||||
@position == @last_position
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
def initialize(position:, image:, interval: 1_500, time_to_live: 3_000, max_particles: 500)
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
def initialize(player)
|
||||
@@ -7,8 +8,8 @@ class IMICFPS
|
||||
@health = HealthWidget.new({ player: player })
|
||||
@chat_history = ChatHistoryWidget.new({ player: player })
|
||||
@score_board = ScoreBoardWidget.new({ player: player })
|
||||
@squad = SquadWidget.new( { player: player } )
|
||||
@crosshair = CrosshairWidget.new( { player: player } )
|
||||
@squad = SquadWidget.new({ player: player })
|
||||
@crosshair = CrosshairWidget.new({ player: player })
|
||||
|
||||
@hud_elements = [
|
||||
@ammo,
|
||||
@@ -18,7 +19,7 @@ class IMICFPS
|
||||
@score_board,
|
||||
@squad,
|
||||
|
||||
@crosshair,
|
||||
@crosshair
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class Widget
|
||||
@@ -24,6 +25,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
attr_reader :options
|
||||
|
||||
def initialize(options = {})
|
||||
@options = options
|
||||
@player = options[:player]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class AmmoWidget < HUD::Widget
|
||||
@@ -18,7 +19,7 @@ class IMICFPS
|
||||
|
||||
def update
|
||||
if (Gosu.milliseconds / 1000.0) % 1.0 >= 0.9
|
||||
random = "#{rand(0..199)}".rjust(3, "0")
|
||||
random = rand(0..199).to_s.rjust(3, "0")
|
||||
@text.text = "#{random}/999"
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class ChatHistoryWidget < HUD::Widget
|
||||
@@ -36,8 +37,8 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def random_message
|
||||
usernames = [
|
||||
"Cyberarm", "Cyber", "TankKiller", "DavyJones",
|
||||
usernames = %w[
|
||||
Cyberarm Cyber TankKiller DavyJones
|
||||
]
|
||||
entities = [
|
||||
"Alternate Tank", "Hover Hank", "Helicopter", "Jeep"
|
||||
@@ -47,12 +48,12 @@ class IMICFPS
|
||||
"Compass Bridge", "Compass Power Plant", "Gort Power Plant", "Gort Bridge", "Nest"
|
||||
]
|
||||
|
||||
events = [:spot, :kill, :target, :message]
|
||||
events = %i[spot kill target message]
|
||||
|
||||
messages = [
|
||||
"Need more tanks!",
|
||||
"I need 351 credits to purchase a tank",
|
||||
"I got 300",
|
||||
"I got 300"
|
||||
]
|
||||
|
||||
segments = {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class CrosshairWidget < HUD::Widget
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class HealthWidget < HUD::Widget
|
||||
@@ -26,9 +27,7 @@ class IMICFPS
|
||||
)
|
||||
|
||||
bottom_right = (window.width / 2 - @width / 2) + @width * @health - @slant
|
||||
if @width * @health - @slant < @slant
|
||||
bottom_right = (window.width / 2 - @width / 2) + @slant
|
||||
end
|
||||
bottom_right = (window.width / 2 - @width / 2) + @slant if @width * @health - @slant < @slant
|
||||
|
||||
# Current Health
|
||||
fill_quad(
|
||||
@@ -41,7 +40,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def update
|
||||
percentage = "#{(@health * 100).round}".rjust(3, "0")
|
||||
percentage = (@health * 100).round.to_s.rjust(3, "0")
|
||||
@text.text = "[Health #{percentage}%]"
|
||||
@text.x = window.width / 2 - @text.width / 2
|
||||
@text.y = @spacer + Widget.margin + @height / 2 - @text.height / 2
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class RadarWidget < HUD::Widget
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class ScoreBoardWidget < HUD::Widget
|
||||
def setup
|
||||
@usernames = Array("AAAA".."zzzz")#"Adran".."Zebra")
|
||||
@usernames = Array("AAAA".."zzzz") # "Adran".."Zebra")
|
||||
|
||||
@text = CyberarmEngine::Text.new(
|
||||
"",
|
||||
@@ -36,12 +37,12 @@ class IMICFPS
|
||||
{
|
||||
name: "Compass",
|
||||
credits: 0,
|
||||
score: 0,
|
||||
score: 0
|
||||
},
|
||||
{
|
||||
name: "Gort",
|
||||
credits: 0,
|
||||
score: 0,
|
||||
score: 0
|
||||
}
|
||||
],
|
||||
players: []
|
||||
@@ -56,8 +57,8 @@ class IMICFPS
|
||||
}
|
||||
end
|
||||
|
||||
data[:teams][0][:credits] = data[:players].select { |player| player[:team] == 0 }.map { |player| player[:credits] }.reduce(0, :+)
|
||||
data[:teams][0][:score] = data[:players].select { |player| player[:team] == 0 }.map { |player| player[:score] }.reduce(0, :+)
|
||||
data[:teams][0][:credits] = data[:players].select { |player| (player[:team]).zero? }.map { |player| player[:credits] }.reduce(0, :+)
|
||||
data[:teams][0][:score] = data[:players].select { |player| (player[:team]).zero? }.map { |player| player[:score] }.reduce(0, :+)
|
||||
|
||||
data[:teams][1][:credits] = data[:players].select { |player| player[:team] == 1 }.map { |player| player[:credits] }.reduce(0, :+)
|
||||
data[:teams][1][:score] = data[:players].select { |player| player[:team] == 1 }.map { |player| player[:score] }.reduce(0, :+)
|
||||
@@ -65,12 +66,12 @@ class IMICFPS
|
||||
data[:teams] = data[:teams].sort_by { |team| team[:score] }.reverse
|
||||
data[:players] = data[:players].sort_by { |player| player[:score] }.reverse
|
||||
|
||||
return data
|
||||
data
|
||||
end
|
||||
|
||||
def set_text
|
||||
team_header = [:name, :credits, :score]
|
||||
player_header = [:username, :credits, :score]
|
||||
team_header = %i[name credits score]
|
||||
player_header = %i[username credits score]
|
||||
|
||||
data = generate_random_data
|
||||
|
||||
@@ -78,7 +79,7 @@ class IMICFPS
|
||||
text += "# Team Credits Score\n"
|
||||
data[:teams].each_with_index do |team, i|
|
||||
i += 1
|
||||
text += "<c=#{team[:name] == "Compass" ? 'ffe66100' : 'ffa51d2d'}>#{i} #{team[:name]} #{i.even? ? team[:credits] : '-----'} #{team[:score]}</c>\n"
|
||||
text += "<c=#{team[:name] == 'Compass' ? 'ffe66100' : 'ffa51d2d'}>#{i} #{team[:name]} #{i.even? ? team[:credits] : '-----'} #{team[:score]}</c>\n"
|
||||
end
|
||||
|
||||
text += "\n"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class SquadWidget < HUD::Widget
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class CollisionManager
|
||||
attr_reader :map, :collisions
|
||||
|
||||
def initialize(map:)
|
||||
@map = map
|
||||
@collisions = {}
|
||||
@@ -48,13 +50,13 @@ class IMICFPS
|
||||
next if entity.manifest.collision_resolution == :static # Only dynamic entities can be resolved
|
||||
|
||||
search = @aabb_tree.search(entity.bounding_box)
|
||||
if search.size > 0
|
||||
search.reject! {|ent| ent == entity || !ent.collidable?}
|
||||
if search.size.positive?
|
||||
search.reject! { |ent| ent == entity || !ent.collidable? }
|
||||
broadphase[entity] = search
|
||||
end
|
||||
end
|
||||
|
||||
broadphase.each do |entity, _collisions|
|
||||
broadphase.each do |_entity, _collisions|
|
||||
_collisions.each do |ent|
|
||||
# aabb vs aabb
|
||||
# next unless entity.bounding_box.intersect?(ent.bounding_box)
|
||||
@@ -73,15 +75,15 @@ class IMICFPS
|
||||
|
||||
# AABBTree on entities is relative to model origin of 0,0,0
|
||||
def localize_entity_bounding_box(entity, target)
|
||||
return entity.bounding_box if target.position == 0 && target.orientation == 0
|
||||
return entity.bounding_box if target.position.zero? && target.orientation.zero?
|
||||
|
||||
# "tranform" entity bounding box into target's space
|
||||
local = (target.position) # needs tweaking, works well enough for now
|
||||
local = target.position # needs tweaking, works well enough for now
|
||||
box = entity.bounding_box.clone
|
||||
box.min -= local
|
||||
box.max -= local
|
||||
|
||||
return box
|
||||
box
|
||||
end
|
||||
|
||||
def on_ground?(entity) # TODO: Use some form of caching to speed this up
|
||||
@@ -96,7 +98,7 @@ class IMICFPS
|
||||
|
||||
broadphase.detect do |ent|
|
||||
ray = Ray.new(entity.position - ent.position, Vector.down)
|
||||
if ent.model.aabb_tree.search(ray).size > 0
|
||||
if ent.model.aabb_tree.search(ray).size.positive?
|
||||
on_ground = true
|
||||
return true
|
||||
end
|
||||
@@ -105,7 +107,7 @@ class IMICFPS
|
||||
break if on_ground
|
||||
end
|
||||
|
||||
return on_ground
|
||||
on_ground
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module EntityManager # Get included into GameState context
|
||||
def add_entity(entity)
|
||||
@collision_manager.add(entity) if @collision_manager && entity.manifest.collision # Add every entity to collision manager
|
||||
if @collision_manager && entity.manifest.collision
|
||||
@collision_manager.add(entity)
|
||||
end # Add every entity to collision manager
|
||||
Publisher.instance.publish(:create, nil, entity)
|
||||
@entities << entity
|
||||
end
|
||||
|
||||
def insert_entity(package, name, position, orientation, data = {})
|
||||
def insert_entity(package, name, position, orientation, _data = {})
|
||||
ent = MapParser::Entity.new(package, name, position, orientation, Vector.new(1, 1, 1))
|
||||
add_entity(IMICFPS::Entity.new(map_entity: ent, manifest: Manifest.new(package: package, name: name)))
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class InputMapper
|
||||
@@keymap = {}
|
||||
@@ -16,11 +17,12 @@ class IMICFPS
|
||||
if id_or_action.is_a?(Integer)
|
||||
@@keys[id_or_action] = true
|
||||
else
|
||||
query = @@keymap.dig(id_or_action)
|
||||
query = @@keymap[id_or_action]
|
||||
|
||||
if query.is_a?(Integer)
|
||||
query
|
||||
elsif query.is_a?(Array)
|
||||
case query
|
||||
when Integer
|
||||
query
|
||||
when Array
|
||||
query.each do |key|
|
||||
@@keys[key] = true
|
||||
end
|
||||
@@ -34,11 +36,12 @@ class IMICFPS
|
||||
if id_or_action.is_a?(Integer)
|
||||
@@keys[id_or_action] = false
|
||||
else
|
||||
query = @@keymap.dig(id_or_action)
|
||||
query = @@keymap[id_or_action]
|
||||
|
||||
if query.is_a?(Integer)
|
||||
case query
|
||||
when Integer
|
||||
query
|
||||
elsif query.is_a?(Array)
|
||||
when Array
|
||||
query.each do |key|
|
||||
@@keys[key] = false
|
||||
end
|
||||
@@ -49,12 +52,14 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def self.get(action)
|
||||
@@keymap.dig(action)
|
||||
@@keymap[action]
|
||||
end
|
||||
|
||||
def self.set(action, key)
|
||||
raise "action must be a symbol" unless action.is_a?(Symbol)
|
||||
raise "key must be a whole number or Array of whole numbers, got #{key}" unless key.is_a?(Integer) || key.is_a?(Array)
|
||||
raise "action must be a symbol" unless action.is_a?(Symbol)
|
||||
unless key.is_a?(Integer) || key.is_a?(Array)
|
||||
raise "key must be a whole number or Array of whole numbers, got #{key}"
|
||||
end
|
||||
|
||||
warn "InputMapper.set(:#{action}) is already defined as #{@@keymap[action]}" if @@keymap[action]
|
||||
|
||||
@@ -74,7 +79,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def self.is?(action, query_key)
|
||||
keys = @@keymap.dig(action)
|
||||
keys = @@keymap[action]
|
||||
|
||||
if keys.is_a?(Array)
|
||||
keys.include?(query_key)
|
||||
@@ -85,16 +90,17 @@ class IMICFPS
|
||||
|
||||
def self.actions(key)
|
||||
@@keymap.select do |action, value|
|
||||
if value.is_a?(Array)
|
||||
case value
|
||||
when Array
|
||||
action if value.include?(key)
|
||||
else
|
||||
action if value == key
|
||||
when key
|
||||
action
|
||||
end
|
||||
end.map { |keymap| keymap.first.is_a?(Symbol) ? keymap.first : keymap.first.first }
|
||||
end
|
||||
|
||||
def self.reset_keys
|
||||
@@keys.each do |key, value|
|
||||
@@keys.each do |key, _value|
|
||||
@@keys[key] = false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module LightManager
|
||||
MAX_LIGHTS = OpenGL::GL_MAX_LIGHTS
|
||||
@@ -7,7 +8,7 @@ class IMICFPS
|
||||
@lights << model
|
||||
end
|
||||
|
||||
def find_light()
|
||||
def find_light
|
||||
end
|
||||
|
||||
def lights
|
||||
@@ -15,7 +16,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def light_count
|
||||
@lights.count+1
|
||||
@lights.count + 1
|
||||
end
|
||||
|
||||
def clear_lights
|
||||
@@ -24,6 +25,7 @@ class IMICFPS
|
||||
|
||||
def available_light
|
||||
raise "Using to many lights, #{light_count}/#{LightManager::MAX_LIGHTS}" if light_count > LightManager::MAX_LIGHTS
|
||||
|
||||
puts "OpenGL::GL_LIGHT#{light_count}" if $window.config.get(:debug_options, :stats)
|
||||
Object.const_get "OpenGL::GL_LIGHT#{light_count}"
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class PhysicsManager
|
||||
def initialize(collision_manager:)
|
||||
@@ -16,7 +17,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def resolve(entity, other)
|
||||
entity.velocity.y = other.velocity.y if other.velocity.y < entity.velocity.y && entity.velocity.y < 0
|
||||
entity.velocity.y = other.velocity.y if other.velocity.y < entity.velocity.y && entity.velocity.y.negative?
|
||||
end
|
||||
|
||||
def simulate
|
||||
@@ -33,7 +34,7 @@ class IMICFPS
|
||||
entity.velocity.y = 0
|
||||
else
|
||||
entity.velocity.y -= @collision_manager.map.gravity * entity.delta_time if entity.manifest.physics
|
||||
entity.velocity.y = 0 if entity.velocity.y < 0
|
||||
entity.velocity.y = 0 if entity.velocity.y.negative?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module SoundManager
|
||||
extend CyberarmEngine::Common
|
||||
|
||||
MASTERS = {}
|
||||
EFFECTS = []
|
||||
PLAYLISTS = {}
|
||||
MASTERS = {}.freeze
|
||||
EFFECTS = [].freeze
|
||||
PLAYLISTS = {}.freeze
|
||||
|
||||
def self.master_volume
|
||||
1.0
|
||||
@@ -20,15 +21,15 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def self.load_master(package)
|
||||
return if MASTERS.dig(package)
|
||||
return if MASTERS[package]
|
||||
|
||||
yaml = YAML.load_file( "#{IMICFPS.assets_path}/#{package}/shared/sound/master.yaml" )
|
||||
yaml = YAML.load_file("#{IMICFPS.assets_path}/#{package}/shared/sound/master.yaml")
|
||||
MASTERS[package] = yaml
|
||||
end
|
||||
|
||||
def self.sound(package, name)
|
||||
if data = sound_data(package, name.to_s)
|
||||
get_sample("#{IMICFPS.assets_path}/#{package}/shared/sound/#{data["path"]}")
|
||||
get_sample("#{IMICFPS.assets_path}/#{package}/shared/sound/#{data['path']}")
|
||||
else
|
||||
raise "Missing sound: '#{name}' in package '#{package}'"
|
||||
end
|
||||
@@ -36,11 +37,11 @@ class IMICFPS
|
||||
|
||||
def self.sound_data(package, name)
|
||||
load_master(package)
|
||||
if master = MASTERS.dig(package)
|
||||
if master = MASTERS[package]
|
||||
return master["sounds"].find { |s| s["name"] == name }
|
||||
end
|
||||
|
||||
return nil
|
||||
nil
|
||||
end
|
||||
|
||||
def self.sound_effect(klass, options)
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Manifest
|
||||
attr_reader :name, :model, :collision, :collision_mesh, :collision_resolution, :physics, :scripts, :uses
|
||||
def initialize(manifest_file: nil, package: nil, name: nil)
|
||||
|
||||
def initialize(manifest_file: nil, package: nil, name: nil)
|
||||
unless manifest_file
|
||||
raise "Entity package not specified!" unless package
|
||||
raise "Entity name not specified!" unless name
|
||||
|
||||
manifest_file = "#{IMICFPS.assets_path}/#{package}/#{name}/manifest.yaml"
|
||||
end
|
||||
|
||||
raise "No manifest found at: #{manifest_file}" unless File.exist?(manifest_file)
|
||||
|
||||
raise "No manifest found at: #{manifest_file}" unless File.exist?(manifest_file)
|
||||
|
||||
@file = manifest_file
|
||||
parse(manifest_file)
|
||||
end
|
||||
|
||||
def parse(file)
|
||||
data = YAML.load(File.read(file))
|
||||
data = YAML.safe_load(File.read(file))
|
||||
|
||||
# required
|
||||
@name = data["name"]
|
||||
@model = data["model"]
|
||||
|
||||
# optional
|
||||
@collision = data["collision"] ? data["collision"] : nil
|
||||
@collision_mesh = data["collision_mesh"] ? data["collision_mesh"] : nil
|
||||
@collision = data["collision"] || nil
|
||||
@collision_mesh = data["collision_mesh"] || nil
|
||||
@collision_resolution = data["collision_resolution"] ? data["collision_resolution"].to_sym : :static
|
||||
@physics = data["physics"] ? data["physics"] : false
|
||||
@physics = data["physics"] || false
|
||||
@scripts = data["scripts"] ? parse_scripts(data["scripts"]) : []
|
||||
@uses = data["uses"] ? parse_dependencies(data["uses"]) : [] # List of entities that this Entity uses
|
||||
end
|
||||
@@ -40,7 +41,7 @@ class IMICFPS
|
||||
|
||||
if script.start_with?("!")
|
||||
script = script.sub("!", "")
|
||||
path = File.expand_path("../shared/", file_path) + "/scripts/" + script
|
||||
path = "#{File.expand_path('../shared/', file_path)}/scripts/#{script}"
|
||||
else
|
||||
path = "#{file_path}/scripts/#{script}"
|
||||
end
|
||||
@@ -48,7 +49,7 @@ class IMICFPS
|
||||
list << Script.new(script, File.read("#{path}.rb"))
|
||||
end
|
||||
|
||||
return list
|
||||
list
|
||||
end
|
||||
|
||||
def parse_dependencies(list)
|
||||
@@ -57,7 +58,7 @@ class IMICFPS
|
||||
dependencies << Dependency.new(item["package"], item["name"])
|
||||
end
|
||||
|
||||
return dependencies
|
||||
dependencies
|
||||
end
|
||||
|
||||
def file_path
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Map
|
||||
include EntityManager
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class MapParser
|
||||
attr_reader :metadata, :terrain, :skydome, :lights, :entities, :spawnpoints
|
||||
attr_reader :assets, :missing_assets
|
||||
attr_reader :metadata, :terrain, :skydome, :lights, :entities, :spawnpoints, :assets, :missing_assets
|
||||
|
||||
def initialize(map_file:)
|
||||
@metadata = MapParser::MetaData.new
|
||||
@terrain = MapParser::Entity.new
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
MULTICAST_ADDRESS = "224.0.0.1"
|
||||
MULTICAST_PORT = 30_000
|
||||
|
||||
REMOTE_GAMEHUB = "i-mic.cyberarm.dev"
|
||||
REMOTE_GAMEHUB_PORT = 98765
|
||||
REMOTE_GAMEHUB_PORT = 98_765
|
||||
|
||||
DEFAULT_SERVER_HOSTNAME = "0.0.0.0"
|
||||
DEFAULT_SERVER_PORT = 56789
|
||||
DEFAULT_SERVER_QUERY_PORT = 28900
|
||||
DEFAULT_SERVER_PORT = 56_789
|
||||
DEFAULT_SERVER_QUERY_PORT = 28_900
|
||||
|
||||
RESERVED_PEER_ID = 0
|
||||
DEFAULT_PEER_LIMIT = 32
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class Channel
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class Connection
|
||||
@@ -63,9 +64,9 @@ module CyberarmEngine
|
||||
@peer.total_data_received += data.length
|
||||
@peer.last_read_time = Networking.milliseconds
|
||||
|
||||
return true
|
||||
true
|
||||
rescue IO::WaitReadable
|
||||
return false
|
||||
false
|
||||
end
|
||||
|
||||
def write(packet:)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class Packet
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
module PacketHandler
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class ControlPacket
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class RawPacket
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class ReliablePacket
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class Peer
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
module Protocol
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module CyberarmEngine
|
||||
module Networking
|
||||
class Server
|
||||
@@ -85,7 +86,7 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def update
|
||||
while(read)
|
||||
while read
|
||||
end
|
||||
|
||||
# handle write queue
|
||||
@@ -117,7 +118,7 @@ module CyberarmEngine
|
||||
)
|
||||
end
|
||||
|
||||
while(packet = peer.write_queue.shift)
|
||||
while (packet = peer.write_queue.shift)
|
||||
write(peer: peer, packet: packet)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class Connection
|
||||
attr_reader :address, :port
|
||||
attr_accessor :total_packets_sent, :total_packets_received, :total_data_sent, :total_data_received, :last_read_time, :last_write_time
|
||||
|
||||
def initialize(address:, port:)
|
||||
@address = address
|
||||
@port = port
|
||||
|
||||
|
||||
@read_buffer = ReadBuffer.new
|
||||
@packet_write_queue = []
|
||||
|
||||
@@ -39,50 +40,49 @@ class IMICFPS
|
||||
)
|
||||
end
|
||||
|
||||
def send_packet( packet )
|
||||
def send_packet(packet)
|
||||
Packet.splinter(packet).each do |pkt|
|
||||
@packet_write_queue << pkt
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
while(read)
|
||||
while read
|
||||
end
|
||||
|
||||
write
|
||||
|
||||
# puts "#{Networking.milliseconds} Total sent: #{@total_packets_sent} packets, #{@total_data_sent} data"
|
||||
# puts "#{Networking.milliseconds} Total received: #{@total_packets_received} packets, #{@total_data_received} data"
|
||||
@read_buffer.reconstruct_packets.each do |packet, addr_info|
|
||||
if packet.peer_id == 0 && packet.type == Protocol::VERIFY_CONNECT
|
||||
@peer_id = packet.payload.unpack1("C")
|
||||
end
|
||||
@read_buffer.reconstruct_packets.each do |packet, _addr_info|
|
||||
@peer_id = packet.payload.unpack1("C") if packet.peer_id.zero? && packet.type == Protocol::VERIFY_CONNECT
|
||||
end
|
||||
|
||||
if @peer_id > 0 && Networking.milliseconds - @last_read_time >= Protocol::HEARTBEAT_INTERVAL
|
||||
if @peer_id.positive? && Networking.milliseconds - @last_read_time >= Protocol::HEARTBEAT_INTERVAL
|
||||
send_packet(Packet.new(peer_id: @peer_id, sequence: 0, type: Protocol::HEARTBEAT, payload: ""))
|
||||
end
|
||||
end
|
||||
|
||||
def close
|
||||
@socket.close if @socket
|
||||
@socket&.close
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read
|
||||
data, addr = @socket.recvfrom_nonblock(Protocol::MAX_PACKET_SIZE)
|
||||
@read_buffer.add(data, addr )
|
||||
@read_buffer.add(data, addr)
|
||||
|
||||
@total_packets_received += 1
|
||||
@total_data_received += data.length
|
||||
@last_read_time = Networking.milliseconds
|
||||
return true
|
||||
true
|
||||
rescue IO::WaitReadable
|
||||
return false
|
||||
false
|
||||
end
|
||||
|
||||
def write
|
||||
while(packet = @packet_write_queue.shift)
|
||||
while (packet = @packet_write_queue.shift)
|
||||
@socket.send(packet.encode, 0, @address, @port)
|
||||
|
||||
@total_data_sent += packet.encode.length
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class Director
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Networking
|
||||
module Events
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class PacketHandler
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class SnapshotPacket < CyberarmEngine::Networking::Packet
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class ReadBuffer
|
||||
@@ -14,10 +15,11 @@ class IMICFPS
|
||||
pairs = []
|
||||
|
||||
@buffer.each do |hash|
|
||||
buffer, addr = hash[:buffer], hash[:addr_info]
|
||||
buffer = hash[:buffer]
|
||||
addr = hash[:addr_info]
|
||||
packet = Packet.from_stream(buffer)
|
||||
|
||||
if true#packet.valid?
|
||||
if true # packet.valid?
|
||||
pairs << [packet, addr]
|
||||
@buffer.delete(hash)
|
||||
else
|
||||
@@ -26,7 +28,7 @@ class IMICFPS
|
||||
end
|
||||
end
|
||||
|
||||
return pairs
|
||||
pairs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Networking
|
||||
class Server < CyberarmEngine::Networking::Server
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Overlay
|
||||
include CommonMethods
|
||||
@@ -13,6 +14,7 @@ class IMICFPS
|
||||
|
||||
def draw
|
||||
return if @text.text.empty?
|
||||
|
||||
width = @text.markup_width + 8
|
||||
|
||||
Gosu.draw_rect(0, 0, width, (@text.height + 4), Gosu::Color.rgba(0, 0, 0, 100))
|
||||
@@ -30,7 +32,9 @@ class IMICFPS
|
||||
|
||||
if window.config.get(:options, :fps)
|
||||
create_slot "FPS: #{Gosu.fps}"
|
||||
create_slot "Frame time: #{(Gosu.milliseconds - window.delta_time).to_s.rjust(3, "0")}ms" if window.config.get(:debug_options, :stats)
|
||||
if window.config.get(:debug_options, :stats)
|
||||
create_slot "Frame time: #{(Gosu.milliseconds - window.delta_time).to_s.rjust(3, '0')}ms"
|
||||
end
|
||||
end
|
||||
|
||||
if window.config.get(:debug_options, :stats)
|
||||
@@ -49,7 +53,7 @@ class IMICFPS
|
||||
@text.text = ""
|
||||
@slots.each_with_index do |slot, i|
|
||||
@text.text += "#{slot.value} <c=ff000000>•</c> " unless i == @slots.size - 1
|
||||
@text.text += "#{slot.value}" if i == @slots.size - 1
|
||||
@text.text += slot.value.to_s if i == @slots.size - 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Publisher
|
||||
def self.subscribe(subscription)
|
||||
raise "Expected IMICFPS::Subscription not #{subscription.class}" unless subscription.is_a?(IMICFPS::Subscription)
|
||||
|
||||
Publisher.instance.add_sub(subscription)
|
||||
end
|
||||
|
||||
@@ -22,13 +24,14 @@ class IMICFPS
|
||||
|
||||
def add_sub(subscription)
|
||||
raise "Expected IMICFPS::Subscription not #{subscription.class}" unless subscription.is_a?(IMICFPS::Subscription)
|
||||
|
||||
@events[subscription.event] ||= []
|
||||
|
||||
@events[subscription.event] << subscription
|
||||
end
|
||||
|
||||
def publish(event, context, *args)
|
||||
if subscribers = @events.dig(event)
|
||||
if subscribers = @events[event]
|
||||
return unless event_handler = EventHandler.get(event)
|
||||
|
||||
subscribers.each do |subscriber|
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Scene
|
||||
attr_reader :camera, :entities, :lights
|
||||
|
||||
def initialize
|
||||
@camera = PerspectiveCamera.new(position: Vector.new, aspect_ratio: $window.aspect_ratio )
|
||||
@camera = PerspectiveCamera.new(position: Vector.new, aspect_ratio: $window.aspect_ratio)
|
||||
@entities = []
|
||||
@lights = []
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class TurnTableScene < Scene
|
||||
def setup
|
||||
@@ -25,7 +26,7 @@ class IMICFPS
|
||||
"power_plant": 0.025,
|
||||
"war_factory": 0.03,
|
||||
"randomish_terrain": 0.004,
|
||||
"river_terrain": 0.004,
|
||||
"river_terrain": 0.004
|
||||
}
|
||||
choice = options.keys.sample
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Scripting
|
||||
def on
|
||||
# self is a Scripting::SandBox
|
||||
Subscription.new(self.entity)
|
||||
Subscription.new(entity)
|
||||
end
|
||||
|
||||
def component(name)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Scripting
|
||||
class SandBox
|
||||
@@ -10,7 +11,7 @@ class IMICFPS
|
||||
execute(script.source) if source_safe?(script.source)
|
||||
end
|
||||
|
||||
def source_safe?(source)
|
||||
def source_safe?(_source)
|
||||
true # TODO: implement whitelisting/safety checks
|
||||
end
|
||||
|
||||
@@ -18,9 +19,7 @@ class IMICFPS
|
||||
instance_eval(source)
|
||||
end
|
||||
|
||||
def entity
|
||||
@entity
|
||||
end
|
||||
attr_reader :entity
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
module Scripting
|
||||
CONSTANTS_WHITELIST = [
|
||||
@@ -7,8 +8,8 @@ class IMICFPS
|
||||
# Ruby information
|
||||
RUBY_VERSION, RUBY_ENGINE,
|
||||
# Local
|
||||
Vector, BoundingBox, Ray,
|
||||
]
|
||||
Vector, BoundingBox, Ray
|
||||
].freeze
|
||||
|
||||
METHOD_WHITELIST = [
|
||||
Subscription.subscribable_events,
|
||||
@@ -45,16 +46,16 @@ class IMICFPS
|
||||
:combination, :compact, :compact!, :compare_by_identity, :compare_by_identity?, :concat, :count, :cycle, :default, :default=, :default_proc,
|
||||
:default_proc=, :delete, :delete_at, :delete_if, :detect, :difference, :dig, :drop, :drop_while, :each, :each_cons, :each_entry, :each_index,
|
||||
:each_key, :each_pair, :each_slice, :each_value, :each_with_index, :each_with_object, :empty?, :entries, :eql?, :fetch, :fetch_values, :fill,
|
||||
:filter, :filter!, :find, :find_all, :find_index, :first, :flat_map, :flatten, :flatten!, :grep, :grep_v, :group_by, :has_key?, :has_value?,
|
||||
:hash, :include?, :index, :inject, :insert, :inspect, :invert, :join, :keep_if, :key, :key?, :keys, :last, :lazy, :length, :map, :map!,
|
||||
:max, :max_by, :member?, :merge, :merge!, :min, :min_by, :minmax, :minmax_by, :none?, :one?, :pack, :partition, :permutation, :pop, :prepend,
|
||||
:product, :push, :rassoc, :reduce, :rehash, :reject, :reject!, :repeated_combination, :repeated_permutation, :replace, :reverse, :reverse!,
|
||||
:reverse_each, :rindex, :rotate, :rotate!, :sample, :select, :select!, :shift, :shuffle, :shuffle!, :size, :slice, :slice!, :slice_after, :slice_before,
|
||||
:slice_when, :sort, :sort!, :sort_by, :sort_by!, :store, :sum, :take, :take_while, :to_a, :to_ary, :to_h, :to_hash, :to_proc, :to_s, :to_set,
|
||||
:transform_keys, :transform_keys!, :transform_values, :transform_values!, :transpose, :union, :uniq, :uniq!, :unshift, :update, :value?, :values,
|
||||
:values_at, :zip,
|
||||
:filter, :filter!, :find, :find_all, :find_index, :first, :flat_map, :flatten, :flatten!, :grep, :grep_v, :group_by, :has_key?, :has_value?,
|
||||
:hash, :include?, :index, :inject, :insert, :inspect, :invert, :join, :keep_if, :key, :key?, :keys, :last, :lazy, :length, :map, :map!,
|
||||
:max, :max_by, :member?, :merge, :merge!, :min, :min_by, :minmax, :minmax_by, :none?, :one?, :pack, :partition, :permutation, :pop, :prepend,
|
||||
:product, :push, :rassoc, :reduce, :rehash, :reject, :reject!, :repeated_combination, :repeated_permutation, :replace, :reverse, :reverse!,
|
||||
:reverse_each, :rindex, :rotate, :rotate!, :sample, :select, :select!, :shift, :shuffle, :shuffle!, :size, :slice, :slice!, :slice_after, :slice_before,
|
||||
:slice_when, :sort, :sort!, :sort_by, :sort_by!, :store, :sum, :take, :take_while, :to_a, :to_ary, :to_h, :to_hash, :to_proc, :to_s, :to_set,
|
||||
:transform_keys, :transform_keys!, :transform_values, :transform_values!, :transpose, :union, :uniq, :uniq!, :unshift, :update, :value?, :values,
|
||||
:values_at, :zip,
|
||||
# Casting
|
||||
:to_c, :to_f, :to_i, :to_r, :to_str, :to_ary, :to_h, :to_hash, :to_proc, :to_a, :to_s, :to_sym,
|
||||
:to_c, :to_f, :to_i, :to_r, :to_str, :to_ary, :to_h, :to_hash, :to_proc, :to_a, :to_s, :to_sym
|
||||
].flatten
|
||||
end
|
||||
end
|
||||
@@ -1,9 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class SoundEffect
|
||||
attr_reader :sound, :options
|
||||
|
||||
def initialize(options = {})
|
||||
raise "expected Hash, got #{options.class}" unless options.is_a?(Hash)
|
||||
|
||||
@options = options
|
||||
|
||||
raise "sound not specified!" unless @options[:sound]
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class SoundEffect
|
||||
class FadeIn < SoundEffect
|
||||
def setup
|
||||
@start_time = Gosu.milliseconds
|
||||
@duration = @options[:duration] # in milliseconds
|
||||
@initial_volume = @options[:volume] ? @options[:volume] : 0.0
|
||||
@initial_volume = @options[:volume] || 0.0
|
||||
@sound = @options[:sound]
|
||||
|
||||
raise "duration not specified!" unless @duration
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class SoundEffect
|
||||
class FadeInAndOut < FadeIn
|
||||
def setup
|
||||
@hang_time = @options[:hang_time] ? @options[:hang_time] : 0.0
|
||||
@hang_time = @options[:hang_time] || 0.0
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class SoundEffect
|
||||
class FadeOut < FadeIn
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class SoundEffect
|
||||
class ShieldRegen < SoundEffect
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class GameState < CyberarmEngine::GameState
|
||||
include CommonMethods
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Boot < GameState
|
||||
def setup
|
||||
@title = Text.new(IMICFPS::NAME, size: 100, z: 0, color: Gosu::Color.new(0xff000000), shadow: false, font: "Droid Serif")
|
||||
@logo = get_image(IMICFPS::GAME_ROOT_PATH + "/static/logo.png")
|
||||
@logo = get_image("#{IMICFPS::GAME_ROOT_PATH}/static/logo.png")
|
||||
|
||||
@start_time = Gosu.milliseconds
|
||||
@time_to_live = 3_000
|
||||
@@ -34,7 +35,7 @@ class IMICFPS
|
||||
|
||||
@title.draw
|
||||
|
||||
fill(Gosu::Color.rgba(0,0,0, 255 * (1.2 - fraction_left)))
|
||||
fill(Gosu::Color.rgba(0, 0, 0, 255 * (1.2 - fraction_left)))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -46,9 +47,9 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
if id == Gosu::KbEscape or
|
||||
(id >= Gosu::GP_LEFT and id >= Gosu::GP_BUTTON_15) or
|
||||
id == Gosu::MsLeft
|
||||
if (id == Gosu::KbEscape) ||
|
||||
((id >= Gosu::GP_LEFT) && (id >= Gosu::GP_BUTTON_15)) ||
|
||||
(id == Gosu::MsLeft)
|
||||
push_state(MainMenu)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Close < GameState
|
||||
def setup
|
||||
@slope = Menu::BAR_SLOPE
|
||||
|
||||
@logo = get_image(IMICFPS::GAME_ROOT_PATH + "/static/logo.png")
|
||||
@logo = get_image("#{IMICFPS::GAME_ROOT_PATH}/static/logo.png")
|
||||
|
||||
@start_time = Gosu.milliseconds
|
||||
@time_to_live = 3_000
|
||||
@@ -31,7 +32,7 @@ class IMICFPS
|
||||
|
||||
@logo.draw(window.width / 2 - @logo.width / 2, window.height / 2 - @logo.height / 2, 0)
|
||||
|
||||
fill(Gosu::Color.rgba(0,0,0, 255 * (1.1 - fraction_left)))
|
||||
fill(Gosu::Color.rgba(0, 0, 0, 255 * (1.1 - fraction_left)))
|
||||
end
|
||||
|
||||
def update
|
||||
@@ -40,9 +41,9 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
if id == Gosu::KbEscape or
|
||||
(id >= Gosu::GP_LEFT and id >= Gosu::GP_BUTTON_15) or
|
||||
id == Gosu::MsLeft
|
||||
if (id == Gosu::KbEscape) ||
|
||||
((id >= Gosu::GP_LEFT) && (id >= Gosu::GP_BUTTON_15)) ||
|
||||
(id == Gosu::MsLeft)
|
||||
window.close!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Game < GameState
|
||||
attr_reader :map
|
||||
@@ -7,7 +8,7 @@ class IMICFPS
|
||||
window.director.load_map(map_parser: @options[:map_parser])
|
||||
|
||||
@player = window.director.map.find_entity_by(name: "character")
|
||||
@camera = PerspectiveCamera.new( position: @player.position.clone, aspect_ratio: window.aspect_ratio )
|
||||
@camera = PerspectiveCamera.new(position: @player.position.clone, aspect_ratio: window.aspect_ratio)
|
||||
@camera_controller = CameraController.new(mode: :fpv, camera: @camera, entity: @player)
|
||||
|
||||
# @connection = Networking::Connection.new(address: "localhost", port: Networking::DEFAULT_SERVER_PORT)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class LoadingState < Menu
|
||||
def setup
|
||||
@@ -13,8 +14,8 @@ class IMICFPS
|
||||
|
||||
title IMICFPS::NAME
|
||||
@subheading = Text.new("Loading Map: #{@map_parser.metadata.name}", y: 100, size: 50, alignment: :center, font: SANS_FONT)
|
||||
@description = Text.new("Map created by: #{@map_parser.metadata.authors.join(", ")}\n#{@map_parser.metadata.description}", y: 180, size: 24, alignment: :center, font: SANS_FONT)
|
||||
@state = Text.new("Preparing...", y: window.height/2-40, size: 40, alignment: :center, font: SANS_FONT)
|
||||
@description = Text.new("Map created by: #{@map_parser.metadata.authors.join(', ')}\n#{@map_parser.metadata.description}", y: 180, size: 24, alignment: :center, font: SANS_FONT)
|
||||
@state = Text.new("Preparing...", y: window.height / 2 - 40, size: 40, alignment: :center, font: SANS_FONT)
|
||||
@percentage = Text.new("0%", y: window.height - 100 + 25, size: 50, alignment: :center, font: SANS_FONT)
|
||||
|
||||
@dummy_entity = nil
|
||||
@@ -45,7 +46,6 @@ class IMICFPS
|
||||
@description.draw
|
||||
@state.draw
|
||||
|
||||
|
||||
progressbar
|
||||
end
|
||||
|
||||
@@ -75,18 +75,16 @@ class IMICFPS
|
||||
@asset_index += 1
|
||||
end
|
||||
|
||||
unless @asset_index < @assets.count
|
||||
if @act && Gosu.milliseconds-@completed_for_ms > 250
|
||||
push_state(@options[:forward], map_parser: @map_parser)
|
||||
else
|
||||
@act = true
|
||||
@completed_for_ms = Gosu.milliseconds unless @lock
|
||||
@lock = true
|
||||
end
|
||||
else
|
||||
if @asset_index < @assets.count
|
||||
@state.text = "Loading #{@assets[@asset_index][:type]} #{@assets[@asset_index][:name].split('/').last}..."
|
||||
@state.x = (window.width/2)-(@state.width/2)
|
||||
@state.x = (window.width / 2) - (@state.width / 2)
|
||||
@cycled = true
|
||||
elsif @act && Gosu.milliseconds - @completed_for_ms > 250
|
||||
push_state(@options[:forward], map_parser: @map_parser)
|
||||
else
|
||||
@act = true
|
||||
@completed_for_ms = Gosu.milliseconds unless @lock
|
||||
@lock = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -95,9 +93,9 @@ class IMICFPS
|
||||
when :model
|
||||
manifest = Manifest.new(manifest_file: IMICFPS.assets_path + "/#{package}/#{name}/manifest.yaml")
|
||||
add_required_assets(manifest)
|
||||
@assets << {type: type, manifest: manifest, package: package, name: name}
|
||||
@assets << { type: type, manifest: manifest, package: package, name: name }
|
||||
when :shader
|
||||
@assets << {type: type, manifest: manifest, package: package, name: name}
|
||||
@assets << { type: type, manifest: manifest, package: package, name: name }
|
||||
else
|
||||
raise TypeError "Unable to load asset of type #{type}"
|
||||
end
|
||||
@@ -105,30 +103,28 @@ class IMICFPS
|
||||
|
||||
def add_required_assets(manifest)
|
||||
manifest.uses.each do |dependency|
|
||||
known = @assets.detect {|asset| asset[:package] == dependency.package && asset[:name] == dependency.name}
|
||||
unless known
|
||||
add_asset(:model, dependency.package, dependency.name)
|
||||
end
|
||||
known = @assets.detect { |asset| asset[:package] == dependency.package && asset[:name] == dependency.name }
|
||||
add_asset(:model, dependency.package, dependency.name) unless known
|
||||
end
|
||||
end
|
||||
|
||||
def progressbar(x = window.width/4, y = window.height - 104)
|
||||
def progressbar(x = window.width / 4, y = window.height - 104)
|
||||
@percentage.draw
|
||||
progress = (@asset_index.to_f/@assets.count)*window.width/2
|
||||
progress = (@asset_index.to_f / @assets.count) * window.width / 2
|
||||
height = 100
|
||||
|
||||
dark_color= Gosu::Color.rgb(@primary_color.red - 100, @primary_color.green - 100, @primary_color.blue - 100)#Gosu::Color.rgb(64, 127, 255)
|
||||
color = Gosu::Color.rgb(@primary_color.red - 50, @primary_color.green - 50, @primary_color.blue - 50)#Gosu::Color.rgb(0,127,127)
|
||||
color_two = Gosu::Color.rgb(@primary_color.red + 50, @primary_color.green + 50, @primary_color.blue + 50)#Gosu::Color.rgb(64, 127, 255)
|
||||
dark_color = Gosu::Color.rgb(@primary_color.red - 100, @primary_color.green - 100, @primary_color.blue - 100) # Gosu::Color.rgb(64, 127, 255)
|
||||
color = Gosu::Color.rgb(@primary_color.red - 50, @primary_color.green - 50, @primary_color.blue - 50) # Gosu::Color.rgb(0,127,127)
|
||||
color_two = Gosu::Color.rgb(@primary_color.red + 50, @primary_color.green + 50, @primary_color.blue + 50) # Gosu::Color.rgb(64, 127, 255)
|
||||
|
||||
draw_rect(x, y-2, x + window.width/4, height+4, dark_color)
|
||||
draw_rect(x, y - 2, x + window.width / 4, height + 4, dark_color)
|
||||
|
||||
Gosu.clip_to(x, y, progress, height) do
|
||||
Gosu.draw_quad(
|
||||
x, y, color,
|
||||
x + x + window.width/4, y, color_two,
|
||||
x + x + window.width / 4, y, color_two,
|
||||
x, y + height, color,
|
||||
x + x + window.width/4, y + height, color_two
|
||||
x + x + window.width / 4, y + height, color_two
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Subscription
|
||||
attr_reader :entity, :event, :args, :block
|
||||
|
||||
def initialize(entity)
|
||||
@entity = entity
|
||||
|
||||
@@ -13,27 +15,27 @@ class IMICFPS
|
||||
def method_missing(event, *args, &block)
|
||||
return unless Subscription.subscribable_events.include?(event)
|
||||
|
||||
@event, @args, @block = event, args, block
|
||||
@event = event
|
||||
@args = args
|
||||
@block = block
|
||||
Publisher.subscribe(self)
|
||||
end
|
||||
|
||||
def trigger(event, *args)
|
||||
if @block
|
||||
@block.call(event, *args)
|
||||
end
|
||||
@block&.call(event, *args)
|
||||
end
|
||||
|
||||
def self.subscribable_events
|
||||
[
|
||||
:tick,
|
||||
:create, :move, :destroy,
|
||||
:entity_moved,
|
||||
:button_down, :button_up,
|
||||
:mouse_move,
|
||||
:interact,
|
||||
:player_join, :player_leave, :player_die,
|
||||
:pickup_item, :use_item, :drop_item,
|
||||
:enter_vehicle, :exit_vehicle,
|
||||
%i[
|
||||
tick
|
||||
create move destroy
|
||||
entity_moved
|
||||
button_down button_up
|
||||
mouse_move
|
||||
interact
|
||||
player_join player_leave player_die
|
||||
pickup_item use_item drop_item
|
||||
enter_vehicle exit_vehicle
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "asset_viewer/lib/main_menu"
|
||||
require_relative "asset_viewer/lib/turn_table"
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class AssetViewerTool
|
||||
class MainMenu < Menu
|
||||
@@ -6,17 +7,17 @@ class IMICFPS
|
||||
window.needs_cursor = true
|
||||
|
||||
@manifests = []
|
||||
Dir.glob(GAME_ROOT_PATH + "/assets/**/manifest.yaml").each do |manifest|
|
||||
Dir.glob("#{GAME_ROOT_PATH}/assets/**/manifest.yaml").each do |manifest|
|
||||
begin
|
||||
@manifests << Manifest.new(manifest_file: manifest)
|
||||
rescue
|
||||
rescue StandardError
|
||||
warn "Broken manifest: #{manifest}"
|
||||
end
|
||||
end
|
||||
|
||||
@manifests.sort_by! { |m| m.name.downcase }
|
||||
|
||||
label "#{IMICFPS::NAME}", text_size: 100, color: Gosu::Color::BLACK
|
||||
label IMICFPS::NAME.to_s, text_size: 100, color: Gosu::Color::BLACK
|
||||
label "Asset Viewer", text_size: 50
|
||||
|
||||
flow(width: 1.0, height: 1.0) do
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class AssetViewerTool
|
||||
class TurnTable < CyberarmEngine::GuiState
|
||||
include LightManager
|
||||
|
||||
attr_reader :map
|
||||
|
||||
def setup
|
||||
window.needs_cursor = false
|
||||
@manifest = @options[:manifest]
|
||||
@@ -42,7 +44,7 @@ class IMICFPS
|
||||
0, 0, color_top,
|
||||
window.width, 0, color_top,
|
||||
window.width, window.height, color_bottom,
|
||||
0, window.height, color_bottom,
|
||||
0, window.height, color_bottom
|
||||
)
|
||||
|
||||
Gosu.gl do
|
||||
@@ -83,6 +85,7 @@ class IMICFPS
|
||||
include EntityManager
|
||||
|
||||
attr_reader :entities
|
||||
|
||||
def initialize
|
||||
@entities = []
|
||||
end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "map_editor/lib/main_menu"
|
||||
require_relative "map_editor/lib/editor"
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class MapEditorTool
|
||||
class Editor < CyberarmEngine::GuiState
|
||||
@@ -10,8 +11,8 @@ class IMICFPS
|
||||
# and refactor Game to use it.
|
||||
Publisher.new
|
||||
@map = Map.new(map_parser: @options[:map_parser])
|
||||
@camera = PerspectiveCamera.new( position: Vector.new, aspect_ratio: window.aspect_ratio )
|
||||
@editor = IMICFPS::Editor.new( manifest: Manifest.new(package: "base", name: "editor") )
|
||||
@camera = PerspectiveCamera.new(position: Vector.new, aspect_ratio: window.aspect_ratio)
|
||||
@editor = IMICFPS::Editor.new(manifest: Manifest.new(package: "base", name: "editor"))
|
||||
@camera_controller = CameraController.new(camera: @camera, entity: @editor)
|
||||
@crosshair = Crosshair.new
|
||||
|
||||
@@ -36,7 +37,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def control_editor
|
||||
InputMapper.keys.each do |key, pressed|
|
||||
InputMapper.each_key do |key, pressed|
|
||||
next unless pressed
|
||||
|
||||
actions = InputMapper.actions(key)
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class MapEditorTool
|
||||
class MainMenu < Menu
|
||||
def setup
|
||||
window.needs_cursor = true
|
||||
|
||||
label "#{IMICFPS::NAME}", text_size: 50
|
||||
label IMICFPS::NAME.to_s, text_size: 50
|
||||
label "Map Editor", text_size: 28
|
||||
|
||||
@maps = []
|
||||
Dir.glob(GAME_ROOT_PATH + "/maps/*.json").each do |map|
|
||||
Dir.glob("#{GAME_ROOT_PATH}/maps/*.json").each do |map|
|
||||
begin
|
||||
@maps << MapParser.new(map_file: map)
|
||||
rescue
|
||||
rescue StandardError
|
||||
warn "Broken map file: #{map}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class AABBTree
|
||||
class AABBNode
|
||||
attr_accessor :bounding_box, :parent, :object
|
||||
attr_reader :a, :b
|
||||
|
||||
def initialize(parent:, object:, bounding_box:)
|
||||
@parent = parent
|
||||
@object = object
|
||||
@@ -34,7 +36,7 @@ class IMICFPS
|
||||
new_node.a = self
|
||||
new_node.b = leaf
|
||||
|
||||
return new_node
|
||||
new_node
|
||||
else
|
||||
cost_a = @a.bounding_box.volume + @b.bounding_box.union(leaf.bounding_box).volume
|
||||
cost_b = @b.bounding_box.volume + @a.bounding_box.union(leaf.bounding_box).volume
|
||||
@@ -52,7 +54,7 @@ class IMICFPS
|
||||
|
||||
@bounding_box = @bounding_box.union(leaf.bounding_box)
|
||||
|
||||
return self
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
@@ -66,21 +68,19 @@ class IMICFPS
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
items
|
||||
end
|
||||
|
||||
def remove_subtree(leaf)
|
||||
if leaf
|
||||
return self
|
||||
self
|
||||
elsif leaf.parent == self
|
||||
other_child = other(leaf)
|
||||
other_child.parent = @parent
|
||||
other_child
|
||||
else
|
||||
if leaf.parent == self
|
||||
other_child = other(leaf)
|
||||
other_child.parent = @parent
|
||||
return other_child
|
||||
else
|
||||
leaf.parent.disown_child(leaf)
|
||||
return self
|
||||
end
|
||||
leaf.parent.disown_child(leaf)
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
@@ -116,7 +116,7 @@ class IMICFPS
|
||||
unless node.leaf?
|
||||
node.bounding_box = node.a.bounding_box.union(node.b.bounding_box)
|
||||
|
||||
while(node = node.parent)
|
||||
while (node = node.parent)
|
||||
node.bounding_box = node.a.bounding_box.union(node.b.bounding_box)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class AABBTree
|
||||
include IMICFPS::AABBTreeDebug
|
||||
|
||||
attr_reader :root, :objects, :branches, :leaves
|
||||
|
||||
def initialize
|
||||
@objects = {}
|
||||
@root = nil
|
||||
@@ -23,11 +25,11 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def insert_leaf(leaf)
|
||||
if @root
|
||||
@root = @root.insert_subtree(leaf)
|
||||
else
|
||||
@root = leaf
|
||||
end
|
||||
@root = if @root
|
||||
@root.insert_subtree(leaf)
|
||||
else
|
||||
leaf
|
||||
end
|
||||
end
|
||||
|
||||
def update(object, bounding_box)
|
||||
@@ -41,17 +43,17 @@ class IMICFPS
|
||||
items = []
|
||||
if @root
|
||||
items = @root.search_subtree(collider)
|
||||
items.map! {|e| e.object} unless return_nodes
|
||||
items.map!(&:object) unless return_nodes
|
||||
end
|
||||
|
||||
return items
|
||||
items
|
||||
end
|
||||
|
||||
def remove(object)
|
||||
leaf = @objects.delete(object)
|
||||
@root = @root.remove_subtree(leaf) if leaf
|
||||
|
||||
return leaf
|
||||
leaf
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,9 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
# Gets included into AABBTree
|
||||
module AABBTreeDebug
|
||||
def inspect
|
||||
@branches, @leaves = 0, 0
|
||||
@branches = 0
|
||||
@leaves = 0
|
||||
if @root
|
||||
node = @root
|
||||
|
||||
@@ -11,7 +13,7 @@ class IMICFPS
|
||||
debug_search(node.b)
|
||||
end
|
||||
|
||||
puts "<#{self.class}:#{self.object_id}> has #{@branches} branches and #{@leaves} leaves"
|
||||
puts "<#{self.class}:#{object_id}> has #{@branches} branches and #{@leaves} leaves"
|
||||
end
|
||||
|
||||
def debug_search(node)
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
module Style
|
||||
def self.error(string)
|
||||
"<c=ff5555>#{string}</c>"
|
||||
end
|
||||
|
||||
def self.warn(string)
|
||||
"<c=ff7700>#{string}</c>"
|
||||
end
|
||||
|
||||
def self.notice(string)
|
||||
"<c=55ff55>#{string}</c>"
|
||||
end
|
||||
|
||||
def self.highlight(string, color = "5555ff")
|
||||
"<c=#{color}>#{string}</c>"
|
||||
end
|
||||
@@ -28,7 +32,9 @@ class IMICFPS
|
||||
@commands = []
|
||||
@list.each do |subclass|
|
||||
cmd = subclass.new
|
||||
raise "Command '#{cmd.command}' from '#{cmd.class}' already exists!" if @commands.detect { |c| c.command == cmd.command }
|
||||
if @commands.detect { |c| c.command == cmd.command }
|
||||
raise "Command '#{cmd.command}' from '#{cmd.class}' already exists!"
|
||||
end
|
||||
|
||||
@commands << cmd
|
||||
end
|
||||
@@ -59,15 +65,19 @@ class IMICFPS
|
||||
setup
|
||||
end
|
||||
|
||||
def setup; end
|
||||
def setup
|
||||
end
|
||||
|
||||
def subcommand(command, type)
|
||||
raise "Subcommand '#{command}' for '#{self.command}' already exists!" if @subcommands.detect { |subcmd| subcmd.command == command.to_sym }
|
||||
if @subcommands.detect { |subcmd| subcmd.command == command.to_sym }
|
||||
raise "Subcommand '#{command}' for '#{self.command}' already exists!"
|
||||
end
|
||||
|
||||
@subcommands << SubCommand.new(self, command, type)
|
||||
end
|
||||
|
||||
def get(key)
|
||||
@store.dig(key)
|
||||
@store[key]
|
||||
end
|
||||
|
||||
def set(key, value)
|
||||
@@ -89,15 +99,16 @@ class IMICFPS
|
||||
def autocomplete(console)
|
||||
split = console.text_input.text.split(" ")
|
||||
|
||||
if @subcommands.size > 0
|
||||
if @subcommands.size.positive?
|
||||
if !console.text_input.text.end_with?(" ") && split.size == 2
|
||||
list = console.abbrev_search(@subcommands.map { |cmd| cmd.command.to_s}, split.last)
|
||||
list = console.abbrev_search(@subcommands.map { |cmd| cmd.command.to_s }, split.last)
|
||||
|
||||
if list.size == 1
|
||||
console.text_input.text = "#{split.first} #{list.first} "
|
||||
else
|
||||
return unless list.size > 0
|
||||
console.stdin("#{list.map { |cmd| Commands::Style.highlight(cmd)}.join(", ")}")
|
||||
return unless list.size.positive?
|
||||
|
||||
console.stdin(list.map { |cmd| Commands::Style.highlight(cmd) }.join(", ").to_s)
|
||||
end
|
||||
|
||||
# List available options on subcommand
|
||||
@@ -106,26 +117,26 @@ class IMICFPS
|
||||
|
||||
if subcommand
|
||||
if split.size == 2
|
||||
console.stdin("Available options: #{subcommand.values.map { |value| Commands::Style.highlight(value) }.join(",")}")
|
||||
console.stdin("Available options: #{subcommand.values.map { |value| Commands::Style.highlight(value) }.join(',')}")
|
||||
else
|
||||
list = console.abbrev_search(subcommand.values, split.last)
|
||||
if list.size == 1
|
||||
console.text_input.text = "#{split.first} #{split[1]} #{list.first} "
|
||||
else
|
||||
console.stdin("Available options: #{list.map { |value| Commands::Style.highlight(value) }.join(",")}") if list.size > 0
|
||||
elsif list.size.positive?
|
||||
console.stdin("Available options: #{list.map { |value| Commands::Style.highlight(value) }.join(',')}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# List available subcommands if command was entered and has only a space after it
|
||||
elsif console.text_input.text.end_with?(" ") && split.size == 1
|
||||
console.stdin("Available subcommands: #{@subcommands.map { |cmd| Commands::Style.highlight(cmd.command)}.join(", ")}")
|
||||
console.stdin("Available subcommands: #{@subcommands.map { |cmd| Commands::Style.highlight(cmd.command) }.join(', ')}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_subcommand(arguments, console)
|
||||
if arguments.size == 0
|
||||
if arguments.size.zero?
|
||||
console.stdin(usage)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class ConnectCommand < Command
|
||||
@@ -14,7 +15,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def usage
|
||||
"Connect to a server.\n#{Style.highlight("connect")} #{Style.notice("[example.com:56789]")}"
|
||||
"Connect to a server.\n#{Style.highlight('connect')} #{Style.notice('[example.com:56789]')}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class DebugCommand < Command
|
||||
@@ -39,7 +40,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def usage
|
||||
"debug\n #{@subcommands.map { |sub| sub.usage }.join("\n ")}"
|
||||
"debug\n #{@subcommands.map(&:usage).join("\n ")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class DisconnectCommand < Command
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class FPSCommand < Command
|
||||
@@ -12,13 +13,13 @@ class IMICFPS
|
||||
|
||||
def handle(arguments, console)
|
||||
if arguments.size > 1
|
||||
console.stdin("to many arguments for #{Style.highlight("#{command}")}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
||||
console.stdin("to many arguments for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
||||
return
|
||||
end
|
||||
|
||||
case arguments.last
|
||||
when "", nil
|
||||
console.stdin("#{Style.highlight("fps")}: #{$window.config.get(:options, :fps)}")
|
||||
console.stdin("#{Style.highlight('fps')}: #{$window.config.get(:options, :fps)}")
|
||||
when "on"
|
||||
var = $window.config[:options, :fps] = true
|
||||
console.stdin("fps => #{Style.highlight(var)}")
|
||||
@@ -26,12 +27,12 @@ class IMICFPS
|
||||
var = $window.config[:options, :fps] = false
|
||||
console.stdin("fps => #{Style.highlight(var)}")
|
||||
else
|
||||
console.stdin("Invalid argument for #{Style.highlight("#{command}")}, got #{Style.error(arguments.last)} expected #{Style.notice("on")}, or #{Style.notice("off")}.")
|
||||
console.stdin("Invalid argument for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.last)} expected #{Style.notice('on')}, or #{Style.notice('off')}.")
|
||||
end
|
||||
end
|
||||
|
||||
def usage
|
||||
"#{Style.highlight("fps")} #{Style.notice("[on|off]")}"
|
||||
"#{Style.highlight('fps')} #{Style.notice('[on|off]')}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class HelpCommand < Command
|
||||
@@ -21,7 +22,7 @@ class IMICFPS
|
||||
if list.size == 1
|
||||
console.text_input.text = "#{split.first} #{list.first} "
|
||||
elsif list.size > 1
|
||||
console.stdin(list.map { |cmd| Style.highlight(cmd) }.join(', '))
|
||||
console.stdin(list.map { |cmd| Style.highlight(cmd) }.join(", "))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -34,7 +35,7 @@ class IMICFPS
|
||||
"#{Style.error(command)} is not a command"
|
||||
end
|
||||
else
|
||||
"Available commands:\n#{Command.list_commands.map { |cmd| "#{Style.highlight(cmd.command)}" }.join(', ')}"
|
||||
"Available commands:\n#{Command.list_commands.map { |cmd| Style.highlight(cmd.command).to_s }.join(', ')}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class ReloadShaderCommand < Command
|
||||
@@ -12,7 +13,7 @@ class IMICFPS
|
||||
|
||||
def handle(arguments, console)
|
||||
if arguments.size > 2
|
||||
console.stdin("to many arguments for #{Style.highlight("#{command}")}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
||||
console.stdin("to many arguments for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -22,7 +23,7 @@ class IMICFPS
|
||||
|
||||
case arguments.size
|
||||
when 0
|
||||
console.stdin( usage )
|
||||
console.stdin(usage)
|
||||
return
|
||||
when 1
|
||||
name = arguments.first
|
||||
@@ -50,9 +51,9 @@ class IMICFPS
|
||||
string = $stdout.string
|
||||
|
||||
if shader.compiled?
|
||||
console.stdin("#{Style.notice("Successfully reloaded shader")}: #{shader.name}")
|
||||
console.stdin("#{Style.notice('Successfully reloaded shader')}: #{shader.name}")
|
||||
else
|
||||
console.stdin("#{Style.error("Failed to reload #{shader.name}")}")
|
||||
console.stdin(Style.error("Failed to reload #{shader.name}").to_s)
|
||||
console.stdin(string)
|
||||
end
|
||||
ensure
|
||||
@@ -61,7 +62,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def usage
|
||||
"#{Style.highlight(command)} #{Style.notice("vertex_name [fragment_name]")}"
|
||||
"#{Style.highlight(command)} #{Style.notice('vertex_name [fragment_name]')}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class RendererInfoCommand < Command
|
||||
@@ -10,7 +11,7 @@ class IMICFPS
|
||||
:renderer_info
|
||||
end
|
||||
|
||||
def handle(arguments, console)
|
||||
def handle(_arguments, console)
|
||||
console.stdin("OpenGL Vendor: #{Style.notice(glGetString(GL_VENDOR))}")
|
||||
console.stdin("OpenGL Renderer: #{Style.notice(glGetString(GL_RENDERER))}")
|
||||
console.stdin("OpenGL Version: #{Style.notice(glGetString(GL_VERSION))}")
|
||||
@@ -18,7 +19,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def usage
|
||||
"#{Style.highlight("renderer_info")} #{Style.notice("Returns OpenGL renderer information")}"
|
||||
"#{Style.highlight('renderer_info')} #{Style.notice('Returns OpenGL renderer information')}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user