mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-25 00:51:55 +00:00
* FOV is Dead (Long Live FOV) * Update _megafauna.dm * Update _vehicle.dm * FOV Hotfix: Actually offsets gameplane render relays * removes redundant visual_shadow * removes GAME_PLANE_UPPER references * Update mob_movement.dm --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
268 lines
8.5 KiB
Plaintext
268 lines
8.5 KiB
Plaintext
/// DEPLOYABLE TURRET (FORMERLY MANNED TURRET)
|
|
//All of this file is five year old shitcode, and I'm too scared to touch more than I have to
|
|
|
|
/obj/machinery/deployable_turret
|
|
name = "machine gun turret"
|
|
desc = "While the trigger is held down, this gun will redistribute recoil to allow its user to easily shift targets."
|
|
icon = 'icons/obj/weapons/turrets.dmi'
|
|
icon_state = "machinegun"
|
|
can_buckle = TRUE
|
|
anchored = FALSE
|
|
density = TRUE
|
|
max_integrity = 100
|
|
buckle_lying = 0
|
|
layer = ABOVE_MOB_LAYER
|
|
var/view_range = 2.5
|
|
var/cooldown = 0
|
|
/// The projectile that the turret fires
|
|
var/projectile_type = /obj/projectile/bullet/manned_turret
|
|
/// Delay between shots in a burst
|
|
var/rate_of_fire = 1
|
|
/// Number of shots fired from one click
|
|
var/number_of_shots = 40
|
|
/// How long it takes for the gun to allow firing after a burst
|
|
var/cooldown_duration = 9 SECONDS
|
|
var/atom/target
|
|
var/turf/target_turf
|
|
var/warned = FALSE
|
|
var/list/calculated_projectile_vars
|
|
/// Sound to play at the end of a burst
|
|
var/overheatsound = 'sound/weapons/sear.ogg'
|
|
/// Sound to play when firing
|
|
var/firesound = 'sound/weapons/gun/smg/shot.ogg'
|
|
/// If using a wrench on the turret will start undeploying it
|
|
var/can_be_undeployed = FALSE
|
|
/// What gets spawned if the object is undeployed
|
|
var/obj/spawned_on_undeploy
|
|
/// How long it takes for a wrench user to undeploy the object
|
|
var/undeploy_time = 3 SECONDS
|
|
/// If TRUE, the turret will not become unanchored when not mounted
|
|
var/always_anchored = FALSE
|
|
|
|
/obj/machinery/deployable_turret/Initialize(mapload)
|
|
. = ..()
|
|
if(always_anchored)
|
|
set_anchored(TRUE)
|
|
|
|
/obj/machinery/deployable_turret/Destroy()
|
|
target = null
|
|
target_turf = null
|
|
return ..()
|
|
|
|
/// Undeploying, for when you want to move your big dakka around
|
|
/obj/machinery/deployable_turret/wrench_act(mob/living/user, obj/item/wrench/used_wrench)
|
|
. = ..()
|
|
if(!can_be_undeployed)
|
|
return
|
|
if(!ishuman(user))
|
|
return
|
|
used_wrench.play_tool_sound(user)
|
|
user.balloon_alert(user, "undeploying...")
|
|
if(!do_after(user, undeploy_time))
|
|
return
|
|
var/obj/undeployed_object = new spawned_on_undeploy(src)
|
|
//Keeps the health the same even if you redeploy the gun
|
|
undeployed_object.modify_max_integrity(max_integrity)
|
|
qdel(src)
|
|
|
|
//BUCKLE HOOKS
|
|
|
|
/obj/machinery/deployable_turret/unbuckle_mob(mob/living/buckled_mob, force = FALSE, can_fall = TRUE)
|
|
playsound(src,'sound/mecha/mechmove01.ogg', 50, TRUE)
|
|
for(var/obj/item/I in buckled_mob.held_items)
|
|
if(istype(I, /obj/item/gun_control))
|
|
qdel(I)
|
|
if(istype(buckled_mob))
|
|
buckled_mob.pixel_x = buckled_mob.base_pixel_x
|
|
buckled_mob.pixel_y = buckled_mob.base_pixel_y
|
|
if(buckled_mob.client)
|
|
buckled_mob.client.view_size.resetToDefault()
|
|
if(!always_anchored)
|
|
set_anchored(FALSE)
|
|
. = ..()
|
|
STOP_PROCESSING(SSfastprocess, src)
|
|
|
|
/obj/machinery/deployable_turret/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
|
|
if(user.incapacitated() || !istype(user))
|
|
return
|
|
M.forceMove(get_turf(src))
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
for(var/V in M.held_items)
|
|
var/obj/item/I = V
|
|
if(istype(I))
|
|
if(M.dropItemToGround(I))
|
|
var/obj/item/gun_control/TC = new(src)
|
|
M.put_in_hands(TC)
|
|
else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand
|
|
var/obj/item/gun_control/TC = new(src)
|
|
M.put_in_hands(TC)
|
|
M.pixel_y = 14
|
|
layer = ABOVE_MOB_LAYER
|
|
setDir(SOUTH)
|
|
playsound(src,'sound/mecha/mechmove01.ogg', 50, TRUE)
|
|
set_anchored(TRUE)
|
|
if(M.client)
|
|
M.client.view_size.setTo(view_range)
|
|
START_PROCESSING(SSfastprocess, src)
|
|
|
|
/obj/machinery/deployable_turret/process()
|
|
if (!update_positioning())
|
|
return PROCESS_KILL
|
|
|
|
/obj/machinery/deployable_turret/proc/update_positioning()
|
|
if (!LAZYLEN(buckled_mobs))
|
|
return FALSE
|
|
var/mob/living/controller = buckled_mobs[1]
|
|
if(!istype(controller))
|
|
return FALSE
|
|
var/client/controlling_client = controller.client
|
|
if(controlling_client)
|
|
var/modifiers = params2list(controlling_client.mouseParams)
|
|
var/atom/target_atom = controlling_client.mouse_object_ref?.resolve()
|
|
var/turf/target_turf = get_turf(target_atom)
|
|
if(istype(target_turf)) //They're hovering over something in the map.
|
|
direction_track(controller, target_turf)
|
|
calculated_projectile_vars = calculate_projectile_angle_and_pixel_offsets(controller, target_turf, modifiers)
|
|
|
|
/obj/machinery/deployable_turret/proc/direction_track(mob/user, atom/targeted)
|
|
if(user.incapacitated())
|
|
return
|
|
setDir(get_dir(src,targeted))
|
|
user.setDir(dir)
|
|
switch(dir)
|
|
if(NORTH)
|
|
layer = BELOW_MOB_LAYER
|
|
user.pixel_x = 0
|
|
user.pixel_y = -14
|
|
if(NORTHEAST)
|
|
layer = BELOW_MOB_LAYER
|
|
user.pixel_x = -8
|
|
user.pixel_y = -4
|
|
if(EAST)
|
|
layer = ABOVE_MOB_LAYER
|
|
user.pixel_x = -14
|
|
user.pixel_y = 0
|
|
if(SOUTHEAST)
|
|
layer = BELOW_MOB_LAYER
|
|
user.pixel_x = -8
|
|
user.pixel_y = 4
|
|
if(SOUTH)
|
|
layer = ABOVE_MOB_LAYER
|
|
user.pixel_x = 0
|
|
user.pixel_y = 14
|
|
if(SOUTHWEST)
|
|
layer = BELOW_MOB_LAYER
|
|
user.pixel_x = 8
|
|
user.pixel_y = 4
|
|
if(WEST)
|
|
layer = ABOVE_MOB_LAYER
|
|
user.pixel_x = 14
|
|
user.pixel_y = 0
|
|
if(NORTHWEST)
|
|
layer = BELOW_MOB_LAYER
|
|
user.pixel_x = 8
|
|
user.pixel_y = -4
|
|
|
|
/obj/machinery/deployable_turret/proc/checkfire(atom/targeted_atom, mob/user)
|
|
target = targeted_atom
|
|
if(target == user || user.incapacitated() || target == get_turf(src))
|
|
return
|
|
if(world.time < cooldown)
|
|
if(!warned && world.time > (cooldown - cooldown_duration + rate_of_fire*number_of_shots)) // To capture the window where one is done firing
|
|
warned = TRUE
|
|
playsound(src, overheatsound, 100, TRUE)
|
|
return
|
|
else
|
|
cooldown = world.time + cooldown_duration
|
|
warned = FALSE
|
|
volley(user)
|
|
|
|
/obj/machinery/deployable_turret/proc/volley(mob/user)
|
|
target_turf = get_turf(target)
|
|
for(var/i in 1 to number_of_shots)
|
|
addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/deployable_turret/, fire_helper), user), i*rate_of_fire)
|
|
|
|
/obj/machinery/deployable_turret/proc/fire_helper(mob/user)
|
|
if(user.incapacitated() || !(user in buckled_mobs))
|
|
return
|
|
update_positioning() //REFRESH MOUSE TRACKING!!
|
|
var/turf/targets_from = get_turf(src)
|
|
if(QDELETED(target))
|
|
target = target_turf
|
|
var/obj/projectile/projectile_to_fire = new projectile_type(targets_from)
|
|
playsound(src, firesound, 75, TRUE)
|
|
projectile_to_fire.preparePixelProjectile(target, targets_from)
|
|
projectile_to_fire.firer = user
|
|
projectile_to_fire.fired_from = src
|
|
projectile_to_fire.fire()
|
|
|
|
/obj/machinery/deployable_turret/ultimate // Admin-only proof of concept for autoclicker automatics
|
|
name = "Infinity Gun"
|
|
view_range = 12
|
|
|
|
/obj/machinery/deployable_turret/ultimate/checkfire(atom/targeted_atom, mob/user)
|
|
target = targeted_atom
|
|
if(target == user || target == get_turf(src))
|
|
return
|
|
target_turf = get_turf(target)
|
|
fire_helper(user)
|
|
|
|
/obj/machinery/deployable_turret/hmg
|
|
name = "heavy machine gun turret"
|
|
desc = "A heavy calibre machine gun commonly used by Nanotrasen forces, famed for it's ability to give people on the recieving end more holes than normal."
|
|
icon_state = "hmg"
|
|
max_integrity = 250
|
|
projectile_type = /obj/projectile/bullet/manned_turret/hmg
|
|
anchored = TRUE
|
|
number_of_shots = 3
|
|
cooldown_duration = 2 SECONDS
|
|
rate_of_fire = 2
|
|
firesound = 'sound/weapons/gun/hmg/hmg.ogg'
|
|
overheatsound = 'sound/weapons/gun/smg/smgrack.ogg'
|
|
can_be_undeployed = TRUE
|
|
spawned_on_undeploy = /obj/item/deployable_turret_folded
|
|
|
|
/obj/item/gun_control
|
|
name = "turret controls"
|
|
icon = 'icons/obj/weapons/hand.dmi'
|
|
icon_state = "offhand"
|
|
w_class = WEIGHT_CLASS_HUGE
|
|
item_flags = ABSTRACT | NOBLUDGEON | DROPDEL
|
|
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
|
var/obj/machinery/deployable_turret/turret
|
|
|
|
/obj/item/gun_control/Initialize(mapload)
|
|
. = ..()
|
|
ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
|
|
turret = loc
|
|
if(!istype(turret))
|
|
return INITIALIZE_HINT_QDEL
|
|
|
|
/obj/item/gun_control/Destroy()
|
|
turret = null
|
|
return ..()
|
|
|
|
/obj/item/gun_control/CanItemAutoclick()
|
|
return TRUE
|
|
|
|
/obj/item/gun_control/attack_atom(obj/O, mob/living/user, params)
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
O.attacked_by(src, user)
|
|
|
|
/obj/item/gun_control/attack(mob/living/M, mob/living/user)
|
|
M.lastattacker = user.real_name
|
|
M.lastattackerckey = user.ckey
|
|
M.attacked_by(src, user)
|
|
add_fingerprint(user)
|
|
|
|
/obj/item/gun_control/afterattack(atom/targeted_atom, mob/user, flag, params)
|
|
. = ..()
|
|
. |= AFTERATTACK_PROCESSED_ITEM
|
|
var/modifiers = params2list(params)
|
|
var/obj/machinery/deployable_turret/E = user.buckled
|
|
E.calculated_projectile_vars = calculate_projectile_angle_and_pixel_offsets(user, targeted_atom, modifiers)
|
|
E.direction_track(user, targeted_atom)
|
|
E.checkfire(targeted_atom, user)
|