Compare commits
29 Commits
dynamic_st
...
f10b98b0f0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f10b98b0f0 | ||
| 8f2d7ff905 | |||
| 580c9d79ce | |||
| 07c8dfa45b | |||
|
|
b69bdc8e46 | ||
| 3481de2498 | |||
|
|
7bcd973a88 | ||
| 1d34cbb63d | |||
|
|
2df2df8488 | ||
| 87bff4ab82 | |||
| cf37b94d80 | |||
| 0fe1d85924 | |||
| ec2b32ff92 | |||
| 3986b1b0af | |||
| 58b2f8b890 | |||
| 5cb48233fb | |||
| da54bf5c53 | |||
| 3570a80d67 | |||
| 51363d2e3d | |||
| a16e14b0e5 | |||
|
|
4ebc4772a1 | ||
| 15ba3fb15b | |||
| c5e0f33f21 | |||
| d3fbf5dcf5 | |||
| 5b662f83cf | |||
| 55bfe6ed79 | |||
| bd414cf765 | |||
| c848a11c12 | |||
| 5759055838 |
37
Gemfile.lock
@@ -1,11 +1,10 @@
|
|||||||
GIT
|
GIT
|
||||||
remote: https://github.com/cyberarm/cyberarm_engine
|
remote: https://github.com/cyberarm/cyberarm_engine
|
||||||
revision: d02c001989ce967e2b3184d1a0f01cd5b20ac241
|
revision: d1d87db070578fefe97f275b63157b4212a44a89
|
||||||
specs:
|
specs:
|
||||||
cyberarm_engine (0.14.0)
|
cyberarm_engine (0.22.0)
|
||||||
clipboard (~> 1.3.4)
|
excon (~> 0.88)
|
||||||
excon (~> 0.76.0)
|
gosu (~> 1.1)
|
||||||
gosu (~> 0.15.0)
|
|
||||||
gosu_more_drawables (~> 0.3)
|
gosu_more_drawables (~> 0.3)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
@@ -21,26 +20,26 @@ GIT
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
clipboard (1.3.5)
|
concurrent-ruby (1.1.10)
|
||||||
concurrent-ruby (1.1.7)
|
|
||||||
cri (2.1.0)
|
cri (2.1.0)
|
||||||
excon (0.76.0)
|
excon (0.96.0)
|
||||||
gosu (0.15.2)
|
gosu (1.4.5)
|
||||||
gosu (0.15.2-x64-mingw32)
|
|
||||||
gosu_more_drawables (0.3.1)
|
gosu_more_drawables (0.3.1)
|
||||||
i18n (1.8.5)
|
i18n (1.12.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
mini_portile2 (2.5.0)
|
mini_portile2 (2.8.1)
|
||||||
nokogiri (1.11.0.rc3)
|
nokogiri (1.14.3)
|
||||||
mini_portile2 (~> 2.5.0)
|
mini_portile2 (~> 2.8.0)
|
||||||
nokogiri (1.11.0.rc3-x64-mingw32)
|
racc (~> 1.4)
|
||||||
ocra (1.3.11)
|
ocra (1.3.11)
|
||||||
opengl-bindings (1.6.10)
|
opengl-bindings (1.6.13)
|
||||||
rake (13.0.1)
|
racc (1.6.2)
|
||||||
rubyzip (2.3.0)
|
rake (13.0.6)
|
||||||
|
rubyzip (2.3.2)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
x64-mingw-ucrt
|
||||||
x64-mingw32
|
x64-mingw32
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
@@ -55,4 +54,4 @@ DEPENDENCIES
|
|||||||
rubyzip
|
rubyzip
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.1.4
|
2.4.1
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Creating a multiplayer first-person-shooter in pure Ruby; Using C extensions onl
|
|||||||

|

|
||||||
|
|
||||||
## Using
|
## Using
|
||||||
Ruby 2.5+ interpeter with support for the Gosu game library C extension.
|
Ruby 3.0+ interpeter with support for the Gosu game library C extension.
|
||||||
* Clone or download this repo
|
* Clone or download this repo
|
||||||
* `bundle install`
|
* `bundle install`
|
||||||
* `bundle exec ruby i-mic-fps.rb [options]`
|
* `bundle exec ruby i-mic-fps.rb [options]`
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ end
|
|||||||
class Window < Gosu::Window
|
class Window < Gosu::Window
|
||||||
def initialize
|
def initialize
|
||||||
super(Gosu.screen_width, Gosu.screen_height, fullscreen: true)
|
super(Gosu.screen_width, Gosu.screen_height, fullscreen: true)
|
||||||
$window = self
|
CyberarmEngine::Window.instance = self
|
||||||
@size = 50
|
@size = 50
|
||||||
@slope = 250
|
@slope = 250
|
||||||
@color_step = 10
|
@color_step = 10
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
component(:vehicle) # Generic, Weapon
|
component(:vehicle) # Generic, Weapon
|
||||||
|
|
||||||
on.button_down(:interact) do |event|
|
on.button_down(:interact) do |event|
|
||||||
$window.console.stdin("#{event.entity.name} handled button_down(:interact)")
|
CyberarmEngine::Window.instance.console.stdin("#{event.entity.name} handled button_down(:interact)")
|
||||||
# if event.player.touching?(event.entity)
|
# if event.player.touching?(event.entity)
|
||||||
# event.player.enter_vehicle
|
# event.player.enter_vehicle
|
||||||
# elsif event.player.driving?(event.entity) or event.player.passenger?(event.entity)
|
# elsif event.player.driving?(event.entity) or event.player.passenger?(event.entity)
|
||||||
|
|||||||
22
assets/base/shared/sound/master.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"playlists": {
|
||||||
|
"menus": [
|
||||||
|
"menu_background"
|
||||||
|
],
|
||||||
|
"nighttime": [],
|
||||||
|
"daytime": []
|
||||||
|
},
|
||||||
|
"music": [
|
||||||
|
{
|
||||||
|
"name": "menu_background",
|
||||||
|
"path": "music/untitled-2-revised-extended_mixed.ogg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sounds": [
|
||||||
|
{
|
||||||
|
"name": "shield_regen",
|
||||||
|
"type": "sfx",
|
||||||
|
"path": "sfx/shield_regen.wav"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
playlists:
|
|
||||||
- menus:
|
|
||||||
- nighttime:
|
|
||||||
- daytime:
|
|
||||||
music:
|
|
||||||
sounds:
|
|
||||||
-
|
|
||||||
name: shield_regen
|
|
||||||
type: sfx
|
|
||||||
path: sfx/shield_regen.wav
|
|
||||||
47
i-mic-fps.rb
@@ -31,6 +31,7 @@ include GLU
|
|||||||
|
|
||||||
def require_all(directory)
|
def require_all(directory)
|
||||||
files = Dir["#{directory}/**/*.rb"].sort!
|
files = Dir["#{directory}/**/*.rb"].sort!
|
||||||
|
file_order = []
|
||||||
|
|
||||||
loop do
|
loop do
|
||||||
failed = []
|
failed = []
|
||||||
@@ -39,6 +40,7 @@ def require_all(directory)
|
|||||||
files.each do |file|
|
files.each do |file|
|
||||||
begin
|
begin
|
||||||
require_relative file
|
require_relative file
|
||||||
|
file_order << file
|
||||||
rescue NameError => e
|
rescue NameError => e
|
||||||
failed << file
|
failed << file
|
||||||
first_name_error ||= e
|
first_name_error ||= e
|
||||||
@@ -52,6 +54,8 @@ def require_all(directory)
|
|||||||
end
|
end
|
||||||
break if failed.empty?
|
break if failed.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# pp file_order.map { |f| f.gsub(".rb", "")}
|
||||||
end
|
end
|
||||||
|
|
||||||
require_all "lib"
|
require_all "lib"
|
||||||
@@ -75,17 +79,36 @@ end
|
|||||||
|
|
||||||
if prevent_launch?[0]
|
if prevent_launch?[0]
|
||||||
puts prevent_launch?[1]
|
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
|
else
|
||||||
IMICFPS::Window.new.show
|
native = ARGV.join.include?("--native")
|
||||||
|
fps_target = ARGV.first.to_i != 0 ? ARGV.first.to_i : 60
|
||||||
|
window_width = native ? Gosu.screen_width : 1280
|
||||||
|
window_height = native ? Gosu.screen_height : 720
|
||||||
|
window_fullscreen = native ? true : false
|
||||||
|
|
||||||
|
window = IMICFPS::Window.new(
|
||||||
|
width: window_width,
|
||||||
|
height: window_height,
|
||||||
|
fullscreen: window_fullscreen,
|
||||||
|
resizable: !window_fullscreen,
|
||||||
|
update_interval: 1000.0 / fps_target
|
||||||
|
)
|
||||||
|
|
||||||
|
if ARGV.join.include?("--profile")
|
||||||
|
begin
|
||||||
|
require "ruby-prof"
|
||||||
|
RubyProf.start
|
||||||
|
|
||||||
|
window.show
|
||||||
|
|
||||||
|
result = RubyProf.stop
|
||||||
|
printer = RubyProf::MultiPrinter.new(result)
|
||||||
|
printer.print(path: ".", profile: "profile", min_percent: 2)
|
||||||
|
rescue LoadError
|
||||||
|
puts "ruby-prof not installed!"
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
else
|
||||||
|
window.show
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class IMICFPS
|
|||||||
attr_accessor :mode, :camera, :entity, :distance, :origin_distance,
|
attr_accessor :mode, :camera, :entity, :distance, :origin_distance,
|
||||||
:constant_pitch, :mouse_sensitivity, :mouse_captured
|
:constant_pitch, :mouse_sensitivity, :mouse_captured
|
||||||
|
|
||||||
def initialize(camera:, entity:, mode: :fpv)
|
def initialize(camera:, entity: nil, mode: :fpv)
|
||||||
# :fpv - First Person View
|
# :fpv - First Person View
|
||||||
# :tpv - Third Person View
|
# :tpv - Third Person View
|
||||||
@mode = mode
|
@mode = mode
|
||||||
@@ -63,24 +63,26 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
position_camera
|
position_camera if @entity
|
||||||
|
|
||||||
if @mouse_captured
|
return unless @mouse_captured
|
||||||
delta = Float(@true_mouse.x - mouse_x) / (@mouse_sensitivity * @camera.field_of_view) * 70
|
|
||||||
@camera.orientation.y -= delta
|
|
||||||
@camera.orientation.y %= 360.0
|
|
||||||
|
|
||||||
@camera.orientation.x -= Float(@true_mouse.y - window.mouse_y) / (@mouse_sensitivity * @camera.field_of_view) * 70
|
delta = Float(@true_mouse.x - mouse_x) / (@mouse_sensitivity * @camera.field_of_view) * 70
|
||||||
@camera.orientation.x = @camera.orientation.x.clamp(-90.0, 90.0)
|
@camera.orientation.y -= delta
|
||||||
|
@camera.orientation.y %= 360.0
|
||||||
|
|
||||||
|
@camera.orientation.x -= Float(@true_mouse.y - window.mouse_y) / (@mouse_sensitivity * @camera.field_of_view) * 70
|
||||||
|
@camera.orientation.x = @camera.orientation.x.clamp(-90.0, 90.0)
|
||||||
|
|
||||||
|
if @entity
|
||||||
@entity.orientation.y += delta
|
@entity.orientation.y += delta
|
||||||
@entity.orientation.y %= 360.0
|
@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 = window.mouse_x
|
|
||||||
@true_mouse.y = window.mouse_y
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
def button_down(id)
|
def button_down(id)
|
||||||
@@ -99,14 +101,49 @@ class IMICFPS
|
|||||||
@camera.max_view_distance += 0.5
|
@camera.max_view_distance += 0.5
|
||||||
elsif actions.include?(:toggle_first_person_view)
|
elsif actions.include?(:toggle_first_person_view)
|
||||||
@mode = first_person_view? ? :tpv : :fpv
|
@mode = first_person_view? ? :tpv : :fpv
|
||||||
@entity.visible = !first_person_view?
|
@entity.visible = !first_person_view? if @entity
|
||||||
elsif actions.include?(:turn_180)
|
elsif actions.include?(:turn_180)
|
||||||
@entity.orientation.y += 180
|
@entity.orientation.y += 180 if @entity
|
||||||
@entity.orientation.y %= 360.0
|
@entity.orientation.y %= 360.0 if @entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_up(id)
|
def button_up(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def free_move
|
||||||
|
relative_y_rotation = (@camera.orientation.y + 180)
|
||||||
|
relative_speed = 2.5
|
||||||
|
relative_speed = 1.5 if InputMapper.down?(:sneak)
|
||||||
|
relative_speed = 10.0 if InputMapper.down?(:sprint)
|
||||||
|
relative_speed *= window.dt
|
||||||
|
|
||||||
|
if InputMapper.down?( :forward)
|
||||||
|
@camera.position.z += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
@camera.position.x -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
end
|
||||||
|
|
||||||
|
if InputMapper.down?(:backward)
|
||||||
|
@camera.position.z -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
@camera.position.x += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
end
|
||||||
|
|
||||||
|
if InputMapper.down?(:strife_left)
|
||||||
|
@camera.position.z += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
@camera.position.x += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
end
|
||||||
|
|
||||||
|
if InputMapper.down?(:strife_right)
|
||||||
|
@camera.position.z -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
@camera.position.x -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed
|
||||||
|
end
|
||||||
|
|
||||||
|
if InputMapper.down?(:ascend)
|
||||||
|
@camera.position.y += relative_speed
|
||||||
|
end
|
||||||
|
if InputMapper.down?(:descend)
|
||||||
|
@camera.position.y -= relative_speed
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class IMICFPS
|
|||||||
|
|
||||||
module CommonMethods
|
module CommonMethods
|
||||||
def window
|
def window
|
||||||
$window
|
CyberarmEngine::Window.instance
|
||||||
end
|
end
|
||||||
|
|
||||||
def delta_time
|
def delta_time
|
||||||
|
|||||||
@@ -11,8 +11,25 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
draw_rect(window.width / 2 - @size, (window.height / 2 - @size) - @thickness / 2, @size * 2, @thickness, @color, 0, :default)
|
draw_rect(
|
||||||
draw_rect((window.width / 2) - @thickness / 2, window.height / 2 - (@size * 2), @thickness, @size * 2, @color, 0, :default)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -77,12 +77,12 @@ class IMICFPS
|
|||||||
when "up"
|
when "up"
|
||||||
input = InputMapper.get(data.last.to_sym)
|
input = InputMapper.get(data.last.to_sym)
|
||||||
key = input.is_a?(Array) ? input.first : input
|
key = input.is_a?(Array) ? input.first : input
|
||||||
$window.current_state.button_up(key) if key
|
CyberarmEngine::Window.instance.current_state.button_up(key) if key
|
||||||
|
|
||||||
when "down"
|
when "down"
|
||||||
input = InputMapper.get(data.last.to_sym)
|
input = InputMapper.get(data.last.to_sym)
|
||||||
key = input.is_a?(Array) ? input.first : input
|
key = input.is_a?(Array) ? input.first : input
|
||||||
$window.current_state.button_down(key) if key
|
CyberarmEngine::Window.instance.current_state.button_down(key) if key
|
||||||
|
|
||||||
when "mouse"
|
when "mouse"
|
||||||
@camera.orientation.z = data[1].to_f
|
@camera.orientation.z = data[1].to_f
|
||||||
|
|||||||
13
lib/ext/element.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
module CyberarmEngine
|
||||||
|
class Element
|
||||||
|
alias enter_original enter
|
||||||
|
|
||||||
|
def enter(_sender)
|
||||||
|
if @block && is_a?(CyberarmEngine::Element::Link)
|
||||||
|
get_sample("#{IMICFPS::GAME_ROOT_PATH}/static/sounds/ui_hover.ogg").play
|
||||||
|
end
|
||||||
|
|
||||||
|
enter_original(_sender)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
10
lib/hud.rb
@@ -10,6 +10,7 @@ class IMICFPS
|
|||||||
@score_board = ScoreBoardWidget.new({ player: player })
|
@score_board = ScoreBoardWidget.new({ player: player })
|
||||||
@squad = SquadWidget.new({ player: player })
|
@squad = SquadWidget.new({ player: player })
|
||||||
@crosshair = CrosshairWidget.new({ player: player })
|
@crosshair = CrosshairWidget.new({ player: player })
|
||||||
|
@chat = ChatWidget.new({ player: player })
|
||||||
|
|
||||||
@hud_elements = [
|
@hud_elements = [
|
||||||
@ammo,
|
@ammo,
|
||||||
@@ -18,6 +19,7 @@ class IMICFPS
|
|||||||
@chat_history,
|
@chat_history,
|
||||||
@score_board,
|
@score_board,
|
||||||
@squad,
|
@squad,
|
||||||
|
@chat,
|
||||||
|
|
||||||
@crosshair
|
@crosshair
|
||||||
]
|
]
|
||||||
@@ -30,5 +32,13 @@ class IMICFPS
|
|||||||
def update
|
def update
|
||||||
@hud_elements.each(&:update)
|
@hud_elements.each(&:update)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def button_down(id)
|
||||||
|
@hud_elements.each { |e| e.button_down(id) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_up(id)
|
||||||
|
@hud_elements.each { |e| e.button_up(id) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,21 +7,37 @@ class IMICFPS
|
|||||||
|
|
||||||
# Widget margin from screen edge
|
# Widget margin from screen edge
|
||||||
# or how much widget is pushed in
|
# or how much widget is pushed in
|
||||||
def self.margin
|
def self.vertical_margin
|
||||||
@@margin ||= 10
|
@@vertical_margin ||= 36
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.padding=(n)
|
def self.vertical_margin=(n)
|
||||||
@@padding = n
|
@@vertical_margin = n
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.horizontal_margin
|
||||||
|
@@horizontal_margin ||= 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.horizontal_margin=(n)
|
||||||
|
@@horizontal_margin = n
|
||||||
end
|
end
|
||||||
|
|
||||||
# Widget element padding
|
# Widget element padding
|
||||||
def self.padding
|
def self.vertical_padding
|
||||||
@@margin ||= 10
|
@@vertical_padding ||= 10
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.padding=(n)
|
def self.vertical_padding=(n)
|
||||||
@@padding = n
|
@@vertical_padding = n
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.horizontal_padding
|
||||||
|
@@horizontal_padding ||= 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.horizontal_padding=(n)
|
||||||
|
@@horizontal_padding = n
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :options
|
attr_reader :options
|
||||||
@@ -41,6 +57,20 @@ class IMICFPS
|
|||||||
|
|
||||||
def update
|
def update
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def button_down(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_up(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def hijack_input!
|
||||||
|
CyberarmEngine::Window.instance.input_hijack = self
|
||||||
|
end
|
||||||
|
|
||||||
|
def release_input!
|
||||||
|
CyberarmEngine::Window.instance.input_hijack = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ class IMICFPS
|
|||||||
class HUD
|
class HUD
|
||||||
class AmmoWidget < HUD::Widget
|
class AmmoWidget < HUD::Widget
|
||||||
def setup
|
def setup
|
||||||
@text = Text.new("", size: 64, mode: :add, font: MONOSPACE_FONT)
|
@text = Text.new("", size: 64, font: MONOSPACE_FONT, border: true, border_color: Gosu::Color::BLACK)
|
||||||
@background = Gosu::Color.new(0x88c64600)
|
@background = Gosu::Color.new(0x88c64600)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
Gosu.draw_rect(
|
Gosu.draw_rect(
|
||||||
@text.x - Widget.padding, @text.y - Widget.padding,
|
@text.x - Widget.horizontal_padding, @text.y - Widget.vertical_padding,
|
||||||
@text.width + Widget.padding * 2, @text.height + Widget.padding * 2,
|
@text.width + Widget.horizontal_padding * 2, @text.height + Widget.vertical_padding * 2,
|
||||||
@background
|
@background
|
||||||
)
|
)
|
||||||
@text.draw
|
@text.draw
|
||||||
@@ -23,8 +23,8 @@ class IMICFPS
|
|||||||
@text.text = "#{random}/999"
|
@text.text = "#{random}/999"
|
||||||
end
|
end
|
||||||
|
|
||||||
@text.x = window.width - (Widget.margin + @text.width + Widget.padding)
|
@text.x = window.width - (Widget.horizontal_margin + @text.width + Widget.horizontal_padding)
|
||||||
@text.y = window.height - (Widget.margin + @text.height + Widget.padding)
|
@text.y = window.height - (Widget.vertical_margin + @text.height + Widget.vertical_padding)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
97
lib/hud/widgets/chat.rb
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class IMICFPS
|
||||||
|
class HUD
|
||||||
|
class ChatWidget < HUD::Widget
|
||||||
|
def setup
|
||||||
|
@deliver_to_text = Text.new("", size: 28, font: BOLD_SANS_FONT)
|
||||||
|
@text = Text.new("", size: 28, font: SANS_FONT)
|
||||||
|
|
||||||
|
@text_input = nil
|
||||||
|
@background = Gosu::Color.new(0x88c64600)
|
||||||
|
@selection_color = Gosu::Color.new(0x88222222)
|
||||||
|
@width = @options[:width] || 400
|
||||||
|
|
||||||
|
@delivery_options = [:all, :team, :squad]
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
return unless @text_input
|
||||||
|
|
||||||
|
Gosu.draw_rect(
|
||||||
|
Widget.horizontal_margin, CyberarmEngine::Window.instance.height / 2 - (@text.height / 2 + Widget.horizontal_padding),
|
||||||
|
@width - Widget.horizontal_padding * 2, @text.height + Widget.vertical_padding * 2,
|
||||||
|
@background
|
||||||
|
)
|
||||||
|
|
||||||
|
@deliver_to_text.draw
|
||||||
|
|
||||||
|
clip_width = @deliver_to_text.width + Widget.horizontal_padding * 3 + Widget.horizontal_margin
|
||||||
|
Gosu.clip_to(@text.x, @text.y, @width - clip_width, @text.height) do
|
||||||
|
x = Widget.horizontal_margin + Widget.horizontal_padding + @deliver_to_text.width
|
||||||
|
|
||||||
|
cursor_x = x + @text.width(@text_input.text[0...@text_input.caret_pos])
|
||||||
|
selection_x = x + @text.width(@text_input.text[0...@text_input.selection_start])
|
||||||
|
selection_width = cursor_x - selection_x
|
||||||
|
cursor_thickness = 2
|
||||||
|
|
||||||
|
Gosu.draw_rect(selection_x, @text.y, selection_width, @text.height, @selection_color)
|
||||||
|
Gosu.draw_rect(cursor_x, @text.y, cursor_thickness, @text.height, Gosu::Color::WHITE)
|
||||||
|
@text.draw
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@deliver_to_text.text = "#{@deliver_to}: "
|
||||||
|
@deliver_to_text.x = Widget.horizontal_margin + Widget.horizontal_padding
|
||||||
|
@deliver_to_text.y = CyberarmEngine::Window.instance.height / 2 - (@text.height / 2)
|
||||||
|
|
||||||
|
@text.text = @text_input&.text.to_s
|
||||||
|
@text.x = Widget.horizontal_margin + Widget.horizontal_padding + @deliver_to_text.width
|
||||||
|
@text.y = CyberarmEngine::Window.instance.height / 2 - (@text.height / 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_down(id)
|
||||||
|
# TODO: Use InputMapper keymap to function
|
||||||
|
# NOTE: Account for Y in QWERTZ layout
|
||||||
|
case id
|
||||||
|
when Gosu::KB_T, Gosu::KB_Y, Gosu::KB_U
|
||||||
|
return if @text_input
|
||||||
|
|
||||||
|
hijack_input!
|
||||||
|
|
||||||
|
@text_input = window.text_input = Gosu::TextInput.new
|
||||||
|
|
||||||
|
@deliver_to = :all if Gosu.button_down?(Gosu::KbT)
|
||||||
|
@deliver_to = :team if Gosu.button_down?(Gosu::KbY)
|
||||||
|
@deliver_to = :squad if Gosu.button_down?(Gosu::KbU)
|
||||||
|
when Gosu::KB_TAB
|
||||||
|
return unless @text_input
|
||||||
|
|
||||||
|
cycle_deliver_to
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_up(id)
|
||||||
|
return unless @text_input
|
||||||
|
|
||||||
|
case id
|
||||||
|
when Gosu::KB_ENTER, Gosu::KB_RETURN
|
||||||
|
release_input!
|
||||||
|
|
||||||
|
# TODO: Deliver message to server
|
||||||
|
|
||||||
|
@text_input = window.text_input = nil
|
||||||
|
when Gosu::KB_ESCAPE
|
||||||
|
release_input!
|
||||||
|
@text_input = window.text_input = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cycle_deliver_to
|
||||||
|
i = @delivery_options.index(@deliver_to)
|
||||||
|
@deliver_to = @delivery_options[(i + 1) % (@delivery_options.size)]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -9,12 +9,9 @@ class IMICFPS
|
|||||||
@text = CyberarmEngine::Text.new(
|
@text = CyberarmEngine::Text.new(
|
||||||
"",
|
"",
|
||||||
size: 16,
|
size: 16,
|
||||||
x: Widget.margin, y: Widget.margin, z: 45,
|
x: Widget.horizontal_margin, y: Widget.vertical_margin, z: 45,
|
||||||
shadow_size: 0.5,
|
border_color: Gosu::Color::BLACK,
|
||||||
shadow_alpha: 0,
|
font: BOLD_SANS_FONT
|
||||||
shadow_color: Gosu::Color::WHITE,
|
|
||||||
mode: :add,
|
|
||||||
font: SANS_FONT
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@last_message_time = 0
|
@last_message_time = 0
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class IMICFPS
|
|||||||
@last_changed_time = Gosu.milliseconds
|
@last_changed_time = Gosu.milliseconds
|
||||||
@change_interval = 1_500
|
@change_interval = 1_500
|
||||||
|
|
||||||
@colors = [0xffffffff, 0xaaffffff, 0x88ffffff, 0x22ffffff]
|
@color = 0xaaffffff
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
@@ -25,14 +25,6 @@ class IMICFPS
|
|||||||
@color
|
@color
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
|
||||||
if Gosu.milliseconds - @last_changed_time >= @change_interval
|
|
||||||
@last_changed_time = Gosu.milliseconds
|
|
||||||
|
|
||||||
@color = @colors.sample
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class IMICFPS
|
|||||||
class HealthWidget < HUD::Widget
|
class HealthWidget < HUD::Widget
|
||||||
def setup
|
def setup
|
||||||
@spacer = 0
|
@spacer = 0
|
||||||
@text = Text.new("", mode: :add, font: MONOSPACE_FONT)
|
@text = Text.new("", font: MONOSPACE_FONT, border: true, border_color: Gosu::Color::BLACK)
|
||||||
@width = 512
|
@width = 512
|
||||||
@height = 24
|
@height = 24
|
||||||
@slant = 32
|
@slant = 32
|
||||||
@@ -19,10 +19,10 @@ class IMICFPS
|
|||||||
def draw
|
def draw
|
||||||
@text.draw
|
@text.draw
|
||||||
fill_quad(
|
fill_quad(
|
||||||
window.width / 2 - @width / 2, @spacer + Widget.margin, # TOP LEFT
|
window.width / 2 - @width / 2, @spacer + Widget.vertical_margin, # TOP LEFT
|
||||||
window.width / 2 + @width / 2, @spacer + Widget.margin, # TOP RIGHT
|
window.width / 2 + @width / 2, @spacer + Widget.vertical_margin, # TOP RIGHT
|
||||||
window.width / 2 + @width / 2 - @slant, @spacer + Widget.margin + @height, # BOTTOM RIGHT
|
window.width / 2 + @width / 2 - @slant, @spacer + Widget.vertical_margin + @height, # BOTTOM RIGHT
|
||||||
window.width / 2 - @width / 2 + @slant, @spacer + Widget.margin + @height, # BOTTOM LEFT
|
window.width / 2 - @width / 2 + @slant, @spacer + Widget.vertical_margin + @height, # BOTTOM LEFT
|
||||||
@color
|
@color
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,10 +31,10 @@ class IMICFPS
|
|||||||
|
|
||||||
# Current Health
|
# Current Health
|
||||||
fill_quad(
|
fill_quad(
|
||||||
window.width / 2 - @width / 2, @spacer + Widget.margin, # TOP LEFT
|
window.width / 2 - @width / 2, @spacer + Widget.vertical_margin, # TOP LEFT
|
||||||
(window.width / 2 - @width / 2) + @width * @health, @spacer + Widget.margin, # TOP RIGHT
|
(window.width / 2 - @width / 2) + @width * @health, @spacer + Widget.vertical_margin, # TOP RIGHT
|
||||||
bottom_right, @spacer + Widget.margin + @height, # BOTTOM RIGHT
|
bottom_right, @spacer + Widget.vertical_margin + @height, # BOTTOM RIGHT
|
||||||
window.width / 2 - @width / 2 + @slant, @spacer + Widget.margin + @height, # BOTTOM LEFT
|
window.width / 2 - @width / 2 + @slant, @spacer + Widget.vertical_margin + @height, # BOTTOM LEFT
|
||||||
@shield
|
@shield
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -43,7 +43,7 @@ class IMICFPS
|
|||||||
percentage = (@health * 100).round.to_s.rjust(3, "0")
|
percentage = (@health * 100).round.to_s.rjust(3, "0")
|
||||||
@text.text = "[Health #{percentage}%]"
|
@text.text = "[Health #{percentage}%]"
|
||||||
@text.x = window.width / 2 - @text.width / 2
|
@text.x = window.width / 2 - @text.width / 2
|
||||||
@text.y = @spacer + Widget.margin + @height / 2 - @text.height / 2
|
@text.y = @spacer + Widget.vertical_margin + @height / 2 - @text.height / 2
|
||||||
|
|
||||||
@health += 0.1 * window.dt
|
@health += 0.1 * window.dt
|
||||||
@health = 0 if @health > 1.0
|
@health = 0 if @health > 1.0
|
||||||
|
|||||||
@@ -12,36 +12,41 @@ class IMICFPS
|
|||||||
@border_color = Gosu::Color.new(0x88c64600)
|
@border_color = Gosu::Color.new(0x88c64600)
|
||||||
@radar_color = Gosu::Color.new(0x88212121)
|
@radar_color = Gosu::Color.new(0x88212121)
|
||||||
|
|
||||||
@text = Text.new("RADAR", size: 18, mode: :add, font: MONOSPACE_FONT)
|
@text = Text.new("RADAR", size: 18, font: MONOSPACE_FONT, border: true, border_color: Gosu::Color::BLACK)
|
||||||
@image = Gosu::Image.new("#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/default.png", retro: true)
|
@image = Gosu::Image.new("#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/default.png", retro: true)
|
||||||
@scale = (@size - Widget.padding * 2.0) / @image.width
|
@scale = (@size - Widget.horizontal_padding * 2.0) / @image.width
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
Gosu.draw_rect(
|
Gosu.draw_rect(
|
||||||
Widget.margin, window.height - (@size + Widget.margin),
|
Widget.horizontal_margin, window.height - (@size + Widget.vertical_margin),
|
||||||
@size, @size,
|
@size, @size,
|
||||||
@border_color
|
@border_color
|
||||||
)
|
)
|
||||||
|
|
||||||
Gosu.draw_rect(
|
Gosu.draw_rect(
|
||||||
Widget.margin + Widget.padding, window.height - (@size + Widget.margin) + Widget.padding,
|
Widget.horizontal_margin + Widget.horizontal_padding,
|
||||||
@size - Widget.padding * 2, @size - Widget.padding * 2,
|
window.height - (@size + Widget.vertical_margin) + Widget.vertical_padding,
|
||||||
|
@size - Widget.horizontal_padding * 2, @size - Widget.horizontal_padding * 2,
|
||||||
@radar_color
|
@radar_color
|
||||||
)
|
)
|
||||||
|
|
||||||
@image.draw(Widget.margin + Widget.padding, window.height - (@size + Widget.margin) + Widget.padding, 46, @scale, @scale, 0x88ffffff)
|
@image.draw(
|
||||||
|
Widget.horizontal_margin + Widget.horizontal_padding,
|
||||||
|
window.height - (@size + Widget.vertical_margin) + Widget.vertical_padding,
|
||||||
|
46, @scale, @scale, 0x88ffffff
|
||||||
|
)
|
||||||
|
|
||||||
@text.draw
|
@text.draw
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@size = (window.width / @target_screen_width.to_f * @max_size).clamp(@min_size, @max_size)
|
@size = (window.width / @target_screen_width.to_f * @max_size).clamp(@min_size, @max_size)
|
||||||
@scale = (@size - Widget.padding * 2.0) / @image.width
|
@scale = (@size - Widget.horizontal_padding * 2.0) / @image.width
|
||||||
|
|
||||||
@text.text = "X: #{@player.position.x.round(1)} Y: #{@player.position.y.round(1)} Z: #{@player.position.z.round(1)}"
|
@text.text = "X: #{@player.position.x.round(1)} Y: #{@player.position.y.round(1)} Z: #{@player.position.z.round(1)}"
|
||||||
@text.x = Widget.margin + @size / 2 - @text.width / 2
|
@text.x = Widget.horizontal_margin + @size / 2 - @text.width / 2
|
||||||
@text.y = window.height - (Widget.margin + @size + @text.height)
|
@text.y = window.height - (Widget.vertical_margin + @size + @text.height)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,13 +9,10 @@ class IMICFPS
|
|||||||
@text = CyberarmEngine::Text.new(
|
@text = CyberarmEngine::Text.new(
|
||||||
"",
|
"",
|
||||||
size: 16,
|
size: 16,
|
||||||
x: Widget.margin, y: Widget.margin, z: 45,
|
x: Widget.horizontal_margin, y: Widget.vertical_margin, z: 45,
|
||||||
shadow: true,
|
border: true,
|
||||||
shadow_size: 0.5,
|
border_color: Gosu::Color::BLACK,
|
||||||
shadow_alpha: 30,
|
font: BOLD_SANS_FONT
|
||||||
shadow_color: Gosu::Color::WHITE,
|
|
||||||
mode: :add,
|
|
||||||
font: MONOSPACE_FONT
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_text
|
set_text
|
||||||
@@ -26,7 +23,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@text.x = window.width - (@text.markup_width + Widget.margin)
|
@text.x = window.width - (@text.markup_width + Widget.horizontal_margin)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_random_data
|
def generate_random_data
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ class IMICFPS
|
|||||||
@text = Text.new(
|
@text = Text.new(
|
||||||
"MATE\nTinyTanker\nOther Player Dude\nHuman 0xdeadbeef",
|
"MATE\nTinyTanker\nOther Player Dude\nHuman 0xdeadbeef",
|
||||||
size: 18,
|
size: 18,
|
||||||
mode: :add,
|
|
||||||
font: SANS_FONT,
|
font: SANS_FONT,
|
||||||
color: @color,
|
color: @color,
|
||||||
shadow: true,
|
border: true,
|
||||||
shadow_color: 0x88000000,
|
border_color: Gosu::Color::BLACK,
|
||||||
shadow_size: 0.75
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -30,8 +28,8 @@ class IMICFPS
|
|||||||
def update
|
def update
|
||||||
@size = (window.width / @target_screen_width.to_f * @max_size).clamp(@min_size, @max_size)
|
@size = (window.width / @target_screen_width.to_f * @max_size).clamp(@min_size, @max_size)
|
||||||
|
|
||||||
@text.x = Widget.margin + @size + Widget.padding
|
@text.x = Widget.horizontal_margin + @size + Widget.horizontal_padding
|
||||||
@text.y = window.height - (Widget.margin + @text.height)
|
@text.y = window.height - (Widget.vertical_margin + @text.height)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class IMICFPS
|
|||||||
def available_light
|
def available_light
|
||||||
raise "Using to many lights, #{light_count}/#{LightManager::MAX_LIGHTS}" if light_count > LightManager::MAX_LIGHTS
|
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)
|
puts "OpenGL::GL_LIGHT#{light_count}" if CyberarmEngine::Window.instance.config.get(:debug_options, :stats)
|
||||||
Object.const_get "OpenGL::GL_LIGHT#{light_count}"
|
Object.const_get "OpenGL::GL_LIGHT#{light_count}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,37 +7,40 @@ class IMICFPS
|
|||||||
@masters = {}
|
@masters = {}
|
||||||
@effects = []
|
@effects = []
|
||||||
@playlists = {}
|
@playlists = {}
|
||||||
|
@current_playlist = nil
|
||||||
|
@current_playlist_package = nil
|
||||||
|
@current_playlist_name = nil
|
||||||
|
@current_playlist_index = 0
|
||||||
|
|
||||||
def self.master_volume
|
def self.master_volume
|
||||||
1.0
|
window.config.get(:options, :audio, :volume_master)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.music_volume
|
def self.music_volume
|
||||||
0.25 * master_volume
|
window.config.get(:options, :audio, :volume_music) * master_volume
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.sfx_volume
|
def self.sfx_volume
|
||||||
0.5 * master_volume
|
window.config.get(:options, :audio, :volume_sound_effects) * master_volume
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.load_master(package)
|
def self.load_master(package)
|
||||||
return if @masters[package]
|
return if @masters[package]
|
||||||
|
|
||||||
yaml = YAML.load_file("#{IMICFPS.assets_path}/#{package}/shared/sound/master.yaml")
|
hash = JSON.parse(File.read("#{IMICFPS.assets_path}/#{package}/shared/sound/master.json"))
|
||||||
@masters[package] = yaml
|
@masters[package] = hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.sound(package, name)
|
def self.sound(package, name)
|
||||||
if data = sound_data(package, name.to_s)
|
raise "Missing sound: '#{name}' in package '#{package}'" unless (data = sound_data(package, name.to_s))
|
||||||
get_sample("#{IMICFPS.assets_path}/#{package}/shared/sound/#{data['path']}")
|
|
||||||
else
|
get_sample("#{IMICFPS.assets_path}/#{package}/shared/sound/#{data['path']}")
|
||||||
raise "Missing sound: '#{name}' in package '#{package}'"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.sound_data(package, name)
|
def self.sound_data(package, name)
|
||||||
load_master(package)
|
load_master(package)
|
||||||
if master = @masters[package]
|
|
||||||
|
if (master = @masters[package])
|
||||||
return master["sounds"].find { |s| s["name"] == name }
|
return master["sounds"].find { |s| s["name"] == name }
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -48,8 +51,61 @@ class IMICFPS
|
|||||||
@effects << klass.new(options)
|
@effects << klass.new(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.music(package, name)
|
||||||
|
raise "Missing song: '#{name}' in package '#{package}'" unless (data = music_data(package, name.to_s))
|
||||||
|
|
||||||
|
get_song("#{IMICFPS.assets_path}/#{package}/shared/sound/#{data['path']}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.music_data(package, name)
|
||||||
|
load_master(package)
|
||||||
|
|
||||||
|
if (master = @masters[package])
|
||||||
|
return master["music"].find { |s| s["name"] == name }
|
||||||
|
end
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.playlist_data(package, name)
|
||||||
|
load_master(package)
|
||||||
|
|
||||||
|
if (master = @masters[package])
|
||||||
|
return master.dig("playlists", name.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.play_playlist(package, name)
|
||||||
|
return if @current_playlist_name == name.to_s
|
||||||
|
return unless (list = playlist_data(package, name.to_s))
|
||||||
|
|
||||||
|
@current_playlist = list
|
||||||
|
@current_playlist_package = package
|
||||||
|
@current_playlist_name = name.to_s
|
||||||
|
@current_playlist_index = 0
|
||||||
|
|
||||||
|
@current_song = music(@current_playlist_package, @current_playlist[@current_playlist_index])
|
||||||
|
@current_song.volume = music_volume
|
||||||
|
@current_song.play
|
||||||
|
end
|
||||||
|
|
||||||
def self.update
|
def self.update
|
||||||
@effects.each { |e| e.update; @effects.delete(e) if e.done? }
|
@effects.each { |e| e.update; @effects.delete(e) if e.done? }
|
||||||
|
|
||||||
|
return unless @current_playlist
|
||||||
|
|
||||||
|
if !@current_song&.playing? && music_volume > 0.0
|
||||||
|
@current_playlist_index += 1
|
||||||
|
@current_playlist_index = 0 if @current_playlist_index >= @current_playlist.size
|
||||||
|
|
||||||
|
@current_song = music(@current_playlist_package, @current_playlist[@current_playlist_index])
|
||||||
|
@current_song.play
|
||||||
|
end
|
||||||
|
|
||||||
|
@current_song&.volume = music_volume
|
||||||
|
@current_song&.stop if music_volume < 0.1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
add_terrain
|
add_terrain if @map_parser.terrain.name
|
||||||
add_skybox
|
add_skybox if @map_parser.skydome.name
|
||||||
add_lights
|
add_lights
|
||||||
add_entities
|
add_entities
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class IMICFPS
|
|||||||
@metadata.thumbnail = section["thumbnail"] # TODO: convert thumbnail to Image
|
@metadata.thumbnail = section["thumbnail"] # TODO: convert thumbnail to Image
|
||||||
@metadata.description = section["description"]
|
@metadata.description = section["description"]
|
||||||
else
|
else
|
||||||
raise "Map metadata is missing!"
|
warn "Map metadata is missing!"
|
||||||
end
|
end
|
||||||
|
|
||||||
if section = data["terrain"]
|
if section = data["terrain"]
|
||||||
@@ -64,7 +64,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
@terrain.water_level = section["water_level"]
|
@terrain.water_level = section["water_level"]
|
||||||
else
|
else
|
||||||
raise "Map terrain data is missing!"
|
warn "Map terrain data is missing!"
|
||||||
end
|
end
|
||||||
|
|
||||||
if section = data["skydome"]
|
if section = data["skydome"]
|
||||||
@@ -87,7 +87,7 @@ class IMICFPS
|
|||||||
@skydome.scale = Vector.new(1, 1, 1)
|
@skydome.scale = Vector.new(1, 1, 1)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise "Map skydome data is missing!"
|
warn "Map skydome data is missing!"
|
||||||
end
|
end
|
||||||
|
|
||||||
if section = data["lights"]
|
if section = data["lights"]
|
||||||
@@ -150,7 +150,7 @@ class IMICFPS
|
|||||||
@entities << entity
|
@entities << entity
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise "Map has no entities!"
|
warn "Map has no entities!"
|
||||||
end
|
end
|
||||||
|
|
||||||
if section = data["spawnpoints"]
|
if section = data["spawnpoints"]
|
||||||
@@ -171,7 +171,7 @@ class IMICFPS
|
|||||||
@spawnpoints << spawnpoint
|
@spawnpoints << spawnpoint
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise "Map has no spawnpoints!"
|
warn "Map has no spawnpoints!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class IMICFPS
|
|||||||
Slot = Struct.new(:value, :width)
|
Slot = Struct.new(:value, :width)
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@text = CyberarmEngine::Text.new("", x: 3, y: 3, shadow_color: Gosu::Color::BLACK)
|
@text = CyberarmEngine::Text.new("", x: 3, y: 3, border_color: Gosu::Color::BLACK)
|
||||||
@slots = []
|
@slots = []
|
||||||
@space_width = @text.textobject.text_width(" ")
|
@space_width = @text.textobject.text_width(" ")
|
||||||
end
|
end
|
||||||
@@ -38,8 +38,8 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
if window.config.get(:debug_options, :stats)
|
if window.config.get(:debug_options, :stats)
|
||||||
create_slot "Vertices: #{formatted_number(window.number_of_vertices)}"
|
create_slot "Vertices: #{formatted_number(window.renderer.opengl_renderer.number_of_vertices)}"
|
||||||
create_slot "Faces: #{formatted_number(window.number_of_vertices / 3)}"
|
create_slot "Faces: #{formatted_number(window.renderer.opengl_renderer.number_of_vertices / 3)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
if window.config.get(:debug_options, :boundingboxes)
|
if window.config.get(:debug_options, :boundingboxes)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class IMICFPS
|
|||||||
attr_reader :camera, :entities, :lights
|
attr_reader :camera, :entities, :lights
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@camera = PerspectiveCamera.new(position: Vector.new, aspect_ratio: $window.aspect_ratio)
|
@camera = PerspectiveCamera.new(position: Vector.new, aspect_ratio: CyberarmEngine::Window.instance.aspect_ratio)
|
||||||
@entities = []
|
@entities = []
|
||||||
@lights = []
|
@lights = []
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def map
|
def map
|
||||||
$window.director.map
|
CyberarmEngine::Window.instance.director.map
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def calculate_volume
|
def calculate_volume
|
||||||
volume = (SoundManager.sfx_volume - @initial_volume) * ratio
|
(SoundManager.sfx_volume - @initial_volume) * ratio
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
|||||||
@@ -3,14 +3,50 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Boot < GameState
|
class Boot < GameState
|
||||||
def setup
|
def setup
|
||||||
@title = Text.new(IMICFPS::NAME, size: 100, z: 0, color: Gosu::Color.new(0xff000000), shadow: false, font: "Droid Serif")
|
@title = Text.new(IMICFPS::NAME, size: 100, z: 0, color: Gosu::Color.new(0xff000000), border: false, font: IMICFPS::BOLD_SANS_FONT)
|
||||||
@logo = get_image("#{IMICFPS::GAME_ROOT_PATH}/static/logo.png")
|
@logo = get_image("#{IMICFPS::GAME_ROOT_PATH}/static/logo.png")
|
||||||
|
|
||||||
|
@title_screen_sound = get_sample("#{IMICFPS::GAME_ROOT_PATH}/static/sounds/title_screen.ogg")
|
||||||
|
|
||||||
@start_time = Gosu.milliseconds
|
@start_time = Gosu.milliseconds
|
||||||
@time_to_live = 3_000
|
@time_to_live = 5_000
|
||||||
|
|
||||||
|
timing = Gosu.milliseconds
|
||||||
|
@animators = [
|
||||||
|
@fade_animator = CyberarmEngine::Animator.new(
|
||||||
|
start_time: timing,
|
||||||
|
duration: 500,
|
||||||
|
from: 0.0,
|
||||||
|
to: 1.0,
|
||||||
|
tween: :ease_in_out
|
||||||
|
),
|
||||||
|
@logo_animator = CyberarmEngine::Animator.new(
|
||||||
|
start_time: timing += 500,
|
||||||
|
duration: 500,
|
||||||
|
from: 0.0,
|
||||||
|
to: 1.0,
|
||||||
|
tween: :swing_to#:bounce_past
|
||||||
|
),
|
||||||
|
@title_animator = CyberarmEngine::Animator.new(
|
||||||
|
start_time: timing += 1_000,
|
||||||
|
duration: 500,
|
||||||
|
from: 0.0,
|
||||||
|
to: 1.0,
|
||||||
|
tween: :swing_to#:ease_out_circ
|
||||||
|
),
|
||||||
|
@arc_animator = CyberarmEngine::Animator.new(
|
||||||
|
start_time: timing += 500,
|
||||||
|
duration: 2_500,
|
||||||
|
from: 0.0,
|
||||||
|
to: 1.0,
|
||||||
|
tween: :ease_in_out
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
# SoundManager.sound_effect(SoundEffect::FadeIn, sound: SoundManager.sound("base", :shield_regen), duration: 3_000.0)
|
# SoundManager.sound_effect(SoundEffect::FadeIn, sound: SoundManager.sound("base", :shield_regen), duration: 3_000.0)
|
||||||
window.needs_cursor = false
|
window.needs_cursor = false
|
||||||
|
|
||||||
|
@title_screen_sound_channel = @title_screen_sound.play(1.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
@@ -19,39 +55,45 @@ class IMICFPS
|
|||||||
menu_background(Menu::PRIMARY_COLOR, Menu::ACCENT_COLOR, Menu::BAR_COLOR_STEP, Menu::BAR_ALPHA, Menu::BAR_SIZE, Menu::BAR_SLOPE)
|
menu_background(Menu::PRIMARY_COLOR, Menu::ACCENT_COLOR, Menu::BAR_COLOR_STEP, Menu::BAR_ALPHA, Menu::BAR_SIZE, Menu::BAR_SLOPE)
|
||||||
|
|
||||||
if fraction_left <= 1.0
|
if fraction_left <= 1.0
|
||||||
Gosu.draw_circle(
|
Gosu.scale(@logo_animator.transition, @logo_animator.transition, window.width / 2, window.height / 2) do
|
||||||
window.width / 2,
|
Gosu.draw_circle(
|
||||||
window.height / 2,
|
window.width / 2,
|
||||||
@logo.width / 2, 128, Gosu::Color.new(0x11ffffff)
|
window.height / 2,
|
||||||
)
|
@logo.width / 2, 128, Gosu::Color.new(0x11ffffff)
|
||||||
|
)
|
||||||
|
|
||||||
Gosu.draw_arc(
|
Gosu.draw_arc(
|
||||||
window.width / 2,
|
window.width / 2,
|
||||||
window.height / 2,
|
window.height / 2,
|
||||||
@logo.width / 2, fraction_left.clamp(0.0, 1.0), 128, 8, Gosu::Color.new(0x33ff8800)
|
@logo.width / 2, @arc_animator.transition, 128, 8, Gosu::Color.new(0x33ff8800)
|
||||||
)
|
)
|
||||||
|
|
||||||
@logo.draw(window.width / 2 - @logo.width / 2, window.height / 2 - @logo.height / 2, 0)
|
@logo.draw(window.width / 2 - @logo.width / 2, window.height / 2 - @logo.height / 2, 0)
|
||||||
|
end
|
||||||
|
|
||||||
@title.draw
|
@title.draw
|
||||||
|
|
||||||
fill(Gosu::Color.rgba(0, 0, 0, 255 * (1.2 - fraction_left)))
|
fill(Gosu::Color.rgba(0, 0, 0, 255 * (1 - @fade_animator.transition)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
@animators.each(&:update)
|
||||||
|
|
||||||
|
y = window.height / 2 - (@logo.height / 2 + @title.height + 8)
|
||||||
|
y = 0 if y < @title.height
|
||||||
|
|
||||||
@title.x = window.width / 2 - @title.width / 2
|
@title.x = window.width / 2 - @title.width / 2
|
||||||
@title.y = 0
|
@title.y = (0 - (@title.height * (1 - @title_animator.transition))) + (y * @title_animator.transition)
|
||||||
|
|
||||||
push_state(MainMenu) if Gosu.milliseconds - @start_time >= @time_to_live
|
push_state(MainMenu) if Gosu.milliseconds - @start_time >= @time_to_live
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_up(id)
|
def button_down(id)
|
||||||
if (id == Gosu::KbEscape) ||
|
super
|
||||||
((id >= Gosu::GP_LEFT) && (id >= Gosu::GP_BUTTON_15)) ||
|
|
||||||
(id == Gosu::MsLeft)
|
@title_screen_sound_channel.stop
|
||||||
push_state(MainMenu)
|
push_state(MainMenu)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,41 +3,63 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Close < GameState
|
class Close < GameState
|
||||||
def setup
|
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
|
@start_time = Gosu.milliseconds
|
||||||
@time_to_live = 3_000
|
@time_to_live = 3_750
|
||||||
|
|
||||||
|
timing = Gosu.milliseconds
|
||||||
|
@animators = [
|
||||||
|
@arc_animator = CyberarmEngine::Animator.new(
|
||||||
|
start_time: timing += 0,
|
||||||
|
duration: 2_500,
|
||||||
|
from: 1.0,
|
||||||
|
to: 0.0,
|
||||||
|
tween: :ease_in_out
|
||||||
|
),
|
||||||
|
@logo_animator = CyberarmEngine::Animator.new(
|
||||||
|
start_time: timing += 2_500,
|
||||||
|
duration: 500,
|
||||||
|
from: 1.0,
|
||||||
|
to: 0.0,
|
||||||
|
tween: :swing_from
|
||||||
|
),
|
||||||
|
@fade_animator = CyberarmEngine::Animator.new(
|
||||||
|
start_time: timing += 500,
|
||||||
|
duration: 500,
|
||||||
|
from: 0.0,
|
||||||
|
to: 1.0,
|
||||||
|
tween: :ease_in_out
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
window.needs_cursor = false
|
window.needs_cursor = false
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
fraction_left = 1 - ((Gosu.milliseconds - @start_time) / (@time_to_live - 200).to_f)
|
menu_background(Menu::PRIMARY_COLOR, Menu::ACCENT_COLOR, Menu::BAR_COLOR_STEP, Menu::BAR_ALPHA, Menu::BAR_SIZE, Menu::BAR_SLOPE)
|
||||||
|
|
||||||
menu_background(Menu::PRIMARY_COLOR, Menu::ACCENT_COLOR, Menu::BAR_COLOR_STEP, Menu::BAR_ALPHA, Menu::BAR_SIZE, @slope.round)
|
Gosu.scale(@logo_animator.transition, @logo_animator.transition, window.width / 2, window.height / 2) do
|
||||||
|
Gosu.draw_circle(
|
||||||
|
window.width / 2,
|
||||||
|
window.height / 2,
|
||||||
|
@logo.width / 2, 128, Gosu::Color.new(0x11ffffff)
|
||||||
|
)
|
||||||
|
|
||||||
Gosu.draw_circle(
|
Gosu.draw_arc(
|
||||||
window.width / 2,
|
window.width / 2,
|
||||||
window.height / 2,
|
window.height / 2,
|
||||||
@logo.width / 2, 128, Gosu::Color.new(0x11ffffff)
|
@logo.width / 2, @arc_animator.transition, 128, 8, Gosu::Color.new(0x33ff8800)
|
||||||
)
|
)
|
||||||
|
|
||||||
Gosu.draw_arc(
|
@logo.draw(window.width / 2 - @logo.width / 2, window.height / 2 - @logo.height / 2, 0)
|
||||||
window.width / 2,
|
end
|
||||||
window.height / 2,
|
|
||||||
@logo.width / 2, fraction_left.clamp(0.0, 1.0), 128, 8, Gosu::Color.new(0x33ff8800)
|
|
||||||
)
|
|
||||||
|
|
||||||
@logo.draw(window.width / 2 - @logo.width / 2, window.height / 2 - @logo.height / 2, 0)
|
fill(Gosu::Color.rgba(0, 0, 0, 255 * @fade_animator.transition))
|
||||||
|
|
||||||
fill(Gosu::Color.rgba(0, 0, 0, 255 * (1.1 - fraction_left)))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
window.close! if Gosu.milliseconds - @start_time >= @time_to_live
|
window.close! if Gosu.milliseconds - @start_time >= @time_to_live
|
||||||
@slope -= 25 * window.dt
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_up(id)
|
def button_up(id)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class IMICFPS
|
|||||||
def draw
|
def draw
|
||||||
window.director.map.render(@camera)
|
window.director.map.render(@camera)
|
||||||
|
|
||||||
@hud.draw
|
@hud.draw if window.config.get(:options, :hud)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@@ -69,6 +69,8 @@ class IMICFPS
|
|||||||
window.director.map.entities.each do |entity|
|
window.director.map.entities.each do |entity|
|
||||||
entity.button_down(id) if defined?(entity.button_down)
|
entity.button_down(id) if defined?(entity.button_down)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@hud.button_down(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_up(id)
|
def button_up(id)
|
||||||
@@ -81,6 +83,8 @@ class IMICFPS
|
|||||||
window.director.map.entities.each do |entity|
|
window.director.map.entities.each do |entity|
|
||||||
entity.button_up(id) if defined?(entity.button_up)
|
entity.button_up(id) if defined?(entity.button_up)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@hud.button_up(id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class IMICFPS
|
|||||||
@assets = []
|
@assets = []
|
||||||
@asset_index = 0
|
@asset_index = 0
|
||||||
|
|
||||||
add_asset(:model, @map_parser.terrain.package, @map_parser.terrain.name)
|
add_asset(:model, @map_parser.terrain.package, @map_parser.terrain.name) if @map_parser.terrain.package
|
||||||
add_asset(:model, @map_parser.skydome.package, @map_parser.skydome.name)
|
add_asset(:model, @map_parser.skydome.package, @map_parser.skydome.name) if @map_parser.skydome.package
|
||||||
@map_parser.entities.each do |entity|
|
@map_parser.entities.each do |entity|
|
||||||
add_asset(:model, entity.package, entity.name)
|
add_asset(:model, entity.package, entity.name)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,17 +17,19 @@ class IMICFPS
|
|||||||
|
|
||||||
@manifests.sort_by! { |m| m.name.downcase }
|
@manifests.sort_by! { |m| m.name.downcase }
|
||||||
|
|
||||||
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
|
flow(width: 1.0, height: 1.0) do
|
||||||
stack(width: 0.25, height: 1.0) do
|
stack(width: 0.25, height: 1.0) do
|
||||||
button "Back", width: 1.0 do
|
|
||||||
pop_state
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
stack(width: 0.5, height: 1.0) do
|
stack(width: 0.5, height: 1.0) do
|
||||||
|
title "Asset Viewer"
|
||||||
|
|
||||||
|
link I18n.t("menus.back"), width: 1.0 do
|
||||||
|
pop_state
|
||||||
|
end
|
||||||
|
|
||||||
flow(width: 1.0, height: 1.0) do
|
flow(width: 1.0, height: 1.0) do
|
||||||
@manifests.each do |manifest|
|
@manifests.each do |manifest|
|
||||||
button manifest.name do
|
button manifest.name do
|
||||||
|
|||||||
@@ -3,16 +3,14 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class AssetViewerTool
|
class AssetViewerTool
|
||||||
class TurnTable < CyberarmEngine::GuiState
|
class TurnTable < CyberarmEngine::GuiState
|
||||||
include LightManager
|
|
||||||
|
|
||||||
attr_reader :map
|
attr_reader :map
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
window.needs_cursor = false
|
window.needs_cursor = false
|
||||||
@manifest = @options[:manifest]
|
@manifest = @options[:manifest]
|
||||||
|
|
||||||
@map = ProtoMap.new
|
window.director.load_map(map_parser: MapParser.new(map_file: "#{GAME_ROOT_PATH}/maps/model_viewer.json"))
|
||||||
Publisher.new
|
@map = window.director.map
|
||||||
|
|
||||||
@entity = Entity.new(manifest: @manifest)
|
@entity = Entity.new(manifest: @manifest)
|
||||||
@entity.bind_model
|
@entity.bind_model
|
||||||
@@ -20,16 +18,15 @@ class IMICFPS
|
|||||||
@map.entities.each { |e| e.backface_culling = false }
|
@map.entities.each { |e| e.backface_culling = false }
|
||||||
@crosshair = Crosshair.new(color: Gosu::Color.rgba(100, 200, 255, 100))
|
@crosshair = Crosshair.new(color: Gosu::Color.rgba(100, 200, 255, 100))
|
||||||
|
|
||||||
@lights = []
|
@map.add_light @light = Light.new(type: Light::DIRECTIONAL, id: @map.available_light, position: Vector.new, diffuse: Vector.new(1, 1, 1, 1))
|
||||||
@light = Light.new(type: Light::DIRECTIONAL, id: available_light, position: Vector.new, diffuse: Vector.new(1, 1, 1, 1))
|
|
||||||
@lights << @light
|
|
||||||
|
|
||||||
@camera = PerspectiveCamera.new(aspect_ratio: window.aspect_ratio, position: Vector.new(0, 1.5, 5), orientation: Vector.forward)
|
@camera = PerspectiveCamera.new(aspect_ratio: window.aspect_ratio, position: Vector.new(0, 1.5, 5), orientation: Vector.forward)
|
||||||
|
@camera_controller = CameraController.new(camera: @camera, entity: nil, mode: :fpv)
|
||||||
|
|
||||||
label @manifest.name, text_size: 50
|
label @manifest.name, text_size: 50, text_border: true, text_border_color: Gosu::Color::BLACK
|
||||||
label @manifest.model
|
label @manifest.model, text_border: true, text_border_color: Gosu::Color::BLACK
|
||||||
@camera_position = label ""
|
@camera_position = label "", text_border: true, text_border_color: Gosu::Color::BLACK
|
||||||
@camera_orientation = label ""
|
@camera_orientation = label "", text_border: true, text_border_color: Gosu::Color::BLACK
|
||||||
|
|
||||||
button "Back" do
|
button "Back" do
|
||||||
pop_state
|
pop_state
|
||||||
@@ -48,7 +45,7 @@ class IMICFPS
|
|||||||
)
|
)
|
||||||
|
|
||||||
Gosu.gl do
|
Gosu.gl do
|
||||||
window.renderer.draw(@camera, [@light], @map.entities)
|
window.renderer.draw(@camera, @map.lights, @map.entities)
|
||||||
end
|
end
|
||||||
|
|
||||||
@crosshair.draw
|
@crosshair.draw
|
||||||
@@ -64,30 +61,24 @@ class IMICFPS
|
|||||||
@camera_position.value = "Camera Position: X #{@camera.position.x.round(2)}, Y #{@camera.position.y.round(2)}, Z #{@camera.position.z.round(2)}"
|
@camera_position.value = "Camera Position: X #{@camera.position.x.round(2)}, Y #{@camera.position.y.round(2)}, Z #{@camera.position.z.round(2)}"
|
||||||
@camera_orientation.value = "Camera Orientation: X #{@camera.orientation.x.round(2)}, Y #{@camera.orientation.y.round(2)}, Z #{@camera.orientation.z.round(2)}\nEntities: #{@map.entities.count}"
|
@camera_orientation.value = "Camera Orientation: X #{@camera.orientation.x.round(2)}, Y #{@camera.orientation.y.round(2)}, Z #{@camera.orientation.z.round(2)}\nEntities: #{@map.entities.count}"
|
||||||
|
|
||||||
@map.entities.each(&:update)
|
@camera_controller.free_move
|
||||||
|
@camera_controller.update
|
||||||
|
|
||||||
|
# @map.entities.each(&:update)
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_down(id)
|
def button_down(id)
|
||||||
super
|
super
|
||||||
|
|
||||||
InputMapper.keydown(id)
|
InputMapper.keydown(id)
|
||||||
|
@camera_controller.button_down(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_up(id)
|
def button_up(id)
|
||||||
super
|
super
|
||||||
|
|
||||||
InputMapper.keyup(id)
|
InputMapper.keyup(id)
|
||||||
end
|
@camera_controller.button_up(id)
|
||||||
end
|
|
||||||
|
|
||||||
# Stub for enabling scripted models to load properly
|
|
||||||
class ProtoMap
|
|
||||||
include EntityManager
|
|
||||||
|
|
||||||
attr_reader :entities
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@entities = []
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ class IMICFPS
|
|||||||
def setup
|
def setup
|
||||||
window.needs_cursor = true
|
window.needs_cursor = true
|
||||||
|
|
||||||
label IMICFPS::NAME.to_s, text_size: 50
|
|
||||||
label "Map Editor", text_size: 28
|
|
||||||
|
|
||||||
@maps = []
|
@maps = []
|
||||||
Dir.glob("#{GAME_ROOT_PATH}/maps/*.json").each do |map|
|
Dir.glob("#{GAME_ROOT_PATH}/maps/*.json").each do |map|
|
||||||
begin
|
begin
|
||||||
@@ -22,15 +19,20 @@ class IMICFPS
|
|||||||
|
|
||||||
flow(width: 1.0, height: 1.0) do
|
flow(width: 1.0, height: 1.0) do
|
||||||
stack(width: 0.25, height: 1.0) do
|
stack(width: 0.25, height: 1.0) do
|
||||||
button "New Map", width: 1.0
|
|
||||||
|
|
||||||
button "Back", margin_top: 64, width: 1.0 do
|
|
||||||
pop_state
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
stack(width: 0.5, height: 1.0) do
|
stack(width: 0.5, height: 1.0) do
|
||||||
label "Edit Map"
|
title "Map Editor"
|
||||||
|
|
||||||
|
flow width: 1.0 do
|
||||||
|
link I18n.t("menus.back"), width: 0.32 do
|
||||||
|
pop_state
|
||||||
|
end
|
||||||
|
|
||||||
|
button "New Map", width: 0.64
|
||||||
|
end
|
||||||
|
|
||||||
|
label "Edit Map", width: 1.0, text_align: :center, text_size: 50
|
||||||
flow(width: 1.0, height: 1.0) do
|
flow(width: 1.0, height: 1.0) do
|
||||||
@maps.each do |map|
|
@maps.each do |map|
|
||||||
button map.metadata.name do
|
button map.metadata.name do
|
||||||
|
|||||||
@@ -25,11 +25,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def insert_leaf(leaf)
|
def insert_leaf(leaf)
|
||||||
@root = if @root
|
@root = @root ? @root.insert_subtree(leaf) : leaf
|
||||||
@root.insert_subtree(leaf)
|
|
||||||
else
|
|
||||||
leaf
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(object, bounding_box)
|
def update(object, bounding_box)
|
||||||
|
|||||||
@@ -1,158 +0,0 @@
|
|||||||
# 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
|
|
||||||
end
|
|
||||||
|
|
||||||
class Command
|
|
||||||
def self.inherited(subclass)
|
|
||||||
@list ||= []
|
|
||||||
@commands ||= []
|
|
||||||
@list << subclass
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.setup
|
|
||||||
@list ||= []
|
|
||||||
@commands = []
|
|
||||||
@list.each do |subclass|
|
|
||||||
cmd = subclass.new
|
|
||||||
if @commands.detect { |c| c.command == cmd.command }
|
|
||||||
raise "Command '#{cmd.command}' from '#{cmd.class}' already exists!"
|
|
||||||
end
|
|
||||||
|
|
||||||
@commands << cmd
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.use(command, arguments, console)
|
|
||||||
found_command = @commands.detect { |cmd| cmd.command == command.to_sym }
|
|
||||||
|
|
||||||
if found_command
|
|
||||||
found_command.handle(arguments, console)
|
|
||||||
else
|
|
||||||
console.stdin("Command #{Style.error(command)} not found.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.find(command)
|
|
||||||
@commands.detect { |cmd| cmd.command == command.to_sym }
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.list_commands
|
|
||||||
@commands
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@store = {}
|
|
||||||
@subcommands = []
|
|
||||||
|
|
||||||
setup
|
|
||||||
end
|
|
||||||
|
|
||||||
def setup
|
|
||||||
end
|
|
||||||
|
|
||||||
def subcommand(command, type)
|
|
||||||
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[key]
|
|
||||||
end
|
|
||||||
|
|
||||||
def set(key, value)
|
|
||||||
@store[key] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
def group
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
def command
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle(arguments, console)
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
def autocomplete(console)
|
|
||||||
split = console.text_input.text.split(" ")
|
|
||||||
|
|
||||||
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.positive?
|
|
||||||
|
|
||||||
console.stdin(list.map { |cmd| Commands::Style.highlight(cmd) }.join(", ").to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
# List available options on subcommand
|
|
||||||
elsif (console.text_input.text.end_with?(" ") && split.size == 2) || !console.text_input.text.end_with?(" ") && split.size == 3
|
|
||||||
subcommand = @subcommands.detect { |cmd| cmd.command.to_s == (split[1]) }
|
|
||||||
|
|
||||||
if subcommand
|
|
||||||
if split.size == 2
|
|
||||||
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} "
|
|
||||||
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(', ')}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_subcommand(arguments, console)
|
|
||||||
if arguments.size.zero?
|
|
||||||
console.stdin(usage)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
subcommand = arguments.delete_at(0)
|
|
||||||
|
|
||||||
found_command = @subcommands.detect { |cmd| cmd.command == subcommand.to_sym }
|
|
||||||
if found_command
|
|
||||||
found_command.handle(arguments, console)
|
|
||||||
else
|
|
||||||
console.stdin("Unknown subcommand #{Style.error(subcommand)} for #{Style.highlight(command)}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def usage
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Commands
|
class Commands
|
||||||
class ConnectCommand < Command
|
class ConnectCommand < CyberarmEngine::Console::Command
|
||||||
def group
|
def group
|
||||||
:global
|
:global
|
||||||
end
|
end
|
||||||
@@ -15,7 +15,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def usage
|
def usage
|
||||||
"Connect to a server.\n#{Style.highlight('connect')} #{Style.notice('[example.com:56789]')}"
|
"Connect to a server.\n#{Console::Style.highlight('connect')} #{Style.notice('example.com[:56789]')}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Commands
|
class Commands
|
||||||
class DebugCommand < Command
|
class DebugCommand < CyberarmEngine::Console::Command
|
||||||
def group
|
def group
|
||||||
:global
|
:global
|
||||||
end
|
end
|
||||||
@@ -12,20 +12,20 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def set(key, value)
|
def set(key, value)
|
||||||
$window.config[:debug_options, key] = value
|
CyberarmEngine::Window.instance.config[:debug_options, key] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(key)
|
def get(key)
|
||||||
$window.config.get(:debug_options, key)
|
CyberarmEngine::Window.instance.config.get(:debug_options, key)
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
set(:boundingboxes, false) if $window.config.get(:debug_options, :boundingboxes).nil?
|
set(:boundingboxes, false) if CyberarmEngine::Window.instance.config.get(:debug_options, :boundingboxes).nil?
|
||||||
set(:wireframe, false) if $window.config.get(:debug_options, :wireframe).nil?
|
set(:wireframe, false) if CyberarmEngine::Window.instance.config.get(:debug_options, :wireframe).nil?
|
||||||
set(:stats, false) if $window.config.get(:debug_options, :stats).nil?
|
set(:stats, false) if CyberarmEngine::Window.instance.config.get(:debug_options, :stats).nil?
|
||||||
set(:skydome, true) if $window.config.get(:debug_options, :skydome).nil?
|
set(:skydome, true) if CyberarmEngine::Window.instance.config.get(:debug_options, :skydome).nil?
|
||||||
set(:use_shaders, true) if $window.config.get(:debug_options, :use_shaders).nil?
|
set(:use_shaders, true) if CyberarmEngine::Window.instance.config.get(:debug_options, :use_shaders).nil?
|
||||||
set(:opengl_error_panic, false) if $window.config.get(:debug_options, :opengl_error_panic).nil?
|
set(:opengl_error_panic, false) if CyberarmEngine::Window.instance.config.get(:debug_options, :opengl_error_panic).nil?
|
||||||
|
|
||||||
subcommand(:boundingboxes, :boolean)
|
subcommand(:boundingboxes, :boolean)
|
||||||
subcommand(:wireframe, :boolean)
|
subcommand(:wireframe, :boolean)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Commands
|
class Commands
|
||||||
class DisconnectCommand < Command
|
class DisconnectCommand < CyberarmEngine::Console::Command
|
||||||
def group
|
def group
|
||||||
:global
|
:global
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Commands
|
class Commands
|
||||||
class FPSCommand < Command
|
class FPSCommand < CyberarmEngine::Console::Command
|
||||||
def group
|
def group
|
||||||
:global
|
:global
|
||||||
end
|
end
|
||||||
@@ -13,26 +13,26 @@ class IMICFPS
|
|||||||
|
|
||||||
def handle(arguments, console)
|
def handle(arguments, console)
|
||||||
if arguments.size > 1
|
if arguments.size > 1
|
||||||
console.stdin("to many arguments for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
console.stdin("to many arguments for #{Console::Style.highlight(command.to_s)}, got #{Console::Style.error(arguments.size)} expected #{Console::Style.notice(1)}.")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
case arguments.last
|
case arguments.last
|
||||||
when "", nil
|
when "", nil
|
||||||
console.stdin("#{Style.highlight('fps')}: #{$window.config.get(:options, :fps)}")
|
console.stdin("#{Console::Style.highlight('fps')}: #{CyberarmEngine::Window.instance.config.get(:options, :fps)}")
|
||||||
when "on"
|
when "on"
|
||||||
var = $window.config[:options, :fps] = true
|
var = CyberarmEngine::Window.instance.config[:options, :fps] = true
|
||||||
console.stdin("fps => #{Style.highlight(var)}")
|
console.stdin("fps => #{Console::Style.highlight(var)}")
|
||||||
when "off"
|
when "off"
|
||||||
var = $window.config[:options, :fps] = false
|
var = CyberarmEngine::Window.instance.config[:options, :fps] = false
|
||||||
console.stdin("fps => #{Style.highlight(var)}")
|
console.stdin("fps => #{Console::Style.highlight(var)}")
|
||||||
else
|
else
|
||||||
console.stdin("Invalid argument for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.last)} expected #{Style.notice('on')}, or #{Style.notice('off')}.")
|
console.stdin("Invalid argument for #{Console::Style.highlight(command.to_s)}, got #{Console::Style.error(arguments.last)} expected #{Console::Style.notice('on')}, or #{Console::Style.notice('off')}.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def usage
|
def usage
|
||||||
"#{Style.highlight('fps')} #{Style.notice('[on|off]')}"
|
"#{Console::Style.highlight('fps')} #{Style.notice('[on|off]')}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class IMICFPS
|
|
||||||
class Commands
|
|
||||||
class HelpCommand < Command
|
|
||||||
def group
|
|
||||||
:global
|
|
||||||
end
|
|
||||||
|
|
||||||
def command
|
|
||||||
:help
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle(arguments, console)
|
|
||||||
console.stdin(usage(arguments.first))
|
|
||||||
end
|
|
||||||
|
|
||||||
def autocomplete(console)
|
|
||||||
split = console.text_input.text.split(" ")
|
|
||||||
if !console.text_input.text.start_with?(" ") && split.size == 2
|
|
||||||
list = console.abbrev_search(Commands::Command.list_commands.map { |cmd| cmd.command.to_s }, split.last)
|
|
||||||
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(", "))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def usage(command = nil)
|
|
||||||
if command
|
|
||||||
if cmd = Command.find(command)
|
|
||||||
cmd.usage
|
|
||||||
else
|
|
||||||
"#{Style.error(command)} is not a command"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
"Available commands:\n#{Command.list_commands.map { |cmd| Style.highlight(cmd.command).to_s }.join(', ')}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
43
lib/ui/commands/hud_command.rb
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class IMICFPS
|
||||||
|
class Commands
|
||||||
|
class HUDCommand < CyberarmEngine::Console::Command
|
||||||
|
def group
|
||||||
|
:global
|
||||||
|
end
|
||||||
|
|
||||||
|
def command
|
||||||
|
:hud
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
CyberarmEngine::Window.instance.config[:options, :hud] = true if CyberarmEngine::Window.instance.config.get(:options, :hud).nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle(arguments, console)
|
||||||
|
if arguments.size > 1
|
||||||
|
console.stdin("to many arguments for #{Console::Style.highlight(command.to_s)}, got #{Console::Style.error(arguments.size)} expected #{Console::Style.notice(1)}.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
case arguments.last
|
||||||
|
when "", nil
|
||||||
|
console.stdin("#{Console::Style.highlight(command.to_s)}: #{CyberarmEngine::Window.instance.config.get(:options, command)}")
|
||||||
|
when "on"
|
||||||
|
var = CyberarmEngine::Window.instance.config[:options, command] = true
|
||||||
|
console.stdin("#{command} => #{Console::Style.highlight(var)}")
|
||||||
|
when "off"
|
||||||
|
var = CyberarmEngine::Window.instance.config[:options, command] = false
|
||||||
|
console.stdin("#{command} => #{Console::Style.highlight(var)}")
|
||||||
|
else
|
||||||
|
console.stdin("Invalid argument for #{Console::Style.highlight(command.to_s)}, got #{Console::Style.error(arguments.last)} expected #{Console::Style.notice('on')}, or #{Console::Style.notice('off')}.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def usage
|
||||||
|
"#{Console::Style.highlight('hud')} #{Console::Style.notice('[on|off]')}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Commands
|
class Commands
|
||||||
class ReloadShaderCommand < Command
|
class ReloadShaderCommand < CyberarmEngine::Console::Command
|
||||||
def group
|
def group
|
||||||
:reload_shader
|
:reload_shader
|
||||||
end
|
end
|
||||||
@@ -13,7 +13,7 @@ class IMICFPS
|
|||||||
|
|
||||||
def handle(arguments, console)
|
def handle(arguments, console)
|
||||||
if arguments.size > 2
|
if arguments.size > 2
|
||||||
console.stdin("to many arguments for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
console.stdin("to many arguments for #{Console::Style.highlight(command.to_s)}, got #{Console::Style.error(arguments.size)} expected #{Console::Style.notice(1)}.")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -51,9 +51,9 @@ class IMICFPS
|
|||||||
string = $stdout.string
|
string = $stdout.string
|
||||||
|
|
||||||
if shader.compiled?
|
if shader.compiled?
|
||||||
console.stdin("#{Style.notice('Successfully reloaded shader')}: #{shader.name}")
|
console.stdin("#{Console::Style.notice('Successfully reloaded shader')}: #{shader.name}")
|
||||||
else
|
else
|
||||||
console.stdin(Style.error("Failed to reload #{shader.name}").to_s)
|
console.stdin(Console::Style.error("Failed to reload #{shader.name}").to_s)
|
||||||
console.stdin(string)
|
console.stdin(string)
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
@@ -62,7 +62,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def usage
|
def usage
|
||||||
"#{Style.highlight(command)} #{Style.notice('vertex_name [fragment_name]')}"
|
"#{Console::Style.highlight(command)} #{Console::Style.notice('vertex_name [fragment_name]')}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Commands
|
class Commands
|
||||||
class RendererInfoCommand < Command
|
class RendererInfoCommand < CyberarmEngine::Console::Command
|
||||||
def group
|
def group
|
||||||
:global
|
:global
|
||||||
end
|
end
|
||||||
@@ -12,14 +12,14 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle(_arguments, console)
|
def handle(_arguments, console)
|
||||||
console.stdin("OpenGL Vendor: #{Style.notice(glGetString(GL_VENDOR))}")
|
console.stdin("OpenGL Vendor: #{Console::Style.notice(glGetString(GL_VENDOR))}")
|
||||||
console.stdin("OpenGL Renderer: #{Style.notice(glGetString(GL_RENDERER))}")
|
console.stdin("OpenGL Renderer: #{Console::Style.notice(glGetString(GL_RENDERER))}")
|
||||||
console.stdin("OpenGL Version: #{Style.notice(glGetString(GL_VERSION))}")
|
console.stdin("OpenGL Version: #{Console::Style.notice(glGetString(GL_VERSION))}")
|
||||||
console.stdin("OpenGL Shader Language Version: #{Style.notice(glGetString(GL_SHADING_LANGUAGE_VERSION))}")
|
console.stdin("OpenGL Shader Language Version: #{Console::Style.notice(glGetString(GL_SHADING_LANGUAGE_VERSION))}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def usage
|
def usage
|
||||||
"#{Style.highlight('renderer_info')} #{Style.notice('Returns OpenGL renderer information')}"
|
"#{Console::Style.highlight('renderer_info')} #{Console::Style.notice('Returns OpenGL renderer information')}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,250 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class IMICFPS
|
|
||||||
class Console
|
|
||||||
Z = 100_000
|
|
||||||
PADDING = 2
|
|
||||||
include CommonMethods
|
|
||||||
|
|
||||||
attr_reader :text_input
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@text_input = Gosu::TextInput.new
|
|
||||||
@width = window.width / 4 * 3
|
|
||||||
@height = window.height / 4 * 3
|
|
||||||
|
|
||||||
@input = Text.new("", x: 4, y: @height - (PADDING * 2), z: Console::Z + 1, font: MONOSPACE_FONT)
|
|
||||||
@input.y -= @input.height
|
|
||||||
|
|
||||||
@history = Text.new("=== #{IMICFPS::NAME} v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME}) ===\n\n", x: 4, z: Console::Z + 1, font: MONOSPACE_FONT)
|
|
||||||
update_history_y
|
|
||||||
|
|
||||||
@command_history = []
|
|
||||||
@command_history_index = 0
|
|
||||||
|
|
||||||
@memory = ""
|
|
||||||
|
|
||||||
@background_color = Gosu::Color.rgba(0, 0, 0, 200)
|
|
||||||
@foreground_color = Gosu::Color.rgba(100, 100, 100, 100)
|
|
||||||
@input_color = Gosu::Color.rgba(100, 100, 100, 200)
|
|
||||||
|
|
||||||
@showing_cursor = false
|
|
||||||
@active_text_input = nil
|
|
||||||
|
|
||||||
@show_caret = true
|
|
||||||
@caret_last_change = Gosu.milliseconds
|
|
||||||
@caret_interval = 250
|
|
||||||
@caret_color = Gosu::Color::WHITE
|
|
||||||
@selection_color = Gosu::Color.new(0x5522ff22)
|
|
||||||
end
|
|
||||||
|
|
||||||
def draw
|
|
||||||
# Background/Border
|
|
||||||
draw_rect(0, 0, @width, @height, @background_color, Console::Z)
|
|
||||||
# Foregound/History
|
|
||||||
draw_rect(PADDING, PADDING, @width - (PADDING * 2), @height - (PADDING * 2), @foreground_color, Console::Z)
|
|
||||||
# Text bar
|
|
||||||
draw_rect(2, @input.y, @width - (PADDING * 2), @input.height, @input_color, Console::Z)
|
|
||||||
|
|
||||||
@history.draw
|
|
||||||
@input.draw
|
|
||||||
# Caret
|
|
||||||
if @show_caret
|
|
||||||
draw_rect(@input.x + caret_from_left, @input.y, Console::PADDING, @input.height, @caret_color, Console::Z + 2)
|
|
||||||
end
|
|
||||||
# Caret selection
|
|
||||||
if caret_start != caret_end
|
|
||||||
if caret_start < @text_input.selection_start
|
|
||||||
draw_rect(@input.x + caret_from_left, @input.y, caret_selection_width, @input.height, @selection_color, Console::Z)
|
|
||||||
else
|
|
||||||
draw_rect((@input.x + caret_from_left) - caret_selection_width, @input.y, caret_selection_width, @input.height, @selection_color, Console::Z)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def caret_from_left
|
|
||||||
return 0 if @text_input.caret_pos.zero?
|
|
||||||
|
|
||||||
@input.textobject.text_width(@text_input.text[0..@text_input.caret_pos - 1])
|
|
||||||
end
|
|
||||||
|
|
||||||
def caret_selection_width
|
|
||||||
@input.textobject.text_width(@text_input.text[caret_start..(caret_end - 1)])
|
|
||||||
end
|
|
||||||
|
|
||||||
def caret_pos
|
|
||||||
@text_input.caret_pos
|
|
||||||
end
|
|
||||||
|
|
||||||
def caret_start
|
|
||||||
@text_input.selection_start < @text_input.caret_pos ? @text_input.selection_start : @text_input.caret_pos
|
|
||||||
end
|
|
||||||
|
|
||||||
def caret_end
|
|
||||||
@text_input.selection_start > @text_input.caret_pos ? @text_input.selection_start : @text_input.caret_pos
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if Gosu.milliseconds - @caret_last_change >= @caret_interval
|
|
||||||
@caret_last_change = Gosu.milliseconds
|
|
||||||
@show_caret = !@show_caret
|
|
||||||
end
|
|
||||||
|
|
||||||
if @width != window.width || @height != @height
|
|
||||||
@width = window.width / 4 * 3
|
|
||||||
@height = window.height / 4 * 3
|
|
||||||
|
|
||||||
@input.y = @height - (PADDING * 2 + @input.height)
|
|
||||||
update_history_y
|
|
||||||
end
|
|
||||||
|
|
||||||
@input.text = @text_input.text
|
|
||||||
end
|
|
||||||
|
|
||||||
def button_down(id)
|
|
||||||
case id
|
|
||||||
when Gosu::KbEnter, Gosu::KbReturn
|
|
||||||
return unless @text_input.text.length.positive?
|
|
||||||
|
|
||||||
@history.text += "\n<c=999999>> #{@text_input.text}</c>"
|
|
||||||
@command_history << @text_input.text
|
|
||||||
@command_history_index = @command_history.size
|
|
||||||
update_history_y
|
|
||||||
handle_command
|
|
||||||
@text_input.text = ""
|
|
||||||
|
|
||||||
when Gosu::KbUp
|
|
||||||
@command_history_index -= 1
|
|
||||||
@command_history_index = 0 if @command_history_index.negative?
|
|
||||||
@text_input.text = @command_history[@command_history_index]
|
|
||||||
|
|
||||||
when Gosu::KbDown
|
|
||||||
@command_history_index += 1
|
|
||||||
if @command_history_index > @command_history.size - 1
|
|
||||||
@text_input.text = "" unless @command_history_index > @command_history.size
|
|
||||||
@command_history_index = @command_history.size
|
|
||||||
else
|
|
||||||
@text_input.text = @command_history[@command_history_index]
|
|
||||||
end
|
|
||||||
|
|
||||||
when Gosu::KbTab
|
|
||||||
split = @text_input.text.split(" ")
|
|
||||||
|
|
||||||
if !@text_input.text.end_with?(" ") && split.size == 1
|
|
||||||
list = abbrev_search(Commands::Command.list_commands.map { |cmd| cmd.command.to_s }, @text_input.text)
|
|
||||||
|
|
||||||
if list.size == 1
|
|
||||||
@text_input.text = "#{list.first} "
|
|
||||||
elsif list.size.positive?
|
|
||||||
stdin("\n#{list.map { |cmd| Commands::Style.highlight(cmd) }.join(', ')}")
|
|
||||||
end
|
|
||||||
elsif split.size.positive? && cmd = Commands::Command.find(split.first)
|
|
||||||
cmd.autocomplete(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
when Gosu::KbBacktick
|
|
||||||
# Remove backtick character from input
|
|
||||||
@text_input.text = if @text_input.text.size > 1
|
|
||||||
@text_input.text[0..@text_input.text.size - 2]
|
|
||||||
else
|
|
||||||
""
|
|
||||||
end
|
|
||||||
|
|
||||||
# Copy
|
|
||||||
when Gosu::KbC
|
|
||||||
if control_down? && shift_down?
|
|
||||||
@memory = @text_input.text[caret_start..caret_end - 1] if caret_start != caret_end
|
|
||||||
p @memory
|
|
||||||
elsif control_down?
|
|
||||||
@text_input.text = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
# Paste
|
|
||||||
when Gosu::KbV
|
|
||||||
if control_down? && shift_down?
|
|
||||||
string = @text_input.text.chars.insert(caret_pos, @memory).join
|
|
||||||
_caret_pos = caret_pos
|
|
||||||
@text_input.text = string
|
|
||||||
@text_input.caret_pos = _caret_pos + @memory.length
|
|
||||||
@text_input.selection_start = _caret_pos + @memory.length
|
|
||||||
end
|
|
||||||
|
|
||||||
# Cut
|
|
||||||
when Gosu::KbX
|
|
||||||
if control_down? && shift_down?
|
|
||||||
@memory = @text_input.text[caret_start..caret_end - 1] if caret_start != caret_end
|
|
||||||
string = @text_input.text.chars
|
|
||||||
Array(caret_start..caret_end - 1).each_with_index do |i, j|
|
|
||||||
string.delete_at(i - j)
|
|
||||||
end
|
|
||||||
|
|
||||||
@text_input.text = string.join
|
|
||||||
end
|
|
||||||
|
|
||||||
# Delete word to left of caret
|
|
||||||
when Gosu::KbW
|
|
||||||
if control_down?
|
|
||||||
split = @text_input.text.split(" ")
|
|
||||||
split.delete(split.last)
|
|
||||||
@text_input.text = split.join(" ")
|
|
||||||
end
|
|
||||||
|
|
||||||
# Clear history
|
|
||||||
when Gosu::KbL
|
|
||||||
@history.text = "" if control_down?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def button_up(id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_history_y
|
|
||||||
@history.y = @height - (PADDING * 2) - @input.height - (@history.text.lines.count * @history.textobject.height)
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_command
|
|
||||||
string = @text_input.text
|
|
||||||
split = string.split(" ")
|
|
||||||
command = split.first
|
|
||||||
arguments = split.length.positive? ? split[1..split.length - 1] : []
|
|
||||||
|
|
||||||
IMICFPS::Commands::Command.use(command, arguments, self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def abbrev_search(array, text)
|
|
||||||
return [] unless text.length.positive?
|
|
||||||
|
|
||||||
list = []
|
|
||||||
Abbrev.abbrev(array).each do |abbrev, value|
|
|
||||||
next unless abbrev&.start_with?(text)
|
|
||||||
|
|
||||||
list << value
|
|
||||||
end
|
|
||||||
|
|
||||||
list.uniq
|
|
||||||
end
|
|
||||||
|
|
||||||
def stdin(string)
|
|
||||||
@history.text += "\n#{string}"
|
|
||||||
update_history_y
|
|
||||||
end
|
|
||||||
|
|
||||||
def focus
|
|
||||||
InputMapper.reset_keys
|
|
||||||
|
|
||||||
@active_text_input = window.text_input
|
|
||||||
window.text_input = @text_input
|
|
||||||
|
|
||||||
@showing_cursor = window.needs_cursor
|
|
||||||
window.needs_cursor = true
|
|
||||||
|
|
||||||
@show_caret = true
|
|
||||||
@caret_last_change = Gosu.milliseconds
|
|
||||||
end
|
|
||||||
|
|
||||||
def blur
|
|
||||||
window.text_input = @active_text_input
|
|
||||||
window.needs_cursor = @showing_cursor
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
107
lib/ui/menu.rb
@@ -22,7 +22,9 @@ class IMICFPS
|
|||||||
@accent_color = ACCENT_COLOR
|
@accent_color = ACCENT_COLOR
|
||||||
window.needs_cursor = true
|
window.needs_cursor = true
|
||||||
|
|
||||||
@__version_text = CyberarmEngine::Text.new("<b>#{IMICFPS::NAME}</b> v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})", font: BOLD_SANS_FONT)
|
@__version_text = CyberarmEngine::Text.new(
|
||||||
|
"<b>#{IMICFPS::NAME}</b> v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})",
|
||||||
|
font: BOLD_SANS_FONT, border: true, border_color: Gosu::Color::BLACK)
|
||||||
@__version_text.x = window.width - (@__version_text.width + 10)
|
@__version_text.x = window.width - (@__version_text.width + 10)
|
||||||
@__version_text.y = window.height - (@__version_text.height + 10)
|
@__version_text.y = window.height - (@__version_text.height + 10)
|
||||||
|
|
||||||
@@ -30,10 +32,45 @@ class IMICFPS
|
|||||||
|
|
||||||
theme(
|
theme(
|
||||||
{
|
{
|
||||||
Label:
|
TextBlock:
|
||||||
{
|
{
|
||||||
font: SANS_FONT
|
font: SANS_FONT
|
||||||
},
|
},
|
||||||
|
Title: {
|
||||||
|
font: BOLD_SANS_FONT,
|
||||||
|
text_size: 100,
|
||||||
|
color: Gosu::Color::BLACK,
|
||||||
|
text_align: :center,
|
||||||
|
text_shadow: true,
|
||||||
|
text_shadow_size: 4,
|
||||||
|
width: 1.0,
|
||||||
|
},
|
||||||
|
Subtitle: {
|
||||||
|
text_size: 50,
|
||||||
|
color: Gosu::Color::WHITE,
|
||||||
|
text_align: :center,
|
||||||
|
width: 1.0
|
||||||
|
},
|
||||||
|
Link: {
|
||||||
|
font: BOLD_SANS_FONT,
|
||||||
|
text_size: 50,
|
||||||
|
text_align: :center,
|
||||||
|
text_border: true,
|
||||||
|
text_border_size: 2,
|
||||||
|
text_border_color: Gosu::Color::BLACK,
|
||||||
|
text_border_alpha: 100,
|
||||||
|
color: Gosu::Color.rgb(0, 127, 127),
|
||||||
|
width: 1.0,
|
||||||
|
hover: {
|
||||||
|
color: Gosu::Color.rgb(64, 128, 255),
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
color: Gosu::Color.rgb(64, 128, 255),
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
color: Gosu::Color.rgb(175, 175, 175),
|
||||||
|
},
|
||||||
|
},
|
||||||
Button:
|
Button:
|
||||||
{
|
{
|
||||||
font: BOLD_SANS_FONT,
|
font: BOLD_SANS_FONT,
|
||||||
@@ -56,21 +93,8 @@ class IMICFPS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
|
||||||
|
|
||||||
def title(text, color = Gosu::Color::BLACK)
|
SoundManager.play_playlist("base", "menus")
|
||||||
@elements << Text.new(text, color: color, size: 100, x: 0, y: 15, font: BOLD_SANS_FONT)
|
|
||||||
@_title = @elements.last
|
|
||||||
end
|
|
||||||
|
|
||||||
def subtitle(text, color = Gosu::Color::WHITE)
|
|
||||||
@elements << Text.new(text, color: color, size: 50, x: 0, y: 100, font: SANS_FONT)
|
|
||||||
@_subtitle = @elements.last
|
|
||||||
end
|
|
||||||
|
|
||||||
def link(text, color = Gosu::Color.rgb(0, 127, 127), &block)
|
|
||||||
text = Text.new(text, color: color, size: 50, x: 0, y: 100 + (60 * @elements.count), font: BOLD_SANS_FONT)
|
|
||||||
@elements << Link.new(text, self, block)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
@@ -133,56 +157,5 @@ class IMICFPS
|
|||||||
mouse_x.between?(object.x, object.x + object.width) &&
|
mouse_x.between?(object.x, object.x + object.width) &&
|
||||||
mouse_y.between?(object.y, object.y + object.height)
|
mouse_y.between?(object.y, object.y + object.height)
|
||||||
end
|
end
|
||||||
|
|
||||||
class Link
|
|
||||||
attr_reader :text, :block
|
|
||||||
|
|
||||||
def initialize(text, host, block)
|
|
||||||
@text = text
|
|
||||||
@host = host
|
|
||||||
@block = block
|
|
||||||
@color = @text.color
|
|
||||||
@hover_color = Gosu::Color.rgb(64, 128, 255)
|
|
||||||
@text.shadow_color = Gosu::Color::BLACK
|
|
||||||
@text.shadow_size = 2
|
|
||||||
@text.shadow_alpha = 100
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@text.color = if @host.mouse_over?(self)
|
|
||||||
@hover_color
|
|
||||||
else
|
|
||||||
@color
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def x
|
|
||||||
text.x
|
|
||||||
end
|
|
||||||
|
|
||||||
def x=(n)
|
|
||||||
text.x = n
|
|
||||||
end
|
|
||||||
|
|
||||||
def y
|
|
||||||
text.y
|
|
||||||
end
|
|
||||||
|
|
||||||
def width
|
|
||||||
text.width
|
|
||||||
end
|
|
||||||
|
|
||||||
def height
|
|
||||||
text.height
|
|
||||||
end
|
|
||||||
|
|
||||||
def draw
|
|
||||||
text.draw
|
|
||||||
end
|
|
||||||
|
|
||||||
def clicked
|
|
||||||
@block&.call
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class ExtrasMenu < Menu
|
class ExtrasMenu < Menu
|
||||||
def setup
|
def setup
|
||||||
title IMICFPS::NAME
|
title I18n.t("menus.extras")
|
||||||
subtitle "Extras"
|
|
||||||
|
|
||||||
link "Asset Viewer" do
|
link "Asset Viewer" do
|
||||||
push_state(IMICFPS::AssetViewerTool::MainMenu)
|
push_state(IMICFPS::AssetViewerTool::MainMenu)
|
||||||
@@ -14,7 +13,7 @@ class IMICFPS
|
|||||||
push_state(IMICFPS::MapEditorTool::MainMenu)
|
push_state(IMICFPS::MapEditorTool::MainMenu)
|
||||||
end
|
end
|
||||||
|
|
||||||
link I18n.t("menus.back") do
|
link I18n.t("menus.back"), margin_top: 25 do
|
||||||
pop_state
|
pop_state
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ class IMICFPS
|
|||||||
class GamePauseMenu < Menu
|
class GamePauseMenu < Menu
|
||||||
def setup
|
def setup
|
||||||
@bar_alpha = 50
|
@bar_alpha = 50
|
||||||
title IMICFPS::NAME
|
title "Paused"
|
||||||
subtitle "Paused"
|
|
||||||
|
|
||||||
link "Resume" do
|
link "Resume" do
|
||||||
pop_state
|
pop_state
|
||||||
@@ -15,7 +14,7 @@ class IMICFPS
|
|||||||
push_state(SettingsMenu)
|
push_state(SettingsMenu)
|
||||||
end
|
end
|
||||||
|
|
||||||
link I18n.t("menus.leave") do
|
link I18n.t("menus.leave"), margin_top: 25 do
|
||||||
push_state(MainMenu)
|
push_state(MainMenu)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class LevelSelectMenu < Menu
|
class LevelSelectMenu < Menu
|
||||||
def setup
|
def setup
|
||||||
title IMICFPS::NAME
|
title I18n.t("menus.singleplayer")
|
||||||
subtitle "Choose a Map"
|
subtitle "Choose a Map"
|
||||||
|
|
||||||
Dir.glob("#{GAME_ROOT_PATH}/maps/*.json").map { |file| [file, MapParser.new(map_file: file)] }.each do |file, map|
|
Dir.glob("#{GAME_ROOT_PATH}/maps/*.json").map { |file| [file, MapParser.new(map_file: file)] }.each do |file, map|
|
||||||
|
next unless map.metadata.gamemode
|
||||||
|
|
||||||
link map.metadata.name do
|
link map.metadata.name do
|
||||||
push_state(
|
push_state(
|
||||||
LoadingState.new(forward: Game, map_file: file)
|
LoadingState.new(forward: Game, map_file: file)
|
||||||
@@ -14,7 +16,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
link I18n.t("menus.back") do
|
link I18n.t("menus.back"), margin_top: 25 do
|
||||||
pop_state
|
pop_state
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class IMICFPS
|
|||||||
title IMICFPS::NAME
|
title IMICFPS::NAME
|
||||||
|
|
||||||
link I18n.t("menus.singleplayer") do
|
link I18n.t("menus.singleplayer") do
|
||||||
push_state(LevelSelectMenu)
|
push_state(SinglePlayerMenu)
|
||||||
end
|
end
|
||||||
|
|
||||||
link I18n.t("menus.multiplayer") do
|
link I18n.t("menus.multiplayer") do
|
||||||
@@ -21,7 +21,7 @@ class IMICFPS
|
|||||||
push_state(ExtrasMenu)
|
push_state(ExtrasMenu)
|
||||||
end
|
end
|
||||||
|
|
||||||
link I18n.t("menus.quit") do
|
link I18n.t("menus.quit"), margin_top: 25 do
|
||||||
window.close
|
window.close
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -40,14 +40,17 @@ Fallback <b>immediate mode renderer</b> will be used."
|
|||||||
(Linux Only) For MESA based drivers append <b>--mesa-override</b>
|
(Linux Only) For MESA based drivers append <b>--mesa-override</b>
|
||||||
as a commandline argument to override reported version."
|
as a commandline argument to override reported version."
|
||||||
message += linux_mesa_message if RUBY_PLATFORM =~ /linux/ && gl_version.downcase.include?(" mesa ")
|
message += linux_mesa_message if RUBY_PLATFORM =~ /linux/ && gl_version.downcase.include?(" mesa ")
|
||||||
@old_gl_warning = Gosu::Image.from_markup(message, 24, align: :center, font: "")
|
@old_gl_warning = Text.new(message, size: 24, z: Float::INFINITY, border: true, border_color: Gosu::Color::BLACK)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
super
|
super
|
||||||
|
|
||||||
@old_gl_warning&.draw(window.width / 2 - @old_gl_warning.width / 2, window.height - (@old_gl_warning.height + 10), Float::INFINITY)
|
@old_gl_warning&.x = window.width / 2 - @old_gl_warning.width / 2
|
||||||
|
@old_gl_warning&.y = window.height - (@old_gl_warning.height + 10)
|
||||||
|
|
||||||
|
@old_gl_warning&.draw
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class MultiplayerMenu < Menu
|
class MultiplayerMenu < Menu
|
||||||
def setup
|
def setup
|
||||||
title IMICFPS::NAME
|
title I18n.t("menus.multiplayer")
|
||||||
subtitle "Multiplayer"
|
|
||||||
|
|
||||||
link "Quick Join"
|
link "Quick Join"
|
||||||
link "Server Browser" do
|
link "Server Browser" do
|
||||||
@@ -13,7 +12,7 @@ class IMICFPS
|
|||||||
link "Profile" do
|
link "Profile" do
|
||||||
push_state(MultiplayerProfileMenu)
|
push_state(MultiplayerProfileMenu)
|
||||||
end
|
end
|
||||||
link I18n.t("menus.back") do
|
link I18n.t("menus.back"), margin_top: 25 do
|
||||||
pop_state
|
pop_state
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,17 +3,22 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class MultiplayerProfileMenu < Menu
|
class MultiplayerProfileMenu < Menu
|
||||||
def setup
|
def setup
|
||||||
label "Profile", text_size: 100, color: Gosu::Color::BLACK
|
|
||||||
|
|
||||||
flow(width: 1.0, height: 1.0) do
|
flow(width: 1.0, height: 1.0) do
|
||||||
stack(width: 0.25, height: 1.0) do
|
stack(width: 0.25, height: 1.0) do
|
||||||
button "Edit Profile", width: 1.0
|
|
||||||
button "Log Out", width: 1.0
|
|
||||||
button I18n.t("menus.back"), width: 1.0, margin_top: 64 do
|
|
||||||
pop_state
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
stack(width: 0.5, height: 1.0) do
|
stack(width: 0.5, height: 1.0) do
|
||||||
|
title "Profile"
|
||||||
|
|
||||||
|
flow width: 1.0 do
|
||||||
|
link I18n.t("menus.back"), width: 0.333 do
|
||||||
|
pop_state
|
||||||
|
end
|
||||||
|
|
||||||
|
button "Edit Profile", width: 0.333
|
||||||
|
button "Log Out", width: 0.333
|
||||||
|
end
|
||||||
|
|
||||||
flow(width: 1.0, padding: 4) do
|
flow(width: 1.0, padding: 4) do
|
||||||
background 0x88_222222
|
background 0x88_222222
|
||||||
|
|
||||||
@@ -25,7 +30,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
flow(margin_top: 4, margin_right: 4) do
|
flow(margin_top: 4) do
|
||||||
stack do
|
stack do
|
||||||
label "Kiil/Death Ratio"
|
label "Kiil/Death Ratio"
|
||||||
label "Kills"
|
label "Kills"
|
||||||
@@ -36,8 +41,8 @@ class IMICFPS
|
|||||||
label "Repair Points"
|
label "Repair Points"
|
||||||
end
|
end
|
||||||
|
|
||||||
stack do
|
stack margin_left: 16 do
|
||||||
label "0.72"
|
label "0.75"
|
||||||
label "21"
|
label "21"
|
||||||
label "28"
|
label "28"
|
||||||
label "14"
|
label "14"
|
||||||
|
|||||||
@@ -30,41 +30,47 @@ class IMICFPS
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
label "Server Browser", text_size: 100
|
flow(width: 1.0, height: 1.0) do
|
||||||
flow width: 1.0, height: 1.0 do
|
|
||||||
stack width: 0.25 do
|
stack width: 0.25 do
|
||||||
button "Host Game", width: 1.0
|
|
||||||
button "Direct Connect", width: 1.0
|
|
||||||
|
|
||||||
button I18n.t("menus.back"), width: 1.0, margin_top: 64 do
|
|
||||||
pop_state
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
stack width: 0.5, height: 1.0 do
|
stack width: 0.5, height: 1.0 do
|
||||||
stack width: 1.0, height: 0.75, border_color: 0xffffffff, border_thickness: 1 do
|
stack width: 1.0, height: 0.25 do
|
||||||
|
title "Server Browser"
|
||||||
|
|
||||||
|
flow(width: 1.0) do
|
||||||
|
link I18n.t("menus.back"), width: 0.333 do
|
||||||
|
pop_state
|
||||||
|
end
|
||||||
|
|
||||||
|
button "Host Game", width: 0.333
|
||||||
|
button "Direct Connect", width: 0.333
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
stack width: 1.0, height: 0.5, border_color: 0xffffffff, border_thickness: 1 do
|
||||||
@sample_games.each_with_index do |game, i|
|
@sample_games.each_with_index do |game, i|
|
||||||
text_size = 18
|
text_size = 18
|
||||||
flow width: 1.0 do
|
flow width: 1.0 do
|
||||||
background i.even? ? 0x55000000 : 0x55ff5500
|
background i.even? ? 0x55000000 : 0x55ff5500
|
||||||
|
|
||||||
flow width: 0.1 do
|
flow width: 0.1 do
|
||||||
label game[:game_type], text_size: text_size
|
label game[:game_type], text_size: text_size, text_wrap: :none, font: i.zero? ? BOLD_SANS_FONT : SANS_FONT
|
||||||
end
|
end
|
||||||
flow width: 0.3 do
|
flow width: 0.3 do
|
||||||
label game[:host], text_size: text_size
|
label game[:host], text_size: text_size, text_wrap: :none, font: i.zero? ? BOLD_SANS_FONT : SANS_FONT
|
||||||
end
|
end
|
||||||
flow width: 0.3 do
|
flow width: 0.3 do
|
||||||
label game[:map], text_size: text_size
|
label game[:map], text_size: text_size, text_wrap: :none, font: i.zero? ? BOLD_SANS_FONT : SANS_FONT
|
||||||
end
|
end
|
||||||
flow width: 0.1 do
|
flow width: 0.1 do
|
||||||
label game[:players], text_size: text_size
|
label game[:players], text_size: text_size, text_wrap: :none, font: i.zero? ? BOLD_SANS_FONT : SANS_FONT
|
||||||
end
|
end
|
||||||
flow width: 0.1 do
|
flow width: 0.1 do
|
||||||
label game[:ping], text_size: text_size
|
label game[:ping], text_size: text_size, text_wrap: :none, font: i.zero? ? BOLD_SANS_FONT : SANS_FONT
|
||||||
end
|
end
|
||||||
flow width: 0.1 do
|
flow width: 0.1 do
|
||||||
label game[:source], text_size: text_size
|
label game[:source], text_size: text_size, text_wrap: :none, font: i.zero? ? BOLD_SANS_FONT : SANS_FONT
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,102 +5,132 @@ class IMICFPS
|
|||||||
include CommonMethods
|
include CommonMethods
|
||||||
|
|
||||||
def self.set_defaults
|
def self.set_defaults
|
||||||
if $window.config.get(:options, :audio, :volume_sound).nil?
|
if CyberarmEngine::Window.instance.config.get(:options, :audio, :volume_master).nil?
|
||||||
$window.config[:options, :audio, :volume_sound] = 1.0
|
CyberarmEngine::Window.instance.config[:options, :audio, :volume_master] = 1.0
|
||||||
end
|
end
|
||||||
if $window.config.get(:options, :audio, :volume_music).nil?
|
|
||||||
$window.config[:options, :audio, :volume_music] = 0.7
|
if CyberarmEngine::Window.instance.config.get(:options, :audio, :volume_sound_effects).nil?
|
||||||
|
CyberarmEngine::Window.instance.config[:options, :audio, :volume_sound_effects] = 1.0
|
||||||
end
|
end
|
||||||
if $window.config.get(:options, :audio, :volume_dialogue).nil?
|
|
||||||
$window.config[:options, :audio, :volume_dialogue] = 0.7
|
if CyberarmEngine::Window.instance.config.get(:options, :audio, :volume_music).nil?
|
||||||
|
CyberarmEngine::Window.instance.config[:options, :audio, :volume_music] = 0.7
|
||||||
|
end
|
||||||
|
|
||||||
|
if CyberarmEngine::Window.instance.config.get(:options, :audio, :volume_dialogue).nil?
|
||||||
|
CyberarmEngine::Window.instance.config[:options, :audio, :volume_dialogue] = 0.7
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@categories = %w[
|
|
||||||
Display
|
|
||||||
Graphics
|
|
||||||
Audio
|
|
||||||
Controls
|
|
||||||
Multiplayer
|
|
||||||
]
|
|
||||||
@pages = {}
|
@pages = {}
|
||||||
@current_page = nil
|
@current_page = nil
|
||||||
|
|
||||||
label "Settings", text_size: 100, color: Gosu::Color::BLACK
|
|
||||||
|
|
||||||
flow(width: 1.0, height: 1.0) do
|
flow(width: 1.0, height: 1.0) do
|
||||||
stack(width: 0.25, height: 1.0) do
|
stack(width: 0.25, height: 1.0) do
|
||||||
@categories.each do |category|
|
end
|
||||||
button category, width: 1.0 do
|
|
||||||
show_page(:"#{category}".downcase)
|
stack(fill: true, height: 1.0) do
|
||||||
|
title "Settings", width: 1.0, text_align: :center
|
||||||
|
|
||||||
|
stack(width: 1.0, height: 96) do
|
||||||
|
flow(width: 1.0) do
|
||||||
|
link I18n.t("menus.back"), width: nil do
|
||||||
|
pop_state
|
||||||
|
end
|
||||||
|
|
||||||
|
flow(fill: true)
|
||||||
|
|
||||||
|
button get_image("#{GAME_ROOT_PATH}/static/icons/settings_display.png"), image_width: 64, tip: I18n.t("settings.display") do
|
||||||
|
show_page(:display)
|
||||||
|
end
|
||||||
|
|
||||||
|
button get_image("#{GAME_ROOT_PATH}/static/icons/settings_graphics.png"), image_width: 64, tip: I18n.t("settings.graphics") do
|
||||||
|
show_page(:graphics)
|
||||||
|
end
|
||||||
|
|
||||||
|
button get_image("#{GAME_ROOT_PATH}/static/icons/settings_audio.png"), image_width: 64, tip: I18n.t("settings.audio") do
|
||||||
|
show_page(:audio)
|
||||||
|
end
|
||||||
|
|
||||||
|
button get_image("#{GAME_ROOT_PATH}/static/icons/settings_controls.png"), image_width: 64, tip: I18n.t("settings.controls") do
|
||||||
|
show_page(:controls)
|
||||||
|
end
|
||||||
|
|
||||||
|
button get_image("#{GAME_ROOT_PATH}/static/icons/settings_multiplayer.png"), image_width: 64, tip: I18n.t("settings.multiplayer") do
|
||||||
|
show_page(:multiplayer)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
button I18n.t("menus.back"), width: 1.0, margin_top: 64 do
|
@page_container = stack(width: 1.0, fill: true, scroll: true, padding: 10) do
|
||||||
pop_state
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@categories.each do |category|
|
stack(width: 0.25, height: 1.0) do
|
||||||
stack(width: 0.5, height: 1.0) do |element|
|
|
||||||
@pages[:"#{category}".downcase] = element
|
|
||||||
element.hide
|
|
||||||
|
|
||||||
send(:"create_page_#{category}".downcase) if respond_to?(:"create_page_#{category}".downcase)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @categories.each do |category|
|
||||||
|
# stack(width: 0.5, height: 1.0) do |element|
|
||||||
|
# @pages[:"#{category}".downcase] = element
|
||||||
|
# element.hide
|
||||||
|
|
||||||
|
# send(:"create_page_#{category}".downcase) if respond_to?(:"create_page_#{category}".downcase)
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
show_page(:display)
|
show_page(:display)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_page(page)
|
def show_page(page)
|
||||||
if element = @pages[page]
|
@page_container.clear do
|
||||||
@current_page&.hide
|
send(:"page_#{page}")
|
||||||
@current_page = element
|
|
||||||
element.show
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@page_container.scroll_top = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_page_display
|
def page_display
|
||||||
label "Display", text_size: 50
|
label "Display", text_size: 50
|
||||||
|
|
||||||
label "Resolution"
|
stack(width: 1.0, height: 128) do
|
||||||
flow do
|
flow(width: 1.0) do
|
||||||
stack do
|
label "Width", width: 96
|
||||||
label "Width"
|
edit_line window.width.to_s, fill: true
|
||||||
label "Height"
|
|
||||||
end
|
end
|
||||||
stack do
|
|
||||||
edit_line window.width.to_s
|
flow(width: 1.0) do
|
||||||
edit_line window.height.to_s
|
label "Height", width: 96
|
||||||
|
edit_line window.height.to_s, fill: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
check_box "Fullscreen", padding_top: 25, padding_bottom: 25
|
# check_box "Fullscreen", margin_top: 25, margin_bottom: 25, width: 1.0
|
||||||
|
|
||||||
stack do
|
stack(width: 1.0, height: 128, margin_top: 20) do
|
||||||
longest_string = "Gamma Correction"
|
flow(width: 1.0, fill: true) do
|
||||||
flow do
|
label "Gamma Correction", width: 256
|
||||||
label "Gamma Correction".ljust(longest_string.length, " ")
|
@display_gamma_correction = slider range: 0.0..1.0, value: 0.5, fill: true
|
||||||
@display_gamma_correction = slider range: 0.0..1.0, value: 0.5
|
|
||||||
@display_gamma_correction.subscribe(:changed) do |_sender, value|
|
@display_gamma_correction.subscribe(:changed) do |_sender, value|
|
||||||
@display_gamma_correction_label.value = value.round(1).to_s
|
@display_gamma_correction_label.value = value.round(1).to_s
|
||||||
end
|
end
|
||||||
@display_gamma_correction_label = label "0.0"
|
@display_gamma_correction_label = label "0.0"
|
||||||
end
|
end
|
||||||
flow do
|
|
||||||
label "Brightness".ljust(longest_string.length, " ")
|
flow(width: 1.0, fill: true) do
|
||||||
@display_brightness = slider range: 0.0..1.0, value: 0.5
|
label "Brightness", width: 256
|
||||||
|
@display_brightness = slider range: 0.0..1.0, value: 0.5, fill: true
|
||||||
@display_brightness.subscribe(:changed) do |_sender, value|
|
@display_brightness.subscribe(:changed) do |_sender, value|
|
||||||
@display_brightness_label.value = value.round(1).to_s
|
@display_brightness_label.value = value.round(1).to_s
|
||||||
end
|
end
|
||||||
@display_brightness_label = label "0.0"
|
@display_brightness_label = label "0.0"
|
||||||
end
|
end
|
||||||
flow do
|
|
||||||
label "Contrast".ljust(longest_string.length, " ")
|
flow(width: 1.0, fill: true) do
|
||||||
@display_contrast = slider range: 0.0..1.0, value: 0.5
|
label "Contrast", width: 256
|
||||||
|
@display_contrast = slider range: 0.0..1.0, value: 0.5, fill: true
|
||||||
@display_contrast.subscribe(:changed) do |_sender, value|
|
@display_contrast.subscribe(:changed) do |_sender, value|
|
||||||
@display_contrast_label.value = value.round(1).to_s
|
@display_contrast_label.value = value.round(1).to_s
|
||||||
end
|
end
|
||||||
@@ -109,105 +139,100 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_page_audio
|
def page_audio
|
||||||
label "Audio", text_size: 50
|
label "Audio", text_size: 50
|
||||||
longest_string = "Dialogue".length
|
volumes = %i[master sound_effects music dialogue]
|
||||||
volumes = %i[sound music dialogue]
|
|
||||||
|
|
||||||
stack do
|
stack(width: 1.0, height: 48 * volumes.count) do
|
||||||
volumes.each do |volume|
|
volumes.each do |volume|
|
||||||
config_value = window.config.get(:options, :audio, :"volume_#{volume}")
|
config_value = window.config.get(:options, :audio, :"volume_#{volume}")
|
||||||
|
|
||||||
flow do
|
flow(width: 1.0, fill: true, margin_bottom: 10) do
|
||||||
label volume.to_s.split("_").join(" ").capitalize.ljust(longest_string, " ")
|
label volume.to_s.split("_").map(&:capitalize).join(" "), width: 172
|
||||||
instance_variable_set(:"@volume_#{volume}", slider(range: 0.0..1.0, value: config_value))
|
|
||||||
|
instance_variable_set(:"@volume_#{volume}", slider(range: 0.0..1.0, value: config_value, fill: true))
|
||||||
instance_variable_get(:"@volume_#{volume}").subscribe(:changed) do |_sender, value|
|
instance_variable_get(:"@volume_#{volume}").subscribe(:changed) do |_sender, value|
|
||||||
instance_variable_get(:"@volume_#{volume}_label").value = format("%03.2f%%", value * 100.0)
|
instance_variable_get(:"@volume_#{volume}_label").value = format("%03.2f%%", value * 100.0)
|
||||||
window.config[:options, :audio, :"volume_#{volume}"] = value
|
window.config[:options, :audio, :"volume_#{volume}"] = value
|
||||||
end
|
end
|
||||||
instance_variable_set(:"@volume_#{volume}_label", label(format("%03.2f%%", config_value * 100.0)))
|
|
||||||
|
instance_variable_set(:"@volume_#{volume}_label", label(format("%03.2f%%", config_value * 100.0), width: 96, text_align: :right))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_page_controls
|
def page_controls
|
||||||
label "Controls", text_size: 50
|
label "Controls", text_size: 50
|
||||||
|
|
||||||
InputMapper.keymap.each do |key, values|
|
InputMapper.keymap.each do |key, values|
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label key.to_s
|
label key.to_s, width: 0.5, max_width: 312
|
||||||
|
|
||||||
[values].flatten.each do |value|
|
[values].flatten.each do |value|
|
||||||
if name = Gosu.button_name(value)
|
unless (name = Gosu.button_name(value))
|
||||||
else
|
|
||||||
name = Gosu.constants.find { |const| Gosu.const_get(const) == value }
|
name = Gosu.constants.find { |const| Gosu.const_get(const) == value }
|
||||||
name = name.to_s.capitalize.split("_").join(" ") if name
|
name = name.to_s.capitalize.split("_").join(" ") if name
|
||||||
end
|
end
|
||||||
button name
|
|
||||||
|
button name, fill: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_page_graphics
|
def page_graphics
|
||||||
label "Graphics", text_size: 50
|
label "Graphics", text_size: 50
|
||||||
|
|
||||||
longest_string = "Surface Effect Detail"
|
check_box "V-Sync (Not Disableable, Yet.)", checked: true, enabled: false, width: 1.0
|
||||||
|
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
check_box "V-Sync (Not Disableable, Yet.)", checked: true, enabled: false
|
label "Field of View", width: 128
|
||||||
end
|
@fov = slider range: 70.0..110.0, fill: true
|
||||||
|
|
||||||
flow do
|
|
||||||
label "Field of View".ljust(longest_string.length, " ")
|
|
||||||
@fov = slider range: 70.0..110.0
|
|
||||||
@fov.subscribe(:changed) do |_sender, value|
|
@fov.subscribe(:changed) do |_sender, value|
|
||||||
@fov_label.value = value.round.to_s
|
@fov_label.value = value.round.to_s
|
||||||
end
|
end
|
||||||
@fov_label = label "90.0"
|
@fov_label = label "90.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Detail".ljust(longest_string.length, " ")
|
label "Detail", width: 128
|
||||||
list_box items: %i[high medium low], width: 250
|
list_box items: %i[high medium low], fill: true
|
||||||
end
|
end
|
||||||
|
|
||||||
label ""
|
advanced_mode = check_box "Advanced Settings", margin_top: 20, margin_bottom: 20
|
||||||
advanced_mode = check_box "Advanced Settings"
|
|
||||||
label ""
|
|
||||||
|
|
||||||
advanced_settings = stack width: 1.0 do |element|
|
advanced_settings = stack(width: 1.0) do |element|
|
||||||
element.hide
|
element.hide
|
||||||
|
|
||||||
stack do
|
stack(width: 1.0, height: 64 * 7) do
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Geometry Detail".ljust(longest_string.length, " ")
|
label "Geometry Detail", width: 312
|
||||||
list_box items: %i[high medium low], width: 250
|
list_box items: %i[high medium low], fill: true
|
||||||
end
|
end
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Shadow Detail".ljust(longest_string.length, " ")
|
label "Shadow Detail", width: 312
|
||||||
list_box items: %i[high medium low off], width: 250
|
list_box items: %i[high medium low off], fill: true
|
||||||
end
|
end
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Texture Detail".ljust(longest_string.length, " ")
|
label "Texture Detail", width: 312
|
||||||
list_box items: %i[high medium low], width: 250
|
list_box items: %i[high medium low], fill: true
|
||||||
end
|
end
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Particle Detail".ljust(longest_string.length, " ")
|
label "Particle Detail", width: 312
|
||||||
list_box items: %i[high medium low off], width: 250
|
list_box items: %i[high medium low off], fill: true
|
||||||
end
|
end
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Surface Effect Detail".ljust(longest_string.length, " ")
|
label "Surface Effect Detail", width: 312
|
||||||
list_box items: %i[high medium low], width: 250
|
list_box items: %i[high medium low], fill: true
|
||||||
end
|
end
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Lighting Mode".ljust(longest_string.length, " ")
|
label "Lighting Mode", width: 312
|
||||||
list_box items: %i[per_pixel per_vertex], width: 250
|
list_box items: %i[per_pixel per_vertex], fill: true
|
||||||
end
|
end
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Texture Filtering".ljust(longest_string.length, " ")
|
label "Texture Filtering", width: 312
|
||||||
list_box items: [:none], width: 250
|
list_box items: [:none], fill: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -218,13 +243,14 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_page_multiplayer
|
def page_multiplayer
|
||||||
label "Multiplayer", text_size: 50
|
label "Multiplayer", text_size: 50
|
||||||
|
|
||||||
flow do
|
flow(width: 1.0, height: 64) do
|
||||||
label "Player Name"
|
label "Player Name", width: 172
|
||||||
edit_line "player-#{SecureRandom.hex(2)}"
|
edit_line "player-#{SecureRandom.hex(2)}", fill: true
|
||||||
end
|
end
|
||||||
|
|
||||||
check_box "Show player names"
|
check_box "Show player names"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
21
lib/ui/menus/single_player_menu.rb
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class IMICFPS
|
||||||
|
class SinglePlayerMenu < Menu
|
||||||
|
def setup
|
||||||
|
title I18n.t("menus.singleplayer")
|
||||||
|
|
||||||
|
link "Tutorial", enabled: false, tip: "No tutorial implemented, yet..."
|
||||||
|
|
||||||
|
link "Campaign", enabled: false, tip: "No campaign, yet..."
|
||||||
|
|
||||||
|
link "Multiplayer Practice" do
|
||||||
|
push_state(LevelSelectMenu)
|
||||||
|
end
|
||||||
|
|
||||||
|
link I18n.t("menus.back"), margin_top: 25 do
|
||||||
|
pop_state
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class IMICFPS
|
|
||||||
class Commands
|
|
||||||
class Command
|
|
||||||
class SubCommand
|
|
||||||
def initialize(parent, command, type)
|
|
||||||
@parent = parent
|
|
||||||
@command = command
|
|
||||||
@type = type
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :command
|
|
||||||
|
|
||||||
def handle(arguments, console)
|
|
||||||
if arguments.size > 1
|
|
||||||
console.stdin("to many arguments for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
case @type
|
|
||||||
when :boolean
|
|
||||||
case arguments.last
|
|
||||||
when "", nil
|
|
||||||
var = @parent.get(command.to_sym) || false
|
|
||||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
|
||||||
when "on"
|
|
||||||
var = @parent.set(command.to_sym, true)
|
|
||||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
|
||||||
when "off"
|
|
||||||
var = @parent.set(command.to_sym, false)
|
|
||||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
|
||||||
else
|
|
||||||
console.stdin("Invalid argument for #{Style.highlight(command.to_s)}, got #{Style.error(arguments.last)} expected #{Style.notice('on')}, or #{Style.notice('off')}.")
|
|
||||||
end
|
|
||||||
when :string
|
|
||||||
case arguments.last
|
|
||||||
when "", nil
|
|
||||||
var = @parent.get(command.to_sym) || "\"\""
|
|
||||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
|
||||||
else
|
|
||||||
var = @parent.set(command.to_sym, arguments.last)
|
|
||||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
|
||||||
end
|
|
||||||
when :integer
|
|
||||||
case arguments.last
|
|
||||||
when "", nil
|
|
||||||
var = @parent.get(command.to_sym) || "nil"
|
|
||||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
var = @parent.set(command.to_sym, Integer(arguments.last))
|
|
||||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
|
||||||
rescue ArgumentError
|
|
||||||
console.stdin("Error: #{Style.error("Expected an integer, got '#{arguments.last}'")}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
when :decimal
|
|
||||||
case arguments.last
|
|
||||||
when "", nil
|
|
||||||
var = @parent.get(command.to_sym) || "nil"
|
|
||||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
var = @parent.set(command.to_sym, Float(arguments.last))
|
|
||||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
|
||||||
rescue ArgumentError
|
|
||||||
console.stdin("Error: #{Style.error("Expected a decimal or integer, got '#{arguments.last}'")}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise RuntimeError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def values
|
|
||||||
case @type
|
|
||||||
when :boolean
|
|
||||||
%w[on off]
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def usage
|
|
||||||
case @type
|
|
||||||
when :boolean
|
|
||||||
"#{Style.highlight(command)} #{Style.notice('[on|off]')}"
|
|
||||||
when :string
|
|
||||||
"#{Style.highlight(command)} #{Style.notice('[string]')}"
|
|
||||||
when :integer
|
|
||||||
"#{Style.highlight(command)} #{Style.notice('[0]')}"
|
|
||||||
when :decimal
|
|
||||||
"#{Style.highlight(command)} #{Style.notice('[0.0]')}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -2,17 +2,10 @@
|
|||||||
|
|
||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Window < CyberarmEngine::Window
|
class Window < CyberarmEngine::Window
|
||||||
attr_accessor :number_of_vertices, :needs_cursor
|
attr_accessor :needs_cursor
|
||||||
attr_reader :renderer, :scene, :config, :director, :console, :delta_time
|
attr_reader :renderer, :scene, :config, :director, :console, :delta_time
|
||||||
|
|
||||||
def initialize(window_width = 1280, window_height = 720, fullscreen = false)
|
def setup
|
||||||
fps_target = ARGV.first.to_i != 0 ? ARGV.first.to_i : 60
|
|
||||||
if ARGV.join.include?("--native")
|
|
||||||
super(width: Gosu.screen_width, height: Gosu.screen_height, fullscreen: true, resizable: true, update_interval: 1000.0 / fps_target)
|
|
||||||
else
|
|
||||||
super(width: window_width, height: window_height, fullscreen: fullscreen, resizable: true, update_interval: 1000.0 / fps_target)
|
|
||||||
end
|
|
||||||
$window = self
|
|
||||||
I18n.load_path << Dir["#{GAME_ROOT_PATH}/locales/*.yml"]
|
I18n.load_path << Dir["#{GAME_ROOT_PATH}/locales/*.yml"]
|
||||||
I18n.default_locale = :en
|
I18n.default_locale = :en
|
||||||
language = Gosu.language.split("_").first.to_sym
|
language = Gosu.language.split("_").first.to_sym
|
||||||
@@ -29,11 +22,11 @@ class IMICFPS
|
|||||||
@config = CyberarmEngine::ConfigFile.new(file: "#{IMICFPS::GAME_ROOT_PATH}/data/config.json")
|
@config = CyberarmEngine::ConfigFile.new(file: "#{IMICFPS::GAME_ROOT_PATH}/data/config.json")
|
||||||
@show_console = false
|
@show_console = false
|
||||||
@console = Console.new
|
@console = Console.new
|
||||||
Commands::Command.setup
|
CyberarmEngine::Console::Command.setup
|
||||||
|
@console.stdin("=== #{IMICFPS::NAME} v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME}) ===\n\n")
|
||||||
SettingsMenu.set_defaults
|
SettingsMenu.set_defaults
|
||||||
|
|
||||||
@renderer = Renderer.new
|
@renderer = Renderer.new
|
||||||
preload_default_shaders
|
|
||||||
@scene = TurnTableScene.new
|
@scene = TurnTableScene.new
|
||||||
@overlay = Overlay.new
|
@overlay = Overlay.new
|
||||||
|
|
||||||
@@ -43,21 +36,15 @@ class IMICFPS
|
|||||||
@config.save!
|
@config.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
push_state(Boot)
|
push_state(CyberarmEngine::IntroState, forward: Boot)
|
||||||
|
|
||||||
@delta_time = Gosu.milliseconds
|
@delta_time = Gosu.milliseconds
|
||||||
end
|
end
|
||||||
|
|
||||||
def preload_default_shaders
|
def input_hijack=(hijacker)
|
||||||
shaders = %w[g_buffer lighting]
|
@input_hijacker = hijacker
|
||||||
shaders.each do |shader|
|
|
||||||
Shader.new(
|
InputMapper.reset_keys
|
||||||
name: shader,
|
|
||||||
includes_dir: "shaders/include",
|
|
||||||
vertex: "shaders/vertex/#{shader}.glsl",
|
|
||||||
fragment: "shaders/fragment/#{shader}.glsl"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def needs_cursor?
|
def needs_cursor?
|
||||||
@@ -89,7 +76,6 @@ class IMICFPS
|
|||||||
@overlay.update
|
@overlay.update
|
||||||
SoundManager.update
|
SoundManager.update
|
||||||
|
|
||||||
@number_of_vertices = 0
|
|
||||||
@delta_time = Gosu.milliseconds
|
@delta_time = Gosu.milliseconds
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -100,12 +86,14 @@ class IMICFPS
|
|||||||
def button_down(id)
|
def button_down(id)
|
||||||
if @show_console
|
if @show_console
|
||||||
@console.button_down(id)
|
@console.button_down(id)
|
||||||
|
elsif @input_hijacker
|
||||||
|
@input_hijacker.button_down(id)
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
if id == Gosu::KbBacktick
|
if id == Gosu::KbBacktick
|
||||||
@show_console ? @console.blur : @console.focus
|
@show_console ? @console.blur : @console.focus && InputMapper.reset_keys
|
||||||
@show_console = !@show_console
|
@show_console = !@show_console
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -113,6 +101,8 @@ class IMICFPS
|
|||||||
def button_up(id)
|
def button_up(id)
|
||||||
if @show_console
|
if @show_console
|
||||||
@console.button_up(id)
|
@console.button_up(id)
|
||||||
|
elsif @input_hijacker
|
||||||
|
@input_hijacker.button_up(id)
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,4 +10,10 @@ en:
|
|||||||
back: Back
|
back: Back
|
||||||
leave: Leave
|
leave: Leave
|
||||||
paused: Paused
|
paused: Paused
|
||||||
resume: Resume
|
resume: Resume
|
||||||
|
settings:
|
||||||
|
display: Display
|
||||||
|
graphics: Graphics
|
||||||
|
audio: Audio
|
||||||
|
controls: Controls
|
||||||
|
multiplayer: Multiplayer
|
||||||
30
maps/model_viewer.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"metadata": {
|
||||||
|
"name": "Model Viewer",
|
||||||
|
"gamemode": null,
|
||||||
|
"authors": [
|
||||||
|
"Cyberarm"
|
||||||
|
],
|
||||||
|
"datetime": "2021-04-25 22:51:00 UTC",
|
||||||
|
"thumbnail": "",
|
||||||
|
"description": "A map for the model viewer tool to use."
|
||||||
|
},
|
||||||
|
|
||||||
|
"entities": [],
|
||||||
|
|
||||||
|
"spawnpoints": [
|
||||||
|
{
|
||||||
|
"team": 0,
|
||||||
|
"position": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"orientation": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# version 330 core
|
|
||||||
|
|
||||||
layout(location = 0) out vec3 fragPosition;
|
|
||||||
layout (location = 1) out vec4 fragColor;
|
|
||||||
layout (location = 2) out vec3 fragNormal;
|
|
||||||
layout (location = 3) out vec3 fragUV;
|
|
||||||
|
|
||||||
in vec3 outPosition, outColor, outNormal, outUV, outFragPos, outCameraPos;
|
|
||||||
flat in int outHasTexture;
|
|
||||||
|
|
||||||
uniform sampler2D diffuse_texture;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec3 result;
|
|
||||||
|
|
||||||
if (outHasTexture == 0) {
|
|
||||||
result = outColor;
|
|
||||||
} else {
|
|
||||||
result = texture(diffuse_texture, outUV.xy).xyz + 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
fragPosition = outPosition;
|
|
||||||
fragColor = vec4(result, 1.0);
|
|
||||||
fragNormal = outNormal;
|
|
||||||
fragUV = outUV;
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#version 330 core
|
|
||||||
out vec4 FragColor;
|
|
||||||
|
|
||||||
@include "light_struct"
|
|
||||||
const int DIRECTIONAL = 0;
|
|
||||||
const int POINT = 1;
|
|
||||||
const int SPOT = 2;
|
|
||||||
|
|
||||||
in vec2 outTexCoords;
|
|
||||||
flat in Light outLight[1];
|
|
||||||
|
|
||||||
uniform sampler2D diffuse, position, texcoord, normal, depth;
|
|
||||||
|
|
||||||
vec4 directionalLight(Light light) {
|
|
||||||
vec3 norm = normalize(texture(normal, outTexCoords).rgb);
|
|
||||||
vec3 diffuse_color = texture(diffuse, outTexCoords).rgb;
|
|
||||||
vec3 fragPos = texture(position, outTexCoords).rgb;
|
|
||||||
|
|
||||||
vec3 lightDir = normalize(light.position - fragPos);
|
|
||||||
float diff = max(dot(norm, lightDir), 0);
|
|
||||||
|
|
||||||
vec3 _ambient = light.ambient;
|
|
||||||
vec3 _diffuse = light.diffuse * diff;
|
|
||||||
vec3 _specular = light.specular;
|
|
||||||
|
|
||||||
return vec4(_diffuse + _ambient + _specular, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 pointLight(Light light) {
|
|
||||||
return vec4(0.25, 0.25, 0.25, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 spotLight(Light light) {
|
|
||||||
return vec4(0.5, 0.5, 0.5, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 calculateLighting(Light light) {
|
|
||||||
vec4 result;
|
|
||||||
|
|
||||||
// switch(light.type) {
|
|
||||||
// case DIRECTIONAL: {
|
|
||||||
// result = directionalLight(light);
|
|
||||||
// }
|
|
||||||
// case SPOT: {
|
|
||||||
// result = spotLight(light);
|
|
||||||
// }
|
|
||||||
// default: {
|
|
||||||
// result = pointLight(light);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (light.type == DIRECTIONAL) {
|
|
||||||
result = directionalLight(light);
|
|
||||||
} else {
|
|
||||||
result = pointLight(light);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
FragColor = texture(diffuse, outTexCoords) * calculateLighting(outLight[0]);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
struct Light {
|
|
||||||
int type;
|
|
||||||
vec3 direction;
|
|
||||||
vec3 position;
|
|
||||||
|
|
||||||
vec3 diffuse;
|
|
||||||
vec3 ambient;
|
|
||||||
vec3 specular;
|
|
||||||
|
|
||||||
float intensity;
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# version 330 core
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 inPosition;
|
|
||||||
layout(location = 1) in vec3 inColor;
|
|
||||||
layout(location = 2) in vec3 inNormal;
|
|
||||||
layout(location = 3) in vec3 inUV;
|
|
||||||
|
|
||||||
uniform mat4 projection, view, model;
|
|
||||||
uniform int hasTexture;
|
|
||||||
uniform vec3 cameraPos;
|
|
||||||
|
|
||||||
out vec3 outPosition, outColor, outNormal, outUV;
|
|
||||||
out vec3 outFragPos, outViewPos, outCameraPos;
|
|
||||||
flat out int outHasTexture;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
// projection * view * model * position
|
|
||||||
outPosition = inPosition;
|
|
||||||
outColor = inColor;
|
|
||||||
outNormal= normalize(transpose(inverse(mat3(model))) * inNormal);
|
|
||||||
outUV = inUV;
|
|
||||||
outHasTexture = hasTexture;
|
|
||||||
outCameraPos = cameraPos;
|
|
||||||
|
|
||||||
outFragPos = vec3(model * vec4(inPosition, 1.0));
|
|
||||||
|
|
||||||
gl_Position = projection * view * model * vec4(inPosition, 1.0);
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#version 330 core
|
|
||||||
@include "light_struct"
|
|
||||||
|
|
||||||
layout (location = 0) in vec3 inPosition;
|
|
||||||
layout (location = 1) in vec2 inTexCoords;
|
|
||||||
|
|
||||||
uniform sampler2D diffuse, position, texcoord, normal, depth;
|
|
||||||
uniform Light light[1];
|
|
||||||
|
|
||||||
out vec2 outTexCoords;
|
|
||||||
flat out Light outLight[1];
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(inPosition.x, inPosition.y, inPosition.z, 1.0);
|
|
||||||
outTexCoords = inTexCoords;
|
|
||||||
outLight = light;
|
|
||||||
}
|
|
||||||
BIN
static/icons/settings_audio.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/icons/settings_controls.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
static/icons/settings_display.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/icons/settings_graphics.png
Normal file
|
After Width: | Height: | Size: 952 B |
BIN
static/icons/settings_multiplayer.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
static/sounds/title_screen.ogg
Normal file
BIN
static/sounds/ui_hover.ogg
Normal file
114
svg/icons/settings_audio.svg
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 33.866666 33.866668"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
sodipodi:docname="settings_audio.svg"
|
||||||
|
inkscape:export-filename="C:\Users\cyber\Code\i-mic-fps\static\icons\settings_audio.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.6568542"
|
||||||
|
inkscape:cx="59.160271"
|
||||||
|
inkscape:cy="53.794164"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid833"
|
||||||
|
empspacing="8" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="2.1166666,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide837" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,31.750001"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide839" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="31.749999,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide841" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="19.05,2.1166667"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide843" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,27.516668"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide855" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,16.933334"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide857" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:#deddda;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 16.933333,8.4666671 12.7,10.583333 H 6.3500001 4.2333333 L 2.1166666,12.7 l 1e-7,8.466667 2.1166668,2.116667 H 12.7 l 4.233333,2.116667 H 19.05 l 0,-16.9333339 z"
|
||||||
|
id="path863"
|
||||||
|
sodipodi:nodetypes="cccccccccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1.05833334;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 21.166667,8.4666669 C 25.4,12.7 25.4,21.166667 21.166667,25.400001"
|
||||||
|
id="path865"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1.05833334;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 23.283334,8.4666667 c 4.233333,4.2333333 4.233333,12.7000003 0,16.9333343"
|
||||||
|
id="path865-8"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1.05833334;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 25.4,8.4666667 C 29.633333,12.7 29.633333,21.166667 25.4,25.400001"
|
||||||
|
id="path865-6"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="M 16.933333,8.4666671 V 25.400001"
|
||||||
|
id="path896" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
127
svg/icons/settings_controls.svg
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 33.866666 33.866668"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
sodipodi:docname="settings_controls.svg"
|
||||||
|
inkscape:export-filename="C:\Users\cyber\Code\i-mic-fps\static\icons\settings_controls.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.6568542"
|
||||||
|
inkscape:cx="59.417753"
|
||||||
|
inkscape:cy="46.567825"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:snap-intersection-paths="false"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:bbox-paths="true"
|
||||||
|
inkscape:snap-bbox-edge-midpoints="true">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid833"
|
||||||
|
empspacing="8" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="2.1166666,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide837" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,31.750001"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide839" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="31.749999,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide841" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="19.05,2.1166667"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide843" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,27.516668"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide855" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,16.933334"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide857" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#deddda;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect898"
|
||||||
|
width="19.050001"
|
||||||
|
height="12.700001"
|
||||||
|
x="2.1166668"
|
||||||
|
y="10.583334"
|
||||||
|
rx="1.058336"
|
||||||
|
ry="1.0583334" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#deddda;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="path900"
|
||||||
|
cx="27.516666"
|
||||||
|
cy="17.197916"
|
||||||
|
rx="3.9245155"
|
||||||
|
ry="6.3499994" />
|
||||||
|
<rect
|
||||||
|
style="fill:#deddda;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect902"
|
||||||
|
width="12.964583"
|
||||||
|
height="1.5875001"
|
||||||
|
x="4.2333336"
|
||||||
|
y="20.902084"
|
||||||
|
rx="1.102295e-06"
|
||||||
|
ry="1.0583334" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="m 24.077084,14.816667 h 6.879167"
|
||||||
|
id="path904" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="m 27.516667,10.847917 v 3.96875"
|
||||||
|
id="path906" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.0 KiB |
113
svg/icons/settings_display.svg
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 33.866666 33.866668"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
sodipodi:docname="settings_display.svg"
|
||||||
|
inkscape:export-filename="C:\Users\cyber\Code\i-mic-fps\static\icons\settings_display.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="4"
|
||||||
|
inkscape:cx="38.887284"
|
||||||
|
inkscape:cy="53.219323"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid833"
|
||||||
|
empspacing="8" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="2.1166666,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide837" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,31.750001"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide839" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="31.749999,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide841" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="19.05,2.1166667"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide843" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,27.516668"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide855" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,16.933334"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide857" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:#deddda;stroke:#000000;stroke-width:0.52916667;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="m 16.933334,23.283334 -4.233334,0 -6.3499999,6.35 H 27.516667 l -6.35,-6.35 z"
|
||||||
|
id="path853"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c0bfbc;stroke-width:0.52916667;stroke:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-linejoin:round;stroke-linecap:round"
|
||||||
|
id="rect845"
|
||||||
|
width="29.633331"
|
||||||
|
height="16.933334"
|
||||||
|
x="2.1166668"
|
||||||
|
y="6.3499999"
|
||||||
|
ry="2.1166663"
|
||||||
|
rx="2.1166663" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;stroke-width:1.05833"
|
||||||
|
id="rect849"
|
||||||
|
width="25.400002"
|
||||||
|
height="12.700001"
|
||||||
|
x="4.2333336"
|
||||||
|
y="8.4666672"
|
||||||
|
ry="1.4885254e-06"
|
||||||
|
rx="1.4885254e-06" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
103
svg/icons/settings_graphics.svg
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 33.866666 33.866668"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
sodipodi:docname="settings_graphics.svg"
|
||||||
|
inkscape:export-filename="C:\Users\cyber\Code\i-mic-fps\static\icons\settings_graphics.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="2.8284271"
|
||||||
|
inkscape:cx="40.619584"
|
||||||
|
inkscape:cy="57.766917"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid833"
|
||||||
|
empspacing="8" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="2.1166666,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide837" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,31.750001"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide839" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="31.749999,16.933334"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide841" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="19.05,2.1166667"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide843" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,27.516668"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide855" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="16.933333,16.933334"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide857" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:#f6f5f4;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 31.750001,10.583333 -8.466667,6.35 L 31.750001,25.4 Z"
|
||||||
|
id="path861" />
|
||||||
|
<rect
|
||||||
|
style="fill:#deddda;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect859"
|
||||||
|
width="23.283335"
|
||||||
|
height="14.816667"
|
||||||
|
x="2.1166666"
|
||||||
|
y="10.583333"
|
||||||
|
rx="1.058336"
|
||||||
|
ry="1.0583334" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.1 KiB |
121
svg/icons/settings_multiplayer.svg
Normal file
|
After Width: | Height: | Size: 11 KiB |