Files
Batrachophreno aaea5d8a57 Assunzione & Port Volturno (#22258)
Contains assets, code, maps, etc. for Assunzione and Port Volturno. This
is something like v0.9 for live unit testing, etc. Do not merge yet.

### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:

| Path | Original Author | License |
| --- | --- | --- |
| icons/obj/structure/urban/arches.dmi |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/structure/urban/assunzione_neon.dmi |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/structure/urban/assunzione_signs.dmi (stafylia_sign) |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/structure/urban/billboard.dmi (sign_assunzione1 & 2) |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/structure/urban/poles.dmi (radial_floodlight) |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/structure/urban/restaurant.dmi (menu_gyro) |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/structure/urban/statues.dmi (aec_small) |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/pottedplants_big.dmi (luce-vine-plant) |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/pottedplants_small.dmi (luce-vine-plant) |
[Fyni](https://github.com/Fyniiy) | CC-BY-SA |
| icons/obj/structure/urban/billboard.dmi (sign_assunzione3) | Minzeyes
| CC-BY-SA |
| icons/obj/structure/urban/assunzione_96x110.dmi | Minzeyes | CC-BY-SA
|
| icons/turf/smooth/composite_brick.dmi |
[nauticall](https://github.com/nauticall) | CC-BY-SA |

---------

Signed-off-by: Batrachophreno <Batrochophreno@gmail.com>
Co-authored-by: Kano <89972582+kano-dot@users.noreply.github.com>
2026-04-19 19:50:20 +00:00

543 lines
17 KiB
Plaintext

/obj/vehicle/bike
name = "space-bike"
desc = "Space wheelies! Woo!"
icon = 'icons/obj/vehicle/bike.dmi'
icon_state = "bike_off"
dir = SOUTH
load_item_visible = 1
mob_offset_y = 5
health = 100
maxhealth = 100
fire_dam_coeff = 0.6
brute_dam_coeff = 0.5
var/protection_percent = 60
/// Speed on land. Higher is slower.
/// If 0 it can't go on land turfs at all.
var/land_speed = 1.4
/// Speed if walk intent is on.
/// Should be slower, but does not crash into other bikes or people at this speed.
/// If land speed is 0, still can't go on land turfs at all.
var/land_speed_careful = 2.2
/// Same as land speed, but for space turfs.
var/space_speed = 1
/// Same as land speed if walk intent is on, but for space turfs.
var/space_speed_careful = 2
var/bike_icon = "bike"
var/storage_type = /obj/item/storage/toolbox/bike_storage
var/obj/item/storage/storage_compartment
var/datum/effect_system/ion_trail/ion
var/ion_type = /datum/effect_system/ion_trail
var/kickstand = TRUE
var/can_hover = TRUE
/// Registration plate string of the vehicle, visible on examine,
/// to distingush different vehicles of the same type from each other.
/// Also used to check if the key is for this vehicle.
/// If null, it is randomly generated on init.
var/registration_plate = null
/// Key type accepted in vehicle ignition.
var/key_type = /obj/item/key/bike
/// Actual key object in the vehicle ignition, or null if no key in ignition.
/// To actually start the vehicle, key data needs to match with the registration plate string.
var/obj/item/key/key = null
/// If TRUE, vehicle spawns with the key that matches its registration plate string.
/// If FALSE, the key needs to be mapped/spawned somewhere outside of the vehicle,
/// otherwise it will be an unusable prop.
var/spawns_with_key = TRUE
/obj/vehicle/bike/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Click-drag yourself onto the bike to climb onto it."
. += "Click-drag it onto yourself to access its mounted storage."
. += "Click the bike with a key to put it in, and click the bike with empty hand to take it out. The bike won't run without a key."
. += "CTRL-click the bike to toggle the engine."
. += "ALT-click to toggle the kickstand which prevents movement by driving and dragging."
. += "Click the resist button or type \"resist\" in the command bar at the bottom of your screen to get off the bike."
. += "Go fast! Use the RUN intent to go fast! Just be careful you don't run anyone over."
/obj/vehicle/bike/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(distance <= 4)
. += "\The [src] has a small registration plate on the back, '[registration_plate]'."
if(key)
. += "\The [src] has \a [key] in."
else
. += "\The [src] does not have a key in."
/obj/vehicle/bike/Destroy()
QDEL_NULL(key)
QDEL_NULL(ion)
QDEL_NULL(storage_compartment)
return ..()
/obj/vehicle/bike/setup_vehicle()
..()
ion = new ion_type(src)
turn_off()
AddOverlays(image(icon, "[icon_state]_off_overlay", MOB_LAYER + 1))
icon_state = "[bike_icon]_off"
if(storage_type)
storage_compartment = new storage_type(src)
if(!registration_plate)
generate_registration_plate()
if(spawns_with_key)
key = new key_type(src)
key.key_data = registration_plate
/obj/vehicle/bike/proc/generate_registration_plate()
registration_plate = "[rand(100,999)]-[rand(1000,9999)]"
/obj/vehicle/bike/CtrlClick(var/mob/user)
if(Adjacent(user) && anchored)
toggle_engine(user)
else
return ..()
/obj/vehicle/bike/proc/toggle_engine(var/mob/user)
if(use_check_and_message(user))
return
if(!on)
if(!key)
to_chat(user, SPAN_WARNING("You cannot turn \the [src] on, without a key."))
return
if((key.key_data != registration_plate))
user.visible_message("\The [user] turns \a [key] in the ignition of \the [src].", "You turn \a [key] in the ignition of \the [src], but it lets out a sharp buzz.")
else
user.visible_message("\The [user] turns \a [key] in the ignition of \the [src].", "You turn \a [key] in the ignition of \the [src], and it beeps happily.")
turn_on()
src.visible_message("\The [src] rumbles to life.", "You hear something rumble deeply.")
playsound(src, 'sound/machines/vehicles/bike_start.ogg', 100, 1)
else
turn_off()
src.visible_message("\The [src] putters before turning off.", "You hear something putter slowly.")
/obj/vehicle/bike/AltClick(var/mob/user)
if(Adjacent(user))
kickstand(user)
else
return ..()
/obj/vehicle/bike/proc/kickstand(var/mob/user)
if(use_check_and_message(user))
return
if(kickstand)
user.visible_message("\The [user] puts up \the [src]'s kickstand.", "You put up \the [src]'s kickstand.", "You hear a thunk.")
playsound(src, 'sound/machines/vehicles/bike_stand_up.ogg', 50, 1)
else
if(isturf(loc))
var/turf/T = loc
if (T.is_hole)
to_chat(user, SPAN_WARNING("You don't think kickstands work here."))
return
user.visible_message("\The [user] puts down \the [src]'s kickstand.", "You put down \the [src]'s kickstand.", "You hear a thunk.")
playsound(src, 'sound/machines/vehicles/bike_stand_down.ogg', 50, 1)
if(ismob(pulledby))
var/mob/M = pulledby
M.stop_pulling()
kickstand = !kickstand
anchored = (kickstand || on)
/obj/vehicle/bike/load(var/atom/movable/C)
var/mob/living/M = C
if(!istype(C)) return 0
if(M.buckled_to || M.restrained() || !Adjacent(M) || !M.Adjacent(src))
return 0
return ..(M)
/obj/vehicle/bike/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params)
if(user == over && ishuman(over))
var/mob/living/carbon/human/H = over
storage_compartment.open(H)
/obj/vehicle/bike/mouse_drop_receive(atom/dropped, mob/user, params)
if(!load(dropped))
to_chat(user, SPAN_WARNING("You were unable to load \the [dropped] onto \the [src]."))
return
/obj/vehicle/bike/attack_hand(var/mob/user as mob)
if(key)
to_chat(user, "You take \the [key] out of \the [src]")
user.put_in_hands(key)
key = null
if(on)
toggle_engine(user)
else if(user != load && load)
user.visible_message ("[user] starts to unbuckle [load] from \the [src]!")
if(do_after(user, 8 SECONDS, src))
unload(load)
to_chat(user, "You unbuckle [load] from \the [src]")
to_chat(load, "You were unbuckled from \the [src] by [user]")
/obj/vehicle/bike/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/key))
if(!key)
if(istype(attacking_item, key_type))
user.drop_from_inventory(attacking_item, src)
key = attacking_item
to_chat(user, SPAN_NOTICE("You put \the [attacking_item] in \the [src]."))
update_icon()
else
to_chat(user, SPAN_NOTICE("You try to put \the [attacking_item] in \the [src], but it does not fit."))
else
to_chat(user, SPAN_NOTICE("\The [src] already has a key in it."))
..()
/obj/vehicle/bike/relaymove(mob/living/user, direction)
. = ..()
if(user != load || !on || user.incapacitated())
return
return Move(get_step(src, direction))
/obj/vehicle/bike/RunOver(var/mob/living/carbon/human/H)
var/mob/living/M
if(!buckled)
return
if(istype(buckled, /mob/living))
M = buckled
var/collision_damage = clamp((maxhealth/6), 5, 30)
if(M.m_intent == M_RUN)
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Was rammed by [src]</font>"
M.attack_log += "\[[time_stamp()]\] <span class='warning'>rammed[M.name] ([M.ckey]) rammed [H.name] ([H.ckey]) with the [src].</span>"
msg_admin_attack("[src] crashed into [key_name(H)] at (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[H.x];Y=[H.y];Z=[H.z]'>JMP</a>)" )
src.visible_message(SPAN_DANGER("\The [src] runs over \the [H]!"))
H.apply_damage(collision_damage, DAMAGE_BRUTE)
H.apply_effect(4, WEAKEN)
return TRUE
/obj/vehicle/bike/proc/check_destination(var/turf/destination)
var/static/list/types = typecacheof(list(/turf/space))
if((is_type_in_typecache(destination,types) && !locate(/obj/structure/lattice)) || pulledby)
return TRUE
else
return FALSE
/obj/vehicle/bike/Move(var/turf/destination)
if(kickstand)
visible_message("The kickstand prevents the bike from moving!")
return
var/mob/living/rider = buckled
if(!istype(buckled))
return
var/is_careful = (rider.m_intent != M_RUN)
var/is_on_space = check_destination(destination)
if(is_on_space)
if(!space_speed)
return FALSE
move_delay = (is_careful ? space_speed_careful : space_speed)
else
if(!land_speed)
return FALSE
move_delay = (is_careful ? land_speed_careful : land_speed)
return ..()
/obj/vehicle/bike/turn_on()
ion.start()
anchored = TRUE
if(can_hover)
flying = TRUE
update_icon()
if(ismob(pulledby))
var/mob/M = pulledby
M.stop_pulling()
..()
/obj/vehicle/bike/turn_off()
ion.stop()
anchored = kickstand
if(can_hover)
flying = FALSE
update_icon()
..()
/obj/vehicle/bike/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
if(buckled && prob(protection_percent))
return buckled.bullet_act(arglist(args))
..()
/obj/vehicle/bike/update_icon()
ClearOverlays()
if(on)
AddOverlays(image(icon, "[bike_icon]_on_overlay", MOB_LAYER + 1))
icon_state = "[bike_icon]_on"
else
AddOverlays(image(icon, "[bike_icon]_off_overlay", MOB_LAYER + 1))
icon_state = "[bike_icon]_off"
..()
/obj/vehicle/bike/Collide(var/atom/movable/AM)
. = ..()
collide_act(AM)
/obj/vehicle/bike/proc/collide_act(var/atom/movable/AM)
var/mob/living/M
if(!buckled)
return
if(istype(buckled, /mob/living))
M = buckled
if(M.m_intent == M_RUN)
if (istype(AM, /obj/vehicle))
M.setMoveCooldown(10)
var/obj/vehicle/V = AM
if(prob(50))
if(V.buckled)
if(ishuman(V.buckled))
var/mob/living/carbon/human/I = V.buckled
I.visible_message(SPAN_DANGER("\The [I] falls off from \the [V]"))
V.unload(I)
I.throw_at(get_edge_target_turf(V.loc, V.loc.dir), 5, 1)
I.apply_effect(2, WEAKEN)
if(prob(25))
if(ishuman(buckled))
var/mob/living/carbon/human/C = buckled
C.visible_message(SPAN_DANGER ("\The [C] falls off from \the [src]!"))
unload(C)
C.throw_at(get_edge_target_turf(loc, loc.dir), 5, 1)
C.apply_effect(2, WEAKEN)
if(isliving(AM))
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Was rammed by [src]</font>"
M.attack_log += "\[[time_stamp()]\] <span class='warning'>rammed[M.name] ([M.ckey]) rammed [H.name] ([H.ckey]) with the [src].</span>"
msg_admin_attack("[src] crashed into [key_name(H)] at (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[H.x];Y=[H.y];Z=[H.z]'>JMP</a>)" )
src.visible_message(SPAN_DANGER("\The [src] smashes into \the [H]!"))
playsound(src, SFX_SWING_HIT, 50, 1)
H.apply_damage(20, DAMAGE_BRUTE)
H.throw_at(get_edge_target_turf(loc, loc.dir), 5, 1)
H.apply_effect(4, WEAKEN)
M.setMoveCooldown(10)
return TRUE
else
var/mob/living/L = AM
src.visible_message(SPAN_DANGER("\The [src] smashes into \the [L]!"))
playsound(src, SFX_SWING_HIT, 50, 1)
L.throw_at(get_edge_target_turf(loc, loc.dir), 5, 1)
L.apply_damage(20, DAMAGE_BRUTE)
M.setMoveCooldown(10)
return TRUE
/obj/vehicle/bike/speeder
name = "retrofitted speeder"
desc = "A short bike that seems to consist mostly of an engine, a hover repulsor, vents and a steering shaft."
icon_state = "speeder_on"
health = 150
maxhealth = 150
fire_dam_coeff = 0.5
brute_dam_coeff = 0.4
storage_type = /obj/item/storage/toolbox/bike_storage/speeder
bike_icon = "speeder"
/obj/vehicle/bike/speeder/izweski
name = "hegemony speeder"
desc = "A Hephaestus-manufactured military speeder, used by the forces of the Izweski Hegemony."
icon_state = "heg_speeder_on"
bike_icon = "heg_speeder"
land_speed = 1
space_speed = 1
health = 250
maxhealth = 250
/obj/vehicle/bike/monowheel
name = "adhomian monowheel"
desc = "A one-wheeled vehicle, fairly popular with Little Adhomai's greasers."
icon_state = "monowheel_off"
health = 250
maxhealth = 250
fire_dam_coeff = 0.5
brute_dam_coeff = 0.4
mob_offset_y = 1
storage_type = /obj/item/storage/toolbox/bike_storage/monowheel
bike_icon = "monowheel"
dir = EAST
land_speed = 1
land_speed_careful = 1.6
space_speed = 0
space_speed_careful = 0
can_hover = FALSE
/obj/vehicle/bike/monowheel/check_destination(var/turf/destination)
var/static/list/types = typecacheof(list(/turf/space))
if((is_type_in_typecache(destination,types) && !locate(/obj/structure/lattice)) || pulledby)
return TRUE
else
return FALSE
/obj/item/storage/toolbox/bike_storage
name = "bike storage"
max_w_class = WEIGHT_CLASS_BULKY
max_storage_space = 50
care_about_storage_depth = FALSE
/obj/item/storage/toolbox/bike_storage/speeder
name = "speeder storage"
/obj/item/storage/toolbox/bike_storage/monowheel
name = "monowheel storage"
/obj/vehicle/bike/casino
name = "retrofitted snowmobile"
desc = "A modified snowmobile. There is a coin slot on the panel."
icon_state = "snow_on"
bike_icon = "snow"
land_speed = 4
protection_percent = 10
can_hover = FALSE
var/paid = FALSE
/obj/vehicle/bike/casino/Move(var/turf/destination)
if(!paid)
return
. = ..()
/obj/vehicle/bike/casino/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/coin/casino))
if(!paid)
paid = TRUE
to_chat(user, SPAN_NOTICE("Payment confirmed, enjoy two minutes of unlimited snowmobile use."))
addtimer(CALLBACK(src, PROC_REF(rearm)), 2 MINUTES)
return
..()
/obj/vehicle/bike/casino/proc/rearm()
visible_message(SPAN_NOTICE("\The [src] beeps lowly, asking for another chip to continue."))
paid = FALSE
/obj/vehicle/bike/casino/check_destination(var/turf/destination)
var/static/list/types = typecacheof(list(/turf/space))
if((is_type_in_typecache(destination,types) && !locate(/obj/structure/lattice)) || pulledby)
return TRUE
else
return FALSE
/obj/vehicle/bike/snow
name = "snowmobile"
desc = "A vehicle adapted to travel on snow."
icon_state = "snow_on"
bike_icon = "snow"
land_speed = 2
space_speed = 0
protection_percent = 10
can_hover = FALSE
/obj/vehicle/bike/motor
name = "sports bike"
desc = "A two-wheeled vehicle meant for easy riding."
icon_state = "sport_on"
bike_icon = "sport"
land_speed = 1
land_speed_careful = 1.6
space_speed = 0
protection_percent = 10
can_hover = FALSE
key_type = /obj/item/key/bike/sport
/obj/vehicle/bike/motor/check_destination(turf/destination)
var/static/list/types = typecacheof(list(/turf/space, /turf/simulated/floor/exoplanet/water))
if((is_type_in_typecache(destination,types) && !locate(/obj/structure/lattice)) || pulledby)
return TRUE
else
return FALSE
/obj/vehicle/bike/motor/generate_registration_plate()
registration_plate = "[rand(10,99)]S-[rand(1000,9999)]"
/obj/vehicle/bike/motor/blue
icon_state = "bluesport_on"
bike_icon = "bluesport"
/obj/vehicle/bike/motor/green
icon_state = "greensport_on"
bike_icon = "greensport"
/obj/vehicle/bike/motor/brown
icon_state = "brownsport_on"
bike_icon = "brownsport"
/obj/vehicle/bike/motor/police_konyang
name = "police bike"
desc = "A two-wheeled vehicle meant for easy riding. This comes in stark white colors with flashy lights, indicating it is the law. It has the insignias of Konyang's police force."
icon_state = "konyangpolice_on"
bike_icon = "konyangpolice"
key_type = /obj/item/key/bike/police
/obj/vehicle/bike/motor/police_konyang/generate_registration_plate()
registration_plate = "[rand(10,99)]P-[rand(1000,9999)]"
/obj/vehicle/bike/motor/moped
name = "moped"
desc = "A cheap, two-wheeled motorized bicycle."
icon_state = "greenmoped_on"
bike_icon = "greenmoped"
land_speed = 2 // slower than a sport bike but will still get you around big maps
key_type = /obj/item/key/bike/moped
/obj/vehicle/bike/motor/moped/generate_registration_plate()
registration_plate = "[rand(10,99)]M-[rand(1000,9999)]"
/obj/vehicle/bike/motor/moped/police_konyang
name = "police moped"
desc = "A cheap, two-wheeled motorized bicycle. This comes in stark white colors with flashy lights, indicating it is the law. It has the insignias of Konyang's police force."
icon_state = "konyangpolicemoped_on"
bike_icon = "konyangpolicemoped"
key_type = /obj/item/key/bike/police
/obj/vehicle/bike/motor/moped/police_konyang/generate_registration_plate()
registration_plate = "[rand(10,99)]P-[rand(1000,9999)]"
/obj/vehicle/bike/motor/moped/red
icon_state = "redmoped_on"
bike_icon = "redmoped"
/obj/vehicle/bike/motor/moped/teal
icon_state = "tealmoped_on"
bike_icon = "tealmoped"
/obj/vehicle/bike/motor/moped/blue
icon_state = "bluemoped_on"
bike_icon = "bluemoped"
/obj/vehicle/bike/motor/sand
name = "sandbike"
desc = "A specialised bike, designed for travelling on sand. Often used by Unathi of the Wasteland."
icon_state = "sport_on" //replace when we have a unique sprite
bike_icon = "sport"