diff --git a/assets/base/alternate_tank/manifest.yaml b/assets/base/alternate_tank/manifest.yaml index d74da7c..1dd6fd6 100644 --- a/assets/base/alternate_tank/manifest.yaml +++ b/assets/base/alternate_tank/manifest.yaml @@ -1,2 +1,5 @@ name: "Alternate Tank" -model: "alternate_tank.obj" \ No newline at end of file +model: "alternate_tank.obj" +scripts: [ + "vehicle" +] \ No newline at end of file diff --git a/assets/base/alternate_tank/scripts/vehicle.rb b/assets/base/alternate_tank/scripts/vehicle.rb new file mode 100644 index 0000000..cbe4fb2 --- /dev/null +++ b/assets/base/alternate_tank/scripts/vehicle.rb @@ -0,0 +1,9 @@ +context Vehicle # Generic, Weapon + +on.button_down(:interact) do |event| + if event.player.touching?(event.entity) + event.player.enter_vehicle + elsif event.player.driving?(event.entity) or event.player.passenger?(event.entity) + event.player.exit_vehicle + end +end \ No newline at end of file diff --git a/assets/base/power_plant/manifest.yaml b/assets/base/power_plant/manifest.yaml index a594f80..c704838 100644 --- a/assets/base/power_plant/manifest.yaml +++ b/assets/base/power_plant/manifest.yaml @@ -2,10 +2,16 @@ name: "power_plant" model: "power_plant.obj" collision: "mesh" collision_mesh: null # Use model mesh for collision detection +scripts: [ + "power_plant" +] uses: - package: "base" - model: "purchase_terminal" + name: "purchase_terminal" - package: "base" - model: "information_panel" \ No newline at end of file + name: "information_panel" + - + package: "base" + name: "door" \ No newline at end of file diff --git a/assets/base/power_plant/scripts/power_plant.rb b/assets/base/power_plant/scripts/power_plant.rb new file mode 100644 index 0000000..4459ddd --- /dev/null +++ b/assets/base/power_plant/scripts/power_plant.rb @@ -0,0 +1,8 @@ +context Building + +on.create do |event| + map.add_entity("base", "purchase_terminal", Vector.new(0, 1.5, 0), Vector.new(0, 90, 0), data: {team: event.entity.team}) + map.add_entity("base", "information_panel", Vector.new(2, 1.5, 0), Vector.new(0, 0, 0)) + map.add_entity("base", "door", Vector.new(2, 0, 6), Vector.new(0, 0, 0)) + map.add_entity("base", "door", Vector.new(2, 0, 6), Vector.new(0, 180, 0)) +end \ No newline at end of file diff --git a/lib/game_objects/camera.rb b/lib/game_objects/camera.rb index 3bd607f..d867726 100644 --- a/lib/game_objects/camera.rb +++ b/lib/game_objects/camera.rb @@ -91,6 +91,7 @@ class IMICFPS if @entity @entity.orientation.y += delta + @entity.orientation.y %= 360.0 position_camera else free_move diff --git a/lib/game_objects/entities/player.rb b/lib/game_objects/entities/player.rb index b46e11a..589ff5e 100644 --- a/lib/game_objects/entities/player.rb +++ b/lib/game_objects/entities/player.rb @@ -7,7 +7,7 @@ class IMICFPS attr_reader :name, :bound_model, :first_person_view def setup - bind_model("base", "biped") + bind_model @collision = :dynamic @physics = true diff --git a/lib/game_objects/entity.rb b/lib/game_objects/entity.rb index 6937739..112266f 100644 --- a/lib/game_objects/entity.rb +++ b/lib/game_objects/entity.rb @@ -17,7 +17,7 @@ class IMICFPS @backface_culling = backface_culling @name = @manifest.name - @bound_model = map_entity ? bind_model(map_entity.package, map_entity.model) : nil + @bound_model = map_entity ? bind_model : nil @visible = true @renderable = true @@ -32,7 +32,7 @@ class IMICFPS # :static => does not move ever, # :none => no collision check, entities can pass through @collision = :static - @physics = false # Entity affected by gravity and what not + @physics = @manifest.physics # Entity affected by gravity and what not @mass = 100 # kg @delta_time = Gosu.milliseconds @@ -56,7 +56,7 @@ class IMICFPS @collidable.include?(@collision) end - def bind_model(package, name) + def bind_model model = ModelLoader.new(manifest: @manifest, entity: @dummy_entity) raise "model isn't a model!" unless model.is_a?(ModelLoader) diff --git a/lib/manifest.rb b/lib/manifest.rb index bf6fa3f..6ada404 100644 --- a/lib/manifest.rb +++ b/lib/manifest.rb @@ -1,17 +1,19 @@ class IMICFPS class Manifest - attr_reader :name, :model, :collision, :collision_mesh, :scripts, :uses - def initialize(manifest_file: nil, package: nil, model: nil) + attr_reader :name, :model, :collision, :collision_mesh, :physics, :scripts, :uses + def initialize(manifest_file: nil, package: nil, name: nil) unless manifest_file raise "Entity package not specified!" unless package - raise "Entity model not specified!" unless model - manifest_file = "#{IMICFPS.assets_path}/#{package}/#{model}/manifest.yaml" + raise "Entity name not specified!" unless name + manifest_file = "#{IMICFPS.assets_path}/#{package}/#{name}/manifest.yaml" end raise "No manifest found at: #{manifest_file}" unless File.exist?(manifest_file) @file = manifest_file parse(manifest_file) + + pp @scripts end def parse(file) @@ -24,12 +26,34 @@ class IMICFPS # optional @collision = data["collision"] ? data["collision"] : nil @collision_mesh = data["collision_mesh"] ? data["collision_mesh"] : nil - @scripts = data["scripts"] ? data["scripts"] : [] - @uses = data["uses"] ? data["uses"] : [] # List of entities that this Entity uses + @physics = data["physics"] ? data["physics"] : false + @scripts = data["scripts"] ? parse_scripts(data["scripts"]) : [] + @uses = data["uses"] ? parse_dependencies(data["uses"]) : [] # List of entities that this Entity uses + end + + def parse_scripts(scripts) + list = [] + scripts.each do |script| + list << Script.new(script, File.read("#{file_path}/scripts/#{script}.rb")) + end + + return list + end + + def parse_dependencies(list) + dependencies = [] + list.each do |item| + dependencies << Dependency.new(item["package"], item["name"]) + end + + return dependencies end def file_path File.expand_path("./../", @file) end + + Script = Struct.new(:name, :source) + Dependency = Struct.new(:package, :name) end end \ No newline at end of file diff --git a/lib/map.rb b/lib/map.rb index 7506370..a356093 100644 --- a/lib/map.rb +++ b/lib/map.rb @@ -31,7 +31,7 @@ class IMICFPS if section = data["terrain"] @terrain.package = section["package"] - @terrain.model = section["model"] + @terrain.name = section["name"] @terrain.position = Vector.new @terrain.orientation = Vector.new if section["scale"] @@ -55,7 +55,7 @@ class IMICFPS if section = data["skydome"] @skydome.package = section["package"] - @skydome.model = section["model"] + @skydome.name = section["name"] @skydome.position = Vector.new @skydome.orientation = Vector.new if section["scale"] @@ -80,7 +80,7 @@ class IMICFPS section.each do |ent| entity = Map::Entity.new entity.package = ent["package"] - entity.model = ent["model"] + entity.name = ent["name"] entity.position = Vector.new( ent["position"]["x"], ent["position"]["y"], @@ -132,7 +132,7 @@ class IMICFPS end MetaData = Struct.new(:name, :gamemode, :authors, :datetime, :thumbnail, :description) - Entity = Struct.new(:package, :model, :position, :orientation, :scale, :water_level, :scripts) + Entity = Struct.new(:package, :name, :position, :orientation, :scale, :water_level, :scripts) SpawnPoint = Struct.new(:team, :position, :orientation) end end \ No newline at end of file diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index 478afd2..f4b9c10 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -6,17 +6,17 @@ class IMICFPS @collision_manager = CollisionManager.new(game_state: self) @renderer = Renderer.new(game_state: self) @map = @options[:map] - add_entity(Terrain.new(map_entity: @map.terrain, manifest: Manifest.new(package: @map.terrain.package, model: @map.terrain.model))) + add_entity(Terrain.new(map_entity: @map.terrain, manifest: Manifest.new(package: @map.terrain.package, name: @map.terrain.name))) @draw_skydome = true - @skydome = Skydome.new(map_entity: @map.skydome, manifest: Manifest.new(package: @map.skydome.package, model: @map.skydome.model), backface_culling: false) + @skydome = Skydome.new(map_entity: @map.skydome, manifest: Manifest.new(package: @map.skydome.package, name: @map.skydome.name), backface_culling: false) add_entity(@skydome) @map.entities.each do |ent| - add_entity(Entity.new(map_entity: ent, manifest: Manifest.new(package: ent.package, model: ent.model))) + add_entity(Entity.new(map_entity: ent, manifest: Manifest.new(package: ent.package, name: ent.name))) end - @player = Player.new(spawnpoint: @map.spawnpoints.sample, manifest: Manifest.new(package: "base", model: "biped")) + @player = Player.new(spawnpoint: @map.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "biped")) add_entity(@player) @camera = Camera.new(position: @player.position.clone) @camera.attach_to(@player) diff --git a/lib/states/game_states/loading_state.rb b/lib/states/game_states/loading_state.rb index a932c14..8f00736 100644 --- a/lib/states/game_states/loading_state.rb +++ b/lib/states/game_states/loading_state.rb @@ -14,10 +14,10 @@ class IMICFPS @asset_index = 0 # add_asset(:shader, nil, "default") - add_asset(:model, @map.terrain.package, @map.terrain.model) - add_asset(:model, @map.skydome.package, @map.skydome.model) + add_asset(:model, @map.terrain.package, @map.terrain.name) + add_asset(:model, @map.skydome.package, @map.skydome.name) @map.entities.each do |entity| - add_asset(:model, entity.package, entity.model) + add_asset(:model, entity.package, entity.name) end add_asset(:model, "base", "biped") @@ -53,6 +53,7 @@ class IMICFPS case hash[:type] when :model manifest = Manifest.new(manifest_file: IMICFPS.assets_path + "/#{hash[:package]}/#{hash[:name]}/manifest.yaml") + add_required_assets(manifest) ModelLoader.new(manifest: manifest, entity: @dummy_entity) when :shader Shader.new(name: hash[:name], vertex: "shaders/vertex/#{hash[:name]}.glsl", fragment: "shaders/fragment/#{hash[:name]}.glsl") @@ -82,6 +83,15 @@ class IMICFPS @assets << {type: type, package: package, name: name} end + def add_required_assets(manifest) + manifest.uses.each do |dependency| + known = @assets.detect {|asset| asset[:package] == dependency.package && asset[:name] == dependency.name} + unless known + add_asset(:model, dependency.package, dependency.name) + end + end + end + def progressbar(x = window.width/4, y = window.height - 104) @percentage.draw progress = (@asset_index.to_f/@assets.count)*window.width/2 diff --git a/maps/test_map.json b/maps/test_map.json index 0445c52..2d8d532 100644 --- a/maps/test_map.json +++ b/maps/test_map.json @@ -10,20 +10,20 @@ "terrain":{ "package":"base", - "model":"river_terrain", + "name":"river_terrain", "water_level":null }, "skydome":{ "package":"base", - "model":"skydome", + "name":"skydome", "scale":0.08 }, "entities":[ { "package":"base", - "model":"tree", + "name":"tree", "position": { "x":0, "y":0.6, @@ -39,7 +39,7 @@ }, { "package":"base", - "model":"tree", + "name":"tree", "position": { "x":16.7, "y":1.1, @@ -55,7 +55,7 @@ }, { "package":"base", - "model":"tree", + "name":"tree", "position": { "x":-21.2121, "y":0.06, @@ -71,7 +71,7 @@ }, { "package":"base", - "model":"power_plant", + "name":"power_plant", "position": { "x":37.8788, "y":0.343869, @@ -87,7 +87,7 @@ }, { "package":"base", - "model":"purchase_terminal", + "name":"purchase_terminal", "position": { "x":37.8788, "y":1.843869, @@ -103,7 +103,7 @@ }, { "package":"base", - "model":"information_panel", + "name":"information_panel", "position": { "x":37.8788, "y":0.343869, @@ -119,7 +119,7 @@ }, { "package":"base", - "model":"door", + "name":"door", "position": { "x":37.8788, "y":0.343869, @@ -135,7 +135,7 @@ }, { "package":"base", - "model":"door", + "name":"door", "position": { "x":37.8788, "y":0.343869, @@ -151,7 +151,7 @@ }, { "package":"base", - "model":"war_factory", + "name":"war_factory", "position": { "x":39.3939, "y":0.499657, @@ -167,7 +167,7 @@ }, { "package":"base", - "model":"alternate_tank", + "name":"alternate_tank", "position": { "x":39.3939, "y":0.799657, @@ -200,13 +200,13 @@ { "team":1, "position": { - "x": 37.8788, - "y": 0.343869, - "z": -4.06061 + "x": 39.3939, + "y": 0.799657, + "z": 17.69697 }, "orientation": { "x": 0, - "y": 180, + "y": 0, "z": 0 } }