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
|
||||
|
||||
@@ -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
|
||||
entity.position = if origin.distance3d(event.entity.position) <= 3.0
|
||||
origin + Vector.up * 2.4
|
||||
else
|
||||
entity.position = origin
|
||||
origin
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
component(:building)
|
||||
|
||||
on.create do |event|
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
component(:vehicle) # Generic, Weapon
|
||||
|
||||
on.button_down(:interact) do |event|
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
component(:building)
|
||||
|
||||
on.create do |event|
|
||||
|
||||
@@ -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
|
||||
|
||||
20
i-mic-fps.rb
20
i-mic-fps.rb
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "fiddle"
|
||||
require "yaml"
|
||||
require "json"
|
||||
@@ -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,11 +70,12 @@ 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")
|
||||
if prevent_launch?[0]
|
||||
puts prevent_launch?[1]
|
||||
elsif ARGV.join.include?("--profile")
|
||||
begin
|
||||
require "ruby-prof"
|
||||
RubyProf.start
|
||||
@@ -86,6 +89,3 @@ unless prevent_launch?[0]
|
||||
else
|
||||
IMICFPS::Window.new.show
|
||||
end
|
||||
else
|
||||
puts prevent_launch?[1]
|
||||
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,10 +44,10 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def position_camera
|
||||
if first_person_view?
|
||||
@distance = 0
|
||||
@distance = if first_person_view?
|
||||
0
|
||||
else
|
||||
@distance = @origin_distance
|
||||
@origin_distance
|
||||
end
|
||||
|
||||
x_offset = horizontal_distance_from_object * Math.sin(@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
|
||||
|
||||
@@ -75,7 +78,8 @@ class IMICFPS
|
||||
|
||||
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
|
||||
@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,24 +43,35 @@ 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,
|
||||
|
||||
@@ -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,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Crosshair
|
||||
include CommonMethods
|
||||
|
||||
21
lib/demo.rb
21
lib/demo.rb
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Demo
|
||||
def initialize(camera:, player:, demo:, mode:)
|
||||
@@ -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
|
||||
|
||||
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,12 +15,10 @@ class IMICFPS
|
||||
|
||||
if action.is_a?(Numeric) && action == key
|
||||
subscriber.trigger(event)
|
||||
else
|
||||
if InputMapper.get(action) == key
|
||||
elsif InputMapper.get(action) == key
|
||||
subscriber.trigger(event)
|
||||
end
|
||||
end
|
||||
end
|
||||
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)
|
||||
@@ -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,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class HUD
|
||||
class ScoreBoardWidget < HUD::Widget
|
||||
@@ -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
|
||||
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)
|
||||
case query
|
||||
when Integer
|
||||
query
|
||||
elsif query.is_a?(Array)
|
||||
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)
|
||||
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
|
||||
@@ -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,7 +21,7 @@ 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")
|
||||
MASTERS[package] = yaml
|
||||
@@ -28,7 +29,7 @@ class IMICFPS
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@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
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -46,29 +47,28 @@ class IMICFPS
|
||||
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)
|
||||
@@ -76,9 +76,9 @@ class IMICFPS
|
||||
@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
|
||||
|
||||
@@ -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,7 +15,8 @@ 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?
|
||||
@@ -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,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class Scene
|
||||
attr_reader :camera, :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,
|
||||
@@ -54,7 +55,7 @@ class IMICFPS
|
||||
: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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IMICFPS
|
||||
class LoadingState < Menu
|
||||
def setup
|
||||
@@ -13,7 +14,7 @@ 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)
|
||||
@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)
|
||||
|
||||
@@ -45,7 +46,6 @@ class IMICFPS
|
||||
@description.draw
|
||||
@state.draw
|
||||
|
||||
|
||||
progressbar
|
||||
end
|
||||
|
||||
@@ -75,19 +75,17 @@ class IMICFPS
|
||||
@asset_index += 1
|
||||
end
|
||||
|
||||
unless @asset_index < @assets.count
|
||||
if @act && Gosu.milliseconds-@completed_for_ms > 250
|
||||
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)
|
||||
@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
|
||||
else
|
||||
@state.text = "Loading #{@assets[@asset_index][:type]} #{@assets[@asset_index][:name].split('/').last}..."
|
||||
@state.x = (window.width/2)-(@state.width/2)
|
||||
@cycled = true
|
||||
end
|
||||
end
|
||||
|
||||
def add_asset(type, package, name)
|
||||
@@ -106,9 +104,7 @@ 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
|
||||
add_asset(:model, dependency.package, dependency.name) unless known
|
||||
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
|
||||
@@ -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
|
||||
else
|
||||
if leaf.parent == self
|
||||
self
|
||||
elsif leaf.parent == self
|
||||
other_child = other(leaf)
|
||||
other_child.parent = @parent
|
||||
return other_child
|
||||
other_child
|
||||
else
|
||||
leaf.parent.disown_child(leaf)
|
||||
return self
|
||||
end
|
||||
self
|
||||
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,10 +25,10 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def insert_leaf(leaf)
|
||||
if @root
|
||||
@root = @root.insert_subtree(leaf)
|
||||
@root = if @root
|
||||
@root.insert_subtree(leaf)
|
||||
else
|
||||
@root = leaf
|
||||
leaf
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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)
|
||||
|
||||
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
|
||||
|
||||
@@ -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