mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
[READY] New clown traitor item: The clown car (#39317)
I've been wanting to add this for a while, and now I have. The clown car is a vehicle you can use if you're a traitor clown to run people over, shove them into your compact trunk, and take them for a ride. If you drive into any walls however, you and everyone you kidnapped, fall out of the car, leaving you somewhat vulnerable. It also comes with a lube-defense mechanism(tm) which has a 1/3 chance to drop some lube if someone decides to shoot at your sweet ride. You can also honk your horn or drop all of the drivers if you would like to.
This commit is contained in:
committed by
yogstation13-bot
parent
94c8cbffb7
commit
c9330feebc
9
code/__DEFINES/vehicles.dm
Normal file
9
code/__DEFINES/vehicles.dm
Normal file
@@ -0,0 +1,9 @@
|
||||
//Vehicle control flags
|
||||
|
||||
#define VEHICLE_CONTROL_PERMISSION 1
|
||||
#define VEHICLE_CONTROL_DRIVE 2
|
||||
#define VEHICLE_CONTROL_KIDNAPPED 4 //Can't leave vehicle voluntarily, has to resist.
|
||||
|
||||
|
||||
//Car trait flags
|
||||
#define CAN_KIDNAP 1
|
||||
@@ -1472,6 +1472,17 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 15
|
||||
restricted_roles = list("Clown")
|
||||
|
||||
/datum/uplink_item/role_restricted/clowncar
|
||||
name = "Clown Car"
|
||||
desc = "The Clown Car is the ultimate transportation method for any worthy clown! \
|
||||
Simply insert your bikehorn and get in, and get ready to have the funniest ride of your life! \
|
||||
You can ram any spacemen you come across and stuff them into your car, kidnapping them and locking them inside until \
|
||||
someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \
|
||||
are very sensetive. Now with our included lube defense mechanism which will protect you against any angry shitcurity!"
|
||||
item = /obj/vehicle/sealed/car/clowncar
|
||||
cost = 18
|
||||
restricted_roles = list("Clown")
|
||||
|
||||
// Pointless
|
||||
/datum/uplink_item/badass
|
||||
category = "(Pointless) Badassery"
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#define VEHICLE_CONTROL_PERMISSION 1
|
||||
#define VEHICLE_CONTROL_DRIVE 2
|
||||
|
||||
/obj/vehicle
|
||||
name = "generic vehicle"
|
||||
desc = "Yell at coderbus."
|
||||
@@ -72,8 +69,8 @@
|
||||
return FALSE
|
||||
occupants[M] = NONE
|
||||
add_control_flags(M, control_flags)
|
||||
grant_passenger_actions(M)
|
||||
after_add_occupant(M)
|
||||
grant_passenger_actions(M)
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/proc/after_add_occupant(mob/M)
|
||||
@@ -119,8 +116,12 @@
|
||||
step(trailer, dir_to_move)
|
||||
return did_move
|
||||
else
|
||||
after_move(direction)
|
||||
return step(src, direction)
|
||||
|
||||
/obj/vehicle/proc/after_move(direction)
|
||||
return
|
||||
|
||||
/obj/vehicle/proc/add_control_flags(mob/controller, flags)
|
||||
if(!istype(controller) || !flags)
|
||||
return FALSE
|
||||
@@ -142,7 +143,7 @@
|
||||
/obj/vehicle/Bump(atom/movable/M)
|
||||
. = ..()
|
||||
if(emulate_door_bumps)
|
||||
if(istype(M, /obj/machinery/door) && has_buckled_mobs())
|
||||
if(istype(M, /obj/machinery/door))
|
||||
for(var/m in occupants)
|
||||
M.Bumped(m)
|
||||
|
||||
|
||||
68
code/modules/vehicles/cars/car.dm
Normal file
68
code/modules/vehicles/cars/car.dm
Normal file
@@ -0,0 +1,68 @@
|
||||
/obj/vehicle/sealed/car
|
||||
layer = ABOVE_MOB_LAYER
|
||||
anchored = TRUE
|
||||
var/car_traits = NONE //Bitflag for special behavior such as kidnapping
|
||||
var/engine_sound = 'sound/vehicles/carrev.ogg'
|
||||
var/last_enginesound_time
|
||||
var/engine_sound_length = 20 //Set this to the length of the engine sound
|
||||
var/escape_time = 200 //Time it takes to break out of the car
|
||||
|
||||
/obj/vehicle/sealed/car/generate_actions()
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/remove_key, VEHICLE_CONTROL_DRIVE)
|
||||
if(car_traits & CAN_KIDNAP)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/DumpKidnappedMobs, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/sealed/car/MouseDrop_T(atom/dropping, mob/M)
|
||||
if(!M.canmove || M.stat || M.restrained())
|
||||
return FALSE
|
||||
if(ismob(dropping) && M != dropping)
|
||||
var/mob/D = dropping
|
||||
M.visible_message("<span class='warning'>[M] starts forcing [D] into [src]!</span>")
|
||||
mob_try_forced_enter(M, D)
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/sealed/car/mob_try_exit(mob/M, mob/user, silent = FALSE)
|
||||
if(M == user && (occupants[M] & VEHICLE_CONTROL_KIDNAPPED))
|
||||
to_chat(user, "<span class='notice'>You push against the back of [src] trunk to try and get out.</span>")
|
||||
if(!do_after(user, escape_time, target = src))
|
||||
return FALSE
|
||||
to_chat(user,"<span class='danger'>[user] gets out of [src]</span>")
|
||||
mob_exit(M, silent)
|
||||
return TRUE
|
||||
mob_exit(M, silent)
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/car/after_move(direction)
|
||||
if(world.time < last_enginesound_time + engine_sound_length)
|
||||
return
|
||||
last_enginesound_time = world.time
|
||||
playsound(src, engine_sound, 100, TRUE)
|
||||
|
||||
/obj/vehicle/sealed/car/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(!(car_traits & CAN_KIDNAP))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start opening [src]'s trunk.</span>")
|
||||
if(do_after(user, 30))
|
||||
if(return_amount_of_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED))
|
||||
to_chat(user, "<span class='notice'>The people stuck in [src]'s trunk all come tumbling out.</span>")
|
||||
DumpSpecificMobs(VEHICLE_CONTROL_KIDNAPPED)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>It seems [src]'s trunk was empty.</span>")
|
||||
|
||||
/obj/vehicle/sealed/car/proc/mob_try_forced_enter(mob/forcer, mob/M, silent = FALSE)
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
if(occupant_amount() >= max_occupants)
|
||||
return FALSE
|
||||
if(do_mob(forcer, get_enter_delay(M), target = src))
|
||||
mob_forced_enter(M, silent)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/vehicle/sealed/car/proc/mob_forced_enter(mob/M, silent = FALSE)
|
||||
if(!silent)
|
||||
M.visible_message("<span class='warning'>[M] is forced into \the [src]!</span>")
|
||||
M.forceMove(src)
|
||||
add_occupant(M, VEHICLE_CONTROL_KIDNAPPED)
|
||||
53
code/modules/vehicles/cars/clowncar.dm
Normal file
53
code/modules/vehicles/cars/clowncar.dm
Normal file
@@ -0,0 +1,53 @@
|
||||
/obj/vehicle/sealed/car/clowncar
|
||||
name = "clown car"
|
||||
desc = "How someone could even fit in there is beyond me."
|
||||
icon_state = "clowncar"
|
||||
max_integrity = 500
|
||||
armor = list("melee" = 70, "bullet" = 40, "laser" = 40, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
enter_delay = 20
|
||||
max_occupants = 50
|
||||
movedelay = 0.6
|
||||
car_traits = CAN_KIDNAP
|
||||
key_type = /obj/item/bikehorn
|
||||
key_type_exact = FALSE
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/generate_actions()
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/horn/clowncar, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/auto_assign_occupant_flags(mob/M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.mind && H.mind.assigned_role == "Clown") //Ensures only clowns can drive the car. (Including more at once)
|
||||
add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION)
|
||||
return
|
||||
add_control_flags(M, VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/mob_forced_enter(mob/M, silent = FALSE)
|
||||
. = ..()
|
||||
playsound(src, pick('sound/vehicles/clowncar_load1.ogg', 'sound/vehicles/clowncar_load2.ogg'), 75)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
. = ..()
|
||||
if(prob(33))
|
||||
visible_message("<span class='danger'>[src] spews out a ton of space lube!/span>/span>")
|
||||
new /obj/effect/particle_effect/foam(loc) //YEET
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/Bump(atom/movable/M)
|
||||
..()
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
C.Knockdown(50)
|
||||
C.visible_message("<span class='warning'>[src] rams into [C] and sucks him up!</span>") //fuck off shezza this isn't ERP.
|
||||
mob_forced_enter(C)
|
||||
|
||||
playsound(src, pick('sound/vehicles/clowncar_ram1.ogg', 'sound/vehicles/clowncar_ram2.ogg', 'sound/vehicles/clowncar_ram3.ogg'), 75)
|
||||
else if(istype(M, /turf/closed))
|
||||
visible_message("<span class='warning'>[src] rams into [M] and crashes!</span>")
|
||||
playsound(src, pick('sound/vehicles/clowncar_crash1.ogg', 'sound/vehicles/clowncar_crash2.ogg'), 75)
|
||||
playsound(src, 'sound/vehicles/clowncar_crashpins.ogg', 75)
|
||||
DumpMobs(TRUE)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/deconstruct(disassembled = TRUE)
|
||||
. = ..()
|
||||
playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100)
|
||||
@@ -35,22 +35,73 @@
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
if(!silent)
|
||||
M.visible_message("<span class='boldnotice'>[M] climbs into \the [src]!</span>")
|
||||
M.visible_message("<span class='notice'>[M] climbs into \the [src]!</span>")
|
||||
M.forceMove(src)
|
||||
add_occupant(M)
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/proc/mob_try_exit(mob/M, mob/user, silent = FALSE)
|
||||
mob_exit(M, silent)
|
||||
/obj/vehicle/sealed/proc/mob_try_exit(mob/M, mob/user, silent = FALSE, randomstep = FALSE)
|
||||
mob_exit(M, silent, randomstep)
|
||||
|
||||
/obj/vehicle/sealed/proc/mob_exit(mob/M, silent = FALSE)
|
||||
/obj/vehicle/sealed/proc/mob_exit(mob/M, silent = FALSE, randomstep = FALSE)
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
remove_occupant(M)
|
||||
M.forceMove(exit_location(M))
|
||||
if(randomstep)
|
||||
var/turf/target_turf = get_step(exit_location(M), pick(GLOB.cardinals))
|
||||
M.throw_at(target_turf, 5, 10)
|
||||
|
||||
if(!silent)
|
||||
M.visible_message("<span class='boldnotice'>[M] drops out of \the [src]!</span>")
|
||||
M.visible_message("<span class='notice'>[M] drops out of \the [src]!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/proc/exit_location(M)
|
||||
return drop_location()
|
||||
|
||||
/obj/vehicle/sealed/attackby(obj/item/I, mob/user, params)
|
||||
if(key_type && !is_key(inserted_key) && is_key(I))
|
||||
if(user.transferItemToLoc(I, src))
|
||||
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
|
||||
if(inserted_key) //just in case there's an invalid key
|
||||
inserted_key.forceMove(drop_location())
|
||||
inserted_key = I
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[I] seems to be stuck to your hand!</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/sealed/proc/remove_key(mob/user)
|
||||
if(!inserted_key)
|
||||
to_chat(user, "<span class='notice'>There is no key in [src]!</span>")
|
||||
return
|
||||
if(!is_occupant(user) || !(occupants[user] & VEHICLE_CONTROL_DRIVE))
|
||||
to_chat(user, "<span class='notice'>You must be driving [src] to remove [src]'s key!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You remove [inserted_key] from [src].</span>")
|
||||
inserted_key.forceMove(drop_location())
|
||||
user.put_in_hands(inserted_key)
|
||||
inserted_key = null
|
||||
|
||||
/obj/vehicle/sealed/deconstruct(disassembled = TRUE)
|
||||
. = ..()
|
||||
DumpMobs()
|
||||
explosion(loc, 0, 1, 2, 3, 0)
|
||||
|
||||
/obj/vehicle/sealed/proc/DumpMobs(randomstep = TRUE)
|
||||
for(var/i in occupants)
|
||||
if(iscarbon(i))
|
||||
var/mob/living/carbon/Carbon = i
|
||||
mob_exit(Carbon, null, randomstep)
|
||||
Carbon.Knockdown(40)
|
||||
|
||||
/obj/vehicle/sealed/proc/DumpSpecificMobs(flag, randomstep = TRUE)
|
||||
for(var/i in occupants)
|
||||
if((occupants[i] & flag) && iscarbon(i))
|
||||
var/mob/living/carbon/C = i
|
||||
mob_exit(C, null, randomstep)
|
||||
C.Knockdown(40)
|
||||
|
||||
|
||||
/obj/vehicle/sealed/AllowDrop()
|
||||
return FALSE
|
||||
@@ -103,6 +103,7 @@
|
||||
/datum/action/vehicle/sealed/climb_out
|
||||
name = "Climb Out"
|
||||
desc = "Climb out of your vehicle!"
|
||||
button_icon_state = "car_eject"
|
||||
|
||||
/datum/action/vehicle/sealed/climb_out/Trigger()
|
||||
if(..() && istype(vehicle_entered_target))
|
||||
@@ -110,3 +111,45 @@
|
||||
|
||||
/datum/action/vehicle/ridden
|
||||
var/obj/vehicle/ridden/vehicle_ridden_target
|
||||
|
||||
/datum/action/vehicle/sealed/remove_key
|
||||
name = "Remove key"
|
||||
desc = "Take your key out of the vehicle's ignition"
|
||||
button_icon_state = "car_removekey"
|
||||
|
||||
/datum/action/vehicle/sealed/remove_key/Trigger()
|
||||
vehicle_entered_target.remove_key(owner)
|
||||
|
||||
//CLOWN CAR ACTION DATUMS
|
||||
/datum/action/vehicle/sealed/horn
|
||||
name = "Honk Horn"
|
||||
desc = "Honk your classy horn."
|
||||
button_icon_state = "car_horn"
|
||||
var/hornsound = 'sound/items/carhorn.ogg'
|
||||
var/last_honk_time
|
||||
|
||||
/datum/action/vehicle/sealed/horn/Trigger()
|
||||
if(world.time - last_honk_time > 20)
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] loudly honks</span>")
|
||||
to_chat(owner, "<span class='notice'>You press the vehicle's horn.</span>")
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
last_honk_time = world.time
|
||||
|
||||
/datum/action/vehicle/sealed/horn/clowncar/Trigger()
|
||||
if(world.time - last_honk_time > 20)
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] loudly honks</span>")
|
||||
to_chat(owner, "<span class='notice'>You press the vehicle's horn.</span>")
|
||||
last_honk_time = world.time
|
||||
if(vehicle_target.inserted_key)
|
||||
vehicle_target.inserted_key.attack_self(owner) //The key plays a sound
|
||||
else
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
|
||||
/datum/action/vehicle/sealed/DumpKidnappedMobs
|
||||
name = "Dump kidnapped mobs"
|
||||
desc = "Dump all objects and people in your car on the floor."
|
||||
button_icon_state = "car_dump"
|
||||
|
||||
/datum/action/vehicle/sealed/DumpKidnappedMobs/Trigger()
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] starts dumping the people inside of it.</span>")
|
||||
vehicle_entered_target.DumpSpecificMobs(VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 31 KiB |
BIN
sound/vehicles/carrev.ogg
Normal file
BIN
sound/vehicles/carrev.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_crash1.ogg
Normal file
BIN
sound/vehicles/clowncar_crash1.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_crash2.ogg
Normal file
BIN
sound/vehicles/clowncar_crash2.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_crashpins.ogg
Normal file
BIN
sound/vehicles/clowncar_crashpins.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_fart.ogg
Normal file
BIN
sound/vehicles/clowncar_fart.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_load1.ogg
Normal file
BIN
sound/vehicles/clowncar_load1.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_load2.ogg
Normal file
BIN
sound/vehicles/clowncar_load2.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_ram1.ogg
Normal file
BIN
sound/vehicles/clowncar_ram1.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_ram2.ogg
Normal file
BIN
sound/vehicles/clowncar_ram2.ogg
Normal file
Binary file not shown.
BIN
sound/vehicles/clowncar_ram3.ogg
Normal file
BIN
sound/vehicles/clowncar_ram3.ogg
Normal file
Binary file not shown.
@@ -97,6 +97,7 @@
|
||||
#include "code\__DEFINES\traits.dm"
|
||||
#include "code\__DEFINES\turf_flags.dm"
|
||||
#include "code\__DEFINES\typeids.dm"
|
||||
#include "code\__DEFINES\vehicles.dm"
|
||||
#include "code\__DEFINES\vv.dm"
|
||||
#include "code\__DEFINES\wall_dents.dm"
|
||||
#include "code\__DEFINES\wires.dm"
|
||||
@@ -2653,6 +2654,8 @@
|
||||
#include "code\modules\vehicles\speedbike.dm"
|
||||
#include "code\modules\vehicles\vehicle_actions.dm"
|
||||
#include "code\modules\vehicles\vehicle_key.dm"
|
||||
#include "code\modules\vehicles\cars\car.dm"
|
||||
#include "code\modules\vehicles\cars\clowncar.dm"
|
||||
#include "code\modules\vending\_vending.dm"
|
||||
#include "code\modules\vending\assist.dm"
|
||||
#include "code\modules\vending\autodrobe.dm"
|
||||
|
||||
Reference in New Issue
Block a user