Added rocket launcher

master
Marc Gilleron 2020-08-17 20:16:08 +01:00
parent 64bb77bbc2
commit 4df06b6637
25 changed files with 1681 additions and 37 deletions

View File

@ -21,3 +21,6 @@ class BaseInfo:
var base_info := BaseInfo.new()
func place(_voxel_tool: VoxelTool, _pos: Vector3, _look_dir: Vector3):
pass

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=16 format=2]
[gd_scene load_steps=17 format=2]
[ext_resource path="res://blocky_game/blocks/voxel_library.tres" type="VoxelLibrary" id=1]
[ext_resource path="res://blocky_game/blocks/terrain_material.tres" type="Material" id=2]
@ -12,6 +12,7 @@
[ext_resource path="res://blocky_game/random_ticks.gd" type="Script" id=10]
[ext_resource path="res://blocky_game/water.gd" type="Script" id=11]
[ext_resource path="res://blocky_game/blocks/blocks.gd" type="Script" id=12]
[ext_resource path="res://blocky_game/items/item_db.gd" type="Script" id=13]
[sub_resource type="ProceduralSky" id=1]
sky_top_color = Color( 0.268204, 0.522478, 0.847656, 1 )
@ -51,6 +52,9 @@ script = ExtResource( 5 )
[node name="Blocks" type="Node" parent="."]
script = ExtResource( 12 )
[node name="Items" type="Node" parent="."]
script = ExtResource( 13 )
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource( 2 )

View File

@ -26,12 +26,16 @@ func _ready():
# Initial contents
var hotbar_begin_index := BAG_WIDTH * BAG_HEIGHT
var hotbar_block_ids := [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in BAG_WIDTH:
var item := InventoryItem.new()
item.type = InventoryItem.TYPE_BLOCK
item.id = hotbar_block_ids[i]
_slots[hotbar_begin_index + i] = item
_slots[hotbar_begin_index + 0] = _make_item(InventoryItem.TYPE_BLOCK, 1)
_slots[hotbar_begin_index + 1] = _make_item(InventoryItem.TYPE_BLOCK, 2)
_slots[hotbar_begin_index + 2] = _make_item(InventoryItem.TYPE_BLOCK, 3)
_slots[hotbar_begin_index + 3] = _make_item(InventoryItem.TYPE_BLOCK, 4)
_slots[hotbar_begin_index + 4] = _make_item(InventoryItem.TYPE_BLOCK, 5)
_slots[hotbar_begin_index + 5] = _make_item(InventoryItem.TYPE_BLOCK, 6)
_slots[hotbar_begin_index + 6] = _make_item(InventoryItem.TYPE_BLOCK, 7)
_slots[hotbar_begin_index + 7] = _make_item(InventoryItem.TYPE_ITEM, 0)
_slots[hotbar_begin_index + 8] = _make_item(InventoryItem.TYPE_BLOCK, 9)
_slots[0] = _make_item(InventoryItem.TYPE_BLOCK, 8)
# Init views
var slot_idx := 0
@ -45,6 +49,13 @@ func _ready():
slot_idx += 1
static func _make_item(type, id):
var i = InventoryItem.new()
i.id = id
i.type = type
return i
func _update_views():
var slot_idx := 0
for container in [_bag_container, _hotbar_container]:

View File

@ -1,10 +1,11 @@
extends TextureRect
const InventoryItem = preload("res://blocky_game/player/inventory_item.gd")
const DefaultTexture = preload("res://icon.png")
const Blocks = preload("../blocks/blocks.gd")
const ItemDB = preload("../items/item_db.gd")
onready var _block_types : Blocks = get_node("/root/Main/Blocks")
onready var _item_db : ItemDB = get_node("/root/Main/Items")
func set_item(data: InventoryItem):
@ -16,8 +17,8 @@ func set_item(data: InventoryItem):
texture = block.base_info.sprite_texture
elif data.type == InventoryItem.TYPE_ITEM:
# TODO Items db
texture = DefaultTexture
var item := _item_db.get_item(data.id)
texture = item.base_info.sprite
else:
assert(false)

View File

@ -0,0 +1,15 @@
extends Node
class BaseInfo:
var id := 0
var name := ""
var sprite : Texture
var base_info := BaseInfo.new()
func use(_trans: Transform):
pass

View File

@ -0,0 +1,38 @@
extends Node
const ROOT = "res://blocky_game/items"
const Item = preload("./item.gd")
var _items := []
func _init():
_create_item({
"name": "rocket_launcher",
"behavior": "rocket_launcher.gd"
})
func get_item(id: int) -> Item:
assert(id >= 0)
return _items[id]
func _create_item(d: Dictionary):
var dir = str(ROOT, "/", d.name, "/")
var item : Item
if d.has("behavior"):
var behavior_script = load(str(dir, d.name, ".gd"))
item = behavior_script.new()
else:
item = Item.new()
var base_info = item.base_info
base_info.id = len(_items)
base_info.name = d.name
base_info.sprite = load(str(dir, d.name, "_sprite.png"))
_items.append(item)
add_child(item)

View File

@ -0,0 +1,51 @@
extends Spatial
const GRAVITY = Vector3(0, -14, 0)
const LIFETIME = 3.0
onready var _mesh_instance = $MeshInstance
onready var _terrain : VoxelTerrain = get_node("/root/Main/VoxelTerrain")
onready var _terrain_tool := _terrain.get_voxel_tool()
var _velocity := Vector3()
var _rotation_axis := Vector3()
var _angular_velocity := 4.0 * TAU * rand_range(-1.0, 1.0)
var _remaining_time := rand_range(0.5, 1.5) * LIFETIME
func _ready():
rotation = Vector3(rand_range(-PI, PI), rand_range(-PI, PI), rand_range(-PI, PI))
scale = Vector3(rand_range(0.5, 1.5), rand_range(0.5, 1.5), rand_range(0.5, 1.5))
_rotation_axis = \
Vector3(rand_range(-PI, PI), rand_range(-PI, PI), rand_range(-PI, PI)).normalized()
func set_velocity(vel: Vector3):
_velocity = vel
func _process(delta: float):
_remaining_time -= delta
if _remaining_time <= 0:
queue_free()
return
_velocity += GRAVITY * delta
var trans := transform
trans.basis = trans.basis.rotated(_rotation_axis, _angular_velocity * delta)
var motion := _velocity * delta
var hit := _terrain_tool.raycast(trans.origin, motion.normalized(), motion.length() * 1.01)
if hit != null:
# BOUNCE
var normal = hit.previous_position - hit.position
_velocity = _velocity.bounce(normal)
# Damp on impact
_velocity *= 0.5
_angular_velocity *= 0.5
trans.origin += _velocity * delta
transform = trans

View File

@ -0,0 +1,16 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://blocky_game/items/rocket_launcher/debris.gd" type="Script" id=1]
[sub_resource type="CubeMesh" id=1]
size = Vector3( 0.3, 0.3, 0.3 )
[sub_resource type="SpatialMaterial" id=2]
albedo_color = Color( 0.458824, 0.266667, 0.0980392, 1 )
[node name="Debris" type="Spatial"]
script = ExtResource( 1 )
[node name="MeshInstance" type="MeshInstance" parent="."]
mesh = SubResource( 1 )
material/0 = SubResource( 2 )

View File

@ -0,0 +1,55 @@
extends Spatial
const LIFETIME = 10.0
const DebrisScene = preload("./debris.tscn")
const ExplosionScene = preload("./rocket_explosion.tscn")
onready var _terrain : VoxelTerrain = get_node("../VoxelTerrain")
onready var _terrain_tool := _terrain.get_voxel_tool()
var _direction := Vector3(0, 0, 1)
var _speed := 20.0
var _remaining_time := LIFETIME
func set_direction(direction: Vector3):
assert(is_inside_tree())
direction += Vector3(0.0001, 0.0001, 0.001) # Haaaaak
_direction = direction.normalized()
look_at(global_transform.origin + _direction, Vector3(0, 1, 0))
func _physics_process(delta: float):
_remaining_time -= delta
if _remaining_time <= 0:
queue_free()
return
var trans = global_transform
var crossed_distance := _speed * delta
var motion := crossed_distance * _direction
var hit = _terrain_tool.raycast(trans.origin, _direction, crossed_distance)
if hit != null:
# EXPLODE
_terrain_tool.do_sphere(hit.position, 4.0)
var explosion = ExplosionScene.instance()
explosion.translation = trans.origin
get_parent().add_child(explosion)
# Create debris
for i in 30:
var debris = DebrisScene.instance()
var debris_velocity := \
Vector3(rand_range(-1, 1), rand_range(-1, 1), rand_range(-1, 1)).normalized()
debris_velocity *= rand_range(5.0, 30.0)
debris.set_velocity(debris_velocity)
debris.translation = trans.origin
get_parent().add_child(debris)
queue_free()
else:
trans.origin += motion
global_transform = trans

View File

@ -0,0 +1,17 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://blocky_game/items/rocket_launcher/rocket.gd" type="Script" id=1]
[sub_resource type="CylinderMesh" id=1]
top_radius = 0.1
bottom_radius = 0.3
height = 1.0
radial_segments = 8
[node name="Rocket" type="Spatial"]
script = ExtResource( 1 )
[node name="MeshInstance" type="MeshInstance" parent="."]
transform = Transform( -1, -3.25841e-07, 5.30863e-14, 0, -1.62921e-07, -1, 3.25841e-07, -1, 1.62921e-07, 0, 0, 0 )
mesh = SubResource( 1 )
material/0 = null

View File

@ -0,0 +1,11 @@
extends Spatial
onready var _particles = $Particles
func _ready():
_particles.emitting = true
func _on_Timer_timeout():
queue_free()

View File

@ -0,0 +1,64 @@
[gd_scene load_steps=10 format=2]
[ext_resource path="res://blocky_game/items/rocket_launcher/smoke_particle.png" type="Texture" id=1]
[ext_resource path="res://blocky_game/items/rocket_launcher/rocket_explosion.gd" type="Script" id=2]
[sub_resource type="SpatialMaterial" id=1]
flags_transparent = true
vertex_color_use_as_albedo = true
params_billboard_mode = 3
particles_anim_h_frames = 1
particles_anim_v_frames = 1
particles_anim_loop = false
albedo_texture = ExtResource( 1 )
[sub_resource type="Gradient" id=2]
colors = PoolColorArray( 1, 1, 1, 1, 1, 1, 1, 0 )
[sub_resource type="GradientTexture" id=3]
gradient = SubResource( 2 )
width = 64
[sub_resource type="Curve" id=6]
_data = [ Vector2( 0, 0.364035 ), 0.0, 6.99055, 0, 0, Vector2( 0.0810811, 0.723684 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.399123 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=7]
curve = SubResource( 6 )
[sub_resource type="ParticlesMaterial" id=4]
render_priority = -1
direction = Vector3( 0, 1, 0 )
spread = 170.0
gravity = Vector3( 0, 1, 0 )
initial_velocity = 10.0
initial_velocity_random = 0.51
linear_accel = -6.0
scale = 10.0
scale_random = 0.39
scale_curve = SubResource( 7 )
color_ramp = SubResource( 3 )
[sub_resource type="QuadMesh" id=5]
[node name="RocketExplosion" type="Spatial"]
script = ExtResource( 2 )
[node name="Particles" type="Particles" parent="."]
material_override = SubResource( 1 )
emitting = false
amount = 15
lifetime = 2.0
one_shot = true
explosiveness = 0.95
process_material = SubResource( 4 )
draw_pass_1 = SubResource( 5 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 1, 0, 0, 0, 0.790016, 0.613086, 0, -0.613086, 0.790016, 0, 3.14598, 4.16366 )
editor_only = true
[node name="Timer" type="Timer" parent="."]
wait_time = 3.0
autostart = true
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]

View File

@ -0,0 +1,15 @@
extends "../item.gd"
const RocketScene = preload("./rocket.tscn")
onready var _world = get_node("/root/Main")
func use(trans: Transform):
var rocket = RocketScene.instance()
rocket.translation = trans.origin
_world.add_child(rocket)
print("Launch rocket at ", rocket.translation)
var forward = -trans.basis.z.normalized()
rocket.set_direction(forward)

View File

@ -0,0 +1,145 @@
{
"asset" : {
"generator" : "Khronos glTF Blender I/O v1.2.75",
"version" : "2.0"
},
"scene" : 0,
"scenes" : [
{
"name" : "Scene",
"nodes" : [
0
]
}
],
"nodes" : [
{
"mesh" : 0,
"name" : "RocketLauncher",
"rotation" : [
0,
0.19509032368659973,
0,
0.9807852506637573
]
}
],
"materials" : [
{
"doubleSided" : true,
"emissiveFactor" : [
0,
0,
0
],
"name" : "rocket_launcher_mat",
"pbrMetallicRoughness" : {
"baseColorTexture" : {
"index" : 0,
"texCoord" : 0
},
"metallicFactor" : 0,
"roughnessFactor" : 1
}
}
],
"meshes" : [
{
"name" : "Cylinder.001",
"primitives" : [
{
"attributes" : {
"POSITION" : 0,
"NORMAL" : 1,
"TEXCOORD_0" : 2
},
"indices" : 3,
"material" : 0
}
]
}
],
"textures" : [
{
"sampler" : 0,
"source" : 0
}
],
"images" : [
{
"mimeType" : "image/png",
"name" : "rocket_launcher",
"uri" : "rocket_launcher.png"
}
],
"accessors" : [
{
"bufferView" : 0,
"componentType" : 5126,
"count" : 358,
"max" : [
0.49119770526885986,
0.34520694613456726,
1.5060045719146729
],
"min" : [
-0.8064760565757751,
-0.6934827566146851,
-0.9066932797431946
],
"type" : "VEC3"
},
{
"bufferView" : 1,
"componentType" : 5126,
"count" : 358,
"type" : "VEC3"
},
{
"bufferView" : 2,
"componentType" : 5126,
"count" : 358,
"type" : "VEC2"
},
{
"bufferView" : 3,
"componentType" : 5123,
"count" : 516,
"type" : "SCALAR"
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteLength" : 4296,
"byteOffset" : 0
},
{
"buffer" : 0,
"byteLength" : 4296,
"byteOffset" : 4296
},
{
"buffer" : 0,
"byteLength" : 2864,
"byteOffset" : 8592
},
{
"buffer" : 0,
"byteLength" : 1032,
"byteOffset" : 11456
}
],
"samplers" : [
{
"magFilter" : 9728,
"minFilter" : 9984
}
],
"buffers" : [
{
"byteLength" : 12488,
"uri" : "rocket_launcher.bin"
}
]
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -0,0 +1,36 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/rocket_launcher.png-39a62c94360c7e30fde0ee1247cbcd43.s3tc.stex"
path.etc2="res://.import/rocket_launcher.png-39a62c94360c7e30fde0ee1247cbcd43.etc2.stex"
metadata={
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
source_file="res://blocky_game/items/rocket_launcher/rocket_launcher.png"
dest_files=[ "res://.import/rocket_launcher.png-39a62c94360c7e30fde0ee1247cbcd43.s3tc.stex", "res://.import/rocket_launcher.png-39a62c94360c7e30fde0ee1247cbcd43.etc2.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@ -0,0 +1,5 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://blocky_game/items/rocket_launcher/rocket_launcher.gltf" type="PackedScene" id=1]
[node name="RocketLauncher" instance=ExtResource( 1 )]

View File

@ -0,0 +1,13 @@
[gd_resource type="SpatialMaterial" load_steps=2 format=2]
[ext_resource path="res://blocky_game/items/rocket_launcher/rocket_launcher.png" type="Texture" id=1]
[resource]
resource_name = "rocket_launcher_mat"
params_cull_mode = 2
albedo_texture = ExtResource( 1 )
emission_enabled = true
emission = Color( 0, 0, 0, 1 )
emission_energy = 1.0
emission_operator = 0
emission_on_uv2 = false

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/rocket_launcher_sprite.png-16646f5a50978a86494ee5643a399252.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://blocky_game/items/rocket_launcher/rocket_launcher_sprite.png"
dest_files=[ "res://.import/rocket_launcher_sprite.png-16646f5a50978a86494ee5643a399252.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -0,0 +1,36 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/smoke_particle.png-fb3550ba61ffc8fc9954e15c5a87c644.s3tc.stex"
path.etc2="res://.import/smoke_particle.png-fb3550ba61ffc8fc9954e15c5a87c644.etc2.stex"
metadata={
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
source_file="res://blocky_game/items/rocket_launcher/smoke_particle.png"
dest_files=[ "res://.import/smoke_particle.png-fb3550ba61ffc8fc9954e15c5a87c644.s3tc.stex", "res://.import/smoke_particle.png-fb3550ba61ffc8fc9954e15c5a87c644.etc2.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@ -2,7 +2,9 @@ extends Node
const Util = preload("res://common/util.gd")
const Blocks = preload("../blocks/blocks.gd")
const ItemDB = preload("../items/item_db.gd")
const InventoryItem = preload("./inventory_item.gd")
const Hotbar = preload("../gui/hotbar/hotbar.gd")
const COLLISION_LAYER_AVATAR = 2
@ -23,15 +25,16 @@ export(Material) var cursor_material = null
# TODO Eventually invert these dependencies
onready var _head : Camera = get_parent().get_node("Camera")
onready var _hotbar = get_node("../HotBar")
onready var _hotbar : Hotbar = get_node("../HotBar")
onready var _block_types : Blocks = get_node("/root/Main/Blocks")
onready var _item_db : ItemDB = get_node("/root/Main/Items")
onready var _water_updater = get_node("../../Water")
var _terrain = null
var _terrain_tool = null
var _cursor = null
var _action_place = false
var _action_remove = false
var _action_use = false
var _action_pick = false
@ -62,7 +65,7 @@ func _get_pointed_voxel():
return hit
func _physics_process(delta):
func _physics_process(_delta):
if _terrain == null:
return
@ -74,34 +77,42 @@ func _physics_process(delta):
else:
_cursor.hide()
DDD.set_text("Pointed voxel", "---")
var inv_item := _hotbar.get_selected_item()
# These inputs have to be in _fixed_process because they rely on collision queries
if hit != null:
if inv_item == null or inv_item.type == InventoryItem.TYPE_BLOCK:
if hit != null:
var hit_raw_id = _terrain_tool.get_voxel(hit.position)
var has_cube = hit_raw_id != 0
if _action_use and has_cube:
var pos = hit.position
_place_single_block(pos, 0)
elif _action_place:
var pos = hit.previous_position
if has_cube == false:
pos = hit.position
if _can_place_voxel_at(pos):
if inv_item != null:
_place_single_block(pos, inv_item.id)
print("Place voxel at ", pos)
else:
print("Can't place here!")
elif inv_item.type == InventoryItem.TYPE_ITEM:
if _action_use:
var item = _item_db.get_item(inv_item.id)
item.use(_head.global_transform)
if _action_pick and hit != null:
var hit_raw_id = _terrain_tool.get_voxel(hit.position)
var has_cube = hit_raw_id != 0
if _action_remove and has_cube:
var pos = hit.position
_place_single_block(pos, 0)
elif _action_place:
var pos = hit.previous_position
if has_cube == false:
pos = hit.position
if _can_place_voxel_at(pos):
var item = _hotbar.get_selected_item()
if item != null and item.type == InventoryItem.TYPE_BLOCK:
_place_single_block(pos, item.id)
print("Place voxel at ", pos)
else:
print("Can't place here!")
elif _action_pick:
var rm := _block_types.get_raw_mapping(hit_raw_id)
_hotbar.try_select_slot_by_block_id(rm.block_id)
var rm := _block_types.get_raw_mapping(hit_raw_id)
_hotbar.try_select_slot_by_block_id(rm.block_id)
_action_place = false
_action_remove = false
_action_use = false
_action_pick = false
@ -110,7 +121,7 @@ func _unhandled_input(event):
if event.pressed:
match event.button_index:
BUTTON_LEFT:
_action_remove = true
_action_use = true
BUTTON_RIGHT:
_action_place = true
BUTTON_MIDDLE: