code upload

master
Alexsandro Percy 2020-05-03 15:50:48 -03:00
parent d1862715b9
commit 5fd7186e34
34 changed files with 745 additions and 2 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 APercy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
README.md Normal file → Executable file
View File

@ -1,2 +1,23 @@
# motorboat
Minetest Motorboat
Minetest 5.2 mod: Motorboat
========================================
This is the "Motorboat", an hybrid of "Not So Simple Helicopter" and "Sailing Kit".
It's water dynamics comes from Sailing Kit (by TheTermos). So it depends on mobkit. And It dependes on the biofuel mod for fuel making.
It starts anchored, so press sneak key to remove anchor. With keyboard you can move the boat. When you press jump, it starts the engine and you can navigate fast, but it consumes fuel. With engine off you use paddles. You can refuel only with the engine turned off. And you can set anchor by pressing sneak, but it only works when the boat is near completely stopped (when the anchor is sucessfull, you receive a message on chat).
It can be painted using dye of any color you want, you must punch the seat with the dye.
Biofuel mod can be found here: https://github.com/APercy/minetest_biofuel
-----------------------
It uses some code from Sailing Kit (by TheTermos)
License of source code:
MIT (see file LICENSE)
License of media (textures and sounds):
---------------------------------------
engine.ogg and collision.ogg by APercy. See License file
Boat model by APercy. See License file

3
depends.txt Normal file
View File

@ -0,0 +1,3 @@
mobkit
default
biofuel

530
init.lua Executable file
View File

@ -0,0 +1,530 @@
--
-- constants
--
local LONGIT_DRAG_FACTOR = 0.13*0.13
local LATER_DRAG_FACTOR = 2.0
local colors ={
black='#2b2b2b',
blue='#0063b0',
brown='#8c5922',
cyan='#07B6BC',
dark_green='#567a42',
dark_grey='#6d6d6d',
green='#4ee34c',
grey='#9f9f9f',
magenta='#ff0098',
orange='#ff8b0e',
pink='#ff62c6',
red='#dc1818',
violet='#a437ff',
white='#FFFFFF',
yellow='#ffe400',
}
dofile(minetest.get_modpath("motorboat") .. DIR_DELIM .. "motorboat_control.lua")
dofile(minetest.get_modpath("motorboat") .. DIR_DELIM .. "motorboat_fuel_management.lua")
last_time = minetest.get_us_time()
local random = math.random
--
-- helpers and co.
--
local creative_exists = minetest.global_exists("creative")
local function get_hipotenuse_value(point1, point2)
return math.sqrt((point1.x - point2.x) ^ 2 + (point1.y - point2.y) ^ 2 + (point1.z - point2.z) ^ 2)
end
local function dot(v1,v2)
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z
end
local function sign(n)
return n>=0 and 1 or -1
end
local function minmax(v,m)
return math.min(math.abs(v),m)*sign(v)
end
--painting
local function paint(self, colstr)
if colstr then
self.color = colstr
local l_textures = self.initial_properties.textures
for _, texture in ipairs(l_textures) do
local i,indx = texture:find('motorboat_painting.png')
if indx then
l_textures[_] = "motorboat_painting.png^[multiply:".. colstr
end
end
self.object:set_properties({textures=l_textures})
end
end
-- destroy the boat
local function destroy(self)
if self.sound_handle then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
if self.driver_name then
-- detach the driver first (puncher must be driver)
puncher:set_detach()
puncher:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
player_api.player_attached[name] = nil
-- player should stand again
player_api.set_animation(puncher, "stand")
self.driver_name = nil
end
local pos = self.object:get_pos()
if self.pointer then self.pointer:remove() end
if self.engine then self.engine:remove() end
self.object:remove()
pos.y=pos.y+2
for i=1,7 do
minetest.add_item({x=pos.x+random()-0.5,y=pos.y,z=pos.z+random()-0.5},'default:steel_ingot')
end
for i=1,7 do
minetest.add_item({x=pos.x+random()-0.5,y=pos.y,z=pos.z+random()-0.5},'default:mese_crystal')
end
--minetest.add_item({x=pos.x+random()-0.5,y=pos.y,z=pos.z+random()-0.5},'motorboat:boat')
minetest.add_item({x=pos.x+random()-0.5,y=pos.y,z=pos.z+random()-0.5},'default:diamond')
local total_biofuel = math.floor(self.energy) - 1
for i=0,total_biofuel do
minetest.add_item({x=pos.x+random()-0.5,y=pos.y,z=pos.z+random()-0.5},'biofuel:biofuel')
end
end
--
-- entity
--
minetest.register_entity('motorboat:engine',{
initial_properties = {
physical = false,
collide_with_objects=false,
pointable=false,
visual = "mesh",
mesh = "engine.b3d",
textures = {"motorboat_helice.png", "motorboat_black.png",},
},
on_activate = function(self,std)
self.sdata = minetest.deserialize(std) or {}
if self.sdata.remove then self.object:remove() end
end,
get_staticdata=function(self)
self.sdata.remove=true
return minetest.serialize(self.sdata)
end,
})
minetest.register_entity("motorboat:boat", {
initial_properties = {
physical = true,
collisionbox = {-0.6, -0.6, -0.6, 0.6, 1.2, 0.6}, --{-1,0,-1, 1,0.3,1},
selectionbox = {-1,0,-1, 1,1,1},
visual = "mesh",
mesh = "hull.b3d",
textures = {"motorboat_black.png", "motorboat_panel.png", "motorboat_glass.png", "motorboat_hull.png", "default_junglewood.png", "motorboat_painting.png"},
},
textures = {},
driver_name = nil,
sound_handle = nil,
tilting = vector.new(),
energy = 0.001,
owner = "",
static_save = true,
infotext = "A nice boat",
lastvelocity = vector.new(),
hp = 50,
color = "#07B6BC",
rudder_angle = 0,
timeout = 0;
buoyancy = 0.35,
max_hp = 50,
engine_running = false,
anchored = true,
--water_drag = 0,
get_staticdata = function(self) -- unloaded/unloads ... is now saved
return minetest.serialize({
stored_energy = self.energy,
stored_owner = self.owner,
stored_hp = self.hp,
stored_color = self.color,
stored_anchor = self.anchored,
})
end,
on_activate = function(self, staticdata, dtime_s)
if staticdata ~= "" and staticdata ~= nil then
local data = minetest.deserialize(staticdata) or {}
self.energy = data.stored_energy
self.owner = data.stored_owner
self.hp = data.stored_hp
self.color = data.stored_color
self.anchored = data.stored_anchor
--minetest.debug("loaded: ", self.energy)
end
paint(self, self.color)
local pos = self.object:get_pos()
local engine=minetest.add_entity(pos,'motorboat:engine')
engine:set_attach(self.object,'',{x=0,y=6,z=-21},{x=0,y=0,z=0})
-- set the animation once and later only change the speed
engine:set_animation({x = 1, y = 8}, 0, 0, true)
self.engine = engine
local pointer=minetest.add_entity(pos,'motorboat:pointer')
local energy_indicator_angle = get_pointer_angle(self.energy)
pointer:set_attach(self.object,'',{x=0,y=5.52451,z=5.89734},{x=0,y=0,z=energy_indicator_angle})
self.pointer = pointer
self.object:set_armor_groups({immortal=1})
--self.object:set_acceleration(vector.multiply(vector_up, -gravity))
mobkit.actfunc(self, staticdata, dtime_s)
end,
on_step = function(self, dtime)
mobkit.stepfunc(self, dtime)
local accel_y = self.object:get_acceleration().y
local rotation = self.object:get_rotation()
local yaw = rotation.y
local newyaw=yaw
local pitch = rotation.x
local newpitch = pitch
local roll = rotation.z
local newroll=roll
local hull_direction = minetest.yaw_to_dir(yaw)
local nhdir = {x=hull_direction.z,y=0,z=-hull_direction.x} -- lateral unit vector
local velocity = self.object:get_velocity()
local longit_speed = dot(velocity,hull_direction)
local longit_drag = vector.multiply(hull_direction,longit_speed*longit_speed*LONGIT_DRAG_FACTOR*-1*sign(longit_speed))
local later_speed = dot(velocity,nhdir)
local later_drag = vector.multiply(nhdir,later_speed*later_speed*LATER_DRAG_FACTOR*-1*sign(later_speed))
local accel = vector.add(longit_drag,later_drag)
local vel = self.object:get_velocity()
local is_attached = false
if self.owner then
local player = minetest.get_player_by_name(self.owner)
if player then
local player_attach = player:get_attach()
if player_attach then
if player_attach == self.object then is_attached = true end
end
end
end
if is_attached then
local impact = get_hipotenuse_value(vel, self.last_vel)
if impact > 1 then
--self.damage = self.damage + impact --sum the impact value directly to damage meter
local curr_pos = self.object:get_pos()
minetest.sound_play("collision", {
to_player = self.driver_name,
--pos = curr_pos,
--max_hear_distance = 5,
gain = 1.0,
fade = 0.0,
pitch = 1.0,
})
--[[if self.damage > 100 then --if acumulated damage is greater than 100, adieu
destroy(self)
end]]--
end
--control
accel = motorboat_control(self, dtime, hull_direction, longit_speed, longit_drag, later_speed, later_drag, accel) or vel
else
if self.sound_handle ~= nil then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
end
self.engine:set_attach(self.object,'',{x=0,y=6,z=-21},{x=0,y=self.rudder_angle,z=0})
if math.abs(self.rudder_angle)>5 then
local turn_rate = math.rad(24)
newyaw = yaw + self.dtime*(1 - 1 / (math.abs(longit_speed) + 1)) * self.rudder_angle / 30 * turn_rate * sign(longit_speed)
end
-- calculate energy consumption --
----------------------------------
if self.energy > 0 and self.engine_running then
local zero_reference = vector.new()
local acceleration = get_hipotenuse_value(accel, zero_reference)
local consumed_power = acceleration/6000
self.energy = self.energy - consumed_power;
local energy_indicator_angle = get_pointer_angle(self.energy)
if self.pointer:get_luaentity() then
self.pointer:set_attach(self.object,'',{x=0,y=5.52451,z=5.89734},{x=0,y=0,z=energy_indicator_angle})
else
--in case it have lost the entity by some conflict
self.pointer=minetest.add_entity({x=0,y=5.52451,z=5.89734},'motorboat:pointer')
self.pointer:set_attach(self.object,'',{x=0,y=5.52451,z=5.89734},{x=0,y=0,z=energy_indicator_angle})
end
end
if self.energy <= 0 and self.engine_running then
self.engine_running = false
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
self.engine:set_animation_frame_speed(0)
end
----------------------------
-- end energy consumption --
--roll adjust
---------------------------------
local sdir = minetest.yaw_to_dir(newyaw)
local snormal = {x=sdir.z,y=0,z=-sdir.x} -- rightside, dot is negative
local prsr = dot(snormal,nhdir)
local rollfactor = -10
newroll = (prsr*math.rad(rollfactor))*later_speed
--minetest.chat_send_all('newroll: '.. newroll)
---------------------------------
-- end roll
local bob = minmax(dot(accel,hull_direction),1) -- vertical bobbing
if self.isinliquid then
accel.y = accel_y+bob
newpitch = velocity.y * math.rad(6)
self.object:set_acceleration(accel)
end
if newyaw~=yaw or newpitch~=pitch or newroll~=roll then self.object:set_rotation({x=newpitch,y=newyaw,z=newroll}) end
--saves last velocy for collision detection (abrupt stop)
self.last_vel = self.object:get_velocity()
end,
on_punch = function(self, puncher, ttime, toolcaps, dir, damage)
if not puncher or not puncher:is_player() then
return
end
local name = puncher:get_player_name()
if self.owner and self.owner ~= name and self.owner ~= "" then return end
if self.owner == nil then
self.owner = name
end
if self.driver_name and self.driver_name ~= name then
-- do not allow other players to remove the object while there is a driver
return
end
local touching_ground, liquid_below = check_node_below(self.object)
local is_attached = false
if puncher:get_attach() == self.object then is_attached = true end
local itmstck=puncher:get_wielded_item()
local item_name = ""
if itmstck then item_name = itmstck:get_name() end
if is_attached == true and item_name == "biofuel:biofuel" and self.engine_running == false then
--refuel
motorboat_load_fuel(self, puncher:get_player_name())
end
if is_attached == false then
-- deal with painting or destroying
if itmstck then
local _,indx = item_name:find('dye:')
if indx then
--lets paint!!!!
local color = item_name:sub(indx+1)
local colstr = colors[color]
--minetest.chat_send_all(color ..' '.. dump(colstr))
if colstr then
paint(self, colstr)
itmstck:set_count(itmstck:get_count()-1)
puncher:set_wielded_item(itmstck)
end
-- end painting
else -- deal damage
if not self.driver and toolcaps and toolcaps.damage_groups and toolcaps.damage_groups.fleshy then
--mobkit.hurt(self,toolcaps.damage_groups.fleshy - 1)
--mobkit.make_sound(self,'hit')
self.hp = self.hp - 10
minetest.sound_play("collision", {
object = self.object,
max_hear_distance = 5,
gain = 1.0,
fade = 0.0,
pitch = 1.0,
})
end
end
end
if self.hp <= 0 then
destroy(self)
end
end
end,
on_rightclick = function(self, clicker)
if not clicker or not clicker:is_player() then
return
end
local name = clicker:get_player_name()
if self.owner and self.owner ~= name and self.owner ~= "" then return end
if self.owner == "" then
self.owner = name
end
if name == self.driver_name then
self.engine_running = false
-- driver clicked the object => driver gets off the vehicle
self.driver_name = nil
-- sound and animation
if self.sound_handle then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
self.engine:set_animation_frame_speed(0)
-- detach the player
clicker:set_detach()
player_api.player_attached[name] = nil
clicker:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
player_api.set_animation(clicker, "stand")
self.driver = nil
elseif not self.driver_name then
-- no driver => clicker is new driver
self.driver_name = name
-- temporary------
self.hp = 50 -- why? cause I can desist from destroy
------------------
-- attach the driver
clicker:set_attach(self.object, "", {x = 0, y = 5, z = -6}, {x = 0, y = 0, z = 0})
clicker:set_eye_offset({x = 0, y = 0, z = -5.5}, {x = 0, y = 0, z = -5.5})
player_api.player_attached[name] = true
-- make the driver sit
minetest.after(0.2, function()
local player = minetest.get_player_by_name(name)
if player then
player_api.set_animation(player, "sit")
end
end)
-- disable gravity
self.object:set_acceleration(vector.new())
end
end,
})
--
-- items
--
-- blades
minetest.register_craftitem("motorboat:engine",{
description = "Boat engine",
inventory_image = "motorboat_engine_inv.png",
})
-- cabin
minetest.register_craftitem("motorboat:hull",{
description = "Hull of the boat",
inventory_image = "motorboat_hull_inv.png",
})
-- boat
minetest.register_craftitem("motorboat:boat", {
description = "Motorboat",
inventory_image = "motorboat_inv.png",
liquids_pointable = true,
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pointed_pos = pointed_thing.under
local node_below = minetest.get_node(pointed_pos).name
local nodedef = minetest.registered_nodes[node_below]
if nodedef.liquidtype ~= "none" then
pointed_pos.y=pointed_pos.y+0.2
local boat = minetest.add_entity(pointed_pos, "motorboat:boat")
if boat and placer then
local ent = boat:get_luaentity()
local owner = placer:get_player_name()
ent.owner = owner
boat:set_yaw(placer:get_look_horizontal())
itemstack:take_item()
end
end
return itemstack
end,
})
--
-- crafting
--
if minetest.get_modpath("default") then
minetest.register_craft({
output = "motorboat:engine",
recipe = {
{"", "default:steel_ingot", ""},
{"default:steel_ingot", "default:mese_block", "default:steel_ingot"},
{"", "default:steel_ingot", "default:diamond"},
}
})
minetest.register_craft({
output = "motorboat:hull",
recipe = {
{"", "default:glass", ""},
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
}
})
minetest.register_craft({
output = "motorboat:boat",
recipe = {
{"", ""},
{"motorboat:hull", "motorboat:engine"},
}
})
end

5
mod.conf Normal file
View File

@ -0,0 +1,5 @@
name = motorboat
depends = mobkit,default,biofuel
author = APercy
description = Adds a craftable motorboat
title = Motorboat

BIN
models/engine.b3d Normal file

Binary file not shown.

BIN
models/hull.b3d Normal file

Binary file not shown.

BIN
models/pointer.b3d Normal file

Binary file not shown.

BIN
models/src/black.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

BIN
models/src/engine.blend Normal file

Binary file not shown.

BIN
models/src/engine.blend1 Normal file

Binary file not shown.

BIN
models/src/glass.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
models/src/helice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

BIN
models/src/hull.blend Normal file

Binary file not shown.

BIN
models/src/hull.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
models/src/motorboat.blend Normal file

Binary file not shown.

BIN
models/src/motorboat.blend1 Normal file

Binary file not shown.

BIN
models/src/panel.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
models/src/pointer.blend Normal file

Binary file not shown.

116
motorboat_control.lua Normal file
View File

@ -0,0 +1,116 @@
--global constants
gravity = tonumber(minetest.settings:get("movement_gravity")) or 9.8
tilting_speed = 1
tilting_max = 0.35
power_max = 15
power_min = 0.2 -- if negative, the helicopter can actively fly downwards
wanted_vert_speed = 10
vector_up = vector.new(0, 1, 0)
vector_forward = vector.new(0, 0, 1)
motorboat_last_time_command = minetest.get_us_time()
function vector_length_sq(v)
return v.x * v.x + v.y * v.y + v.z * v.z
end
function get_pointer_angle(energy)
local angle = energy * 18
angle = angle - 90
angle = angle * -1
return angle
end
function check_node_below(obj)
local pos_below = obj:get_pos()
pos_below.y = pos_below.y - 0.1
local node_below = minetest.get_node(pos_below).name
local nodedef = minetest.registered_nodes[node_below]
local touching_ground = not nodedef or -- unknown nodes are solid
nodedef.walkable or false
local liquid_below = not touching_ground and nodedef.liquidtype ~= "none"
return touching_ground, liquid_below
end
function motorboat_control(self, dtime, hull_direction, longit_speed, longit_drag, later_speed, later_drag, accel)
local player = minetest.get_player_by_name(self.driver_name)
local retval_accel = accel;
-- player control
if player then
local ctrl = player:get_player_control()
if ctrl.sneak then
if ((minetest.get_us_time() - motorboat_last_time_command) / 1000) > 300 and longit_speed < 0.2 and longit_speed > -0.2 then
motorboat_last_time_command = minetest.get_us_time()
if self.anchored == false then
self.anchored = true
self.object:set_velocity(vector.new())
minetest.chat_send_player(self.driver_name, 'anchors away!')
else
self.anchored = false
minetest.chat_send_player(self.driver_name, 'weigh anchor!')
end
end
end
if self.anchored == false then
if self.engine_running then
local engineacc
if longit_speed < 8.0 and ctrl.up then
engineacc = 1.5
else
if longit_speed > -1 and ctrl.down then
engineacc = -0.1
end
end
if engineacc then retval_accel=vector.add(accel,vector.multiply(hull_direction,engineacc)) end
--minetest.chat_send_all('paddle: '.. paddleacc)
else
local paddleacc
if longit_speed < 1.0 and ctrl.up then
paddleacc = 0.5
elseif longit_speed > -1.0 and ctrl.down then
paddleacc = -0.5
end
if paddleacc then retval_accel=vector.add(accel,vector.multiply(hull_direction,paddleacc)) end
--minetest.chat_send_all('paddle: '.. paddleacc)
end
end
if ctrl.jump then
--sets the engine running - but sets a delay also, cause keypress
if ((minetest.get_us_time() - motorboat_last_time_command) / 1000) > 300 then
motorboat_last_time_command = minetest.get_us_time()
if self.engine_running then
self.engine_running = false
-- sound and animation
if self.sound_handle then
minetest.sound_stop(self.sound_handle)
self.sound_handle = nil
end
self.engine:set_animation_frame_speed(0)
elseif self.engine_running == false and self.energy > 0 then
self.engine_running = true
-- sound and animation
self.sound_handle = minetest.sound_play({name = "engine"},
{object = self.object, gain = 2.0, max_hear_distance = 32, loop = true,})
self.engine:set_animation_frame_speed(30)
end
end
end
-- rudder
local rudder_limit = 30
if ctrl.right then
self.rudder_angle = math.max(self.rudder_angle-20*dtime,-rudder_limit)
elseif ctrl.left then
self.rudder_angle = math.min(self.rudder_angle+20*dtime,rudder_limit)
end
end
return retval_accel
end

View File

@ -0,0 +1,47 @@
--
-- fuel
--
minetest.register_entity('motorboat:pointer',{
initial_properties = {
physical = false,
collide_with_objects=false,
pointable=false,
visual = "mesh",
mesh = "pointer.b3d",
textures = {"clay.png"},
},
on_activate = function(self,std)
self.sdata = minetest.deserialize(std) or {}
if self.sdata.remove then self.object:remove() end
end,
get_staticdata=function(self)
self.sdata.remove=true
return minetest.serialize(self.sdata)
end,
})
function motorboat_load_fuel(self, player_name)
if self.energy < 9.5 then
local player = minetest.get_player_by_name(player_name)
local inv = player:get_inventory()
local inventory_fuel = "biofuel:biofuel"
if inv:contains_item("main", inventory_fuel) then
local stack = ItemStack(inventory_fuel .. " 1")
local taken = inv:remove_item("main", stack)
self.energy = self.energy + 1
if self.energy > 10 then self.energy = 10 end
local energy_indicator_angle = get_pointer_angle(self.energy)
self.pointer:set_attach(self.object,'',{x=0,y=5.52451,z=5.89734},{x=0,y=0,z=energy_indicator_angle})
end
else
print("Full tank.")
end
end

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
sounds/collision.ogg Normal file

Binary file not shown.

BIN
sounds/engine.ogg Normal file

Binary file not shown.

BIN
textures/clay.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
textures/motorboat_black.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
textures/motorboat_glass.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

BIN
textures/motorboat_hull.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
textures/motorboat_inv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

BIN
textures/motorboat_painting.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
textures/motorboat_panel.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB