diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm
index d138cf1971..5278122337 100644
--- a/code/datums/components/caltrop.dm
+++ b/code/datums/components/caltrop.dm
@@ -18,6 +18,10 @@
var/atom/A = parent
if(!A.has_gravity())
return
+
+ if(istype(AM, /obj/vehicle/ridden/space/speedbike) && AM.buckled_mobs.len)
+ var/obj/vehicle/ridden/space/speedbike/unfortunatebike = AM
+ unfortunatebike.crashing()
if(!prob(probability))
return
diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm
index 4e48c984fc..e484f13bd0 100644
--- a/code/game/mecha/mecha_construction_paths.dm
+++ b/code/game/mecha/mecha_construction_paths.dm
@@ -41,10 +41,12 @@
return
// Remove default mech power cell, as we replace it with a new one.
var/obj/mecha/M = new result(drop_location())
- QDEL_NULL(M.cell)
+ if(istype(M))
+ QDEL_NULL(M.cell)
var/obj/item/mecha_parts/chassis/parent_chassis = parent
- M.CheckParts(parent_chassis.contents)
+ if(istype(parent_chassis))
+ M.CheckParts(parent_chassis.contents)
SSblackbox.record_feedback("tally", "mechas_created", 1, M.name)
QDEL_NULL(parent)
@@ -69,7 +71,7 @@
/datum/component/construction/unordered/mecha_chassis/spawn_result()
var/atom/parent_atom = parent
parent_atom.icon = 'icons/mecha/mech_construction.dmi'
- if(istype(parent_atom, /obj/item/mecha_parts/chassis/phazon/car))
+ if(istype(parent_atom, /obj/item/mecha_parts/chassis/phazon/car) || istype(parent_atom, /obj/item/mecha_parts/chassis/phazon/bike))
parent_atom.icon = 'icons/fallout/vehicles/medium_vehicles.dmi'
parent_atom.density = TRUE
parent_atom.cut_overlays()
@@ -2222,6 +2224,150 @@
user.visible_message("[user] paints [parent] as a finishing touch.",
"You paint [parent] as a finishing touch.")
return TRUE
+
+/datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/bos
+ result = /datum/component/construction/mecha/phazon/pickuptruck/bos
+/datum/component/construction/mecha/phazon/pickuptruck/bos
+ result = /obj/mecha/combat/phazon/pickuptruck/bos
+/datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/buggy
+ result = /datum/component/construction/mecha/phazon/pickuptruck/buggy
+/datum/component/construction/mecha/phazon/pickuptruck/buggy
+ result = /obj/mecha/combat/phazon/buggy
+/datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/ncrtruck
+ result = /datum/component/construction/mecha/phazon/pickuptruck/ncrtruck
+/datum/component/construction/mecha/phazon/pickuptruck/ncrtruck
+ result = /obj/mecha/combat/phazon/ncrtruck
+/datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/highwayman
+ result = /datum/component/construction/mecha/phazon/pickuptruck/highwayman
+/datum/component/construction/mecha/phazon/pickuptruck/highwayman
+ result = /obj/mecha/combat/phazon/highwayman
+/datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/coverage
+ result = /datum/component/construction/mecha/phazon/pickuptruck/coverage
+/datum/component/construction/mecha/phazon/pickuptruck/coverage
+ result = /obj/mecha/combat/phazon/corvega
+//BIKE
+/datum/component/construction/unordered/mecha_chassis/phazon/bike
+ result = /datum/component/construction/mecha/phazon/bike
+ steps = list(
+ /obj/item/mecha_parts/part/Car_autoshaft,
+ /obj/item/mecha_parts/part/Car_tire,
+ /obj/item/mecha_parts/part/Car_tire,
+ /obj/item/mecha_parts/part/Car_engine,
+ /obj/item/defibrillator/primitive
+ )
+
+/datum/component/construction/mecha/phazon/bike
+ result = /obj/vehicle/ridden/space/speedbike/f13
+ base_icon = "bikechassis"
+ steps = list(
+ //1
+ list(
+ "key" = TOOL_WRENCH,
+ "desc" = "The shaft is removed."
+ ),
+ //2
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "desc" = "The wheels are installed."
+ ),
+ //3
+ list(
+
+ "key" = /obj/item/light/bulb,
+ "back_key" = TOOL_CROWBAR,
+ "action" = ITEM_MOVE_INSIDE,
+ "desc" = "The wheels are secured."
+ ),
+
+ //5
+ list(
+ "key" = /obj/item/stack/cable_coil,
+ "amount" = 5,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "The busted light is replaced."
+ ),
+ //6
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_WIRECUTTER,
+ "desc" = "The headlights are wired."
+ ),
+ //7
+ list(
+ "key" = /obj/item/stack/sheet/glass,
+ "amount" = 5,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "The gearbox is installed."
+ ),
+
+ //8
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "the Windshield is installed."
+ ),
+ //9
+ list(
+ "key" = /obj/item/stock_parts/cell,
+ "action" = ITEM_MOVE_INSIDE,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "The headlights are installed."
+ ),
+ //10
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "The power cell is installed.",
+ )
+ )
+
+
+/datum/component/construction/mecha/phazon/bike/custom_action(obj/item/I, mob/living/user, diff)
+ if(!..())
+ return FALSE
+ //TODO: better messages.
+ switch(index)
+ if(1)
+ user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.")
+ if(2)
+ if(diff==FORWARD)
+ user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.")
+ else
+ user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.")
+ if(3)
+ if(diff==FORWARD)
+ user.visible_message("[user] changes the lightbulb of [parent].", "You change the lightbulb of [parent].")
+ else
+ user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.")
+ if(4)
+ if(diff==FORWARD)
+ user.visible_message("[user] wires the lightbulb of [parent].", " You wire the lightbulb [parent].")
+ else
+ user.visible_message("[user] removes the lightbulb from[parent].", "You remove the lightbulb from [parent].")
+ if(5)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs the lightbulb [parent].", "You installs the lightbulbinto the [parent].")
+ else
+ user.visible_message("[user] removes the lightbulb.", "You remove the lightbulb.")
+ if(6)
+ if(diff==FORWARD)
+ user.visible_message("[user] Positions the Windshield.", "You Position the Windshield.")
+ else
+ user.visible_message("[user] uninstall the windshield.", "You uninstall the windshield.")
+ if(7)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs the windshield of [parent].", "You install windshield of [parent].")
+ else
+ user.visible_message("[user] removes the windshield.", "You remove the windshield.")
+ if(8)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs the battery.", "You install the battery.")
+ else
+ user.visible_message("[user] uninstalls the windshield.", "You uninstall the windshield.")
+ if(9)
+ if(diff==FORWARD)
+ user.visible_message("[user] secures the battery.", "You secure the battery.")
+ return TRUE
//ODYSSEUS
/datum/component/construction/unordered/mecha_chassis/odysseus
diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm
index 3bcf526982..f9072e5b4e 100644
--- a/code/game/mecha/mecha_parts.dm
+++ b/code/game/mecha/mecha_parts.dm
@@ -336,7 +336,30 @@
icon = 'icons/fallout/trash.dmi'
icon_state = "car_engine"
-
+/obj/item/mecha_parts/chassis/phazon/car/bos
+ name = "\improper Brotherhood Car chassis"
+ construct_type = /datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/bos
+/obj/item/mecha_parts/chassis/phazon/car/buggy
+ name = "\improper Buggy Car chassis"
+ construct_type = /datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/buggy
+/obj/item/mecha_parts/chassis/phazon/car/ncrtruck
+ name = "\improper Ncr Truck chassis"
+ construct_type = /datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/ncrtruck
+/obj/item/mecha_parts/chassis/phazon/car/highwayman
+ name = "\improper Highwayman car chassis"
+ construct_type = /datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/highwayman
+/obj/item/mecha_parts/chassis/phazon/car/coverage
+ name = "\improper Coverage car chassis"
+ construct_type = /datum/component/construction/unordered/mecha_chassis/phazon/pickuptruck/coverage
+
+
+////////// Bike
+/obj/item/mecha_parts/chassis/phazon/bike
+ name = "\improper Bike chassis"
+ construct_type = /datum/component/construction/unordered/mecha_chassis/phazon/bike
+ icon = 'icons/obj/vehicles/medium_vehicles.dmi'
+ icon_state = "bikechassis"
+ bound_width = 64
///////// Circuitboards
/obj/item/circuitboard/mecha
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 8d5458333c..1d1873a0d5 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -52,6 +52,9 @@
duration = 10
randomdir = 0
+/obj/effect/temp_visual/dir_setting/speedbike_trail/f13
+ name = "speedbike dust"
+ icon_state = "bite_za_dusto_fade"
/obj/effect/temp_visual/dir_setting/firing_effect
icon = 'icons/effects/effects.dmi'
icon_state = "firing_effect"
diff --git a/code/game/objects/structures/wrecks.dm b/code/game/objects/structures/wrecks.dm
index 0e919dfdc5..f817c15706 100644
--- a/code/game/objects/structures/wrecks.dm
+++ b/code/game/objects/structures/wrecks.dm
@@ -24,6 +24,8 @@
desc = "An old pre-war car, rusted and destroyed with age and weathering."
icon = 'icons/obj/vehicles/medium_vehicles.dmi'
icon_state = "derelict"
+ var/list/allchassis
+ var/obj/item/mecha_parts/chassis/chassis = /obj/item/mecha_parts/chassis/phazon/car
bound_width = 64
/obj/structure/wreck/car/welder_act(mob/living/user, obj/item/I)
@@ -55,10 +57,37 @@
return TRUE
+/obj/structure/wreck/car/welder_act(mob/living/user, obj/item/I)
+ I.play_tool_sound(src)
+ user.visible_message("[user] starts preparing the [src] for a makeover...", \
+ "You start preparing the [src] for a makeover...")
+ if(!I.use_tool(src, user, 50))
+ return
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
+ user.visible_message("[user] dexterly opens up [src]'s space .", \
+ "You dexterly open up [src]'s space.")
+ new chassis(loc)
+ qdel(src)
+ return TRUE
+
+/obj/structure/wreck/car/wrench_act(mob/living/user, obj/item/I)
+ I.play_tool_sound(src)
+ allchassis = subtypesof(/obj/item/mecha_parts/chassis/phazon/car)
+ user.visible_message("[user] changes the chassis type [src]...", \
+ "You change the chassis type of [src]...")
+ chassis = pick(allchassis)
+ user.visible_message("[initial(chassis.name)]!...")
+ return TRUE
+
/obj/structure/wreck/car/bike
name = "wrecked motorcycle"
desc = "An old pre-war motorcycle, rusted and destroyed with age and weathering."
icon_state = "rust_light_no_wheels"
+ chassis = /obj/item/mecha_parts/chassis/phazon/bike
+
+/obj/structure/wreck/car/bike/wrench_act(mob/living/user, obj/item/I)
+ return
+
/obj/structure/wreck/bus
name = "wrecked bus"
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 10e2afb59a..a42ee45e01 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -313,8 +313,9 @@
//view() but with a signal, to allow blacklisting some of the otherwise visible atoms.
/mob/proc/fov_view(dist = world.view)
. = view(dist, src)
- if(client.eye != src)
- . = view(dist, client.eye)
+ if(client)
+ if(client.eye != src)
+ . = view(dist, client.eye)
SEND_SIGNAL(src, COMSIG_MOB_FOV_VIEW, .)
/**
diff --git a/code/modules/vehicles/speedbike.dm b/code/modules/vehicles/speedbike.dm
index a560cbb8f3..5ff9284971 100644
--- a/code/modules/vehicles/speedbike.dm
+++ b/code/modules/vehicles/speedbike.dm
@@ -32,10 +32,85 @@
new /obj/effect/temp_visual/dir_setting/speedbike_trail(loc,move_dir)
. = ..()
+/obj/vehicle/ridden/space/speedbike/proc/crashing(force = 5)
+ if(buckled_mobs.len)
+ for(var/mob/living/H in buckled_mobs)
+ H.adjustStaminaLoss(60)
+ playsound(src, 'sound/effects/bang.ogg', 40, TRUE)
+ var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals))
+ unbuckle_mob(H)
+ H.throw_at(throw_target, force, force)
+ if(iscarbon(H))
+ var/head_slot = H.get_item_by_slot(SLOT_HEAD)
+ if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
+ H.updatehealth()
+ visible_message("[src] crashes, sending [H] flying!")
+ H.Knockdown(80)
/obj/vehicle/ridden/space/speedbike/red
icon_state = "speedbike_red"
overlay_state = "cover_red"
+/obj/item/offhand/handle
+ name = "Bike handle"
+ desc = "The handle of the bike, used to steer the vehicle on the round. Better get a grip on it"
+ icon_state = "bike_handle"
+ var/obj/vehicle/ridden/space/speedbike/attachedveh
+
+/obj/item/offhand/handle/dropped(mob/user)
+ . = ..()
+ attachedveh.crashing()
+
+/obj/vehicle/ridden/space/speedbike/f13
+ icon_state = "speedbike_f13"
+ overlay_state = "cover_f13"
+ key_type = /obj/item/key/custombike
+ var/obj/item/offhand/handle/steer = null
+
+/obj/vehicle/ridden/space/speedbike/f13/attackby(obj/item/I, mob/user, params)
+ var/obj/item/key/custombike/nkf = I
+ if(istype(nkf) && nkf.keyfit != src)
+ to_chat(user, "[nkf] does not fit into [src]!")
+ return
+ . = ..()
+
+
+/obj/vehicle/ridden/space/speedbike/f13/Move(newloc,move_dir)
+ if(has_buckled_mobs())
+ new /obj/effect/temp_visual/dir_setting/speedbike_trail/f13(loc,move_dir)
+ . = ..()
+/obj/vehicle/ridden/space/speedbike/f13/Initialize()
+ . = ..()
+ var/datum/component/riding/D = GetComponent(/datum/component/riding)
+ D.vehicle_move_delay = 0.95
+ var/obj/item/key/custombike/NK = new(loc)
+ NK.keyfit = src
+
+/obj/vehicle/ridden/space/speedbike/f13/post_buckle_mob(mob/living/M)
+ var/obj/item/main_hand = M.get_active_held_item()
+ var/obj/item/other_item = M.get_inactive_held_item()
+ steer = new(M)
+ steer.name = "[src]'s handle"
+ steer.desc = "you are keeping control of the [src] with this hand."
+ steer.attachedveh = src
+ if(!main_hand)
+ M.put_in_active_hand(steer)
+ else if(other_item)
+ if(!M.dropItemToGround(other_item, force=FALSE)) //If you cannot remove the item in your hand, don't try and steer the bike.
+ to_chat(M, "You cannot seem to drop the item in your other hand!")
+ return
+ M.put_in_inactive_hand(steer)
+ else
+ M.put_in_inactive_hand(steer)
+ . = ..()
+
+/obj/vehicle/ridden/space/speedbike/f13/post_unbuckle_mob(mob/living/M)
+ . = ..()
+ qdel(steer)
+ if(inserted_key)
+ if(!M.put_in_active_hand(inserted_key, FALSE, FALSE))
+ M.dropItemToGround(inserted_key)
+ inserted_key = null
//BM SPEEDWAGON
/obj/vehicle/ridden/space/speedwagon
diff --git a/code/modules/vehicles/vehicle_key.dm b/code/modules/vehicles/vehicle_key.dm
index 62e4e612fb..be0d94e2e1 100644
--- a/code/modules/vehicles/vehicle_key.dm
+++ b/code/modules/vehicles/vehicle_key.dm
@@ -17,3 +17,6 @@
desc = "A keyring with a small steel key, and a rubber nightstick accessory."
icon_state = "keysec"
+/obj/item/key/custombike
+ desc = "A keyring with a small steel bike accessory."
+ var/obj/vehicle/ridden/space/speedbike/keyfit = null
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 508a5c5ace..842bc33834 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/fallout/vehicles/medium_vehicles.dmi b/icons/fallout/vehicles/medium_vehicles.dmi
index 6b35614072..97928c7e88 100644
Binary files a/icons/fallout/vehicles/medium_vehicles.dmi and b/icons/fallout/vehicles/medium_vehicles.dmi differ
diff --git a/icons/obj/bike.dmi b/icons/obj/bike.dmi
index aa6cbfc30a..ac179893e7 100644
Binary files a/icons/obj/bike.dmi and b/icons/obj/bike.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index 9ac6f90a24..e48b39659f 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/icons/obj/vehicles/medium_vehicles.dmi b/icons/obj/vehicles/medium_vehicles.dmi
index 44a18f6408..ccb309fcad 100644
Binary files a/icons/obj/vehicles/medium_vehicles.dmi and b/icons/obj/vehicles/medium_vehicles.dmi differ