mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Remains of player blob axed. blob_act() axed. Blob now has an arbitary set of things it can attack. It will flow over everything else. Blob has an awful tendency to destroy non-craftables. Will test more tomorrow. Blob will now attack mechs. Fixes #8106. Fixes #10705.
361 lines
9.1 KiB
Plaintext
361 lines
9.1 KiB
Plaintext
//Dummy object for holding items in vehicles.
|
|
//Prevents items from being interacted with.
|
|
/datum/vehicle_dummy_load
|
|
var/name = "dummy load"
|
|
var/actual_load
|
|
|
|
/obj/vehicle
|
|
name = "vehicle"
|
|
icon = 'icons/obj/vehicles.dmi'
|
|
layer = MOB_LAYER + 0.1 //so it sits above objects including mobs
|
|
density = 1
|
|
anchored = 1
|
|
animate_movement=1
|
|
light_range = 3
|
|
|
|
can_buckle = 1
|
|
buckle_movable = 1
|
|
buckle_lying = 0
|
|
|
|
var/attack_log = null
|
|
var/on = 0
|
|
var/health = 0 //do not forget to set health for your vehicle!
|
|
var/maxhealth = 0
|
|
var/fire_dam_coeff = 1.0
|
|
var/brute_dam_coeff = 1.0
|
|
var/open = 0 //Maint panel
|
|
var/locked = 1
|
|
var/stat = 0
|
|
var/emagged = 0
|
|
var/powered = 0 //set if vehicle is powered and should use fuel when moving
|
|
var/move_delay = 1 //set this to limit the speed of the vehicle
|
|
|
|
var/obj/item/weapon/cell/cell
|
|
var/charge_use = 5 //set this to adjust the amount of power the vehicle uses per move
|
|
|
|
var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable
|
|
var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite
|
|
var/load_offset_x = 0 //pixel_x offset for item overlay
|
|
var/load_offset_y = 0 //pixel_y offset for item overlay
|
|
var/mob_offset_y = 0 //pixel_y offset for mob overlay
|
|
|
|
//-------------------------------------------
|
|
// Standard procs
|
|
//-------------------------------------------
|
|
/obj/vehicle/New()
|
|
..()
|
|
//spawn the cell you want in each vehicle
|
|
|
|
/obj/vehicle/Move()
|
|
if(world.time > l_move_time + move_delay)
|
|
var/old_loc = get_turf(src)
|
|
if(on && powered && cell.charge < charge_use)
|
|
turn_off()
|
|
|
|
var/init_anc = anchored
|
|
anchored = 0
|
|
if(!..())
|
|
anchored = init_anc
|
|
return 0
|
|
|
|
set_dir(get_dir(old_loc, loc))
|
|
anchored = init_anc
|
|
|
|
if(on && powered)
|
|
cell.use(charge_use)
|
|
|
|
//Dummy loads do not have to be moved as they are just an overlay
|
|
//See load_object() proc in cargo_trains.dm for an example
|
|
if(load && !istype(load, /datum/vehicle_dummy_load))
|
|
load.forceMove(loc)
|
|
load.set_dir(dir)
|
|
|
|
return 1
|
|
else
|
|
return 0
|
|
|
|
/obj/vehicle/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
|
if(istype(W, /obj/item/weapon/hand_labeler))
|
|
return
|
|
if(istype(W, /obj/item/weapon/screwdriver))
|
|
if(!locked)
|
|
open = !open
|
|
update_icon()
|
|
user << "<span class='notice'>Maintenance panel is now [open ? "opened" : "closed"].</span>"
|
|
else if(istype(W, /obj/item/weapon/crowbar) && cell && open)
|
|
remove_cell(user)
|
|
|
|
else if(istype(W, /obj/item/weapon/cell) && !cell && open)
|
|
insert_cell(W, user)
|
|
else if(istype(W, /obj/item/weapon/weldingtool))
|
|
var/obj/item/weapon/weldingtool/T = W
|
|
if(T.welding)
|
|
if(health < maxhealth)
|
|
if(open)
|
|
health = min(maxhealth, health+10)
|
|
user.visible_message("\red [user] repairs [src]!","\blue You repair [src]!")
|
|
else
|
|
user << "<span class='notice'>Unable to repair with the maintenance panel closed.</span>"
|
|
else
|
|
user << "<span class='notice'>[src] does not need a repair.</span>"
|
|
else
|
|
user << "<span class='notice'>Unable to repair while [src] is off.</span>"
|
|
else if(hasvar(W,"force") && hasvar(W,"damtype"))
|
|
switch(W.damtype)
|
|
if("fire")
|
|
health -= W.force * fire_dam_coeff
|
|
if("brute")
|
|
health -= W.force * brute_dam_coeff
|
|
..()
|
|
healthcheck()
|
|
else
|
|
..()
|
|
|
|
/obj/vehicle/bullet_act(var/obj/item/projectile/Proj)
|
|
health -= Proj.get_structure_damage()
|
|
..()
|
|
healthcheck()
|
|
|
|
/obj/vehicle/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
explode()
|
|
return
|
|
if(2.0)
|
|
health -= rand(5,10)*fire_dam_coeff
|
|
health -= rand(10,20)*brute_dam_coeff
|
|
healthcheck()
|
|
return
|
|
if(3.0)
|
|
if (prob(50))
|
|
health -= rand(1,5)*fire_dam_coeff
|
|
health -= rand(1,5)*brute_dam_coeff
|
|
healthcheck()
|
|
return
|
|
return
|
|
|
|
/obj/vehicle/emp_act(severity)
|
|
var/was_on = on
|
|
stat |= EMPED
|
|
var/obj/effect/overlay/pulse2 = PoolOrNew(/obj/effect/overlay, src.loc)
|
|
pulse2.icon = 'icons/effects/effects.dmi'
|
|
pulse2.icon_state = "empdisable"
|
|
pulse2.name = "emp sparks"
|
|
pulse2.anchored = 1
|
|
pulse2.set_dir(pick(cardinal))
|
|
|
|
spawn(10)
|
|
qdel(pulse2)
|
|
if(on)
|
|
turn_off()
|
|
spawn(severity*300)
|
|
stat &= ~EMPED
|
|
if(was_on)
|
|
turn_on()
|
|
|
|
/obj/vehicle/attack_ai(mob/user as mob)
|
|
return
|
|
|
|
// For downstream compatibility (in particular Paradise)
|
|
/obj/vehicle/proc/handle_rotation()
|
|
return
|
|
|
|
//-------------------------------------------
|
|
// Vehicle procs
|
|
//-------------------------------------------
|
|
/obj/vehicle/proc/turn_on()
|
|
if(stat)
|
|
return 0
|
|
if(powered && cell.charge < charge_use)
|
|
return 0
|
|
on = 1
|
|
set_light(initial(light_range))
|
|
update_icon()
|
|
return 1
|
|
|
|
/obj/vehicle/proc/turn_off()
|
|
on = 0
|
|
set_light(0)
|
|
update_icon()
|
|
|
|
/obj/vehicle/emag_act(var/remaining_charges, mob/user as mob)
|
|
if(!emagged)
|
|
emagged = 1
|
|
if(locked)
|
|
locked = 0
|
|
user << "<span class='warning'>You bypass [src]'s controls.</span>"
|
|
return 1
|
|
|
|
/obj/vehicle/proc/explode()
|
|
src.visible_message("\red <B>[src] blows apart!</B>", 1)
|
|
var/turf/Tsec = get_turf(src)
|
|
|
|
PoolOrNew(/obj/item/stack/rods, Tsec)
|
|
PoolOrNew(/obj/item/stack/rods, Tsec)
|
|
new /obj/item/stack/cable_coil/cut(Tsec)
|
|
|
|
if(cell)
|
|
cell.forceMove(Tsec)
|
|
cell.update_icon()
|
|
cell = null
|
|
|
|
//stuns people who are thrown off a train that has been blown up
|
|
if(istype(load, /mob/living))
|
|
var/mob/living/M = load
|
|
M.apply_effects(5, 5)
|
|
|
|
unload()
|
|
|
|
new /obj/effect/gibspawner/robot(Tsec)
|
|
new /obj/effect/decal/cleanable/blood/oil(src.loc)
|
|
|
|
qdel(src)
|
|
|
|
/obj/vehicle/proc/healthcheck()
|
|
if(health <= 0)
|
|
explode()
|
|
|
|
/obj/vehicle/proc/powercheck()
|
|
if(!cell && !powered)
|
|
return
|
|
|
|
if(!cell && powered)
|
|
turn_off()
|
|
return
|
|
|
|
if(cell.charge < charge_use)
|
|
turn_off()
|
|
return
|
|
|
|
if(cell && powered)
|
|
turn_on()
|
|
return
|
|
|
|
/obj/vehicle/proc/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
|
|
if(cell)
|
|
return
|
|
if(!istype(C))
|
|
return
|
|
|
|
H.drop_from_inventory(C)
|
|
C.forceMove(src)
|
|
cell = C
|
|
powercheck()
|
|
usr << "<span class='notice'>You install [C] in [src].</span>"
|
|
|
|
/obj/vehicle/proc/remove_cell(var/mob/living/carbon/human/H)
|
|
if(!cell)
|
|
return
|
|
|
|
usr << "<span class='notice'>You remove [cell] from [src].</span>"
|
|
cell.forceMove(get_turf(H))
|
|
H.put_in_hands(cell)
|
|
cell = null
|
|
powercheck()
|
|
|
|
/obj/vehicle/proc/RunOver(var/mob/living/carbon/human/H)
|
|
return //write specifics for different vehicles
|
|
|
|
//-------------------------------------------
|
|
// Loading/unloading procs
|
|
//
|
|
// Set specific item restriction checks in
|
|
// the vehicle load() definition before
|
|
// calling this parent proc.
|
|
//-------------------------------------------
|
|
/obj/vehicle/proc/load(var/atom/movable/C)
|
|
//This loads objects onto the vehicle so they can still be interacted with.
|
|
//Define allowed items for loading in specific vehicle definitions.
|
|
if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly.
|
|
return 0
|
|
if(load || C.anchored)
|
|
return 0
|
|
|
|
// if a create/closet, close before loading
|
|
var/obj/structure/closet/crate = C
|
|
if(istype(crate))
|
|
crate.close()
|
|
|
|
C.forceMove(loc)
|
|
C.set_dir(dir)
|
|
C.anchored = 1
|
|
|
|
load = C
|
|
|
|
if(load_item_visible)
|
|
C.pixel_x += load_offset_x
|
|
if(ismob(C))
|
|
C.pixel_y += mob_offset_y
|
|
else
|
|
C.pixel_y += load_offset_y
|
|
C.layer = layer + 0.1 //so it sits above the vehicle
|
|
|
|
if(ismob(C))
|
|
buckle_mob(C)
|
|
|
|
return 1
|
|
|
|
|
|
/obj/vehicle/proc/unload(var/mob/user, var/direction)
|
|
if(!load)
|
|
return
|
|
|
|
var/turf/dest = null
|
|
|
|
//find a turf to unload to
|
|
if(direction) //if direction specified, unload in that direction
|
|
dest = get_step(src, direction)
|
|
else if(user) //if a user has unloaded the vehicle, unload at their feet
|
|
dest = get_turf(user)
|
|
|
|
if(!dest)
|
|
dest = get_step_to(src, get_step(src, turn(dir, 90))) //try unloading to the side of the vehicle first if neither of the above are present
|
|
|
|
//if these all result in the same turf as the vehicle or nullspace, pick a new turf with open space
|
|
if(!dest || dest == get_turf(src))
|
|
var/list/options = new()
|
|
for(var/test_dir in alldirs)
|
|
var/new_dir = get_step_to(src, get_step(src, test_dir))
|
|
if(new_dir && load.Adjacent(new_dir))
|
|
options += new_dir
|
|
if(options.len)
|
|
dest = pick(options)
|
|
else
|
|
dest = get_turf(src) //otherwise just dump it on the same turf as the vehicle
|
|
|
|
if(!isturf(dest)) //if there still is nowhere to unload, cancel out since the vehicle is probably in nullspace
|
|
return 0
|
|
|
|
load.forceMove(dest)
|
|
load.set_dir(get_dir(loc, dest))
|
|
load.anchored = 0 //we can only load non-anchored items, so it makes sense to set this to false
|
|
load.pixel_x = initial(load.pixel_x)
|
|
load.pixel_y = initial(load.pixel_y)
|
|
load.layer = initial(load.layer)
|
|
|
|
if(ismob(load))
|
|
unbuckle_mob(load)
|
|
|
|
load = null
|
|
|
|
return 1
|
|
|
|
|
|
//-------------------------------------------------------
|
|
// Stat update procs
|
|
//-------------------------------------------------------
|
|
/obj/vehicle/proc/update_stats()
|
|
return
|
|
|
|
/obj/vehicle/attack_generic(var/mob/user, var/damage, var/attack_message)
|
|
if(!damage)
|
|
return
|
|
visible_message("<span class='danger'>[user] [attack_message] the [src]!</span>")
|
|
user.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name]</font>")
|
|
user.do_attack_animation(src)
|
|
src.health -= damage
|
|
if(prob(10))
|
|
new /obj/effect/decal/cleanable/blood/oil(src.loc)
|
|
spawn(1) healthcheck()
|
|
return 1
|