mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 07:32:35 +00:00
Fixed AssetViewer crashing when loading a scripted asset
This commit is contained in:
@@ -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,7 +63,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
position_camera
|
position_camera if @entity
|
||||||
|
|
||||||
return unless @mouse_captured
|
return unless @mouse_captured
|
||||||
|
|
||||||
@@ -74,8 +74,10 @@ class IMICFPS
|
|||||||
@camera.orientation.x -= Float(@true_mouse.y - window.mouse_y) / (@mouse_sensitivity * @camera.field_of_view) * 70
|
@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)
|
@camera.orientation.x = @camera.orientation.x.clamp(-90.0, 90.0)
|
||||||
|
|
||||||
@entity.orientation.y += delta
|
if @entity
|
||||||
@entity.orientation.y %= 360.0
|
@entity.orientation.y += delta
|
||||||
|
@entity.orientation.y %= 360.0
|
||||||
|
end
|
||||||
|
|
||||||
window.mouse_x = window.width / 2 if window.mouse_x <= 1 || window.mouse_x >= window.width - 1
|
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
|
window.mouse_y = window.height / 2 if window.mouse_y <= 1 || window.mouse_y >= window.height - 1
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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_shadow: true, text_shadow_color: Gosu::Color::BLACK
|
||||||
label @manifest.model
|
label @manifest.model, text_shadow: true, text_shadow_color: Gosu::Color::BLACK
|
||||||
@camera_position = label ""
|
@camera_position = label "", text_shadow: true, text_shadow_color: Gosu::Color::BLACK
|
||||||
@camera_orientation = label ""
|
@camera_orientation = label "", text_shadow: true, text_shadow_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
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ class IMICFPS
|
|||||||
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)
|
||||||
|
|||||||
30
maps/model_viewer.json
Normal file
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user